text:
Bootloader problem on Arduino Uno?
Since today, my Arduino Uno (using Arduino IDE version 1.8.13) lost the capacity to store a sketch upon physical disconnection (does not include button reset).
This means, the sketch works properly but when I unplug it and plug it back again, the Arduino will act as if I uploaded a blank sketch by blinking 3 times fast repeatedly.
To check this, I tried several examples like "Blink" on Windows 10 and Ubuntu and repeats the error.
I feel there is something wrong with the bootloader or something like that, but I'm finding hard to understand some concepts.
Does anyone recognizes what is happening on the Arduino? What can I do to address the problem?
Summary:

Uploads fine.
Works fine.
Resets fine.
Hard-resets INCORRECTLY (can't plug and unplug and expect the program will still work).
Keeps working good until loss of power.

did you ask this same question several hours ago?

What happens if you use just a simple USB wall wart to power the Arduino?

@thebusybee Just tried, and the same thing happens

@jsotola I did but it was unaccurate to the point that nobody would answer, sorry about that.

Hm, strange.I would expect that a reset by the button has the same effect as a power cycle. Sorry, I have no idea currently.


text:
How to Set RTC in ES32 using NTP server?
I am working on ESP32 And want to set RTC from the NTP server. How can I get epoch value I have done this thing on CC3200 launchpad and used an NTP server library to obtain epoch value.

this snippet from setup() sets on esp32 the NTP for internal RTC and uses epoch seconds to set time to TimeLib library.
  configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
  time_t now = time(nullptr);
  while (now < SECS_YR_2000) {
    delay(100);
    now = time(nullptr);
  }
  setTime(now);

The ESP32 examples library in IDE examples folder has example SimpleTime.

Is configTime() a blocking function? Seems like it would have to be, seeing as how the Arduino is not a multi-tasking system.

@DuncanC, it is not blocking as you can see on the following while cycle. esp32 core is on esp32 RTOS SDK. arduino is one thread but configTime is a C function from SDK, so the function only activates SNTP

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Holding buttons (keyboard)
I made a wireless keyboard, but I just need 4 button for my project: left control, left shift, F1, F2.
The problem: When I hold button - it acts like many key presses and releases, but I need, that when I press & hold button - it also acts like I press & hold it.
Could you please help me?
Here is source code:
Transfer_e5.ino:  https://www.paste.org/108039
Receiver_e5.ino:  https://www.paste.org/108040
Or 1 rar package:
https://easyupload.io/o3c5sp
Thank you
Or I can put them just here, if you wish.
Receiver:
#include <Keyboard.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7); // (ce,cs)
RF24Network network(radio);

const uint16_t this_node = 00;
const uint16_t other_node = 03;

unsigned int laser_state=0;
const unsigned long my_interval = 500;
unsigned long last_sent;
unsigned int income=0;

void setup(void)
{
  Serial.begin(115200);
  pinMode(9,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);

  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
}

void loop(void){
  digitalWrite(4,LOW);
  network.update();

  if ( network.available() ) {
    RF24NetworkHeader header;
    network.read(header,&income,sizeof(income));

    if(income==10){
      Serial.println("f1");
      Keyboard.press(KEY_F1);
      income=0;
    }

    if(income==11){
      Serial.println("f2");
      Keyboard.press(KEY_F2);
      income=0;
    }

    if(income==12){
      Serial.println("ctrl");
      Keyboard.press(KEY_LEFT_CTRL);
      income=0;
    }

    if(income==13){
      Serial.println("shift");
      Keyboard.press(KEY_LEFT_SHIFT);
      income=0;
    }

    Keyboard.releaseAll();
  }

  unsigned long now = millis();

  if ( now - last_sent >= my_interval  )
  {
//    Serial.print("pin ");
//    Serial.println(digitalRead(9));
    last_sent = now;
    laser_state = digitalRead(9);

    RF24NetworkHeader header(other_node);
    bool ok = network.write(header,&laser_state,sizeof(laser_state));
  }
}

Transfer
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7);
RF24Network network(radio);

const uint16_t this_node = 03;
const uint16_t other_node = 00;

unsigned int laser_state=0;
const unsigned long interval = 5;
unsigned long last_sent;

unsigned int b1=1;
unsigned int b2=1;
unsigned int b3=1;
unsigned int b4=1;

unsigned int d1=10;
unsigned int d2=11;
unsigned int d3=12;
unsigned int d4=13;

//TR1
int btn1 = 3;
int btn2 = 4;
int btn3 = 5;
int btn4 = 6;

void setup(void)
{
//  Serial.begin(9600);
  pinMode(btn1,INPUT_PULLUP);
  pinMode(btn2,INPUT_PULLUP);
  pinMode(btn3,INPUT_PULLUP);
  pinMode(btn4,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);
}

void loop(void){
  network.update();

  unsigned long now = millis();

  if ( now - last_sent >= interval  )
  {
    last_sent = now;

    b1 = digitalRead(btn1);
    b2 = digitalRead(btn2);
    b3 = digitalRead(btn3);
    b4 = digitalRead(btn4);

    if(b1==0){
//      Serial.println("F1");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d1,sizeof(d1));
    }

    if(b2==0){
//      Serial.println("F2");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d2,sizeof(d2));
    }

     if(b3==0){
//      Serial.println("Ctrl");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d3,sizeof(d3));
    }

    if(b4==0){
//      Serial.println("Shift");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d4,sizeof(d4));
    }
  }
}

I am NOT downloading some random RAR file from some random site. Post your code here if you want any help.

your right   , lol

i add codes  to the note  , thanks again

The root problem is that you send each several ms new key event and on receiver each time you get this event, you call Keyboard.press and right away Keyboard.release. So, it behaves as several key press-releases.
At sender side you should send 2 types of events:

Key pressed (and which button)
Key released (and which button)

At receiver side you should

When you receive "press" event, call Keyboard.press, and don't call Keyboard.release
When you receive "release" event, call Keyboard.release

Edit: I've made changes to your source code, please, try it
Transfer
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7);
RF24Network network(radio);

const uint16_t this_node = 03;
const uint16_t other_node = 00;

unsigned int laser_state=0;
const unsigned long interval = 5;
unsigned long last_sent;

unsigned int b1=1;
unsigned int b2=1;
unsigned int b3=1;
unsigned int b4=1;

unsigned int d1=10;
unsigned int d2=11;
unsigned int d3=12;
unsigned int d4=13;

//TR1
int btn1 = 3;
int btn2 = 4;
int btn3 = 5;
int btn4 = 6;

void setup(void)
{
//  Serial.begin(9600);
  pinMode(btn1,INPUT_PULLUP);
  pinMode(btn2,INPUT_PULLUP);
  pinMode(btn3,INPUT_PULLUP);
  pinMode(btn4,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);
}

