Go Down

Topic: NRF24L01 wireless info transmission problem  (Read 2362 times) previous topic - next topic

Emre13

Jun 29, 2017, 07:23 pm Last Edit: Jun 29, 2017, 07:29 pm by Emre13
I have been working on a project lately and I keep bumping into trouble. The Setup is pretty basic there will be multiple sensors connected to different places in our farm and they will send information to a monitor located inside my house. But hey lets test each module to check whether or not the connection is working or not...And they don,t! I am using the nrf24l01 wireless com module, the code is pretty self explanatory. I used to use an older version of the nrf24 library but with a little bit of digging I thought that upgrading to tmrh20 library... and now it does not even complete the loop. My connections are all right. last time I did not have a receiver while I was using the autoACK() and obviously It did not work anyway I still cant make it work and I have made some fixes to the setup...it still does not work.

// The transmitter code is as follows just ignore the parts about temperature readings  

Code: [Select]
#include <SPI.h>

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

#include <OneWire.h>

#ifndef __PRINTF_H__
#define __PRINTF_H__

#ifdef ARDUINO

int serial_putc( char c, FILE * )
{
  Serial.write( c );

  return c;
}

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

#else
#error //This example is only for use on Arduino.
#endif // ARDUINO

#endif // __PRINTF_H__

int DS18S20_Pin = 2; // sets data pin to pin2


OneWire ds(DS18S20_Pin);  

// wifi info
const int CSN = 10;
const int CE = 9;
byte LED1 = 3;
byte LED2 = 4;
byte counter = 1; //used to count the packets sent
bool done = false;
RF24 radio(CE,CSN); //CE, CSN
const uint64_t rAdress = 0xE8E8F0F0E1LL;

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

  fdevopen( &serial_putc, 0 );
  
  radio.begin();            //Start the nRF24 module
  radio.setAutoAck(1); // / Ensure autoACK is enabled so rec sends ack packet to let you know it got the packet
  radio.enableAckPayload();
  
  radio.openWritingPipe(rAdress);  //open writing pipe
  radio.setPALevel(RF24_PA_MAX);
  radio.stopListening(); //go into transmit mode
  radio.printDetails();

  pinMode(LED1, OUTPUT);  
  pinMode(LED2, OUTPUT);  
  
  }

void loop(void) {

 
    
  // gets the temperaute in celcius from the ds18s20
  float temperature = getTemp();
  
  Serial.print("Temperature: "); // shows the temperature value
  Serial.println(temperature);
 
 
  Serial.print("Now send packet: ");
    Serial.println(counter); //serial print the packet number that is being sent
    unsigned long time1 = micros();  //start timer to measure round trip
  
     Serial.print("The payload size is:  ");
    Serial.println(radio.getDynamicPayloadSize());
    //send or write the packet to the rec nRF24 module. Arguments are the payload / variable address and size
    
   if (!radio.write(&temperature,sizeof(float))){  //if the send fails let the user know over serial monitor
       Serial.println("packet delivery failed");  
      
       digitalWrite(LED2, HIGH);  // leds are good manual tools to check if everything is working well
 
 digitalWrite(LED1,LOW);
      
   }
  
  else { //if the send was successful
      
      unsigned long time2 = micros(); //get time new time
      
      time2 = time2 - time1; //calculate round trip time to send packet
      Serial.print("Time from message sent to recieve Ack packet: ");
      Serial.print(time2); //print the time to the serial monitor
      Serial.println(" microseconds");
       counter++; //up the packet count
      
       if (temperature < -273) { // when the sensor is not connceted the getTemp() function prints -1000 and -273C is the coldest it can can in this universe...
  
  Serial.println("ERROR: TEMPERATURE SENSOR NOT CONNECTED!");
  digitalWrite(LED2, HIGH);
 
 digitalWrite(LED1,LOW);}

 else if ( radio.write(&temperature,sizeof(temperature)) && temperature < -273 ) {

  digitalWrite(LED2, LOW);
 
 digitalWrite(LED1,HIGH);}
  
  
  }
  
  delay(100);
  
  
      
  

}



float getTemp(){ //returns the temperature from one DS18S20 in DEG Celsius
  

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;

  return TemperatureSum;

}

// Serial output for this is as follows and neither LEDs light
Code: [Select]
STATUS = 0x0e RX_DR=0 TX_DS=0 STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe8e8f0f0e1 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe8e8f0f0e1
RX_PW_P0-6 = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x03 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
Temperature: 26.19
Now send packet: 1
The payload size is:  0

// this means the code has some trouble with the if(radio.write()) part as it just stops there

//The receiver code is as follows

Code: [Select]
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

#include <OneWire.h>

#ifndef __PRINTF_H__
#define __PRINTF_H__

#ifdef ARDUINO

int serial_putc( char c, FILE * )
{
  Serial.write( c );

  return c;
}

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

