Hi, I'm building a high altitude balloon payload using 433Mhz RFM9X LoRa module running Radiohead library. My latest idea was to reduce the size of the structure I'm using to send the data, so take floats and use int16_t instead, saving 2 bytes of data per field. I ran into some strange problems where half the structure sends fine, but the second half is corrupted. The numbers are all over the place, stable, but very wrong. After debugging I changed all the fields back to float and it worked perfectly.
What is it about having integers in the structure that is doesn't like? Thanks!
Receiver code
#include <SPI.h>
#include <RH_RF95.h>
#define RFM95_CS 53
#define RFM95_RST 2
#define RFM95_INT 3
#define RF95_FREQ 433.050
RH_RF95 rf95(RFM95_CS, RFM95_INT);
struct payload{
uint32_t Secs_since_launch;
int32_t Lat;
int32_t Long;
float GPS_Alt;
float GPS_Speed;
float VS;
float Temp_out;
float V_batt;
float Max_Alt;
uint8_t SF;
};
payload Data;
void setup() {
Serial.begin(115200);
delay(500);
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
while (!rf95.init()) {
Serial.println("LoRa radio init failed");
while (1);
}
if (!rf95.setFrequency(RF95_FREQ)) {
while (1);
}
rf95.setTxPower(14, false);
rf95.setSpreadingFactor(7);
rf95.setCodingRate4(5);
rf95.setSignalBandwidth(62500);
Serial.println("Setup Finished");
}
void loop() {
if (rf95.available())
{
uint8_t len = 251;
if (rf95.recv((uint8_t*)&Data, &len))
{
//Print data
}
}
}
Transmitter code
#include <SPI.h>
#include <RH_RF95.h>
#include <NMEAGPS.h>
#define RFM95_CS 5
#define RFM95_RST 6
#define RFM95_INT 7 // Must be hardware interrupt
#define gpsPort Serial1
#define RF95_FREQ 433.050
#define Serial SerialUSB // Use this line for the MKR Zero!!
RH_RF95 rf95(RFM95_CS, RFM95_INT); // Singleton instance of the radio driver
static NMEAGPS gps;
struct payload{
uint32_t Secs_since_launch;
int32_t Lat;
int32_t Long;
uint16_t GPS_Alt;
uint16_t GPS_Speed;
int16_t VS;
float Temp_out;
uint16_t V_batt;
uint16_t Max_Alt;
uint8_t SF;
};
payload data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 7};
unsigned long previousMillis = 0;
float last_Alt;
int Receive_count = 0;
uint32_t timer, looptime = 4000;
void setup()
{
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
Serial.begin(115200);
//while (!Serial);
delay(500);
Serial.println(F("SerialUSB started"));
digitalWrite(RFM95_RST, LOW); // manual reset
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
GPS_setup();
while (!rf95.init()){
Serial.println("LoRa radio init failed");
while (1);
}
if (!rf95.setFrequency(RF95_FREQ)) {
while (1);
}
rf95.setTxPower(10, false); //set transmitter powers from 5 to 23 dBm:
rf95.setSpreadingFactor(data.SF);
rf95.setSignalBandwidth(62500); //Don't go lower than this without temp compensated Xtal
rf95.setCodingRate4(5);
Serial.println(F("LoRa power, freq, BW & SF set"));
//sensors.begin(); //Initialise temp sensors
/*if (!sd.begin(chipSelect, SPI_FULL_SPEED)){
SD_present = false;
}
else{
SD_present = true;
SD_header();
}*/
//Buzzer to signal setup complete.
Serial.println("Setup Complete");
}
void loop()
{
GPS();
if ((millis() - previousMillis) >= looptime){
previousMillis += looptime;
//Read Battery voltage
analogReadResolution(8);
int sensorValue = analogRead(A1);
data.V_batt = sensorValue * 2 * (3.3 / 2.56);
float V_batt_temp = data.V_batt / 100.0;
//Read Temp data
float Temp_in_temp = 23.5;
float Temp_out_temp = -65.6;
data.Temp_out = Temp_out_temp;
//Calculate VS
float dT = looptime / 1000;
float VS10 = (data.GPS_Alt - last_Alt)*10 / dT;
data.VS = VS10;
float VS_temp = data.VS / 10.0;
last_Alt = data.GPS_Alt;
//Send data packet over LoRa
data.Secs_since_launch = millis() / 1000ul;
rf95.send((uint8_t *)&data, sizeof(data));
rf95.waitPacketSent();
}
} //end of main loop
In a nutshell, This doesn't work:
struct payload{
uint32_t Secs_since_launch;
int32_t Lat;
int32_t Long;
uint16_t GPS_Alt;
uint16_t GPS_Speed;
int16_t VS;
float Temp_out;
uint16_t V_batt;
uint16_t Max_Alt;
uint8_t SF;
};
But this does:
struct payload{
uint32_t Secs_since_launch;
int32_t Lat;
int32_t Long;
float GPS_Alt;
float GPS_Speed;
float VS;
float Temp_out;
float V_batt;
float Max_Alt;
uint8_t SF;
};
When using the first struct all values after Temp_out are garbage. Really drawing a blank with this one.