[SOLVED] Arduino UNO and arduino mega boards keep resetting with nrf24L01 module

I´m going crazy soon.

I have this project which consists of two Arduinos, one Uno and one Mega that should talk to each other via nrf24L01 modules. The end goal is to send joystick data between them but for now I´m just happy to have the code running sending pings and pongs back and forth. I can get the code to work but as soon as the establish connection the boards reset i.e they exit the “look_for_…” -function. I thought the problem was with the serial.println function and that the boards run out of memory but I have also tried the code without printing stuff but then it´s difficult to see whats happening =). As usual it´s probably something simple that I´m doing wrong but I will post the code anyway and maybe someone spots the problem right away.

#include <SPI.h>
#include <avr/sleep.h>

#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>

#include <MemoryFree.h>

int left_joy_x_pin = A0;
int left_joy_y_pin = A1;
int right_joy_x_pin = A2;
int right_joy_y_pin = A3;
int left_joy_x_value = 0;
int left_joy_y_value = 0;
int right_joy_x_value = 0;
int right_joy_y_value = 0;

int joy_keypad_buttons = 0;
char left_joy_buttons = 0;
char right_joy_buttons = 0;

char client_con_ok = 0;

void setup() {
  //---- Setup serial communication  -----//
  Serial.begin(115200);
  Serial.print(F("Welcome!"));

  //---- Setup I/O pins -----//

  //---- Setup interrupt ------//

  //---- Setup nRF24L01 module -----//
  Mirf.channel = 90;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init(); // Setup pins / SPI.
  Mirf.setRADDR((byte *)"serv1"); // Configure local address of this device.
  Mirf.payload = 32;  //Set payload size, payload on client and server must be the same.
  Mirf.config(); // Write channel and payload config then power up reciver.

  delay(500);
}

void loop() {

  look_for_client_connection();

  if (client_con_ok == 0) {
    if (look_for_client_connection() == 1)
      Serial.println(F("Connection to server established!"));
    else
      Serial.println(F("Connection to server failed!"));
  }

  //get_data_from client();
  delay(500);
}

byte look_for_client_connection() {
  byte data[5]  = "PING";
  byte data2[4] = "OK!";
  byte data3[5]  = "PONG";
  byte temp[5] = {0};
  int reply_timeout_counter = 0;
  byte n;

  Serial.println(F("Start searching for client device"));

  while (client_con_ok == 0) {
    Serial.println(F("Sending out PING"));  //Send PING to client

    Mirf.setTADDR((byte *)"clie1");      //Set adress to send data to...
    Mirf.send(data);                     //Send data
    while (Mirf.isSending()) {           //Wait for sending.
    }
    //    delay(50);
    reply_timeout_counter = 1000;

    while (reply_timeout_counter > 0) { //Wait for PONG back from client
      if (Mirf.dataReady()) {           //Check for incoming data
        Mirf.getData(temp);             //Read data from buffer
        n = memcmp(data3, temp, 4);

        if (n == 0) {
          Serial.println(F("PONG received from client"));
          Serial.println(F("Answer OK! back to client"));

          delay(30);
          Mirf.send(data2);                     //Send data
          while (Mirf.isSending()) {           //Wait for sending.
          }
          client_con_ok = 1;
        }
        else {
          Serial.println(F("Data receive ERROR"));
          break;
        }
      }
      delay(1);    //Pause for 1ms
      reply_timeout_counter--;
    }
  }
  return (client_con_ok);
}

It's nothing to do with serial print as that blocks when its buffer is full. So the next question is how are you powering all this?

Could we see your circuit diagram?

A link to the actual modules you are using would be use full.

Mark

If the boards are resetting from the code, it’s usually a memory issue.
Start debugging by taking away libraries. Not sure why you need the sleep library but I don’t think that’s the issue.

Thanks for the quick answers.
Here´s a link to the connection diagram

The Arduino board and the module is powered from USB (powered USB hub).

The sleep library is not needed at the moment so I tried the code without it, but the same result.

Here’s the output from both boards copied from realterm.

Output from client side (Arduino MEGA)
"Welcome!
Start searching for server device
PING received from server
Sending PONG back to server and wait for OK!
OK! received from server
<----- Board should print “Connection to server established!” or “Connection to server failed!” here but instead it restarts.
Welcome!
Start searching for server device
PING received from server
Sending PONG back to server and wait for OK!
OK! received from server
"