void loop(void){
  network.update();

  unsigned long now = millis();

  if (now - last_sent >= interval)
  {
    last_sent = now;

    auto newB1 = digitalRead(btn1);
    auto newB2 = digitalRead(btn2);
    auto newB3 = digitalRead(btn3);
    auto newB4 = digitalRead(btn4);

    unsigned int packet[2];

    if(newB1 != b1){
//      Serial.println("F1");
      packet[0] = d1;
      packet[1] = newB1;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    if(newB2 != b2){
//      Serial.println("F2");
      packet[0] = d2;
      packet[1] = newB2;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

     if(newB3 != b3){
//      Serial.println("Ctrl");
      packet[0] = d3;
      packet[1] = newB3;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    if(newB4 != b4){
//      Serial.println("Shift");
      packet[0] = d4;
      packet[1] = newB4;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    b1 = newB1;
    b2 = newB2;
    b3 = newB3;
    b4 = newB4;
  }
}

Receiver
#include <Keyboard.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7); // (ce,cs)
RF24Network network(radio);

const uint16_t this_node = 00;
const uint16_t other_node = 03;

unsigned int laser_state=0;
const unsigned long my_interval = 500;
unsigned long last_sent;

void setup(void)
{
  Serial.begin(115200);
  pinMode(9,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);

  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
}

void loop(void){
  digitalWrite(4,LOW);
  network.update();

  unsigned int income[2] = {0, 0};

  if ( network.available() ) {
    RF24NetworkHeader header;
    network.read(header,&income,sizeof(income));

    auto keyCode = income[0];
    auto keyPress = !income[1];

    if(keyCode == 10){
      Serial.println("f1");

      if (keyPress) {
        Keyboard.press(KEY_F1);
      } else {
        Keyboard.release(KEY_F1);
      }
    }

    if(keyCode == 11){
      Serial.println("f2");

      if (keyPress) {
        Keyboard.press(KEY_F2);
      } else {
        Keyboard.release(KEY_F2);
      }
    }

    if(keyCode == 12){
      Serial.println("ctrl");

      if (keyPress) {
        Keyboard.press(KEY_LEFT_CTRL);
      } else {
        Keyboard.release(KEY_LEFT_CTRL);
      }
    }

    if(keyCode == 13){
      Serial.println("shift");

      if (keyPress) {
        Keyboard.press(KEY_LEFT_SHIFT);
      } else {
        Keyboard.release(KEY_LEFT_SHIFT);
      }
    }

    keyCode = 0;
  }

  unsigned long now = millis();

  if ( now - last_sent >= my_interval  )
  {
//    Serial.print("pin ");
//    Serial.println(digitalRead(9));
    last_sent = now;
    laser_state = digitalRead(9);

    RF24NetworkHeader header(other_node);
    bool ok = network.write(header,&laser_state,sizeof(laser_state));
  }
}

thanks for answering my question  ,  what i want from this keyboard is while i am holding 3 button together  ( left control +  left shift + F1 ) then i will push F2 button   ,,,    it should work like that   ( i know i sounds stupid   but  i need that ) ,,, i will be greatful  if you could fix the codes  and send them for me  , thanks again

@AminAbbasi done

thanks again and again  , i am in  travel and it takes 2 days ,,  i will check the codes and device  at sunday and report it to you immediately ,   thanks again  and   how can i compensate   ,,, i owe you one

@AminAbbasi glad to help you, hope it will work :) If not - write again and we will try to find out what's wrong!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Can we use UART COMMUNICATION with MCP23017?
I am using MCP23017 as a GPIO expander with Arduino in my project. I have too many serial devices and no pins left on Arduino for UART communication.
I am wondering if I can use this MCP23017 GPIO expander pins for UART communication or not?

with SoftwareSerial? no

I can think of one way.
In theory you could use the GPIO pins of the mcp23017 to control a couple of 2-way multiplexers. With these multiplexers you could split your Rx/Tx pins to more than one serial bus.
May it be obvious that you cannot used the split busses at the same time. So depending on your specific use-case this may or may not be a solution.

No. No you can't. Serial takes precise timing and fast reactions. Things you can't do with a remote device like that.
Instead there are SPI UART devices specifically for the job, such as the MAX3107.


text:
Arduino Nano 33 IoT StandardFirmataPlus
newbie here. So I've been trying to upload StandardFirmataPlus into my Arduino Nano 33 IoT so that I can program in Johnny-Five. However I have this issue.

I've checked that my port is connected and that the libraries are up to date. The docs say that if my board does not enough flash or RAM then the code wouldn't work. The code seems to work fine on other boards which have the same memory such as the Arduino UNO. My board is not a clone. And I've also checked that my Board Manager is set to "SAMD". If anyone has faced this issue and resolved, do share how you did it. Thanks in advance. If I've mentioned anything wrong do correct me =).
EDIT 1: I'm using macOS Catalina 10.15.5. Arduino version 1.8.13. All I did was to try compiling the code. This is the Arduino IDE.
EDIT 2: Error Messages:
In file included from /Users/thebird/Desktop/Code/Arduino1/libraries/Firmata/Firmata.h:17:0,
from /Users/thebird/Desktop/Code/Arduino1/libraries/Firmata/examples/StandardFirmataPlus/StandardFirmataPlus.ino:49:
/Users/thebird/Desktop/Code/Arduino1/libraries/Firmata/Boards.h:824:2: error: #error "Please edit Boards.h with a hardware abstraction for this board"
#error "Please edit Boards.h with a hardware abstraction for this board"
^~~~~
Multiple libraries were found for "Firmata.h"
Used: /Users/thebird/Desktop/Code/Arduino1/libraries/Firmata
Not used: /private/var/folders/kx/l1lw7kfn0t387jt7bd3ccg3h0000gn/T/AppTranslocation/D1572E71-F02B-4F61-BAF9-E73A3ABEB39A/d/Arduino.app/Contents/Java/libraries/Firmata
exit status 1
Error compiling for board Arduino NANO 33 IoT.

what is the issue?  ... you did not include the error message printout

Hello, sorry about that, I thought it was only 2 lines, I've added the error screenshot to my question.

why are you bothering with screenshots? ... it is much easier and much more useful to add the actual text ... screenshot of text cannot be used for doing web searches so most people won't even bother to look at your post

Hello, sorry this is my first time asking a question here. Yeah I've learnt my mistake, thank you =). I've also added the text for the errors.


text:
Serial port usage in code
I want to write a function that defines a serial port based on a flag but I'm not sure it's possible.
For example:
void writeToSerial(bool useSerial1)
{
   SerialPortClass serialPortObject; // Is there some way of defining a generic Serial port object and reusing it below?

   if (useSerial1)
   {
      serialPortObject = Serial1;
   }
   else
   {
      serialPortObject = Serial2;
   }

   serialPortObject.write("test123");
}

Does this answer your question? Passing HardwareSerial and SoftwareSerial as a Class Property

According to sources at c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial* (on Windows platform), you can use pointer to Stream class (because Serials are inherited from Stream).
So, your function could look like this:
void writeToSerial(bool useSerial1)
{
   Stream* serialPortObject;

   if (useSerial1)
   {
      serialPortObject = &Serial1;
   }
   else
   {
      serialPortObject = &Serial2;
   }

   serialPortObject->write("test123");
}

Note that the serial port has to be already initialized for this to work, as Stream lacks the begin() method. If you need to call either begin() or end(), you should use a pointer to HardwareSerial.

This is not a proper answer, but rather a suggestion to reconsider your
approach. The code posted in the question is obviously just a simplified
example, and printing “test123” is likely not your final goal. I assume
what you really want to do is print out some information about some
variables. You can then collect these variables into a data structure (a
C++ object) and make writeToSerial() a method of this object. The
object can the be printed like so:
myDataStructure::writeToSerial(true);   // printed to Serial1
myDataStructure::writeToSerial(false);  // printed to Serial2

In this case, what I suggest is to instead explicitly print() (or
println()) the object to the relevant serial port, like this:
Serial1.print(myDataStructure);
Serial2.print(myDataStructure);

This makes the code self-explanatory, and easier to maintain.
Obviously, you cannot just print arbitrary objects this way, as
Serial1 and Serial2 would have no idea about how to serialize them.
But the thing is, you can teach them! Make your class derive from
Printable, implement the virtual printTo() method, and you will be
able to print it to any serial port, LCD, or whatever understands
print():
class MyDataStructure : public Printable {
public:
    size_t printTo(Print& p) const {
        return p.print("test123");
    }
};

MyDataStructure someData;

void setup() {
    Serial1.begin(9600);
    Serial2.begin(9600);
    Serial1.println(someData);
    Serial2.println(someData);
}

void loop(){}

See the answer to Is it possible to print a custom object by passing it
to Serial.print()? for an example with actual data in the
object.


text:
Arduino Nano 33 Sense won't upload
When I try to upload an example code from the Arduino_LSM9DS1 Library it either jumps ports so the upload cannot complete or spits out some red text and never completes the upload, just gets stuck on uploading.
The red text is:
processing.app.debug.RunnerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2047)
    at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port 'COM5'.
    at processing.app.Serial.touchForCDCReset(Serial.java:107)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
    ... 5 more
Caused by: jssc.SerialPortException: Port name - COM5; Method name - openPort(); Exception type - Port busy.
    at jssc.SerialPort.openPort(SerialPort.java:164)
    at processing.app.Serial.touchForCDCReset(Serial.java:101)
    ... 6 more

I'm not that new to Arduino but I've never looked into uploading (I guess I should) and am struggling to get it to work.
Any help is appreciated, thanks

but you can upload Blink? or did this happen after uploading the Arduino_LSM9DS1 exmple? did you try double reset to activate the bootloader?

With the bootloader active it will still sometimes jump ports either during or after uploading

yes, they do that. is is because the USB is handled by the MCU, not by a separate chip (which would not reset)

ok, so the board should be fine to use


text:
Why is it considered bad practice to use the 'new' keyword in Arduino?
I previously asked this question:
Is it required to delete variables before going to sleep?
On that question, @Delta_G posted this comment:

... Really on a microcontroller I would create the object in a smaller scope and try to do everything in my power to avoid having to use new or any other form of dynamic allocation. .... etc.

That comment got three likes and when I google about dynamic allocation using Arduino, everyone also tries to stay away from that. In summary from all the research I did, my conclusion is now Do not allocate memory unless you really really have to.
I am using the Visual Studio IDE to create my C++ libraries that I intend to use with Arduino. On the Arduino IDE I just reference those libraries and the code compiles great. Visual Studio is very powerful and it enables me to create really nice code, because I can test it on my computer before running it on Arduino. For example, I created this library:
// MyQueue.h

typedef struct QueueItem
{
    void* item;

    QueueItem* next;

    QueueItem()
    {
        item = nullptr;
        next = nullptr;
    }

} QueueItem;

class Queue
{
public:
    unsigned char count;        /* Number of items on queue */
    QueueItem* first;           /* Points to first item on the queue */

    Queue()                     /* Constructor */
    {
        count = 0;
        first = nullptr;
    }

    void enqueue(void* item)    /* Enqueue an object into the queue */
    {
        count++;

        if (first == nullptr)
        {
            first = new QueueItem();
            first->item = item;

            // Log message because we are using the "new" keword. We need to make sure we dispose QueueItem later

            #ifdef windows

            std::cout << "Creating " << first << endl;

            #endif // windows
        }
        else {

            // Find last item
            QueueItem* current = first;
            while (current->next != NULL)
            {
                current = current->next;
            }
            QueueItem* newItem = new QueueItem();
            newItem->item = item;

            // Log message because we are using the "new" keyword. We need to make sure we dispose QueueItem later
            #ifdef windows
            std::cout << "Creating " << newItem << endl;
            #endif // windows

            current->next = newItem;
        }
    }

    void* dequeue()
    {
        if (count == 0)
            return nullptr;

        QueueItem* newFirst = first->next;

        void* pointerToItem = first->item;

        // Log message we are deleting an object because we created it with the 'new' keyword
        #ifdef windows
        std::cout << "Deleting " << first << endl;
        #endif // windows

        delete first;
        first = newFirst;
        count--;

        return pointerToItem;
    }

    void clear()                /* Empty queue */
    {
        while (count > 0)
        {
            dequeue();
        }
    }

    ~Queue()                    /* Destructor. Dispose everything */
    {
        clear();
    }
};

Now on my Arduino sketch, I can have the following code if I reference that header file.
typedef struct Foo
{
    int id;
} Foo;

void someMethod()
{

    Queue q;

    // Create items
    Foo a;
    a.id = 1;

    Foo b;
    b.id = 2;

    // Enqueue a,b and c
    q.enqueue(&a);
    q.enqueue(&b);

    // Deque
    Foo * pointerTo_a = (Foo*)q.dequeue();
    int x = pointerTo_a->id; // =1

    Foo * pointerTo_b = (Foo*)q.dequeue();
    int y = pointerTo_b->id; // =2

    // Error
    Foo * test = (Foo*)q.dequeue();
    // test == null pointer
}

Most people say do not use void pointers. Why!? Because I am using void pointers I can now use this queue class with whatever object I want!
So I guess my question is: Why is everyone trying to stay away and avoid code like this?
I am using the NRF24L01 radio module to send messages to several Arduinos. It is convenient to have a queue of messages to be sent. I would be able to code the same program without allocating memory and avoiding the new keyword. But that code will look ugly in my opinion.
In this quarantine I decided to learn C++ and that has changed the way I code Arduino. The moment I learned C++ I stopped using the Arduino IDE. I been a backed developer for 12 years, and that is the reason why I learned C++ in a couple of months. Arduino is just a hobby for me. I am still very new to microcontrollers and I will like to understand why people stay away from the full power of C++ when it comes to microcontrollers. I know I have only 2 kilobytes of RAM. I will not be allocating that much memory. I still want to take advantage of the C++ programming language by using the new , delete , poineters and destructors`. I want to keep using Visual Studio to write powerful C++ libraries.
In C++ I write interfaces like this
// Note I use uint32_t instead of 'unsigned long' because an unsigned long is different size on Windows than on Arduino. Also I use an unsigned short instead of an int because an unsigned short is the same size on Windows and Arduino.

class IArduinoMethods
{
public:

    // Unsigned long in Arduino
    virtual void delay(uint32_t delayInMilliseconds) = 0;

    virtual void print(const char* text) = 0;

    virtual uint32_t millis() = 0; // Get elapsed time in milliseconds
};

And I then implement the classes like this. For example, this is the class that I will use when testing my code on a windows computer:
// Class to be run on Windows.
class ArduinoMockWindows : public IArduinoMethods
{
public:

    // Inherited via IArduinoMethods
    virtual void delay(uint32_t delayInMilliseconds) override
    {
        // This code will be different on Arduino, and that is why I need this dependency
        Sleep(delayInMilliseconds); // Windows
    }

    virtual uint32_t millis()
    {
        //clock_begin = std::chrono::steady_clock::now();

        std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
        auto duration = now.time_since_epoch();
        // etc..
        return someDuration;

    }

};

Because a Windows computer cannot send NRF24 radio messages, I can implement an interface (dependency) that will write to a file, for example instead of sending a real radio packet just for testing.
The caveat is that my libraries will require these dependencies. For my library to work, I will have to pass it an object of type IArduinoMethods and INrfRadio. If I am running my code on Windows I will pass it a class that will implement those methods that can run on windows. Anyways the point is not to show how C++ works. I am just showing how I use pointers and allocate memory for a lot of things.
Because I allocated memory I was able to test my library on Windows and on Arduino for example. I may also create unit tests. I see so many benefits by allocating memory. If I am organized and remember to free the objects I no longer use, I can gain all this benefits. Why people do not code like this when it comes to Arduino?

Edit 1

Now that I understand how heap fragmentation works, I know I have to be careful when using the new keyword.
I hate when people do what they are told to do without understanding how things work. For example, the answer https://arduino.stackexchange.com/a/77078/51226 from Why is the queue library in this question for starters?. There are going to be times when a ring buffer works better and other times when the new keyword works better. Probably the ring buffer will work best for most cases.
Take the following scenario where you only have 1 KB of memory left.

There is a hierarchy of nodes where a node have a child and a sibling. For example, node A can have child B and sibling C. Then child B can have another child, etc.

(I will be storing this in memory)

I have a queue of work that needs to be done.

(I will have to store this work somewhere)

I will have a queue of events

(I will have to store this somewhere)
If I use what most people say I should do then I will be have to:

Reserve 500 kB to be able to store nodes (I will be limited to n number of nodes)

Reserve 250 kB for the queue of work that needs to be done.

Reserve 250 kB for the queue of events.

This is what most people will do and it will work great with no problems of heap fragmentation.
Now this is what I will do

Ensure that everything that I allocate is of size 12 bytes. A node only has its id (unsigned int), child (pointer), type (unsigned char), etc.. with a total of 12 bytes.

Ensure that all the work that will be enqueued is of size 12 bytes as well.

Ensure that all the events that will be enqueued is of size 12 bytes as well.

Now if I have more work than events, this will work. I just have to program in my code that I never allocate more than 70 items. I will have a global variable that has that count of allocations. My code will be more flexible. I will not have to be stuck with strictly 20 events, 20 work and 30 nodes. If I have fewer nodes then I will be able to have more events. **Anyways my point is that one solution is not better than the other. There are going to be scenarios when one solution is better.
In conclusion, just understand how heap fragmentation works and you will gain a lot of power by using the new keyword. Do not be a sheep and do what people tell you to do without understanding how things work.**.

Edit 2

Thanks to @EdgarBonet, I ended up storing Nodes on the stack. Here is why:
I have a hierarchy of nodes that can be represented as:
typedef struct Node
{
   unsigned short id;
   Node * sibling;
   Node * child;
} Node;

As you can see every node is only 6 bytes. That is another reason why I did not care to much about allocating Nodes at the beginning. If I allocate this node on the heap I will be losing 2 more bytes (33%) for every allocation because on every allocation the size of the node has to be stored. As a result I created these two methods and a buffer:
// For this to work a node can never have an id of 0 !!!

Node nodeBuffer[50];                     /* Buffer to store nodes on stack */

Node* allocateNode(Node nodeToAllocate)  /* Method to store a node */
{
    // Find first available spot where a node can be saved
    for (char i = 0; i < 50; i++)
    {
        if (nodeBuffer[i].id == 0)
        {
            nodeBuffer[i] = nodeToAllocate;
            return & nodeBuffer[i];
        }
    }
    return nullptr;
}

void freeNode(Node* nodeToFree)          /* Method to delete a node */
{
    nodeToFree->id = 0; // If the id of a node is 0 this is my convention of knowing it is deleted.
}

And on my code I used to have things like:
Node * a = new Node();
a->id = 234423;
// ....
// .. etc
// ..
delete a;

Now I just have to replace that code with:
Node * a = allocateNode({});
a->id = 234423;
// ....
// .. etc
// ..
freeNode(a);

And my code works exactly the same without having to use the new keyword. I thought it was going to be complicated to refactor the code and create a buffer.
I made this modification because I wanted to be able to store more nodes on my code. By loosing that 33% I was not going to be able to create that many. If I only allocate objects of the same size and I do not allocate that many it is perfectly fine to use the new keyword. > Also in the case of the queue I will allocate and delete objects very fast. Because the objects will not persist on memory for too long, and the chances of having heap fragmentation are very low.

short answer: there is no heap management to defragament it. so you can allocate at setup or create a pool of objects, but don't delete/free the memory.

Because you have very limited memory space and no operating system to clean up behind you.  That means you have to do a lot of things manually that you wouldn’t ordinarily have to do like watch for heap fragmentation.  Add to that the fact that an Arduino is a one program at a time device and that sort of eliminates most of the advantage to using heap memory.  You got nobody else to share with so it’s ok to be stingy.  But it’s mostly about not having the OS to keep things clean for you.

This question looks like a duplicate of Is using malloc() and free() a really bad idea on Arduino?. 2. Before dereferencing the pointer returned by new, you should check it is not nullptr. Otherwise your code is bound to crash on memory exhaustion. 3. For this particular use case, a ring buffer is presumably the easiest, memory-safe option. This is what Serial uses to enqueue the bytes.

-1 for "Do not be a sheep and do what people tell you to do."

You can be a sheep then @null and do what people tell you to do ;) being very null .

I can't call this an answer, because it's not targeted at the Arduino, but on some embedded platforms with very little memory for things like heap management, maloc is implemented as uint8_t* rval = __frontier; __frontier += sz; return rval and free is a no-op.  Needless to say, on such a platform, using heap memory this way goes poorly!

Of course you are right, but as shown by your edit, using dynamic allocation safely brigs some uncomfortable constraints. I would not recommend it to a beginner (i.e. most of those who ask questions here). It also has its own memory cost: two bytes per allocated chunk, plus some padding, because it is more than unlikely that all your objects happen to naturally have the same size.

@CortAmmon: Do you have an example? The avr-libc's malloc() does heap management, and it runs on devices as small as the ATtiny13A (1 KiB flash, 64 bytes of RAM). Not that it would be very sensible to use it on such device though...

@EdgarBonet: yes I am wasting 2 bytes for every allocation I perform :/ . I wish the heap stored the sizes in a char instead than using 2 bytes since I am never storing anything larger than 255. Because I am storing very few objects I will use this keep using this approach. Is there a way to instruct the compiler to store the sizes of heap objects using one byte instead of two?

@TonoNam You could compress that by using simple segregated storage like boost.pool does.  That lets you use arbitrarially sized chunks (at the cost of fragmenting if you don't free them uniformly, of course).  The extreme version of this, with 1 large chunck, of course, is the typical storage reservation approach you document above.

@CortAmmon thanks that will be great to know but I thing I am complicated thins a lot. I just ended up storing the items on a buffer. I thought it was going to be hard to refactor when it was not. Thanks for the help

@TonoNam You got my downvote for that last paragraph of your first edit. You are aggressively defending your original solution, that there are scenarios in which it can be the better solution - as if anybody claimed that this wasn't the case. I find this sort of  "I could have gotten away with what I had in the first place" attitude somewhat childish. As you have done what people told you (and rightfully so, because you got some good advice), your recommendation is plain false: doing what people tell you to do is actually key to understanding things.

Re:  " If I only allocate objects of the same size and I do not allocate that many it is perfectly fine to use the new keyword".   But what advantage does it gain you at that point?  If the objects are a set size and you have room for a set number of them then why would you not just statically allocate that much?   It's about more than just that you could, think about the consequences of it going wrong.  I guess you don't really learn that until it bites you.  But one day you'll be telling people the same thing we're telling you because you'll have been bit by it.

Re:  "In conclusion, just understand how heap fragmentation works and you will gain a lot of power by using the new keyword. Do not be a sheep and do what people tell you to do without understanding how things work.".  It's not about being a sheep.  You say you hate when people blindly follow rules.  I hate when someone who has to ask this kind of question thinks I'm just a sheep following.  I know what I'm doing.  I know where the danger is.  You think you've outsmarted it.  I've seen a thousand before you who thought the same.  They all learn the same hard lesson eventually.  You will too.

Most Arduinos (like the Uno or Nano) have very few RAM, thus you first need to make sure that you never allocate too much memory. Dynamically allocating memory can also lead to heap fragmentation (heap being the part of memory where dynamic allocation happens).
In most cases you would want to allocate memory of different sizes (for example arrays of different sizes) or just different objects (with each having it's own size) (!!! This is the key point here). Then you are going to delete some of these objects which will create holes inside the memory. They can be filled again with objects with the same or less size. As time passes and more allocation and deleting happens these holes tend to get smaller, up to the point where none of your new to allocate objects can fit in there. That memory then is unusable. This phenomenon is called heap fragmentation.
These holes appear naturally also on a PC but there are 2 key differences:

The Arduino has such little RAM that the holes can fill up your memory very very fast.

While the PC has an operating system, which manages the RAM (defragmenting it or putting unused stuff away into a paging/swap file), the Arduino does not have an OS. So noone keeps an eye on the real available RAM and noone tidies up the memory once in a while.

That does not mean that you cannot use dynamic allocation on an Arduino, but that is very risky depending on what exactly you are doing and how long the program should work without failing.
Considering this big caveat, you are very limited on how to use dynamic allocation. Doing it too much will result in very unstable code. The remaining possibilities, where it might be safe to use it, can also be easily done with static allocation. For example take your queue, which is basically a linked list. Where is the problem with allocating an array of QueueItems at the start. Each item gets a way to determine if it is valid. When creating a new item you just pick the first element in the array, which has a non-valid item, and set it to the desired value. You still can use the data via the pointers, just as before, but now you have it with static allocation.
You might find that the code looks uglier that way but you need to adapt to the platform that you use.
Note that this does not apply when you are going to create only objects with the same size. Any deleted object will leave a hole where any new object can fit into. The compiler uses that fact. So in that case you are safe. Just every object that you dynamically create in your program needs to be the exact same size. That of course also includes objects that are created inside different libraries or classes. For this reason it can still be a bad design choice, as you or others (if you want to publish your code), may want to pair your library with other code.
Another way to be safe is to only create and delete objects in closed cycles, meaning, that a created object needs to be deleted before the next object is created. Though that is not fitting for your application.

'Bigger' microcontrollers, for example the non-Arduino boards with the ESP32, have much more memory. Thus the use of dynamic allocation is not that bad on them. Though you still don't have an OS to manage the RAM.

Thanks a lot for the explanation. I already coded a lot of libraries using pointers. So I guess that now I have to be careful on the number of objects I alocate correct? The code works now because I am allocating very few objects and there is always room in the heap for new objects. As long as my allocations are small size and I do not allocate to many objects I should be good correct?

is there any way to de-fragment memory manually?

@TonoNam Yes, that is correct. You need to consider the size, the rate of allocation and how long the code should run. Assuming a constant rate of allocation, the code might run good for a day. But if you want it to run like a month, that could be way different. If you want to use dynamic allocation you will need to just test this out.

@dandavis I don't know of a way, other than just deleting all dynamic objects and recreating them. If you do this, I would guess, that then you again have a linear bunch of memory without holes in it (effectively defragmented). Though I'm not enough of an expert in the compiler, that I could guarantee that. Also I don't think, that this is really an option most of the time.

"Most Arduinos (like the Uno or Nano) have very few RAM"  Plus, Arduino programs are typically controllers that are expected to run unattended; they don't run to completion and get re-started some other time like most desktop programs. So even a large-memory PC using new/delete allocation would eventually fragment its memory, too. It would just take (a lot) longer.

@dandavis: The only way to defrag new/delete allocated memory is to don't. ;-) What I do instead, is to declare an array of buffers of a fixed size, and hand out one of those, no matter how much the caller asked for (up to the buffer size, of course). That mechanism won't cause fragmentation because you never split blocks, so every hole is re-usable. You do have to know - or guess well! - the maximum number of buffers your application will ever need and declare a few more than that for safety.

@dandavis Yes, you can de-fragment memory. It's called "memory management," and while an OS will have a sophisticated program for this, you can write a simple one. The biggest caveat is, you have to update all pointers to an object once you move it, so you have to be able to find every pointer to it from your memory management routine. I don't know whether such a program would fit reasonably on an Arduino. Haven't tried.

I would suggest using the ETL, which is like the STL but for embedded programming. It provides all the vectors, queues, linked lists, maps, iterators, algorithms, and other useful stuff from the C++ standard library, without using dynamic allocation at all. (You have to specify the maximum size of your structure, and everything will be handled automatically inside it). Note: I have no affiliation with the ETL, I'm just a satisfied user of it.

For a Queue implementation, it's probably better to have a pointers or indexes of the first and last item, than giving each item a valid flag. That way access becomes O(1), it's much easier to wrap around the array to reuse the memory and there are no weird situations like "holes" you weren't trying to express.

I would add to this that dynamic allocation is often slow and somwhat unpredictable in terms of timings (due to fragmentation and other effects), so if you're writing performance or timing sensitive code, it's often best to avoid it even if memory usage is not an issue.

Dynamic allocation is generally discouraged in embedded applications because you cannot guarantee that you do not exceed (attempt to allocate more than) the available memory. Static allocation will generally have this guarantee although out-of-memory bugs may still be possible.
Additionally, far fewer services or tools are available to automatically manage and mind the memory for you. Any service that does so will consume computational resources.
This means that you inherently create a mechanism in your device that would cause a memory (heap) overflow and possible undefined behavior (UB). This is true even if your code is bug-free and has no memory leaks.
In non-critical, exploration, learning, and prototype applications this may not be important.
Consider that without careful consideration undefined behavior can result in hardware failures and unsafe performance, for example if the device reconfigures GPIO through an errant write to the correct registers during a crash.

Yes Dynamic allocation is generally discouraged. +1 for using the word generally. In some cases it might work. I will just have to keep track of how many objects I allocate and ensure that all of them are of the same size.

For starters, fix your library
As noted by @crasic, dynamic memory allocation is generally not recommended for embedded systems.  It may be acceptable for embedded devices which have a larger amount of free memory - embedded Linux is commonly used, for example, and all Linux apps/services will tend to use dynamic memory allocation - but on small devices such as an Arduino there simply is no guarantee that this will work.
Your library illustrates one common reason why this is a problem.  Your enqueue() function creates a new QueueItem() but does not check that the allocation succeeded.  The result of failed allocation may either be a C++ bad_alloc exception, or it may be returning a null pointer, which when you reference it will give a system memory access exception (SIGSEGV signal in Linux, for example).  It is nearly universal in Linux and Windows programming to ignore memory allocation failure (as encouraged by most textbooks), because the massive amount of free RAM and the existence of virtual memory makes this very unlikely, but this is unacceptable in embedded programming.
More generally though, as @crasic says, memory fragmentation can leave even non-buggy code unable to allocate memory.  The result will be a failure to allocate memory, but the code will at least know this has happened and will probably be able to continue.
But better, use a fixed-size FIFO queue instead
Your code relies on dynamic allocation to add and remove elements in a queue.  It is perfectly possible (and equally easy coding-wise) to create a fixed-size array for the queue, so the various failure modes of dynamic allocation simply do not apply.  An item to be queued is simply copied into the next free queue slot, and a queue slot is marked free when it has been used.  (Don't forget to use a mutex when adding and removing items from the queue, because adding and removing will often be called from different places.)
The queue can be made whatever size you feel is appropriate (allowing for how much RAM you have).  With a fixed size, you are forced to make a design decision on what should happen if the queue overflows - do you delete the oldest data to make room for the new value, or do you ignore the new value?  This may seem an unwelcome new feature, but it is a good thing, because the third option which you've currently got is that your code goes "Aaaarrggghhh I don't know what to do!" and crashes fatally, and we don't really want that.

A fixed-size FIFO queue is typically implemented as a ring buffer.

@EdgarBonet Yes it is.  The OP should be able to find plenty of existing code for FIFOs online though, so I guess I'm more interested in helping them getting the concept than exactly how they do the implementation.

The FIFO fix sized as ring buffer is a great sollution. There are going to be times when the ring buffer is better (probably most of the time) and there are others when it is not. Take a look at the edit of the question. If you keep track of allocations and you never exceed the count of allocations all of the same size you should have no problem allocating a new queue item.

Exactly graham your answer is probably the best solution for most of the cases and also the safest. But for cases when I am building a hierarchy of nodes it will be harder to create with a buffer. If I am already allocating Nodes I guess I can keep allocating them using the queue. My point is that if you know how things work it is ok to not go with the convention. Also the probability of an alloc not working is very small since I am not using interupts or running my code in different places. For the rest of my projects I will probably use your solution.

@TonoNam You are assuming there that your allocation granularity goes down to at least 4 bytes. If the granularity is 8 bytes at best, then each 12-byte allocation will actually occupy 16 bytes of RAM. So your heap-based code would only be able to store 3/4 of what could be stored with a statically-allocated queue. Plus whatever overheads are involved in running the heap, which can be significant when you're allocating small amounts of data (and 12 bytes is usually "small"). You can't just divide RAM length by structure length and assume that's how many you get.

That is the reason why I made edit number 2 on the question Graham. Thanks for all the help.

I'm adding this not so much to add to the answer as to add some real world implications for those that may be down this particular rabbit hole.  It's nice to talk about what could happen theoretically, but a new programmer may still be tempted to think that he can out-think these limitation and still do something useful.  Here is some real world talk about why that is foolish even if you are capable.
Let's say we're developing code on an Arduino UNO.  We've got 2K of RAM to work with.  We have a class that loads a list of names, maybe it's a building access device or something.  Anyways, this hypothetical class has a name field to store someone's name.  And we decide to use the String class to hold the name as a String.
Let's say after our program is all there and doing what it's doing that there is 500 bytes left for this list of objects, each with a name field that could be of varying length.  So we run along nicely for years with a crew of 14 or 15 people with an average name length of 30 characters or so.
But one day a new guy signs up.  And his name is really long.  Let's say it takes 100 characters.  Even if we're smart coders and only have one copy of this String in memory, we've got it there and suddenly it doesn't fit.  Now a program that has worked for years suddenly fails.  And nobody knows why.
So the solution is easy right?  Enforce a maximum limit on the length of the name.  Some simple code that checks the name length and we can write a great piece that still allows the variable name length and won't let you create a new user if there's less than that much left.  Seems simple enough, but then Becky in accounting gets married and her last name changes from Smith to Wolfeschlegelsteinhausenbergerdorff and suddenly our program breaks again for no reason.
So the solution is simple right?  We'll enforce a maximum length and we'll be sure to reserve enough memory for each object that it can afford to have the maximum length name.  And that's something that we do most efficiently without dynamic allocation since we already know the size of the object.
I hear what you're saying, "but Delta-G, if we have all those short names in there, why are we going to waste all that memory on them when we don't have to.  Let's only save space for a long one if we have a long one."  And I like your thinking, this is good thinking.  But it doesn't help anything to save that memory.  If you do save some, what are you going to do with it?  If your program uses it, then there is no longer room for the longer case and suddenly you have to enforce an even shorter maximum length to accommodate that usage.
Say for instance we have 500 bytes of room and we enforce a maximum length of 50 bytes for 10 users.  And let's say that when the names are short we want to let the program use some of that saved space.  If the program can encroach 100 bytes into that space when the names are short, then why wouldn't the same situation happen with long names?  So really since the program can use all but 400 bytes then there's really only 400 bytes of room and we have to enforce a 40 byte maximum for 10 users or 50 bytes for 8.
Since you're going to have to make that sacrifice anyway, then it only makes sense to remove the work of dynamic allocation and just make things fixed sizes or use fixed size buffers.
If we had a PC with gigabytes of memory, we wouldn't even be thinking about this.  But on an Arduino UNO with 2K bytes of memory it can become a big problem really fast.
The other problem is that these bugs are so insidious.  If out of memory bugs just caused a simple crash and the thing no longer worked then it wouldn't be nearly so scary.  But that's not how out of memory bugs work on a microcontroller.  It all depends on how things are arranged in memory by the compiler.
These bugs often manifest as something that seems to work most of the time but has some funny bugs nobody can explain.  Maybe there's only a problem if someone has a name that is exactly 26 characters long and tries to open the door on a Wednesday.  Or maybe the issue will only arise if Becky logs in immediately after Bob.  Maybe it just garbles three letters on the screen but other than that everything works.  Maybe with a different name changed that suddenly turns into our lock opens for anyone.  There's no guessing or explaining out of memory bugs.  So we have to be super careful to avoid even the remote possibility of running into one.
And that's why we avoid using dynamic allocation on small microcontrollers.  At the end of the day, there's nothing you can save with it, and even if you could the consequences of getting something a little wrong are terribly frustrating.  With these types of programs you almost always have to end up enforcing some sort of limit on everything and once you're enforcing limits there's no use for dynamic allocation anymore.

Again in your real life example you are allocating objects of different sizes (names). That will lead to heap fragmentation. If you where to allocate names of the same size and very few of them it is perfectly fine to use heap allocation.

But like I said in the example, if you’re allocating a fixed number of things of a fixed size then why do you want to use dynamic allocation to do that?  What would be the advantage at that point?

That if I have multiple queues I do not have to create one buffer for each. There might be cases when allocation is helpful. My point is that if you understand how it works it is ok to use it. Probably most of the time it makes no sense to use it but not never.

Yeah not never, but not for what you're thinking either.  You run into the same issue.  If you have multiple queues and you want them to be able to share a buffer space then it would certainly be easier to have one buffer allocated and a single class that is controlling adding and removing.  I'm thinking probably anything that can add to the queue needs to inherit some base class that allows you to have code in one place doing it.  That is exactly the use case I'm on about where you think you know what you're doing and one day some corner case you never suspected bites you.

I guess it's one of those things that you just can't truly learn any way but the hard way.  But at the end of the day, if you want shared buffer space you must put a limit on its size and if you're going to do that then you might as well allocate it all and let your code control putting things in and out.

The one good exception I can think of is when you have a class you need to instantiate later in the code.  Maybe you need some user input before you can build the instance.  So you just have a pointer and then later in code you can construct a new object with new and set that pointer.  But in that case the plan is to create the object early on in the program and leave it there for the duration.  In this case you never plan to ever free or delete the object and create another.


text:
nRF24L01+ radio not transmitting anything but says it is
I have a nRF24L01+ radio that was working like a charm for many months now, and a few days back, I was trying to send something and then receive it. The transmitter initialized properly and said it was transmitting but the receiver got nothing. I made sure all wiring is good, power is sufficient, etc. I made sure the receiver was working with another radio and indeed. So what is wrong. Any help is appreciated.
The transmitter is a high range radio with large antenna and the receiver is the standard PCB antenna ones. When I do printDetails, everything looks fine.
TX Code:
/*
Demonstrates simple RX and TX operation.
Any of the Basic_RX examples can be used as a receiver.
Please read through 'NRFLite.h' for a description of all the methods available in the library.
Radio    Arduino
CE    -> 9
CSN   -> 10 (Hardware SPI SS)
MOSI  -> 11 (Hardware SPI MOSI)
MISO  -> 12 (Hardware SPI MISO)
SCK   -> 13 (Hardware SPI SCK)
IRQ   -> No connection
VCC   -> No more than 3.6 volts
GND   -> GND
*/

#include <SPI.h>
#include <NRFLite.h>

const static uint8_t RADIO_ID = 1;             // Our radio's id.
const static uint8_t DESTINATION_RADIO_ID = 0; // Id of the radio we will transmit to.
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
    Serial.begin(115200);

    // By default, 'init' configures the radio to use a 2MBPS bitrate on channel 100 (channels 0-125 are valid).
    // Both the RX and TX radios must have the same bitrate and channel to communicate with each other.
    // You can run the 'ChannelScanner' example to help select the best channel for your environment.
    // You can assign a different bitrate and channel as shown below.
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 100) // THE DEFAULT
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE1MBPS, 75)
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE250KBPS, 0)

    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }

    _radioData.FromRadioId = RADIO_ID;
}

void loop()
{
    _radioData.OnTimeMillis = millis();

    Serial.print("Sending ");
    Serial.print(_radioData.OnTimeMillis);
    Serial.print(" ms");

    // By default, 'send' transmits data and waits for an acknowledgement.  If no acknowledgement is received,
    // it will try again up to 16 times.  This retry logic is built into the radio hardware itself, so it is very fast.
    // You can also perform a NO_ACK send that does not request an acknowledgement.  In this situation, the data packet
    // will only be transmitted a single time and there is no verification of delivery.  So NO_ACK sends are suited for
    // situations where performance is more important than reliability.
    //   _radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData), NRFLite::REQUIRE_ACK) // THE DEFAULT
    //   _radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData), NRFLite::NO_ACK)

    if (_radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData))) // Note how '&' must be placed in front of the variable name.
    {
        Serial.println("...Success");
    }
    else
    {
        Serial.println("...Failed");
        _radioData.FailedTxCount++;
    }

    delay(1000);
}

RX Code:
/*
Demonstrates simple RX and TX operation.
Any of the Basic_TX examples can be used as a transmitter.
Please read through 'NRFLite.h' for a description of all the methods available in the library.
Radio    Arduino
CE    -> 9
CSN   -> 10 (Hardware SPI SS)
MOSI  -> 11 (Hardware SPI MOSI)
MISO  -> 12 (Hardware SPI MISO)
SCK   -> 13 (Hardware SPI SCK)
IRQ   -> No connection
VCC   -> No more than 3.6 volts
GND   -> GND
*/

#include <SPI.h>
#include <NRFLite.h>

const static uint8_t RADIO_ID = 0;       // Our radio's id.  The transmitter will send to this id.
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
};

NRFLite _radio;
RadioPacket _radioData;

void setup()
{
    Serial.begin(115200);

    // By default, 'init' configures the radio to use a 2MBPS bitrate on channel 100 (channels 0-125 are valid).
    // Both the RX and TX radios must have the same bitrate and channel to communicate with each other.
    // You can run the 'ChannelScanner' example to help select the best channel for your environment.
    // You can assign a different bitrate and channel as shown below.
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 100) // THE DEFAULT
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE1MBPS, 75)
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE250KBPS, 0)

    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_radioData); // Note how '&' must be placed in front of the variable name.

        String msg = "Radio ";
        msg += _radioData.FromRadioId;
        msg += ", ";
        msg += _radioData.OnTimeMillis;
        msg += " ms, ";
        msg += _radioData.FailedTxCount;
        msg += " Failed TX";

        Serial.println(msg);
    }
}

Please provide details of what you mean by "said it was transmitting", eg. evidence. Have you tried it with more than one receiver? Are each of those receivers known to be working currently?

I only have 1 receiver and it is working just fine. By transmitting, I meant that in the Serial Monitor, it says that it transmitter and an acknowledgment signal was received but the receiver got nothing.

I suggest you go for the simplest program possible to echo what is transmitted. If that doesn’t work then please post the simple program together with the results.

Yes, I am currently running an echo program and it is the default examples on the nRFLite library. I am using the Basic TX and RX example. I put the program in the question.

this is unrelated ... you had a deleted post about flysky and nRF24L01 ... here is some info that came up since you deleted your post .... google DeviationTX ... also look here for possibly useful info ... https://drones.stackexchange.com/questions


text:
Understanding heap fragmentation
I finally understand why people do not allocate memory when it comes to micro-controllers. The reason is because as you allocate different objects on the heap of various sizes and then you delete them you end up with holes. This is called heap fragmentation. Anyways I know what is heap fragmentation. I just want to know how it works. So that I know when I can use the new keyword to allocate memory and when not..
(1) To make things simple consider this example. Lets say my heap looks like this. The bottom numbers represent the addresses. In a real example I will be allocating structs with larger sizes but lets use bytes to make things simple.
0    0    0    0    0    0    0    0    0    0
1    2    3    4    5    6    7    8    9    10

(2)  I allocate a char with value 123 in memory. Now my heap looks like this
1    0   123   0    0    0    0    0    0    0
1    2    3    4    5    6    7    8    9    10

the first 2 bytes 1  0 store the size of the data being allocated followed by the byte 123 that has the actual value.
(3)  I allocate another char with value 111 in memory. Now my heap looks like this
1    0   123   1    0   111   0    0    0    0
1    2    3    4    5    6    7    8    9    10

(4) I delete the first object created on step 2 with value 123. It now looks like:
0    0    0    1    0   111   0    0    0    0
1    2    3    4    5    6    7    8    9    10

I now have a hole at the beginning (heap fragmentation)
Now my question is if I where to allocate another byte say 222 will it be allocated on the beginning like this?
1    0   222   1    0   111   0    0    0    0
1    2    3    4    5    6    7    8    9    10

Or will it be allocated at the end like this?
0    0    0    1    0   111   1    0   222   0
1    2    3    4    5    6    7    8    9    10

If arduino is smart enough to place that object at the beginning, then I will no be that afraid of using the new keyword as long as I am allocating objects of small sizes and never allocating to many of them.
Reason why I am asking this question is because I have a class Queue that I use in c++. Whenever I add an item to that queue it allocates the objects that I create. The objects that I pass to that queue are 10 bytes. The queue size is never larger that size 30. Will it be safe if that queue is constantly allocating (enqueing) and deleting (dequeing) items?

Edit
Sorry for the question I guess I asked this question when I should had done more research. Thanks to your comments and my previous question I now know that this only occurs when allocating memory of different sizes.

Heap fragmentation occurs specifically when you are allocating objects of different sizes and a smaller object is placed into a larger hole leaving a bit of left over memory too small for another object later on. With single bytes or always the same size objects you won't get that problem, since a hole will always be the right size.

When having always the same object size (in your example always only 3 bytes per object) you don't have that problem. I added a small paragraph about that in my answer to your previous question, because it fits good into the answer.

@chrisl thanks I just want to make sure I understand because I am allocating a lot of memory in my code. For example all the events that ocur on arduino of interest I place them on a queue. Then my library uses that queue to send the messages with the NRFL24L01 radio. Thanks for all the help!

I suggest you keep at that idea.  When you hit the wall and can’t understand why it sometimes just does weird things you can’t explain then come back and we can help you find a proper memory budget.  Doing what you’re doing on a microcontroller is like trying to live like a king on minimum wage.  You can use credit and pull it off for a while but eventually it catches up with you.  Unless you’re writing code to make sure each of these queued things fits neatly into memory eventually you’ll queue something that doesn’t fit.  And there will be no explanation for what happens next.

Your method is good thinking on a PC.  But on a microcontroller you’re asking for trouble.  It would be best to go ahead and set a limit for how many things can be queued and how big they can be.  And if you can set that limit then you no longer need dynamic allocation.  You don’t have anything to share memory with so why not just allocate what you need from the start.  You’ll see.

You may want to take a look at the source code of malloc() (this is the AVR version): it is very well documented in the comments. And maybe also at this answer to a related question.


text:
sent commends by bluetooth to sd card as one line of string
 void loop() {

  if (Bluetooth.available() > 0) {
           dataIn = Bluetooth.readString();
   //the problem is here
           while(dataIn !=""){
                   dataSd += dataIn;
                   dataSd += "," ;
           }

 if (dataIn.startsWith("s1")) {-----------}
 if (dataIn.startsWith("save"){ save to sd card }

// what I want is to sent command by bluetooth to variable dataSd as a line
of string seperated by commas
like ("left,right,up,down,left,stop,right") and  when i send command save, it
will save to sd card, but this code didnt work

while loop didnt work does not mean anything useful ... what did happen?

And please provide a full compilable code, which is formatted correctly

sorry this is the first time i posted something here now i modified the code

What's the reason for that while ? It won't ever stop repeating


text:
Using Two Arduino to Lower Power Consumption
I am planning to build a water quality sensor with ph, temperature, and dissolved oxygen, conductivity. The power consumption looks like it will be very high especially due to the signal isolator, I'm estimating about 250mA. I'm going to place it in a remote area so I need it to be as power-efficient as possible.
I was thinking would this work?
What if I use two Arduino to control the power? The first Arduino will control the power supply to second Arduino, which has the sensor installed, using a timer(RTC) to turn off the power for 30 minutes and on for 30 seconds for it to read the sensor data.
Can this work? What would the circuit look like?
For the isolator, I was thinking to use Tentacle Shield and in the documentation, it says that the isolator itself uses about 150mA plus the sensor circuit.
https://www.whiteboxes.ch/docs/tentacle/t1/#/
Thanks for the help.

Please tell us what signal isolator you are referring to. Some Arduino's (maybe all of them) can be put into sleep modes which can save a lot of power. A good place to start learning how to do this is by using the search bar at the top of the page. There is a LowPower library available in the Arduino IDE.

First of all, you don't need two arduino. You can put arduino in deep sleep. Secondly, if you have a power consumption of 250mA, it is most likely come from all the sensor boards that you have, so you need to have a circuitry (such as an MOSFET) to cut off the power for those boards before the Arduino go into sleep mode.

I added details on the isolator

An Arduino with its leds and linear power regulators is not optimized for minimal power consumption. BTW: How do you signal the results of your sensors and measurement?

I would do as follows:
Software:

Arduino is in sleep mode

every x seconds (x depending on your needs), wake up then switch on and read one sensor after the other and transmit the results or whatever you want to do.

then go back to sleep

Hardware:

as you have 4 sensors, you can connect their outputs to the arduino analog inputs (or digital...)
you will need 4 electronic switches, preferably Mosfets, connected to 4 digital outputs to switch the power of each sensor independently

This should reduce the consumption to the minimum.
Once your system is running, you may also think about using only the AVR microchip, not the complete Arduino, e.g. If you don't need the USB connection. In addition, you can further reduce consumption by clocking the AVR chip to a lower clock, if not using Arduino.

In fact, for a project like this, you should use two Arduinos, one as SLAVE and the other as MASTER.
You mentioned 4 sensors for measuring water quality, but you will have more modules such as RTC and MicroSD to store the data.
So, I think you should use Slave to colect the data from sensors using the Tentacle Shield, and the other Arduino as Master, to MANAGE other modules and the SLAVE.
For this, you can setup the communication between using I2C protocol. For my Major Qualifying Project, I presented a full prototype for Remote Surface Water Parameter Plataform Sensor, using both Arduino Uno (SLAVE) and Mega (MASTER). For power supply, I have used 12V 8A motorcycle battery.
All the data captured by the sensors, were stored locally by SDModulo and sent by a SIM module to a RaspberryPi server.
For low power consumption, you should DeepSleep mode for the Arduinos. You can setup this mode using the RTC module.
Arduino LowPowerDeepSleep.
For the circuit, I think you will be fine if you use the Tentacle Shield. It's already done.

Actually, you can just run 1 Arduino and use it for

All needed measurements
Control power supply to sensors (power off when unneeded)
Additional: use low-power modes of MCU installed in Arduino

Upd: About 2nd option:
You can use electric relay or transistor to control power supply to sensor. Often sensors have several connections: ground (-), Vin(+) and some signal connections. So between power supply and Vin(+) of sensor you can put electric relay. Control pin of electric relay connect to any free pin on Arduino. Therefore, Arduino can enable and disable power supply to sensor just by settings 1 or 0 to that pin. I recommend you to use electric relay, because it is easier, but if you want to try transistor, you can refer to this question & answers: https://electronics.stackexchange.com/questions/95089/switching-9v-using-a-npn-transistor-and-an-arduino
About 3rd option: Arduinos are based on some MCU (often AVR, not always). These MCUs have several low-power modes. You can directly control power mode of MCU to achieve better power-efficiency.
So, you can do 1st and 2nd options, and try to do the 3rd one:

Investigate which MCU installed in your Arduino
Investigate which power modes it supports
Implement power management according to datasheet of this MCU

For example, if you have Arduino Mega 2560, then it is based on ATmega2560 MCU, find datasheet (https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf) and there find info about power/sleep modes (page 50) and ways to "wake up" from these modes.
Also you can read about it here: https://microchipdeveloper.com/8avr:avrsleep
Also you can try to find some handy libraries for Arduino, for example "Low-Power" and just use them without diving into MCUs, datasheets, etc

How would I go about doing the second option?

@JSK, I've updated answer: added more info about 2nd option


text:
Using a template inside a class
I'm trying to use a template function, but I get an error
home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `startIOTservices()':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:37: undefined reference to `void myTest::funcOne<bool>(bool)'
/home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `setup':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:70: undefined reference to `void myTest::funcOne<bool>(bool)'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

inside .cpp file:
myTest::myTest()
{
        Serial.println("start");
}

template <class T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

inside .h file:
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

and calling it from .ino file:
testA.funcOne(true);
What am I doing wrong ?
EDIT 1:
complete .h .cpp files - which originaly belongs to myJSON library which are deleted in this snip
#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"

#define DOC_SIZE 1000

class myJSON
{
};

class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

#endif

.cpp file
#include "Arduino.h"
#include "myJSON.h"
#include "FS.h"
#include <ArduinoJson.h>

#define LOG_LENGTH 4

myJSON::myJSON(char *filename, bool useserial)
{
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

myTest::myTest()
{
        Serial.println("start");
}

// template <typename T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

put the template function definition in the .h file.

@Juraj when leaving the template defining inside .h file only I get :error: variable or field 'funcOne' declared void  void myTest::funcOne(T1 arg)

Please provide a minimal complete example. The error might be in the calling/using source.

@thebusybee Since it is only example -  I've put myTest class inside another .cpp  , and .hfiles I'm currently using. funcOne is called during setup() function

Would you mind to show us the commands to compile and link? Oh, and the source of this other module, please. You can enable verbose output of the build in the preferences.

@thebusybee what do you mean commands to complie and link ?

You might like to [edit] your question with the now-current code. Please don't remove the old code because comments refer to it.

@thebusybee, there is nothing to edit. it is simple to reproduce the problem. it is build with Arduino IDE.

@thebusybee see edit 1

@Juraj you are right - Arduino IDE 1.8.2

@Juraj The OP said "when leaving the template defining inside .h file only I get :error..." so the source is not up-to-date. Therefore I asked for current sources. And I still miss the main module which calls funcOne(), since the mentioned error presumambly points there.

move the template method definiton to .h or define it in class. it is not a real function, only a prescription for functions. Like this:
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

template <class T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

or this
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg)
    {
            Serial.println(arg);
    }
};

