Notifications
Clear all

Structures, Serialisation, XOR Checksums etc.

91 Posts
7 Users
8 Likes
26.2 K Views
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@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!


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@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..


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 
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)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 
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)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@robo-pi

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


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 
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)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@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!


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@robo-pi

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

And get back to you later!


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

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)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  
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!


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@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.


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
 

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)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@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!


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@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 / 7