Go Down

Topic: Strange behaviour of radio.openWritingPipe with NRF24L01 (Read 160 times) previous topic - next topic

wonderfuliot

May 18, 2018, 01:27 pm Last Edit: May 18, 2018, 01:29 pm by wonderfuliot
I am attaching two codes, one for Rx and one for Tx for NRF24L01. The Tx code has variable 'address' defined locally as well as globally. When global is enabled, it works, but when local is enabled, it does not. Why? I see no reason. setAddressWidth is set to 4 so only 4 bytes of address are supposed to beused irrespective of local or global. Its strange.

Thanks,
WonderfulIOT

Robin2

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

wonderfuliot

It matters. This code is a part of larger code. I spent 2 days to figure out this nasty behaviour. I dont want a global variable to hold the address and the library wants it to be global, probably not intentional. I have no idea why. Hopefully somebody can explain.

Robin2

I dont want a global variable to hold the address and the library wants it to be global,
Maybe that is because local variables go out of scope. Or maybe because the compiler puts the local variable in a register.

Have you tried making the local variable static?

Have you looked at the library source code to see what it is expecting?


And, more simply, what harm would it be to use a global variable?

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

wonderfuliot

I felt its to do with stack variables in Arduino and ran a sample code.
The code prints 3 lines, first is the address of p1 and then the values of p2, p3 respectively as 8 and 9.
However the moment we disable the print_addr by making '#if 0' the p2 and p3 are printed as 9 and 0.
Interesting, but why?

Code: [Select]


void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400);
  uint8_t  p1 = 8;
  uint8_t  p2 = 9;

  uint8_t* p = (void*) &p2;
  #if 1
  uint16_t print_addr = &p1;
  Serial.println(print_addr, HEX);
  #endif

 
  Serial.println(*p);
  p++;
  Serial.println(*p);

}

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

}


Whandall

You are using the wrong datatype for the address,
it is supposed to be 5 bytes, you are supplying only 4.

Code: [Select]
uint32_t addresses = 1;

The fifth byte will be taken from behind the variable, which will probably be different in both cases.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

wonderfuliot

You are using the wrong datatype for the address,
it is supposed to be 5 bytes, you are supplying only 4.

The fifth byte will be taken from behind the variable, which will probably be different in both cases.
Yes, but the address width is already set to 4 bytes by a call to setAddressWidth(4) and the implementation of openWritingPipe takes care of the address width. See the 2 write_register calls.
Code: [Select]

void RF24::openWritingPipe(const uint8_t *address)
{
  // Note that AVR 8-bit uC's store this LSB first, and the NRF24L01(+)
  // expects it LSB first too, so we're good.

  write_register(RX_ADDR_P0,address, addr_width);
  write_register(TX_ADDR, address, addr_width);

  //const uint8_t max_payload_size = 32;
  //write_register(RX_PW_P0,rf24_min(payload_size,max_payload_size));
  write_register(RX_PW_P0,payload_size);
}

Whandall

My bad. I overlooked that strange setting.

I never used 4 byte addresses.

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

Go Up