LoRa packets gets 2 extra bytes?

Hello, i'm trying to acquire and send sensor data but when i make the packet to send the data to the receiver, i get the same 2 extra bytes added at the end. And the main focus of this project is having the code on the sender as efficient as possible in terms of energy used.

#include <SPI.h>
#include <MKRWAN.h>
#include <SD.h>
//#include <ArduinoLowPower.h>
#include <Arduino_MKRENV.h>
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_SHT31.h>
#include <SensirionI2CScd4x.h>
#include <microDS18B20.h>
#include <LoRa.h>

const int SD_CS_PIN = 4;
uint8_t ID_packet = 1;
uint16_t val_watermark;
float ds18b_temp;
File dataFile;

uint8_t pachet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

//declarare senzor
Adafruit_SHT31 sht31 = Adafruit_SHT31();

//declarare senzor
SensirionI2CScd4x scd4x;

//declarare senzor
MicroDS18B20<0> DS18B20;

void setup() {
  Serial.begin(9600);
  Serial.println("LoRa message service");
  if (!LoRa.begin(868E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  SPI.begin();
  SD.begin(SD_CS_PIN);
  dataFile = SD.open("log-0003.csv", FILE_WRITE);
  delay(1000);
  dataFile.println("VOLTAGE, ILLUMINANCE, PRESSURE, NODE TEMPERATURE, NODE HUMIDITY, UVA, UVB, AIR TEMPERATURE, AIR HUMIDITY, SOIL TEMPERATURE, CO2, SOIL TENSION,SOIL HUMIDITY 1, SOIL HUMIDITY 2");
  // close the file
  dataFile.close();
}

void loop() {
  //setup
  digitalWrite(5, HIGH);  //supply voltage
  delay(100);
  
  //ENV shield initialization
  ENV.begin();
  
  //I2C address SHT31 initialization
  sht31.begin(0x44);
  
  //SCD41 initialization
  Wire.begin();
  uint16_t error;
  scd4x.begin(Wire);
  error = scd4x.startPeriodicMeasurement();
  uint16_t co2;
  uint16_t temperature;
  uint16_t humidity;
  
  //DS18B20 initialization
  DS18B20.requestTemp();
  
  //Watermark initialization
  digitalWrite(2, HIGH);
  delay(2500);
  int val_watermark1 = 1024 - analogRead(A5);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  delay(2500);
  int val_watermark2 = analogRead(A5);
  digitalWrite(3, LOW);
  int val_watermark = int((val_watermark1 + val_watermark2) / 2);
  
  //SDcard initialization
  dataFile = SD.open("log-0003.csv", FILE_WRITE);



  //node battery voltage
  int voltage;
  voltage = analogRead(A6);
  uint16_t word_voltage = (voltage + 1024);       //1024= 1 00 0000 0000 node ID=1
  //to decode ID: ID = high_word_voltage & 0xFC (1111 1100)
  uint8_t high_word_voltage = word_voltage >> 8;
  uint8_t low_word_voltage = word_voltage;

  pachet[0] = high_word_voltage;
  pachet[1] = low_word_voltage;

  //ENV shield
  //ENV illuminance
  float env_illuminance = ENV.readIlluminance();
  uint16_t word_illuminance = env_illuminance * 100;
  uint8_t high_word_illuminance = word_illuminance >> 8;
  uint8_t low_word_illuminance = word_illuminance;
  pachet[2] = high_word_illuminance;
  pachet[3] = low_word_illuminance;

  //ENV pressure
  float env_pressure = ENV.readPressure();
  uint16_t word_pressure = env_pressure * 100;
  uint8_t high_word_pressure = word_pressure >> 8;
  uint8_t low_word_pressure = word_pressure;
  pachet[4] = high_word_pressure;
  pachet[5] = low_word_pressure;

  //ENV temperature
  float env_temp = ENV.readTemperature();
  uint16_t word_temp = env_temp * 100;
  uint8_t high_word_temp = word_temp >> 8;
  uint8_t low_word_temp = word_temp;
  pachet[6] = high_word_temp;
  pachet[7] = low_word_temp;

  //ENV humidity
  float env_hum = ENV.readHumidity();
  uint16_t word_hum = env_hum * 100;
  uint8_t high_word_hum = word_hum >> 8;
  uint8_t low_word_hum = word_hum;
  pachet[8] = high_word_hum;
  pachet[9] = low_word_hum;

  //ENV UVA
  float env_uva = ENV.readUVA();
  uint16_t word_uva = env_uva * 100 + 32768;
  uint8_t high_word_uva = word_uva >> 8;
  uint8_t low_word_uva = word_uva;
  pachet[10] = high_word_uva;
  pachet[11] = low_word_uva;

  //ENV UVB
  float env_uvb = ENV.readUVB();
  uint16_t word_uvb = env_uvb * 100 + 32768;
  uint8_t high_word_uvb = word_uvb >> 8;
  uint8_t low_word_uvb = word_uvb;
  pachet[12] = high_word_uvb;
  pachet[13] = low_word_uvb;

  //SHT31
  float temp = sht31.readTemperature();
  float hum = sht31.readHumidity();

  uint16_t word_sht_temp = temp * 100;
  uint16_t word_sht_hum = hum * 100;
  uint8_t high_word_sht_temp = word_sht_temp >> 8;
  uint8_t low_word_sht_temp = word_sht_temp;
  uint8_t high_word_sht_hum = word_sht_hum >> 8;
  uint8_t low_word_sht_hum = word_sht_hum;

  pachet[14] = high_word_sht_temp;
  pachet[15] = low_word_sht_temp;
  pachet[16] = high_word_sht_hum;
  pachet[17] = low_word_sht_hum;

  //DS18B20
  ds18b_temp = DS18B20.getTemp();
  uint16_t word_ds18b = ds18b_temp * 100;
  uint8_t high_word_ds18b = word_ds18b >> 8;
  uint8_t low_word_ds18b = word_ds18b;

  pachet[18] = high_word_ds18b;
  pachet[19] = low_word_ds18b;

  //SCD41
  error = scd4x.readMeasurement(co2, temperature, humidity);
  uint8_t high_word_co2 = co2 >> 8;
  uint8_t low_word_co2 = co2;

  pachet[20] = high_word_co2;
  pachet[21] = low_word_co2;
  error = scd4x.stopPeriodicMeasurement();

  //Watermark
  uint8_t high_word_watermark = val_watermark >> 8;
  uint8_t low_word_watermark = val_watermark;

  pachet[22] = high_word_watermark;
  pachet[23] = low_word_watermark;

  //Soil humidity
  uint16_t soil1 = analogRead(A0);
  uint16_t soil2 = analogRead(A1);
  uint8_t high_word_soil1 = soil1 >> 8;
  uint8_t low_word_soil1 = soil1;
  uint8_t high_word_soil2 = soil2 >> 8;
  uint8_t low_word_soil2 = soil2;

  pachet[24] = high_word_soil1;
  pachet[25] = low_word_soil1;
  pachet[26] = high_word_soil2;
  pachet[27] = low_word_soil2;



  //creating and sending packet
  Serial.println(" ");
  for(int i=0; i<28; i++)
  {
    if(pachet[i]==0)
      {
        pachet[i]=1;
      }
      
    Serial.print(pachet[i]);
    Serial.print(" ");
  }

  Serial.println();
  
  LoRa.beginPacket();

  LoRa.print((char*)pachet);

  delay(1000);

  LoRa.endPacket();




  //write SDcard data
  //dataFile = SD.open("log-0003.csv", FILE_WRITE);
  dataFile.print(voltage * 3.22);
  dataFile.print(",");
  dataFile.print(env_illuminance);
  dataFile.print(",");
  dataFile.print(env_pressure);
  dataFile.print(",");
  dataFile.print(env_temp);
  dataFile.print(",");
  dataFile.print(env_hum);
  dataFile.print(",");
  dataFile.print(env_uva);
  dataFile.print(",");
  dataFile.print(env_uvb);
  dataFile.print(",");
  dataFile.print(temp);
  dataFile.print(",");
  dataFile.print(hum);
  dataFile.print(",");
  dataFile.print(ds18b_temp);
  dataFile.print(",");
  dataFile.print(co2);
  dataFile.print(",");
  dataFile.print(val_watermark * 3.22);
  dataFile.print(",");
  dataFile.print(soil1 * 3.22);
  dataFile.print(",");
  dataFile.println(soil2 * 3.22);
  dataFile.close();
  
  //serial data display
  Serial.print(voltage * 6.44); //3.22*2=6.44
  Serial.print(" mV, ");
  Serial.print(env_illuminance);
  Serial.print(" lux, ");
  Serial.print(env_pressure);
  Serial.print(" kPa, ");
  Serial.print(env_temp);
  Serial.print(" *C, ");
  Serial.print(env_hum);
  Serial.print(" %, ");
  Serial.print(env_uva);
  Serial.print(" uva, ");
  Serial.print(env_uvb);
  Serial.print(" uvb, ");
  Serial.print(temp);
  Serial.print(" *C, ");
  Serial.print(hum);
  Serial.print(" %, ");
  Serial.print(ds18b_temp);
  Serial.print(" *C, ");
  Serial.print(co2);
  Serial.print(" ppm, ");
  Serial.print(val_watermark * 3.22);
  Serial.print(" mV, ");
  Serial.print(soil1 * 3.22);
  Serial.print(" mV, ");
  Serial.print(soil2 * 3.22);
  Serial.println(" mV ");
  digitalWrite(5, LOW); //cut the voltage
  //ENV shield shutdown
  ENV.end();
  delay(3000);
}

I tried to check it for problems but i couldn't figure out why i keep getting the added 2 extra bytes at the end of the packet.

Please edit your post to add code tags.

Forum guidelines and instructions here: How to get the best out of this forum

hey, i changed it i think. sorry, i'm new here and to arduino in general

You're passing a string to Lora.print. It's not null terminated, so the print is sending the string and whatever is after it in memory until it finds a null.

Post evidence for this, and post the receive code, using code tags.

the main focus of this project is having the code on the sender as efficient as possible in terms of energy used.

In that case, there are many major errors in the code that make the radio problem completely insignificant, such as opening the SD log file every time you write some data. All the begin() and open() stuff should be done once only, in setup().

Close the log file only when you are finished writing all data.

Finally, instead of using delay(3000) in each loop, you should be putting the processor, radio and sensors to sleep, and since you send the data elsewhere, eliminate the power hungry SD device.

For some insight into how this is done, see this excellent solar powered remote sensor tutorial: https://www.gammon.com.au/forum/?id=12821

#include <LoRa.h>
String LoRaData;
  
void setup() {

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(868E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
    Serial.println("LoRa Initializing OK!");
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();

  
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");
    // read packet

  Serial.print(packetSize);
  Serial.println(" ");
  
    while (LoRa.available()) {

      //Serial.println((char)LoRa.read());
      LoRaData = LoRa.readString();
      Serial.print(LoRaData);
      // print RSSI of packet
      Serial.print("' with RSSI ");
      Serial.println(LoRa.packetRssi());
       
    int d = LoRaData.toInt();         //convert String to Int
    Serial.print("Int Value = ");
    Serial.println(d);
    Serial.println("");               
    }  
  }
}

Thank you for the advice. I'm opening and closing the SD log file on every setup because i wasn't sure it would work with opening only one time as the env shield should stop from the ENV.end line near the end, and the SD slot is on the shield. But i will try changing it.

Putting everything on sleep while not needing to gather data is also in progress but right now being able to send and receive the right amount of data is of higher priority for me.

Thank you for the advice. I tried to have it print a null after but i seem to do something wrong. Do you have any advice for what the line or change to the code would look like?

You write a variable to the last byte in the array;

pachet[27] = low_word_soil2;

So how about increasing the array length by 1 and writing a 0 to location 28 ?

1 Like

Fix this:

  LoRa.print((char*)pachet);

by replacing with this:

  LoRa.write((char*)pachet, sizeof(pachet));

But that is the least of your problems.

changing the line like that gives me the following error:

" invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}"

This worked! But i'd still like to be able to solve this without roundabout ways like that. But thank you nonetheless since now i have this option!

I suspect this code here is a workaround for using LoRa.print rather than LoRa.write:

If so, that should probably be removed, otherwise some byte values will be arbitrarily changed from 0 to 1.

Then use the library as it was intended to be used.

Of course it is. Otherwise the data bytes that happen to be zero prematurely terminate the string. So, the data are arbitrarily modified, introducing potentially very large (orders of magnitude!) errors.

The posted code is, in its entirety, a kluge.

Yes, data is arbitrarily changed, but i already know what values the sensors may return so the errors this may create are very small after the data sent is processed.

And as i said above, attempting to use write instead of print returns me an error. The only reason i asked here for advice is because i'm new to arduino and couldn't find on my own how to solve it.

Which would be? I tried using write as it was suggested but attempting to replace LoRa.print with LoRa.write return me an error.

" invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}"

You could get that error, probably something to do with the code you are using.