Can you please explain what does it differ from what I originaly wrote in my question ?

the template is a declaration. the source where you use the template can't see it in cpp

Actually duplicate the function insde .h file ?

I write "move". It should be only in .h

Compilers don't know which class to use for the templated class if you compile the method separately. The common way is to put the method implementation into the header so the compiler is able to instantiate the specific implementation.

@thebusybee, there is myTest:: to assign the method to class

Sorry, I forgot the @Guy.D the comment was addressed to.

@thebusybee, I know, but Guy has it right

@Guy.D, did it help?

@Juraj - tested now. YES! thank you very much


text:
Arduino split comma separated serial stream
I'm trying to read serial data into Arduino.
I usually use a Serial to USB cable to connect to the hardware and is sending data like
33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68

At 38400 bound rate.
I have been reading this post Splitting a comma separated string through serial (Arduino) https://www.arduino.cc/reference/en/language/functions/communication/serial/print/
I have tried to write something my own but none return readable data.
Any tips please?

Your device seems to use a line-oriented protocol, where each message ends with a CR and/or LF character. The first thing you should do is make sure you buffer the input in order to process one line at a time. See Reading Serial on the Arduino, by Majenko. Once you have this sorted out, follow chrisl's advice.

see https://arduino.stackexchange.com/questions/1013/how-do-i-split-an-incoming-string

