Variable float crash controller Arduino Yun

I transfer data between two controllers using modules nRF24L01. Receiver is Arduino YUN. Data is transmitted by the structure:

struct SensorData {
  byte id;
  float payload[5];
} data;

Sometimes it happens that the Arduino YUN crash. The reason why is the operation on a float variable payload from struct, which may be due to transmission errors changing. Command Serial.println() then displays the "ovf".

I tried to fix it like this:

if (data.payload [i]> 1000.0) {
data.payload [i] = 1000.0;
}

but such an operation crash controller.

I tried with exchange to String and checking isdigit, but also failed. How to detect and eliminate such value that it has not been processed by the program?

What is the value of "i"? Why can't I see your code?

For example:

void loop() {

  if (RadioNRF24.available()) {

    RadioNRF24.read((uint8_t *) &data);

    if (check(data)) {

      appendDataToFile(data);
    }
  }
}

boolean check(struct SensorData _data) {

  if ((_data.id >= 0) && (_data.id < 9)) {

    for (byte i = 0; i < 5; i++) {
      Serial.println(i);                // displays "ovf"

      if (_data.payload[i] > 1000.0) {            //yun crash
        _data.payload[i] = 1000.0;


      if ( _data.payload[i] < -1000.0) {
        _data.payload[i] = -1000.0;

      }

      Serial.println(_data.payload[k] );
    }


    return true;
  } else {
    return false;
  }
}

Does RadioNRF24.available() indicate when a full packet has been received or when any data is available?

When we have a bit to pick up RadioNRF24.available() returns TRUE.

There's no way for us to know for sure how the NRF24 is sending/receiving the data unless you include ALL your code for both the transmitter and receiver.

Pete

There is sender (with Radio library for ATtiny84):

#include <Radio.h>
#include <SPI.h>


const byte SENSORS_NUM = 5;

struct SensorData
  {
  byte id;
  float payload[SENSORS_NUM];
  byte num;
  byte seq;
  byte retry;
} data;

void setup()
{
    
  data.id = 1;
  data.num = SENSORS_NUM;
    
  byte address[5] = {0,0,1};
  Radio.begin(address,100);
}

void radioWrite(struct SensorData &data, byte retry = 0)
{
  byte addressRemote[3] = { 0, 1, 0};
  
  if (retry == 3) {
   
    data.seq ++;
    return;
  }
  data.retry = retry;
  
  Radio.write(addressRemote,data);
  
  while(true) {
    switch(Radio.flush()){
      case RADIO_SENT:
        data.seq++;
        return;
      case RADIO_LOST:
        radioWrite(data,retry+1);
        return;
    }
  }
  
}

void loop()
{
  for (byte i = 0; i < SENSORS_NUM; i++){
    data.payload[i] = sensor_read(sensorsAddress[i]);
        
   }
    
  radioWrite(data);
  Radio.off();
  sleep(240000);
 
}

There is receiver (with RadioNRF24 library for Arduino Yun):

#include <SPI.h>
#include <RadioNRF24.h>
#include <FileIO.h>

const byte sensors_NUM = 5;

struct SensorData {
  byte id;
  float payload[sensors_NUM];
  byte num;
  byte seq;
  byte retry;
} data;


void setup() {
  Serial.begin(57600);
  
  FileSystem.begin();

  byte address[3] = {0, 1, 0};
  RadioNRF24.begin(address, 100, 8, 7);
 
}


void loop() {

  if (RadioNRF24.available()) {

    RadioNRF24.read((uint8_t *) &data);

    if (check(data)) {

      appendDataToFile(data);
    }
  }
}

boolean check(struct SensorData _data) {

  if ((_data.id >= 0) && (_data.id < 9)) {

    for (byte i = 0; i < 5; i++) {
      Serial.println(i);                // displays "ovf"

      if (_data.payload[i] > 1000.0) {            //yun crash
        _data.payload[i] = 1000.0;


      if ( _data.payload[i] < -1000.0) {
        _data.payload[i] = -1000.0;

      }

      Serial.println(_data.payload[k] );
    }


    return true;
  } else {
    return false;
  }
}

void appendDataToFile(struct SensorData _data) {


}

As attachment I added library Radio.h and RadioNRF24.h.
Sometimes everything works properly all day and sometimes only an hour, then follows the crash of the receiver.

Radio.h (8.9 KB)

RadioNRF24.h (8.91 KB)

available only tells you that at least one byte is ready to be read. The rest may or may not have been transferred yet. The Arduino can read them a lot faster than they can be transmitted. available should return the number of bytes ready to be read. You could check that it is greater than or equal to the size of the data packet so you know the whole thing has arrived before you start reading and processing.

I don't think the receiver code can compile because 'k' is not declared anywhere:

     Serial.println(_data.payload[k] );

Pete

It should be "i". This is a result of many trials and code fixes.

How can I check if all the data has been properly read?

If for example you're expecting 4 bytes:

if(RadioNRF24.available() >= 4)

You might want to investigate the maximum size of a payload, for those radios, with those libraries, too.

It looks to me like you attached the same file under two different names.

You're right. Indeed, the files are the same. I downloaded the library for different devices. But since the library are the same, it's probably fine.

As suggested by Delta_G I set checking download 4 bytes. I'm testing it. For now, it's ok.

simsoft: As suggested by Delta_G I set checking download 4 bytes. I'm testing it. For now, it's ok.

I didn't suggest that you check for 4 bytes. I suggested you check for the size of your payload. The four bytes was an example. Your payload appears to be larger than that from what I can tell.

Of course, I wrote it wrong. I did check in accordance with your suggestion about 4B. As I counted my data, which is transmitted, it got 24B. I'm testing this setting.