Output from server side (Arduino UNO), I added a print of the available memory but I´m not sure it´s the SRAM or the program memory.
"
Welcome!
freeMemory()=1790
Start searching for client device
Sending out PING
PONG received from client
Answer OK! back to client
<----- Board should print “Connection to client established!” or “Connection to client failed!” here but instead it restarts.
Welcome!
freeMemory()=1790
Start searching for client device
Sending out PING
PONG received from client
Answer OK! back to client
"

From what I can see the two boards does exactly what they are supposed to be doing but as soon as they leave the look_for…-function they reset. I also tried and do everything in the main-loop, like this…

void loop() {
  byte data[5]  = "PING";
  byte data2[4] = "OK!";
  byte data3[5]  = "PONG";
  byte temp[5] = {0};
  int reply_timeout_counter = 0;
  byte n;

 Serial.print("freeMemory()=");
 Serial.println(freeMemory());

//  look_for_client_connection();

  if (client_con_ok == 0) {

    
    
  Serial.println(F("Start searching for client device"));

  while (client_con_ok == 0) {
    Serial.println(F("Sending out PING"));  //Send PING to client

    Mirf.setTADDR((byte *)"clie1");      //Set adress to send data to...
    Mirf.send(data);                     //Send data
    while (Mirf.isSending()) {           //Wait for sending.
    }
    //    delay(50);
    reply_timeout_counter = 1000;

    while (reply_timeout_counter > 0) { //Wait for PONG back from client
      if (Mirf.dataReady()) {           //Check for incoming data
        Mirf.getData(temp);             //Read data from buffer
        n = memcmp(data3, temp, 4);

        if (n == 0) {
          Serial.println(F("PONG received from client"));
          Serial.println(F("Answer OK! back to client"));

          delay(30);
          Mirf.send(data2);                     //Send data
          while (Mirf.isSending()) {           //Wait for sending.
          }
          client_con_ok = 1;
        }
        else {
          Serial.println(F("Data receive ERROR"));
          break;
        }
      }
      delay(1);    //Pause for 1ms
      reply_timeout_counter--;
    }
  }
    
/*
    if (look_for_client_connection() == 1)
      Serial.println(F("Connection to server established!"));
    else
      Serial.println(F("Connection to server failed!"));
*/
  }


 Serial.print("freeMemory()=");
 Serial.println(freeMemory());


    if (client_con_ok == 1)
      Serial.println(F("Connection to server established!"));
    else
      Serial.println(F("Connection to server failed!"));

  //get_data_from client();
  delay(500);
}

And then the output to realterm is…
"
Welcome!
Start searching for server device
PING received from server
Sending PONG back to server and wait for OK!
OK! received from server
freeMemory()=7847
Connection to server established!
<---- Everything seems to be fine up until here, but then the board resets… It´s the same for the server side also.
Welcome!
Start searching for server device
"

I forgot to attach the client side code, but it´s basically the same as the server only minor differences.

#include <SPI.h>
//#include <avr/sleep.h>

#include <LiquidCrystal.h>

#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>

#define WAIT_FOR_SLEEP 60000

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
char mirf_int = 3;
char wake_up = 2;

int left_joy_x_pin = A0;
int left_joy_y_pin = A1;
int right_joy_x_pin = A2;
int right_joy_y_pin = A3;
int left_joy_x_value = 0;
int left_joy_y_value = 0;
int right_joy_x_value = 0;
int right_joy_y_value = 0;

int joy_keypad_buttons = 0;
char left_joy_buttons = 0;
char right_joy_buttons = 0;

char sleepmode_active = 0;

char server_con_ok = 0;

//byte look_for_server_connection();