#else
#error //This example is only for use on Arduino.
#endif // ARDUINO

#endif // __PRINTF_H__

// wifi info
const int CSN = 10;
const int CE = 9;
byte LED1 = 3;
byte LED2 = 4;
byte counter = 1; //used to count the packets sent
RF24 radio(CE,CSN); //CE, CSN
const uint64_t tAdress = 0xE8E8F0F0E1LL;

float temperature = -1000;
int payload_size;

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

  fdevopen( &serial_putc, 0 );
  
  radio.begin(); //Start the nRF24 module
   radio.setAutoAck(1); // / Ensure autoACK is enabled so rec sends ack packet to let you know it got the packet
  radio.enableAckPayload();
  radio.openReadingPipe(1,tAdress);  //open reading pipe
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening(); //go into receiving mode
  radio.printDetails();
  

}

void loop() {

  while(radio.available()){
    Serial.println("comms available");
     radio.read( &temperature, sizeof(float) ); //read size of data and store it in tempersture variable
     Serial.print("Temperature: "); //payload counts packet number
     Serial.println(temperature); //print payload / packet number
    }
    Serial.println("no comms available");
    Serial.print("The payload size is:  ");
    payload_size = radio.getDynamicPayloadSize();
    Serial.println(payload_size);
    delay(1000);

  
    

}


The serial output for this part is as follows

Code: [Select]
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xe8e8f0f0e1
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x02
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0f
DYNPD/FEATURE = 0x03 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0
no comms available
The payload size is:  0


// I guess no signal ever leaves the transmitter what may be the problem ? I know these nrf24l01 modules work properly, it either has something to do with my code or I had done something wrong uploading the library or something...can you please help.

terryking228

Hi,

Take a look at This Page which has lots of nRF24L01 How-To.

I suggest you get a simple example working with only the radios, and THEN integrate your other parts..
Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

Emre13

Sir I have done that...these modules do work...just not with my application, that indicates some problem on my part, I just can't see through it and I need help. Still thanks for the fast response.

Robin2

Try the examples in this Simple nRF24L01+ Tutorial

It will be much easier to help if you are working with code that I am familiar with.

Have you got 10µF capacitors across Vcc and GND for your nRF24 modules?

Are you using the regular modules with the PCB antenna or the high-power modules with the external antenna? I believe the Arduino 3.3v pin cannot provide enough current for the high power module.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Emre13

I am using the internal antenna ones, I do not have any 10uF capacitors at the moment, I do have 100UF capacitors though I do not know if using those will cause any problems

CrossRoads

100uF will be fine, will help to hold the supply voltage even steadier.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Whandall

Code: [Select]
    Serial.println(radio.getDynamicPayloadSize());


getDynamicPayloadSize returns the size of the next unread received packet,
it absolute nonsense in the context you are using it.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Emre13

#7
Jun 29, 2017, 11:50 pm Last Edit: Jun 29, 2017, 11:57 pm by Emre13
@Whandall

I used it to understand if anything at all was being received or not, it gives 0 bytes so nothing at all was received... I kind of am desperate at this point so I am using every method I can think of to understand what is going on. I thought it might be a good idea that way...Anyway even if it was nonsense it probably has nothing to do with the error I am facing at the moment.


EDIT: wait you are talking about the transmitter code I used it on both transmitter and receiver to be monitoring absolutely everything.

Whandall

#8
Jun 30, 2017, 12:15 am Last Edit: Jun 30, 2017, 12:39 am by Whandall
I used it to understand if anything at all was being received or not,
Lame excuse IMHO. What do you think radio.available() is for?

You should study the NRF datasheet to understand its operation, if you had you would have removed
Code: [Select]
radio.stopListening(); //go into transmit mode

from setup (including the wrong comment).

radio.write() triggers the transition to transmit mode,
radio.stopListening() ends receive mode and enters standby mode.
radio.begin() starts the system in standby.



Start simple, I see no reason for your two sends in different places with the same data.

Code: [Select]
radio.setAutoAck(1); // / Ensure autoACK is enabled so rec sends ack packet to let you know it got the packet
  radio.enableAckPayload();

AutoAck is default (and explicit only needed if you use pipes 2 to 5 IIRC), AckPayloads are not used.

Your receiver code:

Use if not while, loop does that part.

Again there is the misunderstanding of getDynamicPayloadSize():
you remove all packets, and then ask the chip how long the current packet is.
Printing unconditionally "no comms available" and "The payload size is:  0" each second
seems to me pointless and obfuscating.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Emre13

#9
Jun 30, 2017, 01:02 am Last Edit: Jun 30, 2017, 01:20 am by Emre13
@Whandall

