The library’s code shows that value 407.00 is sent as a 16 bits signed integer, using int16_t val = value * 100, hence as 40,700. That’s too large to fit in a 16 bits signed integer which ranges from -32,768 through 32,767.
In hexadecimal, 40,700 is 0x9EFC† which when interpreted as a signed integer is indeed -24,836, which divided by 100 indeed yields -248.36.
It’s quite weird LPP does not provide some generic methods for larger values. Some options:
You could (ab)use addTemperature which uses int16_t val = celsius * 10, hence sends 4,070 which fits just fine. Same goes for addBarometricPressure.
Or, as you know CO2 values are always positive, you could use addLuminosity which expects an unsigned 16 bits integer, which ranges from 0 through 65,535. If you need the two decimals then you’d have to multiply the float by 100 yourself before adding it to LPP, and divide by 100 after receiving it.
I was confused by the AnalogInput conversion but after seeing the post from @arjanvanb I suspect that the Cayenne coders weren’t thinking 10 bit arduino analog inputs when they created the function. So a possible workaround is to save the analogRead value as a float, then divide by 100. Therefore the 10 bit range of (0 to 1023) is converted to (0 to 10.23) which is perfectly fine to work with.
// Prepare upstream data transmission at the next possible time.
Serial.print(F("Reading sensor..."));
lpp.reset();
float x = analogRead(A0); // cast to float but don't divide the integer by 100 here or the number will be rounded off
x = x / 100; // divide by 100
Serial.println(x, 2);
lpp.addAnalogInput(1, x);
LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
In this case the analogRead function read 451 and 507
In my opinion the problem is that addAnalogInput accepts floats, but in the implementation they are binary-converted in signed int, divided by 100 and sent. So if from my ESP32 i send the following values:
// Send our data
int numdati=8;
float f[numdati];
f[0]=327;
f[1]=327.66;
f[3]=328;
f[4]=-327.66;
f[5]=-327.69;
f[6]=-327;
f[7]=-328;
lpp.reset();
for (int i=0;i<numdati;i++)
{
lpp.addAnalogInput(i+1,f[i]);
Serial.printf(“Invio in LoRaWAN su port %i Valore: %f\n”,i,f[i]);
}
in my application server I’m getting:
1:327
2:327.66
3:1.96
4:-327.36
5:-327.66
6:327.67
7:-327
8:327.36
In other words, AddAnalogRead can only send values between -327,67 and +327,67 with 2 decimals.