void setup() {
  //---- Setup serial communication  -----//
  Serial.begin(115200);
  Serial.println(F("Welcome!"));
  
  //---- Setup I/O pins -----//
  pinMode(wake_up, INPUT_PULLUP);
  pinMode(mirf_int, INPUT_PULLUP);
//  pinMode(49, OUTPUT);
//  pinMode(53, OUTPUT);

  //---- Setup interrupt ------//
//  attachInterrupt(0, wake_up_button, FALLING);    //Interrupt channel 0
//  attachInterrupt(1, mirf_interrupt, FALLING);    //Interrupt channel 1
  
  //---- Setup LCD display ------//
  lcd.begin(16, 2);
  lcd.print("    Welcome!    ");

  //---- Setup nRF24L01 module -----//
//  Mirf.csnpin = 49;
//  Mirf.cepin = 53;
  Mirf.channel = 90;              // Start channel
  Mirf.spi = &MirfHardwareSpi;   // Set the SPI Driver.
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");   // Configure local address of this device.
  Mirf.payload = 32;  //Set payload size, payload on client and server must be the same.
  //Mirf.payload = sizeof(unsigned long);
  //  Write channel and payload config then power up reciver.
  Mirf.config();

  // Configure sleep mode to save power.
//  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
//  sleep_enable();

  // Set the address to send data to.
  //  Mirf.setTADDR((byte *)"clie1");
  delay(500);
}

void loop() {

//look_for_server_connection();

    if(server_con_ok == 0) {
        if(look_for_server_connection())
          Serial.println(F("Connection to server established!"));
        else
          Serial.println(F("Connection to server failed!"));
        }

    delay(500);  
}


byte look_for_server_connection() {
  byte data[5]  = "PONG";
  byte data2[4] = "OK!";
  byte data3[5]  = "PING";
  byte temp[5] = {0};
  unsigned int reply_timeout_counter = 1000;
  unsigned int goto_sleep_counter = WAIT_FOR_SLEEP;
  byte n;

Serial.println(F("Start searching for server device"));

while (server_con_ok == 0) {
      if (Mirf.dataReady()) {           //Check for incoming data
        Mirf.getData(temp);             //Read data from buffer
        n = memcmp(data3,temp, 4);

        if(n == 0) {      //Is incoming data = PING ?
          Serial.println(F("PING received from server"));
          Serial.println(F("Sending PONG back to server and wait for OK!"));
          Mirf.setTADDR((byte *)"serv1");      //Set server adress
          Mirf.send(data);                     //Send data
          while (Mirf.isSending()) {           //Wait for sending.
          }
//          delay(30);

          while(reply_timeout_counter > 0) {    //Wait for OK! back from master
            if (Mirf.dataReady()) {           //Check for incoming data
              Mirf.getData(temp);             //Read data from buffer 
              n = memcmp(data2,temp, 3);
  
              if(n == 0) {
                Serial.println(F("OK! received from server"));
        //        delay(50);
                server_con_ok = 1;
                break;            
              }
              else {
                Serial.println(F("OK! not received from server"));
              }
            }
               if(reply_timeout_counter > 0)
                 reply_timeout_counter--;
               else {
                 Serial.println(F("Reply timeout from server"));      // If not, go back to listening mode
                 break;
               }
             }
      }
      else {
        Serial.println(F("Data receive ERROR1"));      // If not, go back to listening mode
        goto_sleep_counter = WAIT_FOR_SLEEP;
        break;
      }
	}
	else {
      if (goto_sleep_counter == 0) {
        goto_sleep();
//--- Program resumes here after waking up from sleep ----//
        goto_sleep_counter = WAIT_FOR_SLEEP;
      }
      else
        goto_sleep_counter--;
     
      if ((goto_sleep_counter % 500) == 0)
 //       Serial.println("Listening for master device ");

      delay(1);                         //1ms delay
    }
  }
return(server_con_ok);
}

void goto_sleep() {
    sleepmode_active = 1;
    Serial.println(F("Going to sleep"));
    delay(100);
//    set_sleep_mode(SLEEP_MODE_STANDBY);   // sleep mode is set here
//    sleep_enable();
//    sleep_mode();    // here the device is actually put to sleep!!
}


void mirf_interrupt() {
  Serial.println(F("Wake up! Radio data received"));
  if(sleepmode_active == 1) {
//    sleep_disable();
//    sleepmode_active = 0;
  }  
}

void wake_up_button() {
  Serial.println(F("Wake up! Button pressed"));
  if(sleepmode_active == 1) {
//    sleep_disable();
//    sleepmode_active = 0;
  }  
}

Problem solved!

Turned out that I tried to cram 32 bytes of data in to an array with lenght of only 5 =)

Mirf.payload = 32;
.
.
.
.
temp[5] ={0}; <--This also have to hold 32 bytes otherwise the Mirf.getdata will write outside the array and crash the Arduino.
.
.
.
Mirf.getData(temp);
.
.