I currently am not looking for excuses, I came here to find help as I do know my code is not perfect...If I was the best programer I would not have been here in the first place don't you think. I am just trying to figure out what is going wrong...
well I have tried if (radio.available()) { receiver code here}, it returns false every time and does not work I changed the code to this form after that. By the way I transformed a code from a tutorial and I did not want to take many things out... Thanks for the info by the way, so how do I "remove all packets" as you have said in your comment could you explain that a little deeper. I am not a software engineer you see am a 17 year old, who just graduated from secondary school. So I naturally do not know much about radio communication but I do want to make life easier at the ranch. So as far as I understand from your comment what ever the transmitter sends the receiver will always print "no comms available" am I correct so why is that? As far as I understand the radio.write() does not properly work or does it if so what am I doing wrong exactly, and the first time I used radio.available() it again failed why might that be? Thanks for the response by the way it did help me understand a little bit better. So to solve the issue what should I do next, please give me some guidance, preferably as dot points.

Edit: I took a look at the nrf24l01s data sheet but that has no information on the code how is that supposed to help me?

Edit to Edit: okay I have found the SPI commands which I may be able to use but first how do I use R_RX_Payload and W_TX_Payload  commands exactly?

Whandall

Code: [Select]
  while (radio.available()) {
    radio.read(....);
  }

Removes obviously all packets, doesn't it?

Even if you change that into an 'if', loop will so fast, that under normal circumstances you will pick up each packet
before you call getDynamicPayloadSize() which will always return zero,
because it is only valid when a packet is waiting for download.
It may even return zero if a packet arrived that has no payload (which is legal).

If I was the best programer I would not have been here in the first place don't you think.
Some people are here without seeking help, so being here (and even asking questions about unknown areas)
does not qualify you as a non-programmer.

So I naturally do not know much about radio communication but I do want to make life easier at the ranch.
That's like saying "I don't know much about surgery, but I do want to make life easier at the hospital.".
Maybe it even makes life easier in the hospital (because there will be less living patients),
but you will make life harder for the morgue department.

You don't have to be an expert in wireless communications to get a wireless system running,
but you need at least some basic understanding what is going on.

Edit: I took a look at the nrf24l01s data sheet but that has no information on the code how is that supposed to help me?

Edit to Edit: okay I have found the SPI commands which I may be able to use but first how do I use R_RX_Payload and W_TX_Payload  commands exactly?
The state transition diagram tells you how the different modes are reached and how long the transitions will take.
The datasheet is the only place of documentation for the pipe system, which you have to understand
if you want to use the chip in more advanced ways.

R_RX_Payload is used by radio.read(), W_TX_Payload by radio.write(), you do not need to use the raw commands.
A look at the library source code could have told you that.

Start with a simple send / receive sketch which you can expand after it works.

You probably supply the 3.3V for the NRF from the unspecified Arduino,
that will only work reliably with a 2 - 10 µF capacitor attached directly to the NRFs power pins.
(A bigger value will probaly work too, but if it gets too big it could detach your USB device by demanding
a too strong power up current.)

It seems to me that the transmitter NRF stops working when sending the first packet,
which is an indication of either bad wiring or a bad power supply.
As radio.printDetails() works, a wiring problem is mostly ruled out.

So I would add capacitors to all NRFs before going on.
(You could also use an adapter board with its own regulator and a capacitor but that is not really needed.)
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Robin2

Start with a simple send / receive sketch which you can expand after it works.
+1

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Emre13


@Whandall

Well I have written a very simple test code to verify that everything is working alright and installed 10uF capacitors between 3.3V and GND (which I salvaged from broken electronics this morning).

The transmitter code is as follows

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>




const int CSN = 10;
const int CE = 9;
RF24 radio(CE,CSN); //CE, CSN
const uint64_t rAdress = 0xABCDABCD71LL;
char test[4]= "test";


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

 
 
  radio.begin();            //Start the nRF24 module
  radio.openWritingPipe(rAdress);  //open writing pipe
 
  }

void loop(void) {

 Serial.println("Sending");
    radio.write(test,sizeof(test));

    Serial.println("done");
   
}

And the receiver code is as follows
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

const int CSN = 10;
const int CE = 9;
RF24 radio(CE,CSN); //CE, CSN
const uint64_t tAdress = 0xABCDABCD71LL;
char test[4]= "";


void setup() {
  Serial.begin(9600);
  radio.begin(); //Start the nRF24 module
   
  radio.openReadingPipe(1,tAdress);  //open reading pipe
  radio.startListening(); //go into receiving mode
 

}

void loop() {
  // put your main code here, to run repeatedly:

if (radio.available()) {radio.read( &test, sizeof(test) );
Serial.println(test);
Serial.println("com available");
}
}

The serial output for receiver is

com available
test
com available
test
com available
test
com available
test
com available
test
com available

so it worked like a charm after I followed your advice...You saved me a lot of trouble Thanks a lot.

Whandall

Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

terryking228

Based on this experience I added this at the top of the page:


http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

ALWAYS start with the simple Getting Started tests. THEN add your own code!

That page has received 45938 hits this June alone. So hopefully more people will start there...
Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

Go Up