Communication-issue between two ATMEGA328P with NRF24l01

Hi everyone.

I'm currently working on a small project for my room. If i push a button (later CapSense) i want to increase / decrease a value(ledBrightness) and send the Value to the room-lamp
Here's a simple schematic of my hardware:

Master: Sensor/Pixels (installed on the bed): Room-Lamp:
[Iboard+NRF24l01]-->[ATMEGA328P+NRF24l01+CapSensor+WS2801-Pixels]--->[ATMEGA328P+NRF24l01+Mosfet->LED]

The ATMEGA's are currently placed on a breadboard with a external 16Mhz-clock crystal, later the will get on a PCB.
I'm still a beginner, so i have to be honest that i don't really understand what exactly happens in the line:

radio.write( &ledBrightness, sizeof(uint8_t) );

...especially all the things in the background... :frowning:

My question is about the communication between the NRF24l01's. The code below works, but he does not work properly. Sometimes Data (ledBrightness) get's transferred without any problems, but sometimes the receiver stops receiving data. Even when i release the switch and wait 20s and press it again, the receiver seems to be freezed. I noticed that the Serial-ouput from the receiver gets slower as bigger the ledBrightness-value is. Is the sendig-rate too high? Or did i messed something with the datatypes? Can anyone point me in the right direction? Thank you

I had to remove some code because the max. of 9500 characters, so it wont compile.

Code of the Sensor/Pixels (installed on the bed)

#include <CapacitiveSensor.h>
#include <CapacitiveSensor.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include "WS2801.h"

uint8_t ledBrightness = 0;             // Value that holds the brightness of the LED
uint8_t factor= 30;                    // Factor for the sample-resolution of cap-sense
uint8_t red,blue,green;                // RGB values of the LED-Strip
uint8_t pipe_num;                      // Value that holds the Pipenumber of the incoming NRF-Data
uint8_t dataPin = 2;                   // SPI DataPin for the WS2801    
uint8_t clockPin = 3;                  // SPI ClockPin for the WS2801 
uint8_t StripDelay = 50;               // Delay for the LED-Pixels

boolean increase = true;               // When variable is true, ledBrightness gets increased, otherwise decreased
boolean exitWhileTouch = false;        // Variable to exit WhileTouch loop


char inCharNRF;                        // Char used receiving the NRF-Data    

// Set up WS2801 LED-Strip
WS2801 strip = WS2801(9, dataPin, clockPin);

// Configure RF Radio pins
RF24 radio(9,10);

// Radio pipe addresses for the nodes to communicate
const uint64_t pipes[5] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL, 0xF0F0F0F0D3LL, 0xF0F0F0F0D4LL, 0xF0F0F0F0D5LL };

// Configure capacitive sensor-input
CapacitiveSensor   cs_4_6 = CapacitiveSensor(4,6);    

//#define SERIAL_DEBUG_BOOL 1          // serial debug on for all boolean variables
#define SERIAL_DEBUG_INT 1           // serial debug on for all int variables
//#define SERIAL_DEBUG_OTHER 1         // serial debug on for other serial prints


void setup() 
{ 
  pinMode(8, INPUT); //button pin for increase / decrease ledBrightness
  Serial.begin(115200);
  strip.begin();
  
  radio.begin(); 
  radio.setRetries(15,15);
  radio.setPayloadSize(2);
  readingMode();
}

void loop ()
{

  // if (long total =  cs_4_6.capacitiveSensor(factor)> 200) 
  // !!!currently working with a simple digital-read to avoid problems with the capsense sensor
  if (digitalRead(8) == HIGH)
  {
    writingMode(); // Set the NRF24L01 in the writing-mode
    sensorRead();  // Read the Capsense 
    readingMode(); // Set the NRF24L01 in the reading-mode
  }

  /*************************************Waiting for Data from NRF24l01***************************************************/

  if (radio.available(&pipe_num) )
  {
    #ifdef SERIAL_DEBUG_OTHER
    Serial.println("Received data from master");
    #endif
  
     ...removed code here...should not be importand..

  } // end of: if (radio.available(&pipe_num))
  

  }


} // end of void loop()


