After hours of trial and error modifying LMIC node I’ve managed to get my first temperature sensor (2x DS18B20) node working with TTN albeit postive temperatures work great. However when it comes to negative temperatures I’m stuck… having read several comments here and elsewhere on the net I was actually expecting I might come across this issue but not being a remotely competant coder I’m struggling to get anywhere with it…
I have the LMIC node preparing the uplink payload:
static volatile uint16_t temp_ = 0;
static volatile uint16_t temp2_ = 0;
uint16_t getTempValue()
{
float temp;
uint16_t tempInt;
// Send the command to get temperatures
ds18b20_sensors.requestTemperatures();
temp = ds18b20_sensors.getTempCByIndex(0);
tempInt = temp * 100;
#ifdef USE_SERIAL
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("TEMP value: "));
Serial.println(temp);
#endif
return tempInt;
}
uint16_t getTemp2Value()
{
float temp2;
uint16_t temp2Int;
// Send the command to get temperatures
ds18b20_sensors.requestTemperatures();
temp2 = ds18b20_sensors.getTempCByIndex(1);
temp2Int = temp2 * 100;
#ifdef USE_SERIAL
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("TEMP 2 value: "));
Serial.println(temp2);
#endif
return temp2Int;
}
void processWork(ostime_t doWorkJobTimeStamp)
{
// This function is called from the doWorkCallback()
// callback function when the doWork job is executed.
// Uses globals: payloadBuffer and LMIC data structure.
// This is where the main work is performed like
// reading sensor and GPS data and schedule uplink
// messages if anything needs to be transmitted.
// Skip processWork if using OTAA and still joining.
if (LMIC.devaddr != 0)
{
// Collect input data.
uint16_t tempValue = getTempValue();
uint16_t temp2Value = getTemp2Value();
ostime_t timestamp = os_getTime();
#ifdef USE_DISPLAY
// Interval and Counter values are combined on a single row.
// This allows to keep the 3rd row empty which makes the
// information better readable on the small display.
display.clearLine(INTERVAL_ROW);
display.setCursor(COL_0, INTERVAL_ROW);
display.print("I:");
display.print(doWorkIntervalSeconds);
display.print("s");
display.print(" Ctr:");
display.print(tempValue);
#endif
/* #ifdef USE_SERIAL
printEvent(timestamp, "Input data collected", PrintTarget::Serial);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("TEMP value: "));
serial.println(tempValue);
printSpaces(serial, MESSAGE_INDENT);
serial.print(F("TEMP2 value: "));
serial.println(temp2Value);
#endif
*/
// For simplicity LMIC-node will try to send an uplink
// message every time processWork() is executed.
// Schedule uplink message if possible
if (LMIC.opmode & OP_TXRXPEND)
{
// TxRx is currently pending, do not send.
#ifdef USE_SERIAL
printEvent(timestamp, "Uplink not scheduled because TxRx pending", PrintTarget::Serial);
#endif
#ifdef USE_DISPLAY
printEvent(timestamp, "UL not scheduled", PrintTarget::Display);
#endif
}
else
{
// Prepare uplink payload.
uint8_t fPort = 10;
payloadBuffer[0] = (tempValue >> 8) & 0xff;
payloadBuffer[1] = tempValue & 0xFF;
payloadBuffer[2] = (temp2Value >> 8) & 0xff;
payloadBuffer[3] = temp2Value & 0xFF;
uint8_t payloadLength = 8;
scheduleUplink(fPort, payloadBuffer, payloadLength);
}
}
}
void processDownlink(ostime_t txCompleteTimestamp, uint8_t fPort, uint8_t* data, uint8_t dataLength)
{
// This function is called from the onEvent() event handler
// on EV_TXCOMPLETE when a downlink message was received.
// Implements a 'reset counter' command that can be sent via a downlink message.
// To send the reset counter command to the node, send a downlink message
// (e.g. from the TTN Console) with single byte value resetCmd on port cmdPort.
const uint8_t cmdPort = 100;
const uint8_t resetCmd= 0xC0;
if (fPort == cmdPort && dataLength == 1 && data[0] == resetCmd)
{
#ifdef USE_SERIAL
printSpaces(serial, MESSAGE_INDENT);
serial.println(F("Reset cmd received"));
#endif
ostime_t timestamp = os_getTime();
//resetCounter();
printEvent(timestamp, "Counter reset", PrintTarget::All, false);
}
}
And for the the Uplink Decoder I have:
function Decoder(bytes, port) {
var temp = ((bytes[0]<<8 | bytes[1]) & 0x3FFF)/ 100;
var temp2 = ((bytes[2]<<8 | bytes[3]) & 0x3FFF)/ 100;
return {
Temp: temp,
Temp2: temp2,
};
}
Can anyone suggest how I might go about getting a sensible value for neative temperatures, or at least point me in the right direction…