The reference article, that you linked to, is about sending data over Serial, not about reading.
You can use the strtok() function, which can split a character buffer into tokens based on a delimiting character (the comma in your case).
First you have a buffer, where your Serial message in saved (I'm not covering the actual receiving/reading of the Serial data here, because there are tons of tutorials on the web):
char buffer[] = "1,2.3,4,0x56";

Then you can get the first token:
char *token1 = strtok(buffer, ",");

token1 is a pointer to the start of the token. strtok() replaces the found delimiter (which you specify with the second parameter) with a null character. That means, that token1 points to a null terminated C string with only the first token in it (Keep in mind that the buffer is changed with that, so it does not make any sense to try printing buffer after you used strtok()). Note, that this does not create a new buffer. It simply points to a specific place inside buffer.
You could also directly process it, for example convert it to an integer:
int token1_value = atoi(strtok(buffer, ",");

To get the next token, you simply again call strtok(), but now you provide NULL instead of buffer in the first parameter. That tells strtok(), that you still want to process the same buffer from the last execution.
float token2_value = atof(strtok(NULL, ",");

You can now do this, until no token is left unprocessed in the buffer. In that case strtok() returns NULL.
char *token = strtok(NULL, ",");
while(token != NULL){
    Serial.println(token);
    token = strtok(NULL, ",");
}

Have a look at the C++ reference for strtok(). It also includes an online editor, where you can run the provided example and play with it.


text:
Sea level pressure for BMP280
I have a BMP280 and BMP180 pressure sensor and I have both of them connected via I²C to a ESP8266.
For the BMP180, I can get the sea level air pressure when I pass the pressure and altitude like so:
// https://github.com/sparkfun/BMP180_Breakout_Arduino_Library
#include <SFE_BMP180.h>
SFE_BMP180 bmp180;
[...]
Serial.print(bmp180.sealevel(pressure, 800));

Is there a similar thing for the BMP280? Reading pressure and temperature works fine:
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp280;
[...]
double temperature = bmp280.readTemperature();
double pressure = bmp280.readPressure() / 100;

It seems this was planned for the Adafruit BMP280 library but not implemented. Looking at Adafruit_BMP280.h we see commented code that has a method seaLevelForAltitude():
/*
class Adafruit_BMP280_Unified : public Adafruit_Sensor
{
  public:
    Adafruit_BMP280_Unified(int32_t sensorID = -1);

    bool  begin(uint8_t addr = BMP280_ADDRESS, uint8_t chipid = BMP280_CHIPID);
    void  getTemperature(float *temp);
    void  getPressure(float *pressure);
    float pressureToAltitude(float seaLevel, float atmospheric, float temp);
    float seaLevelForAltitude(float altitude, float atmospheric, float temp);
    void  getEvent(sensors_event_t*);
    void  getSensor(sensor_t*);

  private:
    uint8_t   _i2c_addr;
    int32_t   _sensorID;
};

*/

In another library, BMP280-arduino-library, I found a function that seems to work:
double BMP280::sealevel(double P, double A)
// Given a pressure P (mb) taken at a specific altitude (meters),
// return the equivalent pressure (mb) at sea level.
// This produces pressure readings that can be used for weather measurements.
{
    return(P/pow(1-(A/44330.0),5.255));
}

First, I just copied that function into my code (without the class name), due to the friendly pizza license. Later I switched to that library and it also worked fine.

thanks, it worked to me as well, and works actually the same way around like the way I suggested, it only defines another method return the sealevel pressure!

@PritamSarkar: sorry, I didn't try your solution, because I have already deployed mine. Yes, it's the same formula.

yeah, both are totally fine @ThomarWeller.

Try this following segment: I used it myself and it worked fine.
As you don't get any default Method for returning the sea-level pressure from BMP280, I had to calculate on my own.
#include <Wire.h>
#include "SPI.h" //Why? Because library supports SPI and I2C connection
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

//Setup connection of the sensor
Adafruit_BMP280 bmp; // I2C
/*//For SPI connection!
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10
//Adafruit_BMP280 bme(BMP_CS); // hardware SPI
//Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);
*/

//Variables
float pressure;       //To store the barometric pressure (Pa)
float temperature;    //To store the temperature (oC)
float SLpressure_mB;
int ELEVATION = 9;  //PUT HERE THE ELEVATION OF YOUR LOCATION IN METERS

void setup() {
  bmp.begin();    //Begin the sensor
    Serial.begin(9600); //Begin serial communication at 9600bps
    Serial.println("Equivalent Sea Level Pressure Test:");
}

void loop() {
  //Read values from the sensor:
  pressure = bmp.readPressure();
  temperature = bmp.readTemperature();
  SLpressure_mB = (((pressure * 100.0)/pow((1-((float)(ELEVATION))/44330), 5.255))/100.0)
  //Print values to serial monitor:
  Serial.print(F("Pressure: "));
    Serial.print(pressure, 2);
    Serial.print(" Pa");
    Serial.print("\t");
    Serial.print(("Temp: "));
    Serial.print(temperature);
    Serial.print(" oC");
  Serial.print("\t");
    Serial.print("Equivalent Sea Level Pressure: ");
    Serial.print(SLpressure_mB, 2);
    Serial.println(" mB");

    delay(5000); //Update every 5 sec
}


text:
Arduino EPROM dumper with utility program in C
I am writing EPROM dumper with Arduino UNO and utility program in C and I am using Ubuntu 20.04. The Arduino sketch works fine, but I am having few problems with the utility program. The first problem is that the utility hangs (like in some kind of infinite loop) if I don't open the serial monitor in Arduino IDE previously, or any other serial communication app (like puTTY). The second problem I have is that the utility also hangs when reading the last bytes which Arduino sends - inspecting the dumped file in hex editor, the last 4-6 bytes are missing. By printing string messages in the function serial_port_read_block_file, I think that the program hangs up in the read function.
Thank you in advance and sorry if I understood something wrong configuring the serial communication.
EDIT: Adding switch-case statement for setting the baud rate solved the first problem. The second problem is that I forgot that byte with the value of '\n' can be received, and I was just discarding this byte, so at the end I was missing few bytes. Also, I should have checked in the serial_port_read_block_file function if n>0, so I don't access address beyond the scope of the block array (with the statement buffer_cur_pos[-1], if n=0 I accessed invalid address).
Conclusion: As @Majenko suggested, I should implement some protocol that will wrap up the data transfer, to distinguish the data from the start/stop conditions. I also changed the code below with the fixes which made the program working (both, in the Arduino sketch and the utility program).
The Arduino sketch:
//74HC595 pins
const int shiftData = 10;
const int shiftClock = 11;
const int shiftLatch = 12;

//ROM data pins (successive)
const int romD0 = 2;

//pgm constants and variables
static const uint16_t BLOCK_SIZE = 256;
uint16_t nBytes = 0;
boolean readMode = false;

void sendAddress(uint16_t addr) {
  //first, send the high byte of the address
  shiftOut(shiftData, shiftClock, MSBFIRST, addr >> 8);
  //then, send the low byte of the address
  shiftOut(shiftData, shiftClock, MSBFIRST, addr);
  //pulse the shiftLatch pin, to output the address
  digitalWrite(shiftLatch, LOW);
  digitalWrite(shiftLatch, HIGH);
  digitalWrite(shiftLatch, LOW);
}

uint8_t readByte(uint16_t addr) {
  uint8_t data = 0;
  //send the address
  sendAddress(addr);
  for (int i = 7; i >= 0; i--)
    data = (data << 1) | digitalRead(romD0 + i);
  return data;
}

void sendBytes(uint16_t bytes) {
  //send the data in blocks with size BLOCK_SIZE
  const uint16_t BLOCKS = bytes / BLOCK_SIZE; //number of whole blocks
  const uint16_t REMAINDER = bytes % BLOCK_SIZE; //the remaining bytes that don't form a block

  uint8_t data[BLOCK_SIZE]; //buffer for block of bytes to be sent

  //send the whole blocks
  for (uint16_t block = 0; block < BLOCKS; block++) {
    for (uint16_t offset = 0; offset < BLOCK_SIZE; offset++) {
      data[offset] = readByte(block * BLOCK_SIZE + offset);
    }
    Serial.write(data, BLOCK_SIZE);
    delay(100);
  }

  //send the remaining bytes
  for (uint16_t offset = 0; offset < REMAINDER; offset++) {
    data[offset] = readByte(BLOCKS * BLOCK_SIZE + offset);
  }
  Serial.write(data, REMAINDER);
  Serial.write("\r\n"); //end of transmission
  delay(100);
}

void setup() {
  pinMode(shiftData, OUTPUT);
  pinMode(shiftClock, OUTPUT);
  pinMode(shiftLatch, OUTPUT);

  for (int i = 0; i < 8; i++)
    pinMode(romD0 + i, INPUT);

  Serial.begin(57600);

  //wait for serial port to connect
  while (!Serial) {}
}

void loop() {
  while (!Serial.available()) {} //wait until data is available
  char c = Serial.read();
  delay(100);
  switch (c) {
    case 'S': //send ready command
      Serial.write("> ");
    break;
    case 'R':
      readMode = true;
      while ((c = Serial.read()) != '\n') {
        nBytes = nBytes * 10 + (c - '0');
      }
      delay(100);
    break;
    default:
    break;
  }

  if (readMode) {
    sendBytes(nBytes);
  }

  //reset for next loop
  readMode = false;
  nBytes = 0;
  delay(100);
}

The utility program:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

static const uint16_t BLOCK_SIZE = 256;
static const uint32_t BAUD_RATE = 57600;

void help(void) {
    printf(
            "rdump - ROM dumper\n"
            "usage: rdump [OPTIONS]\n"
            "Options:\n"
            "-p <serial port>       specify serial port of the Arduino\n"
            "-f <filename>          specify output filename\n"
            "-s <num bytes>         specify the number of bytes to read\n"
            "-h                     print this help file\n"
    );
}

//opening and initializing serial communication
int serial_port_init(const char *port, uint32_t baud) {

    //open serial port for read/write, save its file descriptor in fd
    int fd = open(port, O_RDWR | O_NOCTTY | O_SYNC);

    if(fd == -1) {
        fprintf(stderr, "serial_port_init: unable to open %s\n", port);
        return -1;
    }

    struct termios options; //serial port options

    //get the initial serial port options
    if(tcgetattr(fd, &options) < 0) {
        fprintf(stderr, "serial_port_init: unable to get terminal options\n");
        return -1;
    }

    //set the baud rate
    cfsetispeed(&options, (speed_t)baud);
    cfsetospeed(&options, (speed_t)baud);

    options.c_cflag |= (CLOCAL | CREAD); //enable the receiver and block control lines

    //set the character size to 8 bits, no parity bit and 1 stop bit (8N1 configuration)
    options.c_cflag &= ~PARENB; //no parity
    options.c_cflag &= ~CSTOPB; //1 stop bit
    options.c_cflag &= ~CSIZE; //bit mask for character size
    options.c_cflag |= CS8; //8 bit character size
    //disable hardware flow control
    options.c_cflag &= ~CRTSCTS;
    //configure for non-canonical mode
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ISIG); //disable cannonical mode, echo, erasure, new-line echo,  INTR, QUIT and SUSP
    options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control
    options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); //disable any special handling of received bytes
    options.c_oflag &= ~OPOST; // prevent special interpretation of output bytes
    options.c_oflag &= ~ONLCR; // prevent conversion of newline to carriage return/line feed

    //read returns after 0.5 second timeout
    options.c_cc[VMIN] = 0;
    options.c_cc[VTIME] = 5;

    serial_port_flush(fd); //flush the serial port

    //set the new options for the serial port
    if(tcsetattr(fd, TCSANOW, &options) < 0) {
        fprintf(stderr, "serial_port_init: unable to set terminal options\n");
        return -1;
    }

    return fd;
}

//closing the serial communication
void serial_port_close(int fd) {
    close(fd);
}

void serial_port_flush(int fd) {
    sleep(2);
    tcflush(fd, TCIOFLUSH);
}

//check if serial port is ready
int serial_port_ready(int fd) {
    uint8_t c[1];
    uint8_t prev = 0;
    ssize_t n = read(fd, c, 1);
    int done = 0;
    if(n <= 0) return 0;
    prev = c[0];
    do {
        //printf("%02X", (uint8_t)prev);
        n = read(fd, c, 1);
        if(n <= 0) return 0;
        done = (prev == '>') && (c[0] == ' ');
        prev = c[0];
    } while(!done);
    return 1;
}

//writing to the serial port
ssize_t serial_port_write(int fd, const char *data) {
    size_t data_length = strlen(data);
    ssize_t n = write(fd, data, data_length);
    if(n != data_length) {
        fprintf(stderr, "serial_port_write: unable to write the data\n");
        return -1;
    }
    return n;
}

//reading block of bytes from the serial port into file
int32_t serial_port_read_block_file(int fd, uint8_t *block, uint16_t block_size, FILE **file) {
    uint8_t *block_cur_pos = block;
    memset(block, 0, block_size);

    ssize_t n;
    uint16_t total = 0;
    int done = 0;
    int try = 0;
    static const int TRIES = 5;
    //printf("serial_port_read_block_file: started reading block.\n");
    do {
        n = read(fd, block_cur_pos, block_size - (block_cur_pos - block));
        if(n == -1) {
            fprintf(stderr, "serial_port_read_block_file: unable to read the data\n");
            return -1;
        }
        block_cur_pos += n;
        total += n;
        //print_byte_array(block, block_cur_pos - block + 1);
        if(n > 0) {
            done = (block_cur_pos[-1] == '\n' && block_cur_pos[-2] == '\r') || (total == block_size);
        } else {
            try++;
            if(try >= TRIES) done = 1;
        }
    } while(!done);
    //printf("serial_port_read_block_file: done reading the required block. Total read: %u bytes\n", total);
    if(total == 0) return 0;
    if(block_cur_pos[-1] == '\n' && block_cur_pos[-2] == '\r') {
        total -= 2;
        fwrite(block, sizeof(uint8_t), total, *file);
    } else {
        fwrite(block, sizeof(uint8_t), total, *file);
    }
    fflush(*file);
    //printf("serial_port_read_block_file: done writing the bytes to the file.\n");
    return total;
}

//reading (bytes) bytes from the serial port into file
int32_t serial_port_read_file(int fd, FILE **file, uint16_t bytes) {
    uint8_t *block = (uint8_t*)malloc(BLOCK_SIZE * sizeof(uint8_t));
    uint16_t total = 0;
    ssize_t n;
    do {
        n = serial_port_read_block_file(fd, block, BLOCK_SIZE, file);
        if(n == -1) {
            return -1;
        }
        total += n;
    } while(total < bytes);
    free(block);
    //printf("Done reading.......\n");
    return total;
}

int main(int argc, char *argv[]) {
    char *port_name = NULL;
    char *file_name = NULL;
    uint16_t bytes;
    //parsing command line arguments
    opterr = 0;
    char c;
    while((c = getopt(argc, argv, "p:f:s:h")) != -1) {
        switch(c) {
            case 'p':
                port_name = strdup(optarg);
            break;
            case 'f':
                file_name = strdup(optarg);
            break;
            case 's':
                bytes = atoi(optarg);
            break;
            case 'h':
                help();
                return 0;
            break;
            default:
                fprintf(stderr,
                        "rdump: invalid option: %c\n"
                        "Try 'rdump -h' for more information.\n",
                        optopt);
                return 0;
            break;
        }
    }

    //opening serial port communication with the arduino
    int port = serial_port_init(port_name, BAUD_RATE);
    if(port < 0) {
        //fprintf(stderr, "rdump: unable to open port %s\n", port_name);
        free(port_name);
        free(file_name);
        return -1;
    }

    printf("rdump: serial communication to %s opened successfully\n", port_name);
    sleep(3); //wait for serial port to be ready

    //send command for testing if the serial port is ready
    char cmd[20];
    cmd[0] = 'S';
    cmd[1] = '\0';
    if(serial_port_write(port, cmd) < 0) {
        serial_port_close(port);
        return -3;
    }
    //check if serial port is ready
    if(!serial_port_ready(port)) {
        fprintf(stderr, "rdump: serial port is not ready.\n");
        serial_port_close(port);
        free(port_name);
        free(file_name);
        return -2;
    }
    printf("rdump: serial port is ready\n");
    //send command for reading n bytes
    sprintf(cmd, "R%d\n", bytes);
    if(serial_port_write(port, cmd) < 0) {
        serial_port_close(port);
        free(port_name);
        free(file_name);
        return -3;
    }
    //receive the requested data
    FILE *rom = fopen(file_name, "wb");
    fsync(fileno(rom));
    if(rom == NULL) {
        fprintf(stderr, "rdump: unable to create file %s\n", file_name);
        serial_port_close(port);
        free(port_name);
        free(file_name);
        return -4;
    }
    printf("rdump: file %s created successfully.\n", file_name);
    printf("Dumping ROM to file %s...\n", file_name);
    //uint8_t buffer[10000];
    //int n = serial_port_read_block_file(port, buffer, 10000, rom);
    //int n = serial_port_read(port, buffer, 10000);
    //fwrite(buffer, sizeof(uint8_t), n, rom);
    ssize_t dumped_bytes = serial_port_read_file(port, &rom, bytes);
    if(dumped_bytes < 0) {
        return -5;
    }
    if(dumped_bytes != bytes) {
        fprintf(stderr, "Dumped %zd of %u bytes\n", dumped_bytes, bytes);
    } else {
        printf("Done!\n");
    }
    //close the file, serial port and free the memory
    fclose(rom);
    serial_port_close(port);
    free(port_name);
    free(file_name);
    //printf("Exiting...\n");
    return 0;
}

For the baud rate on Linux you must use B57600 not 57600.

For your data transfer you should implement some form of protocol that wraps your data transfer and is distinguishable from your data transfer. One example would be to transfer the data as ASCII HEX with transfer start and stop markers that don't use 0-9A-F. One good example would be to implement Intel HEX format (the same format Arduino sketches are uploaded in) since that is a standard for EEPROM programmers to work with.

I've used https://github.com/Ghostbird/Arduino_EEPROM_RW in the past. Which is somewhat similar to what you are trying to do, as far as I can see.

@Majenko Thank you very much for your information. I thought that conversion from int to baud rate could be done just by casting the int to speed_t. Also I will try to implement protocol which you suggested.


text:
Ethernet Shield doesn't work at all
I connected corresponding pins of Arduino Nano and the Ethernet Shield, connected my computer to a router (the light indicated the connection) and Ethernet Shield to the same router. Nevertheless, there is no sign of connection on the router and the leds on the Shield don't light up either. I tried changing cables and Shields, but this didn't work. Here is my code example. What could be wrong?
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192, 168, 1, 3};
byte myDns[] = {192, 168, 1, 1};
byte gateway[] = {192, 168, 1, 1};
byte subnet[] = {255, 255, 255, 0};