/************************************* detection of the Capsensor ***********************************************/

void sensorRead()

{ 
  #ifdef SERIAL_DEBUG_OTHER
  Serial.println("I'm now in void sensorRead");
  #endif

  // while (long total =  cs_4_6.capacitiveSensor(factor) > 300 and exitWhileTouch == false)
  // !!!currently working with a simple digital-read to avoid problems with the capsense sensor
  while (digitalRead(8) == HIGH and exitWhileTouch == false)
  {   

    if (increase == true)
    {
      ledBrightness += 5; 
    }
    else
    {
      ledBrightness -= 5;
    }
    
    #ifdef SERIAL_DEBUG_INT 
    Serial.print("ledBrightness: ");
    Serial.println(ledBrightness);
    #endif
    
    if (ledBrightness <= 0) // ledBrightness is equal / less than 0 --> exit and change direction
    { 
      exitWhileTouch = true;
      delay(1000);  // Delay do give time to take your hand away from the sensor

      #ifdef SERIAL_DEBUG_OTHER
      Serial.println("Exit while touch true because brightness == 0");
      #endif
    }
    else if (ledBrightness >= 255) // ledBrightness is equal / greater than 255 --> exit and change direction
    { 
      exitWhileTouch = true;
      delay(1000);  // Delay do give time to take your hand away from the sensor

      #ifdef SERIAL_DEBUG_OTHER
      Serial.println("Exit while touch true because brightness == 255");
      #endif
    }

    radio.write( &ledBrightness, sizeof(uint8_t) );
    delay(100); // Delay for the decrease / increase speed
   
  } // end of: while loop
  
  exitWhileTouch = true; // sensor is inactive now or ledBrightness was 255 or zero
  
  if (exitWhileTouch == true) // change the direction whenever we run through the while-loop
  {
    increase == true ? increase = false : increase = true;
    exitWhileTouch = false;
  }
  
} // end of: void sensorRead()
/***************************************** Modes for the NRF24l01 ************************************************/
void readingMode()
{ 
  radio.openReadingPipe(2,pipes[1]);
  radio.openReadingPipe(3,pipes[2]);
  radio.openReadingPipe(4,pipes[3]);
  radio.openReadingPipe(5,pipes[4]);
  radio.startListening();

  #ifdef SERIAL_DEBUG_OTHER
  Serial.println("NRF is now in reading-mode");
  #endif
}

void writingMode()
{ 
  radio.stopListening();
  radio.openWritingPipe(pipes[0]);

  #ifdef SERIAL_DEBUG_OTHER
  Serial.println("NRF is now in writing-mode");
  #endif
}

Code of Room-Lamp

#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include "WS2801.h"
#include <SPI.h>

uint8_t optocoupler = 0;               // Value that holds the analogvalue of the optokoppler
uint8_t optocouplerPin = 0;            // Number of the Pin where the optocoupler is attached to
uint8_t ledBrightness;                 // Value that holds the brightness of the LED
uint8_t ledPin = 3;                    // Number of the Pin where the LED is attached to

boolean b_optocoupler = false;         // Variable that holds the state of the optocoupler
boolean b_lastState = true;            // Variable that holds the last state of the optocoupler

// Configure RF Radio pins
RF24 radio(9,10);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[5] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL, 0xF0F0F0F0D3LL, 0xF0F0F0F0D4LL, 0xF0F0F0F0D5LL };

//#define SERIAL_DEBUG_BOOL 1          // serial debug on for all boolean variables
#define SERIAL_DEBUG_INT 1           // serial debug on for all int variables
//#define SERIAL_DEBUG_OTHER 1         // serial debug on for other serial prints


void setup()  
{  
  Serial.begin(115200);
  pinMode(optocouplerPin, INPUT);      // Analoginput used for the optocoupler
  pinMode(ledPin, OUTPUT);             // PWM-Ouput used for the LED

  radio.begin();
  radio.setRetries(15,15);
  radio.setPayloadSize(2);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
}

