Dragino LGT-92 and Node-RED TTN nodes

Hello everyone,

This is my first post on this forum and my first steps into the major rabbithole of LoRa and wonder if I should have done this or not :’)

I have a Dragino LGT-92 have followed various tutorials and the thing is talking to the TTN and I see data coming in the console.

On the serial port I see:

***** UpLinkCounter= 39 *****
TX on freq 868100000 Hz at DR 2
Server_TX_DUTYCYCLE: 30000
txDone
rxTimeOut
rxTimeOut
Roll=226  Pitch=348
South: 52.1393
East: 4.4697

I have setup the decoder for the payload, the data shows up incorrectly for long/lat, battery, pitch/roll are ok.

On TTN console it shows up as:

payload:07F4B100AE980FD600E2015C alarm:false batV:4.054 latitude:-1625.5823 longitude:-1673.252 pitch:3.48 roll:2.26

Function used (from Dragino documentation):

function Decoder(bytes, port) {
    // Decode an uplink message from a buffer
    // (array) of bytes to an object of fields.
    var alarm = bytes[6] & 0x40 ? true : false; //Alarm status
    value = ((bytes[6] & 0x3f) << 8) | bytes[7];
    var batV = value / 1000; //Battery,units:Volts
    value = (bytes[8] << 8) | bytes[9];
    if (bytes[8] & 0x80) {
        value |= 0xffff0000;
    }
    var roll = value / 100; //roll,units: °
    value = (bytes[10] << 8) | bytes[11];
    if (bytes[10] & 0x80) {
        value |= 0xffff0000;
    }
    var pitch = value / 100; //pitch,units: °
    var json = {
        roll: roll,
        pitch: pitch,
        batV: batV,
        alarm: alarm,
    };
    var value = (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
    if (bytes[0] & 0x80) {
    }
    value |= 0xffffff000000;
    var value2 = (bytes[3] << 16) | (bytes[4] << 8) | bytes[5];
    if (bytes[3] & 0x80) {
    }
    value2 |= 0xffffff000000;

    if (value == 0x0fffff && value2 == 0x0fffff) {
        //gps disabled (low battery)
    } else if (value === 0 && value2 === 0) {
        //gps no position yet
    } else {
    }
    json.latitude = value / 10000; //gps latitude,units: °
    json.longitude = value2 / 10000; //gps longitude,units: °
    return json;
}

Is it parsing incorrect bytes ?

Next I use Node-RED extensively, so an opportunity to use the TTN nodes (on github the repo shows as archived ? Are the nodes still correct to use?)

The quickstart guide talks about ‘ttn message node’ which does not exist ?

The payload data shows up in Node-red (using the TTN Event node and using # for the event), however, after a while it stops receiving for some unknown reason, payload still shows up in the TTN console.

Resetting the LGT-92 (ATZ) and it starts to talk again in Node-red, can this behaviour be explained ?

The payload itself appears to be encrypted, get something like: YDIpASaFAAADIf8AAV8FExI=

Using the nodejs lora-packet decoder with the nwskey and appskey for decrypting base64, nothing useful comes out of it.

How can I receive readable data in Node-red ?

Ok - edit

Apparently I did not have correct rights for the access key setup, I receive the payload in readable format now, only thing left is the decoder that produces incorrect location details.

This seems to be a problem with the decoder, though I’m not entirely sure what.

payload:07F4B100AE980FD600E2015C

What your decoder seems to be doing a bad job of, is trying to extract a pair of 24 bit (3 byte each) big-endian values from the start of the packet. Those would be

07F4B1 and 00AE98

Abusing bash on a Linux box we can convert these ourselves

$ echo $((0x07F4B1)) $((0x00AE98))

521393 44696

Which does seem to correspond with the node serial output, so the problem must be in the decoder.

if (bytes[0] & 0x80) {
}
value |= 0xffffff000000;

This is broken - what the author intended to write was

if (bytes[0] & 0x80) {
value |= 0xffffff000000;
}

Which is to say, that if the MSB of the most significant byte is on, the value should be treated as a 2’s complement negative number and sign extended to the full width so that it will be treated as a negative number. But even that isn’t going to work, as the code mistakenly sign extends to 48 bits, and I’m not aware of any common programming language where that is a normally used datatype - if one were going to sign extend it should be to 64 bits, but there are probably better ways to do subtraction. I’ll leave that to those who understand this variation of javascript - if I simulate the error in a different language, I don’t get the same wrong answers, though I do get wrong answers.

Luckily for you, your coordinates are positive…

For your purposes it may be enough to fix the typo of misordered lines; the code might possibly (but likely not) still fail in north or west locations and needs to be fixed, luckily you and Dragino seem to be in the same part of the world.

UPDATE:

If we assume an execution environment where calculations will be carried out in signed 32-bit variables (which may in fact be the case for javascript, at least it’s what happens if I try this in a jsfiddle) then the mistaken attempt to sign extended a positive number caused by the two mis-ordered lines above does explain the specific erroneous values produced. Possibly the code will work for actual negative numbers if the mis-ordering of lines is corrected; I still don’t particularly like the implicit assumption of an unstated data type, and the goofy sign extension to 48 bits in a 32-bit context…

Thanks for your elaborate response!

You are indeed correct, it is either bad copy and paste work or the documentation is incorrect (code in a pdf document is never a good idea).

It works with this fix, now working on consistent connections. Thanks again.

Have you check the accuracy of the GPS, are you getting 10 meters or less accuracy ?