Payload decoder adeunis field tester


function Decode( fPort, bytes )
{

// Functions
function parseCoordinate( raw_value, coordinate )

{

// This function parses a coordinate payload part into

// dmm and ddd

var raw_itude = raw_value;

var temp = "";


// Degree section

var itude_string = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


itude_string += ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


coordinate.degrees += itude_string;

itude_string += "°";


// Minute section

temp = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


temp += ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;

itude_string += temp;

itude_string += ".";

coordinate.minutes += temp;


// Decimal section

temp = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


temp += ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


itude_string += temp;

coordinate.minutes += ".";

coordinate.minutes += temp;

return itude_string;

}

function parseLatitude( raw_latitude, coordinate )

{

var latitude = parseCoordinate( raw_latitude, coordinate );

latitude += ((raw_latitude & 0xF0) >> 4).toString( );

coordinate.minutes += ((raw_latitude & 0xF0) >> 4).toString( );


return latitude;

}

function parseLongitude( raw_longitude, coordinate )

{

var longitude = ( ((raw_longitude >> 28) & 0xF ) ).toString( );

coordinate.degrees = longitude;

longitude += parseCoordinate( raw_longitude << 4, coordinate );


return longitude;

}

function addField( field_no, payload )

{

switch( field_no )

{

// Presence of temperature information

case 0:

payload.temperature = bytes[bytes_pos_] & 0x7F;

// Temperature is negative

if( (bytes[bytes_pos_] & 0x80) > 0 )

{

payload.temperature -= 128;

}

bytes_pos_++;

break;

// Transmission triggered by the accelerometer

case 1:

payload.trigger = "accelerometer";

break;

// Transmission triggered by pressing pushbutton 1

case 2:

payload.trigger = "pushbutton";

break;

// Presence of GPS information

case 3:

// GPS Latitude

// An object is needed to handle and parse coordinates into ddd notation

var coordinate = {};

coordinate.degrees = "";

coordinate.minutes = "";


var raw_value = 0;

raw_value |= bytes[bytes_pos_++] << 24;

raw_value |= bytes[bytes_pos_++] << 16;

raw_value |= bytes[bytes_pos_++] << 8;

raw_value |= bytes[bytes_pos_++];


payload.lati_hemisphere = (raw_value & 1) == 1 ? "South" : "North";

payload.latitude_dmm = payload.lati_hemisphere.charAt( 0 ) + " ";

payload.latitude_dmm += parseLatitude( raw_value, coordinate );

payload.latitude = ( parseFloat( coordinate.degrees ) + parseFloat( coordinate.minutes ) / 60 ) * ( (raw_value & 1) == 1 ? -1.0 : 1.0);


// GPS Longitude

coordinate.degrees = "";

coordinate.minutes = "";

raw_value = 0;

raw_value |= bytes[bytes_pos_++] << 24;

raw_value |= bytes[bytes_pos_++] << 16;

raw_value |= bytes[bytes_pos_++] << 8;

raw_value |= bytes[bytes_pos_++];


payload.long_hemisphere = (raw_value & 1) == 1 ? "West" : "East";

payload.longitude_dmm = payload.long_hemisphere.charAt( 0 ) + " ";

payload.longitude_dmm += parseLongitude( raw_value, coordinate );

payload.longitude = ( parseFloat( coordinate.degrees ) + parseFloat( coordinate.minutes ) / 60 ) * ( (raw_value & 1) == 1 ? -1.0 : 1.0);


// GPS Quality

raw_value = bytes[bytes_pos_++];


switch( (raw_value & 0xF0) >> 4 )

{

case 1:

payload.gps_quality = "Good";

break;

case 2:

payload.gps_quality = "Average";

break;

case 3:

payload.gps_quality = "Poor";

break;

default:

payload.gps_quality = (raw_value >> 4) & 0xF;

break;

}

payload.hdop = (raw_value >> 4) & 0xF;


// Number of satellites

payload.sats = raw_value & 0xF;


break;

// Presence of Uplink frame counter

case 4:

payload.ul_counter = bytes[bytes_pos_++];

break;

// Presence of Downlink frame counter

case 5:

payload.dl_counter = bytes[bytes_pos_++];

break;

// Presence of battery level information

case 6:

payload.battery_level = bytes[bytes_pos_++] << 8;

payload.battery_level |= bytes[bytes_pos_++];

break;

// Presence of RSSI and SNR information

case 7:

// RSSI

payload.rssi_dl = bytes[bytes_pos_++];

payload.rssi_dl *= -1;


// SNR

payload.snr_dl = bytes[bytes_pos_] & 0x7F;

if( (bytes[bytes_pos_] & 0x80) > 0 )

{

payload.snr_dl -= 128;

}

bytes_pos_++;

break;

default:

// Do nothing

break;

}

}


// Declaration & initialization

var status_ = bytes[0];

var bytes_len_ = bytes.length;

var bytes_pos_ = 1;

var i = 0;

var payload = {};


// Get raw payload

var temp_hex_str = ""

payload.payload = "";

for( var j = 0; j < bytes_len_; j++ )

{

temp_hex_str = bytes[j].toString( 16 ).toUpperCase( );

if( temp_hex_str.length == 1 )

{

temp_hex_str = "0" + temp_hex_str;

}

payload.payload += temp_hex_str;

}


// Get payload values

do

{

// Check status, whether a field is set

if( (status_ & 0x80) > 0 )

{

addField( i, payload );

}

i++;

}

while( ((status_ <<= 1) & 0xFF) > 0 );


return payload;

}
Advertisements