void loop ()
{    
  if (radio.available())
  {
    // Dump the payloads until we've gotten everything

    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &ledBrightness, sizeof(unsigned long) );
    }
    #ifdef SERIAL_DEBUG_INT 
    Serial.print("ledBrightness: ");
    Serial.println(ledBrightness);
    #endif
    
    analogWrite(ledPin,ledBrightness); 


  } // end of: if (radio.available())

  /*************************************     State change detection    ***************************************************/

  analogRead(optocoupler) >= 500 ? b_optocoupler = true : b_optocoupler = false;

   #ifdef SERIAL_DEBUG_BOOL 1
   Serial.print("optocoupler-state: ");
   Serial.println(b_optocoupler);
   delay(500);
   #endif

 ...removed code here...should not be importand..

  b_lastState = b_optocoupler ; // store the current state 


}   // end of void loop

Busi4:
I had to remove some code because the max. of 9500 characters, so it wont compile.

You can add attachments.

How to use this forum

From your description you have three Arduinos each with an RF24 transceiver and all using the same set of addresses.

It's not clear to me why you have five addresses, and it's not clear whether you have got each Arduino listening on a unique address. If you have multiple transceivers in range and listening to the same address then you can get a situation where the same message is received in multiple places and the acknowledgments trample over each other, so the sender doesn't get a clean acknowledgment.

I suggest you start by simplifying your setup so you have one sender and one receiver, with each receiver listening to a single address, and get that working. It should be simple enough just based on the standard examples for whichever RF24 library you're using.

Then get it clear in your head which of these two devices the third Arduino will be sending to, and write that to send to the corresponding address. If you have three Arduinos, that should need a total of three addresses and each address should only have one Arduino listening to it.

I had to remove some code because the max. of 9500 characters, so it wont compile.

But, you have this:

#include <CapacitiveSensor.h>
#include <CapacitiveSensor.h>

Some particular reason you need that twice? Some particular reason you need that twice?

Sorry for not reading both topics. :~

@ PeterH

I followed your advice and made the sketches more simple. Still got the same issue. But i had a strange serial output, there was some text of Nick Gammon Atmega_Board_Programmer i've burned the arduino bootloader with. I've attached the picture.

Transmitter:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

uint8_t ledBrightness = 0;             // Value that holds the brightness of the LED

boolean increase = true;               // When variable is true, ledBrightness gets increased, otherwise decreased
boolean exitWhileTouch = false;        // Variable to exit WhileTouch loop


// Configure RF Radio pins
RF24 radio(9,10);

// Radio pipe addresses for the nodes to communicate
const uint64_t pipes[1] = {0xF0F0F0F0E1LL};

//#define SERIAL_DEBUG_BOOL 1          // serial debug on for all boolean variables
//#define SERIAL_DEBUG_INT 1           // serial debug on for all int variables
//#define SERIAL_DEBUG_OTHER 1         // serial debug on for other serial prints


void setup() 
{ 
  pinMode(8, INPUT); //button pin for increase / decrease ledBrightness
  Serial.begin(115200);
  radio.begin(); 
  radio.setRetries(15,15);
  radio.setPayloadSize(2);
  radio.openWritingPipe(pipes[0]);
  
}

void loop ()
{

 // while (long total =  cs_4_6.capacitiveSensor(factor) > 300 and exitWhileTouch == false)
  // !!!currently working with a simple digital-read to avoid problems with the capsense sensor
  while (digitalRead(8) == HIGH and exitWhileTouch == false)
  {   

    if (increase == true)
    {
      ledBrightness += 10; 
    }
    else
    {
      ledBrightness -= 10;
    }
    
    #ifdef SERIAL_DEBUG_INT 
    Serial.print(F("ledBrightness: "));
    Serial.println(ledBrightness);
    #endif
    
    if (ledBrightness <= 0) // ledBrightness is equal / less than 0 --> exit and change direction
    { 
      exitWhileTouch = true;
      delay(1000);  // Delay do give time to take your hand away from the sensor

      #ifdef SERIAL_DEBUG_OTHER
      Serial.println(F("Exit while touch true because brightness == 0"));
      #endif
    }
    else if (ledBrightness >= 255) // ledBrightness is equal / greater than 255 --> exit and change direction
    { 
      exitWhileTouch = true;
      delay(1000);  // Delay do give time to take your hand away from the sensor

      #ifdef SERIAL_DEBUG_OTHER
      Serial.println(F("Exit while touch true because brightness == 255"));
      #endif
    }

    radio.write( &ledBrightness, sizeof(uint8_t) );
    delay(50); // Delay for the decrease / increase speed
    
  } // end of: while loop
  
  exitWhileTouch = true; // sensor is inactive now or ledBrightness was 255 or zero
  
  if (exitWhileTouch == true) // change the direction whenever we run through the while-loop
  {
    increase == true ? increase = false : increase = true;
    exitWhileTouch = false;
  }
} // end of void loop()

