Heltec Cubecell AB01 with SHT20 sensor

Ater a frustrating sunday afternoon, I’m almost ready to give up. My last attempt is to seek help here.

On a Heltec Cubell AB-01 with an SHT20 sensor I use the sketch below that transmits the temperature, humidity and battery voltage without any problems. That is, as long as the temperature does not fall below zero. When it freezes, the sensor measures the correct temperature, but a value of approximately 655 (temp16 in the sketch) is sent as tempeature.

I suspect this has to do with converting (highByte lowByte?) negative values but after many hours I have not found a solution.

Who can help me? How do I fix this?

#include "LoRaWan_APP.h"
#include "Arduino.h"
#include "uFire_SHT20.h"


// TTN OTAA
uint8_t devEui[] = { 0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
uint8_t appEui[] = { 0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };                
uint8_t appKey[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

// TTN ABP
uint8_t nwkSKey[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t appSKey[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint32_t devAddr =  ( uint32_t )0x00000000;

uint32_t appTxDutyCycle = 600000;
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };

LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
DeviceClass_t  loraWanClass = LORAWAN_CLASS;

bool overTheAirActivation = LORAWAN_NETMODE;
bool loraWanAdr = LORAWAN_ADR;
bool keepNet = LORAWAN_NET_RESERVE;
bool isTxConfirmed = LORAWAN_UPLINKMODE;

uint8_t appPort = 2;
uint8_t confirmedNbTrials = 4;

int ledBrightness = 250;

uFire_SHT20 sht20;

static void prepareTxFrame( uint8_t port ) {
  analogWrite(PWM1,ledBrightness);
  delay(250);
  digitalWrite(Vext,LOW);
  Wire.begin();
  delay(250); 
  float temperature = (float)(sht20.temperature());
  float humidity = (float)(sht20.humidity());
  Wire.end();
  digitalWrite(Vext,HIGH);
  pinMode(VBAT_ADC_CTL,OUTPUT);
  digitalWrite(VBAT_ADC_CTL,LOW);
  float voltage = analogRead(ADC)*2;
  digitalWrite(VBAT_ADC_CTL,HIGH);
  Serial.print("Filling appData array with temperature/humidity/voltage: ");
  Serial.print(temperature);
  Serial.print("/");
  Serial.print(humidity);
  Serial.print("/");
  Serial.println(voltage);
  appDataSize = 6;
  uint16_t temp16 = temperature * 100;
  uint16_t humi16 = humidity * 100;
  uint16_t volt16 = voltage;
  appData[0] = highByte(temp16);
  appData[1] = lowByte(temp16);
  appData[2] = highByte(humi16);
  appData[3] = lowByte(humi16);
  appData[4] = highByte(volt16);
  appData[5] = lowByte(volt16);
  analogWrite(PWM1,ledBrightness);
}
  
void setup() {
	boardInitMcu();
	Serial.begin(115200);
  sht20.begin();
  pinMode(Vext, OUTPUT);
	deviceState = DEVICE_STATE_INIT;
	LoRaWAN.ifskipjoin();
}

void loop() {
	switch( deviceState ) {
		case DEVICE_STATE_INIT: {
			printDevParam();
			LoRaWAN.init(loraWanClass,loraWanRegion);
			deviceState = DEVICE_STATE_JOIN;
			break;
		}
		case DEVICE_STATE_JOIN: {
			LoRaWAN.join();
			break;
		}
		case DEVICE_STATE_SEND: {
			prepareTxFrame( appPort );
			LoRaWAN.send();
			deviceState = DEVICE_STATE_CYCLE;
			break;
		}
		case DEVICE_STATE_CYCLE: {
			txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
			LoRaWAN.cycle(txDutyCycleTime);
			deviceState = DEVICE_STATE_SLEEP;
			break;
		}
		case DEVICE_STATE_SLEEP: {
			LoRaWAN.sleep();
			break;
		}
		default: {
			deviceState = DEVICE_STATE_INIT;
			break;
		}
	}
}

You are storing your temperature in an unsigned integer for a start, so no negative numbers will be readily apparent. Then there is the issue of casting a float to an integer.

You also cast the temperature to a float earlier.

The simplest thing to do is add an offset like 50 to the temp, so the range starts at -50, on the server side, just subtract 50.

Thanks for helping. Do you mean something like this:

float temperature = (float)(sht20.temparature());
temperature = temperature + 50;

Yes, but without all the float conversions, you can’t reliably stuff a 4 byte value in to a two byte payload

Looks like my problem has been resolved, thank you Nick!

I always feel burdened to post my problems here but today I should have done so earlier…