Connecting ESP32 with RFM95w


esp32

 

 

 

 

 

Catatan untuk menghubungkan ESP32 dengan LoRa Module RFM95w

ESP32 RFM95W
23 MOSI
19 MISO
18 SCK
21 SCL
5 NSS
26 DIO0
33 DIO1
25 RST

Parsing data from mqtt ttn


Postingan kali ini adalah lanjutan dari postingan saya sebelumnya disini , nah pada postingan saya kali ini akan membahas bagaimana cara memparsing data json yang kita dapat dari ttn kemudian menampilkannya ke dalam dashboard, sehingga hasilnya seperti dibawah ini

[{"id":"1f1f6ed1.81cf91","type":"mqtt in","z":"7609c47a.c51b3c","name":"","topic":"+/devices/+/up","qos":"2","broker":"7833904b.af11d","x":220,"y":200,"wires":[["d839d790.4b77c8"]]},{"id":"d839d790.4b77c8","type":"json","z":"7609c47a.c51b3c","name":"","property":"payload","action":"obj","pretty":true,"x":470,"y":200,"wires":[["e2efc94c.1de158","47698174.a787f","9db17467.71c868","b38807c2.074058","6cc7cd06.b7c634"]]},{"id":"e2efc94c.1de158","type":"function","z":"7609c47a.c51b3c","name":"battery","func":"var obj = msg.payload;\nmsg.payload = obj.payload_fields.analog_in_3;\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":180,"wires":[["9ea82fec.53c49"]]},{"id":"47698174.a787f","type":"function","z":"7609c47a.c51b3c","name":"temperature","func":"var obj = msg.payload;\nmsg.payload = obj.payload_fields.temperature_1;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":240,"wires":[["491b941b.7cb80c"]]},{"id":"9db17467.71c868","type":"function","z":"7609c47a.c51b3c","name":"humidity","func":"var obj = msg.payload;\nmsg.payload = obj.payload_fields.relative_humidity_2;\nreturn msg;","outputs":1,"noerr":0,"x":700,"y":300,"wires":[["754ca03c.46161"]]},{"id":"491b941b.7cb80c","type":"ui_chart","z":"7609c47a.c51b3c","name":"","group":"7fb7eee3.fc934","order":1,"width":0,"height":0,"label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":930,"y":240,"wires":[[],[]]},{"id":"9ea82fec.53c49","type":"ui_gauge","z":"7609c47a.c51b3c","name":"","group":"d98f26c6.56b8b8","order":1,"width":0,"height":0,"gtype":"gage","title":"Battery","label":"units","format":"{{value}}","min":0,"max":10,"colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":920,"y":180,"wires":[]},{"id":"754ca03c.46161","type":"ui_chart","z":"7609c47a.c51b3c","name":"","group":"7fb7eee3.fc934","order":2,"width":0,"height":0,"label":"Humidity","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":920,"y":300,"wires":[[],[]]},{"id":"b38807c2.074058","type":"function","z":"7609c47a.c51b3c","name":"rssi","func":"var obj = msg.payload;\nmsg.payload = obj.metadata.gateways[0].rssi;\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":360,"wires":[["9e68c3c6.729e5"]]},{"id":"9e68c3c6.729e5","type":"ui_chart","z":"7609c47a.c51b3c","name":"","group":"9a2e91ee.5594a","order":2,"width":0,"height":0,"label":"RSSI","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":910,"y":360,"wires":[[],[]]},{"id":"6cc7cd06.b7c634","type":"function","z":"7609c47a.c51b3c","name":"rssi","func":"var obj = msg.payload;\nmsg.payload = obj.metadata.gateways[0].snr;\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":420,"wires":[["c2e09073.55f99"]]},{"id":"c2e09073.55f99","type":"ui_chart","z":"7609c47a.c51b3c","name":"","group":"9a2e91ee.5594a","order":3,"width":0,"height":0,"label":"SNR","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":910,"y":420,"wires":[[],[]]},{"id":"7833904b.af11d","type":"mqtt-broker","z":"","name":"application_name","broker":"asia-se.thethings.network","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"7fb7eee3.fc934","type":"ui_group","z":"","name":"Chart","tab":"5d83a158.d5268","order":2,"disp":true,"width":"6","collapse":false},{"id":"d98f26c6.56b8b8","type":"ui_group","z":"","name":"Gauge","tab":"5d83a158.d5268","order":1,"disp":true,"width":"6","collapse":false},{"id":"9a2e91ee.5594a","type":"ui_group","z":"","name":"Others","tab":"5d83a158.d5268","order":3,"disp":true,"width":"6","collapse":false},{"id":"5d83a158.d5268","type":"ui_tab","z":"","name":"Home","icon":"timeline"}]

TTN payload format for Rising HF RHF1S001


function Decoder(bytes, port) {
var obj = new Object();

//temp
var tempEncoded=(bytes[2]<<8)|(bytes[1]);
var tempDecoded=(tempEncoded*175.72/65536)-46.85;
obj.temp=tempDecoded.toFixed(2);

//humidity
var humEncoded=(bytes[3]);
var humDecoded=(humEncoded*125/256)-6;
obj.hum=humDecoded.toFixed(2);

//period
var periodEncoded=(bytes[5]<<8)|(bytes[4]);
var periodDecoded=(periodEncoded*2);
obj.period=periodDecoded+" sec";

//battery
var batteryEncoded=(bytes[8]);
var batteryDecoded=(batteryEncoded+150)*0.01;
obj.battery=batteryDecoded.toFixed(2);


return obj;
}

lora mini dev and ttn


lora_mini_devKali ini nyobain lora module buatan dragino namanya lora mini dev, uniknya dari module ini adalah sudah jadi satu antara RF dan mikro kontrollernya, untuk programmingnya sendiri cukup mudah karena sudah ada usb nya jadi tinggal colok aja mikro usb bawaannya terus bisa diprogram menggunakan arduino ide.

Reviewnya menyusul ya ini tadi baru  test OTAA ke thethingsnetwork si lancar jaya cuman awalnya sempat bingung untuk pin mapping lmicnya, soalnya nyari nyari didokumentasinya ngga nemu.

Beruntung banget pas lagi browsing nemu, nah dibawah ini adalah pinout mappingnya karena kalau pinout ini salah dijamin lora mini dev ini ngga akan bekerja di lmic

 const lmic_pinmap lmic_pins = {
 .nss = 10,
 .rxtx = LMIC_UNUSED_PIN,
 .rst = 9,
 .dio = {2, 6, 7},
};

Silahkan yang pingin nyoba nyoba ini modul bisa pake lmic standard tinggal nanti menyesuaikan lmicnya seperti diatas.

kalau mau liat2 codingannya ke github saya disini tinggal ganti lmicnya seperti diatas

Happy Coding ..

Salam ngoprek …

simple paho-mqtt with python


Bagi kalian yang sedang main IOT mungkin simple script main-main saya dibawah ini mudah-mudahan bisa bermanfaat, iseng sebelum tidur main-main dengan python dan paho mqtt, simple nya si hanya untuk subscribe mqtt dan publish mqtt, mungkin kedepannya ditambahin fitur web.

Yang penasaran silahkan main ke github saya disini 

Sekian semoga bermanfaat

Happy Coding !!!

 

MQTT Subscribe esp8266


mqtt pub sub esp8266

Nambah catatan aja semoga bermanfaat juga buat yang membutuhkan cara subscribe ke mqtt server dengan esp8266

Pertama tama download dan pasang plugin ini di arduino libraries, lalu sesuaikan coding dibawah dengan alamat server dan topic yang anda gunakan

/*
 MQTT subscriber example

- connects to an MQTT server
 - subscribes to the topic "inTopic"
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char *ssid = "ssid"; // cannot be longer than 32 characters!
const char *pass = "pass"; //

// Update these with values suitable for your network.
IPAddress server(xx,xx,xx,xx);

#define BUFFER_SIZE 100

void callback(const MQTT::Publish& pub) {
 Serial.print(pub.topic());
 Serial.print(" => ");
 if (pub.has_stream()) {
 uint8_t buf[BUFFER_SIZE];
 int read;
 while (read = pub.payload_stream()->read(buf, BUFFER_SIZE)) {
 Serial.write(buf, read);
 }
 pub.payload_stream()->stop();
 Serial.println("");
 } else
 Serial.println(pub.payload_string());
}

WiFiClient wclient;
PubSubClient client(wclient, server);

void setup() {
 // Setup console
 Serial.begin(115200);
 delay(10);
 Serial.println();
 Serial.println();
}

void loop() {
 if (WiFi.status() != WL_CONNECTED) {
 Serial.print("Connecting to ");
 Serial.print(ssid);
 Serial.println("...");
 WiFi.begin(ssid, pass);

if (WiFi.waitForConnectResult() != WL_CONNECTED)
 return;
 Serial.println("WiFi connected");
 }

if (WiFi.status() == WL_CONNECTED) {
 if (!client.connected()) {

if (client.connect(MQTT::Connect("arduinoClient")
 .set_auth("username mqtt", "pass mqtt"))) {
 
 client.set_callback(callback);
 client.subscribe("topic");
 }
 }

if (client.connected())
 client.loop();
 }
}

 

Udah gitu aja, semoga bermanfaat

Happy coding !!!