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 CO_{2} 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.