Wow awesome work, thanks!
Great work TTN ! Thanks for pushing Cayenne LPP !
Per the JS decoder function, we are going to open source ou Cayenne LPP decoder.
Weāll be able to provide you the code then
Hi All, great discussion and great reads on Cayenne LPP.
Thank you so muchā¦
I tried to combine the TTN Build your own Sensor Workshop, with an implementation of Cayenne LPP.
I think the payload looks ok, but Cayenne does not accept it, since on the dashboard I only see the RSSI and SNR.
Question:
Is there an cayenne LPP Decoder online available that I can feed my byte string and then see what I did wrong?
// Cayenne LPP Byte definition
// https://github.com/myDevicesIoT/cayenne-docs/blob/master/docs/LORA.md
// Cayenne LPP Payload buildup
// https://hansboksem.wordpress.com/2017/03/06/sending-sensor-data-through-the-things-network-to-cayenne/
// Lora TTN via LMIC and bmp280 code
// https://github.com/galagaking/ttn_nodeworkshop/blob/master/ttn_bmp280_abp.ino
// Edzoās First LoRa TTN Cayenne LPP Implementation
// https://github.com/edzob/loraNode/blob/master/sketch_20170406_lora.ino
old
// Byte string in the Lora TTN Payload
// 036700E9046800057328163C94100F141E3D6F08
Itās not too hard to manually decode this? I run into problems using the documentation:
03 67 00E9 67 = temperature
04 68 00 68 = humidity
05 73 2816 73 = barometer
3C 94 100F141E3D6F08 94 = unknown type?
(My guess is that youāre missing xx 88
at the start of the last section, for GPS location. Any online decoder would fail as well, so is of little helpā¦)
@arjanvanb Thanks for the hint.
I first build a hardcoded message with the existing code
and then used the example functions to build up payload with the sensor data
and now it works!
I needed some reading on Hex Decimals and and Byte Arrayā¦ and learned a lot.
Thanks for the nudge into the right direction
Code on github is updated.
Hi,
I have a TTN/Cayenne device integration. This device has a DHT11 sensor and the payload is in LPP format.
The application data in the TTN Console looks fine to me: 036700C804684400
channel 03, type 67, tempvalue: 20C and channel 04, type 68, humvalue: 34%
My problem; I only see the RSI and SNR widget in Cayenne and reading the answers in previous posts there must be something wrong with my payload but I have no idea. Anyone else?
That should be one byte, not two, for the value. But youāre sending 04 68 4400
.
Thanks Arjan, that is exactly what played in my mind.
At the moment Iāve no access to the code but Iāll try to remove the last byte.
int16_t val;
uint8_t channel;
byte buffer[8];
uint8_t cursor = 0;
val = temperature;
val = temperature * 10;
channel = 0x03;
buffer[cursor++] = 0x03;
buffer[cursor++] = LPP_TEMPERATURE;
buffer[cursor++] = val >> 8;
buffer[cursor++] = val;
val = humidity;
channel = 0x04;
buffer[cursor++] = channel;
buffer[cursor++] = LPP_RELATIVE_HUMIDITY;
buffer[cursor++] = humidity * 2;
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F(āOP_TXRXPEND, not sendingā));
} else {
// Prepare upstream data transmission at the next possible time.
//LMIC_setTxData2(1, buffer, sizeof(buffer)/sizeof(buffer[0]), 0);
LMIC_setTxData2(1, buffer, 7, 0); //brute force
ā¦or:
byte buffer[7];
...
LMIC_setTxData2(1, buffer, sizeof(buffer)/sizeof(buffer[0]), 0);
ā¦or better yet:
byte buffer[20]; // any maximum size your payload might need
...
buffer[cursor++] = ...
buffer[cursor++] = ...
LMIC_setTxData2(1, buffer, cursor, 0);
Iād really like to know this as well. Cayenne seems like a great tool and i want to use it but use more efficient payloads. The channel is inferred from the node ID, node sensor has a fixed structure so there is no need to repeat the meta data for the sensor data every time etc.
Hi Johan
Im trying to use your example code on a 32u4 Lora feather with thing works. few questions if you dont mind.
TTN OTAA
- Are you not missing the DEV EUI input?
- is the input(s) straight copy and past from TTN like so or does it need to be reveresed the same as the LMIC stuff?
- const char *appEui = ā70B3D57EF0004C11ā;
- const char *appKey = ā0000110220330440550660770880990Aā;
I have installed your library, copied your example changed the two keys and uploaded the code but i see not registration attemps in TTN or any data flowing.
Thank you
Johann
The example in TheThingsNetwork Arduino library are specifically for Arduinos with the Microchip RN2xx3 module. With the 32u4 LoRa feather Iād suggest using LMiC. And then, indeed, you need to reverse the byte order.
Hi,
Iām also having trouble getting my data to Cayenne. Can you guys help me with what Iām doing wrong? (I know itās not the prettiest code)
void do_send(osjob_t* j) {
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
// Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Read distance
int distance = readDistance();
mydata[0] = (uint8_t)distance;
// LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
// Cayenne LPP Protocal Definition
#define LPP_DIGITAL_OUTPUT 1
// Init declaration
uint8_t val;
uint8_t channel;
byte buffer[8];
uint8_t cursor = 0;
// set Sensor Barometric Pressure into payload
val = mydata;
channel = 0x04;
{
buffer[cursor++] = channel;
buffer[cursor++] = LPP_DIGITAL_OUTPUT;
buffer[cursor++] = val;
return cursor;
}
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
//Serial output of message
Serial.println(F("Sending: "));
for (byte b = 0; b < (sizeof(buffer) / sizeof(buffer[0])); b++) {
Serial.print(buffer[b]);
}
// Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
}
you have an Cayenne account and set integrations in the Console to Cayenne ? (just to be sure)
Code is not very easy to read. Maybe use the lpp library in the sketch? TTN LPP GitHub . Check if message is received on gateway and application. If so try a manual upload of the data from console and see if it is received by mydevices.
ā¦but it seems to me youāre not filling the whole buffer with data.
So, maybe something like:
LMIC_setTxData2(1, buffer, cursor, 0);
for (byte b = 0; b < cursor; b++) {
Serial.print(buffer[b]);
}
Also, if I understand your code formatting correctly then it seems the return cursor;
exits the function prematurely (and Serial.println(F("Sending: "));
is never even invoked), but Iāll leave proper formatting to you, before asking againā¦
Admitting that is never an excuse!
I made a CayenneLPP to JSON decoder (C++), but it could of course also be used as a start template for your own code.
Maybe it could be of use for some reading this topic
Hii
Iām also having trouble getting my data to Cayenne. Iām tried to sending GPS data to Cayenne Dashboard but only RSSI and SNR data shown but not GPS location, here it is code i tried. Can you guys help me whatās wrong in this?
function Decoder(b,port)
{
var decode = {};
var decode204 = {};
var decode205 = {};
var decode207 = {};
if(port == 204)
{
decode204.payload = b;
decode204.porta = port;
decode.lat = b[0]<<16 | b[1]<<8 | b[2];
decode.lng = b[3]<<16 | b[4]<<8 | b[5];
decode204.altitude = b[6]<<8 | b[7];
decode204.hdop = b[8];
decode204.temperature=(b[9]&0x0F)*100;
decode204.temperature+=(b[10]>>4)*10;
decode204.temperature+=(b[10]&0x0F);
if (b[9]&0xF0)
decode204.temperature/=-10;
else
decode204.temperature/=10;
decode204.battery =(b[11]>>4)*10;
decode204.battery+=(b[11]&0x0F);
decode204.latitude = (decode.lat / 8388606) * 90;
decode204.longitude = (decode.lng / 8388606) * 180;
return {
payload: decode204.payload,
port: decode204.porta,
longitude: decode204.longitude,
latitude: decode204.latitude,
altitude: decode204.altitude,
temperature: decode204.temperature,
hdop: decode204.hdop,
}
}
else if(port===205)
{
decode205.payload = b;
decode205.porta = port;
decode205.temperature =(b[0]&0x0F)*100;
decode205.temperature+=(b[1]>>4)*10;
decode205.temperature+=(b[1]&0x0F);
if (b[0]&0xF0)
decode205.temperature/=-10;
else
decode205.temperature/=10;
decode205.battery=(b[2]>>4)*10;
decode205.battery+=(b[2]&0x0F);
return {
payload: decode205.payload,
port: decode205.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: decode205.temperature,
hdop: "",
}
}
else if(port===207)
{
decode207.payload = b;
decode207.porta = port;
decode207.temperature =(b[0]&0x0F)*100;
decode207.temperature+=(b[1]>>4)*10;
decode207.temperature+=(b[1]&0x0F);
if (b[0]&0xF0)
decode207.temperature/=-10;
else
decode207.temperature/=10;
decode207.battery=(b[2]>>4)*10;
decode207.battery+=(b[2]&0x0F);
return {
payload: decode207.payload,
port: decode207.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: decode207.temperature,
hdop: "",
}
}
else
{
decode.porta = port;
decode.payload = b;
return {
payload: decode.payload,
port: decode.porta,
longitude: "",
latitude: "",
altitude: "",
temperature: "",
hdop: "",
}
}
}
Are you using a Custom Payload Format??!
I guess you need to change to Cayenne LPP on Payload Formats.
And your Node need to payload data with the CayenneLPP library ā> https://www.thethingsnetwork.org/docs/devices/arduino/api/cayennelpp.html
#include <CayenneLPP.h>
CayenneLPP lpp(51);
void PayloadNow(Stream &out)
{
lpp.reset();
lpp.addTemperature(1, get_temperature());
if (gps_read()){
lpp.addGPS(1, gps_latitude(), gps_longitude() , gps_meters());
}
lpp.addAnalogInput(4, readVcc() / 1000.0);
out.write(lpp.getBuffer(), lpp.getSize());
}
Something like this!