Receiver:

#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <SPI.h>


uint8_t ledBrightness;                 // Value that holds the brightness of the LED
uint8_t ledPin = 3;                    // Number of the Pin where the LED is attached to

// Configure RF Radio pins
RF24 radio(9,10);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[1] = {0xF0F0F0F0E1LL};

//#define SERIAL_DEBUG_BOOL 1          // serial debug on for all boolean variables
//#define SERIAL_DEBUG_INT 1           // serial debug on for all int variables
//#define SERIAL_DEBUG_OTHER 1         // serial debug on for other serial prints


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

  pinMode(ledPin, OUTPUT);             // PWM-Ouput used for the LED

  radio.begin();
  radio.setRetries(15,15);
  radio.setPayloadSize(2);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
}

void loop ()
{    
  if (radio.available())
  {
    // Dump the payloads until we've gotten everything

    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &ledBrightness, sizeof(unsigned long) );
    }
   
    #ifdef SERIAL_DEBUG_INT 
    Serial.print(F("ledBrightness: "));
    Serial.println(ledBrightness);
    #endif
    
    analogWrite(ledPin,ledBrightness); 


  } // end of: if (radio.available())

}   // end of void loop

Alright, first i changed sizeof() in the receiver code:

  bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &ledBrightness, sizeof(unsigned long) );
    }
  bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &ledBrightness, sizeof(uint8_t) );
    }

But that was not the reason.
Then i tried to comment out the analogWrite(ledPin,ledBrightness). Afther that, the receiving worked flawlessly. Does anybody know what the problem could be? I've already tried with another output (Pin 6) and also with a ArduinoUNO board.

Code of the receiver:

#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <SPI.h>


uint8_t ledBrightness;                 // Value that holds the brightness of the LED
uint8_t ledPin = 6;                    // Number of the Pin where the LED is attached to

// Configure RF Radio pins
RF24 radio(9,10);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[1] = {
  0xF0F0F0F0E1LL};

//#define SERIAL_DEBUG_BOOL 1          // serial debug on for all boolean variables
#define SERIAL_DEBUG_INT 1           // serial debug on for all int variables
//#define SERIAL_DEBUG_OTHER 1         // serial debug on for other serial prints


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

  //pinMode(ledPin, OUTPUT);             // PWM-Ouput used for the LED

  radio.begin();
  radio.setRetries(15,15);
  radio.setPayloadSize(1);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
}

void loop ()
{    
  if (radio.available())
  {
    // Dump the payloads until we've gotten everything

    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &ledBrightness, sizeof(uint8_t) );
    }

    #ifdef SERIAL_DEBUG_INT 
    Serial.print(F("ledBrightness: "));
    Serial.println(ledBrightness);
    #endif

    //  analogWrite(ledPin,ledBrightness);
  } // end of: if (radio.available())



}   // end of void loop

Then i tried to comment out the analogWrite(ledPin,ledBrightness). Afther that, the receiving worked flawlessly. Does anybody know what the problem could be?

When you stop using PWM, which uses timers (which one depends on which pin), and other code then starts behaving properly, that's a clue that the other code was trying to use the same timer.

I'm curious why you are connecting the radio to two PWM pins. Is that a requirement of the library?