Structures, Serialisation, XOR Checksums etc.  

Page 2 / 4
  RSS

Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 6:17 am  

Here's the alternative Receive routine:  It also works precisely the same as the one-liner.  So there doesn't appear to be anything gained by doing it this way:  They both work just fine for hard-defined numbers, but give wrong values when casting floats to uint8_t.   I've also tried casting to just plain int as well but that doesn't work either.

 

   // ------------ Radio Receive ------------
    digitalWrite(Radio_RELAY_pin, LOW); //Recieve MODE
    // Set buffer to size of expected message
    uint8_t buf[sizeof(pacRecv)]; // 5 Bytes
    uint8_t buflen = sizeof(buf);     
    // Check if received packet is correct size
    if (rf_driver.recv(buf, &buflen))
         // NOTE: I also tried the following instead of all of the above,...
         // but it didn't make any difference.
         //if (rf_driver.recv((uint8_t *)&pacRecv, (uint8_t *)sizeof(pacRecv)))
    {
      memcpy((uint8_t *) &pacRecv, buf, sizeof(pacRecv));
      // Message received
      Serial.println("Message Received: ");
      Serial.println(pacRecv.temp1);   
      Serial.println(pacRecv.humid1);   
      Serial.println(pacRecv.temp2);   
      Serial.println(pacRecv.humid2);
      Serial.println(pacRecv.checksum); // The make-believe checksum is always correct. 
    }
    delay(radioRecoveryDelay); // Probably not needed.
   // --- END ---- Radio Receive ------------ 

 

 

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 8:29 am  

@robo-pi

I think you have a conceptual problem. I don't believe you have to declare the transmitted variables as uint8_t and there is no need to cast the floats to uint8_t.

Declare the elements of the object as floats, and then write the floating-point values from the DHT sensors directly to the pacSend object. The microcontroller then stores the object as a series of bytes.

The only point where uint8_t is required is in the transmit line. The microcontroller is only telling the 433MHz board!

"Hey you, I am sending you a series of bytes starting at this address of object pacSend, expect this many bytes in the form of unsigned 8-bit integers".

On the other side, when the data packet is received the microcontroller will already know that the first four bytes is a floating-point number called temp1.

// Define data structure as as uint8_t:
typedef struct{
  float temp1;
  float temp2;
  float humid1;
  float humid2;
  byte checksum;
} radioPacket;

// Declare an object as pacRecv:               17 NOT 5 bytes long.
radioPacket pacRecv;

// Floats declared for the DHT Sensors         Delete all this it is not needed
float temp10;
float temp20;
float humid10;
float humid20;

Trying to pack four floating point numbers (each of which is four bytes) into 5 bytes, just doesn't work!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 9:33 am  

@robo-pi

pacSend.humid1 = (uint8_t)humid10;

This statement, if run on a microprocessor, would throw a runtime error!

Microcontrollers don't throw runtime errors, the Arduino C++ compiler only checks spelling, grammar and punctuation. To check the sketch works properly, you have to build in your own checks on values of variables etc..

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 9:36 am  
Posted by: @pugwash

I think you have a conceptual problem. I don't believe you have to declare the transmitted variables as uint8_t and there is no need to cast the floats to uint8_t.

I tried sending them as floats but I couldn't get that to work either. 

Posted by: @pugwash

Trying to pack four floating point numbers (each of which is four bytes) into 5 bytes, just doesn't work!

I'm not trying to do that.  I don't need float precision at the receiving end.   Just a simple 2 or 3-digit integer temperature reading is all I need.    So if I can transmit the data as short integers that would  be fine. 

I mean,  I'll take the floats too, but like I say, I couldn't get the floats to work so I thought I'd try with simple ints, but even that isn't working.

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 9:42 am  
Posted by: @pugwash

@robo-pi

pacSend.humid1 = (uint8_t)humid10;

This statement, if run on a microprocessor, would throw a runtime error!

Microcontrollers don't throw runtime errors, the Arduino C++ compiler only checks spelling, grammar and punctuation. To check the sketch works properly, you have to build in your own checks on values of variables etc..

So how do you convert a float to an int then?

I tried using

pacSend.humid1 = (int)humid10;

But that didn't work either.

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 9:52 am  

@robo-pi

I didn't realise you were deliberately trying to lose the decimal remainder!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 9:58 am  
Posted by: @pugwash

I didn't realise you were deliberately trying to lose the decimal remainder!

I'll take whatever I can get to work. 😊 

I just went back and changed the entire struct to ints and then tried casting the floats into the ints.   But it's still isn't working.  The program doesn't crash, but I'm not getting the correct numbers.

But if I type them in directly they work perfectly.   Why is that?

I don't understand why it works if the struct variables are typed in directly, but  not if they are cast from floats.  There must be something not working right with the cast function?

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 10:01 am  

@robo-pi

After the following code in the transmitter sketch:

// Casting floats to uint8_t for ASK radio library function:
  // Note: This is the data to be transmitted but does not receive correctly.
  pacSend.humid1 = (uint8_t)humid10;
  pacSend.temp1 = (uint8_t)temp10;
  pacSend.humid2 = (uint8_t)humid20;
  pacSend.temp2 = (uint8_t)temp20;
  pacSend.checksum =  57; // make-believe checksum for now.

Add the following lines to see what the values are:

Serial.println(pacSend.humid1);
Serial.println(pacSend.temp1);
Serial.println(pacSend.humid2);
Serial.println(pacSend.temp2);
Serial.println(pacSend.checksum);

Let me know what this throws up!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 10:04 am  

@robo-pi

Would you like to post the files, and I will take a look at them!

And get back to you later!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 10:07 am  

I just when back over everything and used floats everywhere with no casting at all.  That's actually back to square one where I first started.   I still get the same results.    I get actual floats at the receiving end.  But the numbers aren't making any sense.   Definitely not the numbers that were sent.

Like I say, if I actually type the numbers in on the  transmitter side I'll get those  exact numbers back on the receiving side.  So typed in numbers appear to be working.   But the moment I try to equate them to dynamic variables it's goes all haywire.  This is driving me crazy!

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 10:18 am  
Posted by: @robo-pi

I just when back over everything and used floats everywhere with no casting at all.  That's actually back to square one where I first started.   I still get the same results.    I get actual floats at the receiving end.  But the numbers aren't making any sense.   Definitely not the numbers that were sent.

Like I say, if I actually type the numbers in on the  transmitter side I'll get those  exact numbers back on the receiving side.  So typed in numbers appear to be working.   But the moment I try to equate them to dynamic variables it's goes all haywire.  This is driving me crazy!

This would mean that there is a discrepancy when filling the object with the values from the sensors, I guess!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 10:25 am  

@joelyddon

The files in the post directly above your post are the latest working and tested versions. All errors have been ironed out as far as I can tell.

I will be publishing new versions soon after I have added a UV sensor to the balcony prototype.

And some code for power management. I don't need readings every 10 seconds for this project, this was just for testing. I intend to get the data every 5 or 10 minutes and put the Arduino to sleep in between.

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 6 months ago
Posts: 1041
2019-12-02 10:34 am  

Never mind.  I'm a COMPLETE IDIOT!

It's all my fault.   I figure out the problem.

I've been getting the correct numbers all along!  There was never a problem to begin with.

I can't believe I did this.

In the Serial Print routine I converted the temperatures from C to F.   I also did this for the LED display.  But for whatever reason I never did it for the numbers I was sending over to the receiver.   So I was sending over Celsius expecting to see Fahrenheit.   And for some idiotic reason it never dawned on me that this might be the reason I'm getting bad numbers.

I can't believe I did this!  It's been working correctly the whole time.  There was never a problem to begin with and I've been banging my head against the wall for several days trying to figure out what's wrong.

It never dawned on me that my conversion routine wasn't acting on these numbers.   I though I had already taken care of the conversion, but not for these numbers.

So I'm an idiot.  What can I say?   That's the problem.  I can't believe I didn't figure this out sooner!  Blame it on  an aging brain I guess. 😖 

At least it's solved now.  I can get on with my LIFE!

DroneBot Workshop Robotics Engineer
James


ReplyQuote
Pugwash
(@pugwash)
Honorable Member
Joined: 6 months ago
Posts: 561
2019-12-02 10:52 am  

@robo-pi

I had a similar brain glitch earlier in this thread, you may have noticed! 🤔 

Sometimes you just "can't see the wood for the trees"!

Here is a bit of code to get rid of the float variables.

// Casting floats to uint8_t for ASK radio library function:
// Note: This is the data to be transmitted but does not receive correctly.
pacSend.humid1 = byte(dht_1.readHumidity());
pacSend.temp1 = byte(dht_1.readTemperature());
pacSend.humid2 = byte(dht_2.readHumidity());
pacSend.temp2 = byte(dht_2.readTemperature());
pacSend.checksum = 57; // make-believe checksum for now.

Now you can get rid of:

// Floats declared for the DHT Sensors
float temp10;
float temp20;
float humid10;
float humid20;

and

// Read DHT sensors - NOTE: These are Float variables.
// end in 10 and 20 instead of 1 and 2   
humid10 = dht_1.readHumidity();
temp10 = dht_1.readTemperature();
humid20 = dht_2.readHumidity();
temp20 = dht_2.readTemperature();

If you want too!

Get some sleep!

SteveC - Oh Lord, please don't let me be misunderstood! (Eric Burdon and the Animals)


ReplyQuote
frogandtoad
(@frogandtoad)
Estimable Member
Joined: 6 months ago
Posts: 106
2019-12-02 11:26 am  

@pugwash

LOL... nice discussion gents!

I once spent hours convinced that my Oracle PL/SQL interpreter was broken while trying to work with Char(13) instead of CHR(13) 🙂

 


ReplyQuote
Page 2 / 4

Please Login or Register