EthernetServer server = EthernetServer(23);

void setup() {
// initialize the ethernet device
  Ethernet.begin(mac, ip, myDns, gateway, subnet);
  // start listening for clients
  server.begin();

  Serial.begin(9600);
  Serial.println(Ethernet.localIP());
  Serial.end();
}

try the examples of the Ethermet library. they have better diagnostic. what pins did you wire?

MISO, MOSI, SCK, CS to pin D10, RST, VCC to 3.3V and GND

the Ethernet shield is powered from 5V pin

Thank you, I think this will help


text:
Using an ATTiny85 and DigiKeyboard.h, can I detect when USB HID is connected?
I am building a project to send HID keystrokes to a computer with an ATTiny85. I want to detect when the USB communication is working, in order to turn on a LED saying that everything is good. If USB stops working, I want a watchdog to turn the LED off. Ideally it would also attempt to reconnect automatically.
DigiUSB has the DigiUSB.available() method, but DigiKeyboard does not, and I can't seem to use both headers in the same program because of conflicts. How can I do this without DigiUSB?

I see, well I would like to figure out any way to determine the connection status, and I'm coming up short.

@jsotola it is specifically in reference to using the attiny85 with a Micronucleus bootloader being programmed from the Arduino IDE. Unfortunately, delving into the complexities of V-USB and DigiKeyboard/DigiUSB headers is beyond my skill set, so I'm posting to try and find someone who does know.

Well, that's slightly complicated. It appears as two different devices in Windows - when first plugged in, it shows up under libusb-win32 devices as Micronucleus, and then after the 5-second bootloader timeout that becomes disconnected and then it shows up as HID Keyboard. I haven't had an issue with it disconnecting randomly, but I'm attempting to think ahead in case such a thing did happen. For example, the board has a separate power input independent of the USB power, so if comms are lost and the board still has power, I want it to be able to detect that and provide an output.

some thoughts ... turn the LED on when the device is enumerated ... turn the LED off when the device misses getting polled a couple of times .... reset the device when the device misses getting polled 10 times or so