• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
NMEA Parser/Converter
#1
Great work on OP, very excited to see where it goes in the coming years.

Are there any plans for a NMEA parser/converter built directly into OP same as the OpenCPN plugin?

https://opencpn.org/wiki/dokuwiki/doku.p..._converter

As an example I have an old DataMarine depth sounder that is not outputting a checksum:

$IIDPT,2.1,0.0
$IIDBT,7.1,f,2.1,M,1.1,F

A work-around is to disable force checksum in OpenCPN but this doesn't work for other applications on my local NMEA0183 network.

Another benefit is to parse sentences from proprietary sources. (Ie. ComNav autopilot rudder position which is buried in a long proprietary sentience)
  Reply
#2
We have a tool "NMEA 0183 generator" that builds sentences from signal k values. If your sentences without checksum can be digested by the Signal k server, I think so, you can rebuild your sentences. This tool will suffer big changes and improvements soon because is in the TODO list.
  Reply
#3
I did it with Node-RED (with some great help from this board). It was surprisingly simple and works very well.

Do you want the code? It should be really easy to modify to accommodate your strings.
  Reply
#4
(07-03-2017, 12:45 PM)Sailoog Wrote: We have a tool "NMEA 0183 generator" that builds sentences from signal k values. If your sentences without checksum can be digested by the Signal k server, I think so, you can rebuild your sentences. This tool will suffer big changes and improvements soon because is in the TODO list.

So far I have not been able to get a signalK sentence from a NMEA0183 input without a checksum. Would a "ignore checksum" or "force checksum" be on the feature list for the NMEA0183 input dialog one day?

Another option for me is to generate a checksum in hardware but I would like to avoid that.

(07-03-2017, 01:27 PM)abarrow Wrote: I did it with Node-RED (with some great help from this board). It was surprisingly simple and works very well.

Do you want the code? It should be really easy to modify to accommodate your strings.

I haven't looked into Node-RED at all yet but if you say that's a decent solution I would definitely give it a try. Code post here ok?
  Reply
#5
I've been messing around with this today. It might give you some ideas. Import it into a new flow in Node-RED.
Code:
[
    {
        "id": "8ec62a14.f63ac8",
        "type": "switch",
        "z": "f9bd0a33.c9b318",
        "name": "Filter RMC, pass everything else",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "regex",
                "v": "^(?=...*RMC)",
                "vt": "str",
                "case": false
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "outputs": 2,
        "x": 530,
        "y": 480,
        "wires": [
            [
                "6519c937.dc56b8"
            ],
            [
                "e1799bbe.a60b08"
            ]
        ],
        "inputLabels": [
            "Input"
        ],
        "outputLabels": [
            "RMC",
            ""
        ]
    },
    {
        "id": "f1d525e4.908778",
        "type": "function",
        "z": "f9bd0a33.c9b318",
        "name": "calc checksum",
        "func": "var nmea = msg.payload;\nvar checksum = 0; \n\nfor(var i = 0; i < nmea.length; i++) { \n  checksum = checksum ^ nmea.charCodeAt(i); \n}\nchecksum = checksum.toString(16);    //convert to hex\nnmea = '$' + nmea + '*' + checksum;  //make the full nmea sentence again\n\nmessage = 'Full message =' + nmea + '\\r\\n' + 'Checksum = ' + checksum ;\n\nmsg.payload = nmea;\nmsg.payload = msg.payload+\"\\r\\n\";\n\nvar msg1 = {\n     payload: msg.payload\n };\n return msg1;",
        "outputs": 1,
        "noerr": 0,
        "x": 1180,
        "y": 540,
        "wires": [
            [
                "9648f94e.06f568",
                "b4d70c7e.c6a58"
            ]
        ]
    },
    {
        "id": "9648f94e.06f568",
        "type": "udp out",
        "z": "f9bd0a33.c9b318",
        "name": "",
        "addr": "127.0.0.1",
        "iface": "",
        "port": "10108",
        "ipv": "udp4",
        "outport": "",
        "base64": false,
        "multicast": "false",
        "x": 1400,
        "y": 460,
        "wires": []
    },
    {
        "id": "5640ac5c.6b5634",
        "type": "comment",
        "z": "f9bd0a33.c9b318",
        "name": "This takes NMEA Output, changes date string and adds checksum",
        "info": "",
        "x": 800,
        "y": 260,
        "wires": []
    },
    {
        "id": "e7485e56.706cb",
        "type": "serial in",
        "z": "f9bd0a33.c9b318",
        "name": "NMEA Input",
        "serial": "c5d7ff46.19d73",
        "x": 230,
        "y": 700,
        "wires": [
            [
                "8ec62a14.f63ac8"
            ]
        ]
    },
    {
        "id": "7c9f7c22.f815c4",
        "type": "inject",
        "z": "f9bd0a33.c9b318",
        "name": "Inject GLL String",
        "topic": "",
        "payload": "$GPGLL,5930.030,N,00254.792,E,163415,A*11",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 240,
        "y": 480,
        "wires": [
            [
                "8ec62a14.f63ac8"
            ]
        ]
    },
    {
        "id": "6db2a42d.3e034c",
        "type": "inject",
        "z": "f9bd0a33.c9b318",
        "name": "Inject RMC String",
        "topic": "",
        "payload": "$GPRMC,163415,A,5930.030,N,00254.792,E,00.0,000.,171197,000.8,E*79",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 238,
        "y": 556.9999876022339,
        "wires": [
            [
                "8ec62a14.f63ac8"
            ]
        ]
    },
    {
        "id": "b4d70c7e.c6a58",
        "type": "debug",
        "z": "f9bd0a33.c9b318",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 1370,
        "y": 660,
        "wires": []
    },
    {
        "id": "e1799bbe.a60b08",
        "type": "function",
        "z": "f9bd0a33.c9b318",
        "name": "Create unmodified string - change only device code",
        "func": "var nmeaFull=msg.payload;\n\nvar nmeaStripped=\"\";\n//If it has a checksum, strip it\nvar n = nmeaFull.indexOf(\"*\")\nif (n > 0){\n    nmeaStripped=nmeaFull.substring(0, n);}\nelse {\n    nmeaStripped=nmeaFull;\n}\n\nvar nmeaSplit=nmeaStripped.split(\",\");\n\nvar deviceCode=\"AB\";\n   \nvar nmeaFinal=deviceCode+nmeaSplit[0].substring(3,6)+\",\";\n\nvar i=1;\n\ndo {\n    nmeaFinal += nmeaSplit[i] + \",\";\n    i++;\n}\nwhile (i < (nmeaSplit.length-2));\n\nnmeaFinal=nmeaFinal+nmeaSplit[(nmeaSplit.length-1)];\n\nmsg.payload = nmeaFinal;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 850,
        "y": 600,
        "wires": [
            [
                "f1d525e4.908778"
            ]
        ]
    },
    {
        "id": "3c8b2779.e12068",
        "type": "inject",
        "z": "f9bd0a33.c9b318",
        "name": "Inject GGA String",
        "topic": "",
        "payload": "$GPGGA,163415,5930.030,N,00254.792,E,1,04,001,0001,M,040,M,,",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 239.99993133544922,
        "y": 399.9999170303345,
        "wires": [
            [
                "8ec62a14.f63ac8"
            ]
        ]
    },
    {
        "id": "a7fb3463.c10b98",
        "type": "inject",
        "z": "f9bd0a33.c9b318",
        "name": "Inject VTG String",
        "topic": "",
        "payload": "$GPVTG,000,T,359,M,00.0,N,00.0,K",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 239.99993133544922,
        "y": 319.9999170303345,
        "wires": [
            [
                "8ec62a14.f63ac8"
            ]
        ]
    },
    {
        "id": "6519c937.dc56b8",
        "type": "function",
        "z": "f9bd0a33.c9b318",
        "name": "Create RMC string with correct year",
        "func": "var nmeaFull=msg.payload;\n\nvar nmeaStripped=\"\";\n//If it has a checksum, strip it\nvar n = nmeaFull.indexOf(\"*\")\nif (n > 0){\n    nmeaStripped=nmeaFull.substring(0, n);}\nelse {\n    nmeaStripped=nmeaFull;\n}\n\n\nvar nmeaSplit=nmeaStripped.split(\",\");\n\nvar nmeaYear=nmeaSplit[9].substring(4, 6);\nvar nmeaMonth=nmeaSplit[9].substring(2, 4);\nvar nmeaDay=nmeaSplit[9].substring(0, 2);\n\nvar nmeaYearInt=parseInt(nmeaYear)+1920;\nvar nmeaYearStr=nmeaYearInt.toString();\nnmeaYear=nmeaYearStr.substring(2,4);\n\nnmeaSplit[9]=nmeaDay+nmeaMonth+nmeaYear;\n\nvar nmeaFinal=\"ABRMC,\";\n\nvar i=1;\n\ndo {\n    nmeaFinal += nmeaSplit[i] + \",\";\n    i++;\n}\nwhile (i < (nmeaSplit.length-2));\n\nnmeaFinal=nmeaFinal+nmeaSplit[(nmeaSplit.length-1)];\n\nmsg.payload = nmeaFinal;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 860,
        "y": 380,
        "wires": [
            [
                "f1d525e4.908778"
            ]
        ]
    },
    {
        "id": "c5d7ff46.19d73",
        "type": "serial-port",
        "z": "",
        "serialport": "/dev/ttyOP_485",
        "serialbaud": "4800",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": false
    }
]
  Reply
#6
(07-04-2017, 05:44 PM)Denham Wrote: So far I have not been able to get a signalK sentence from a NMEA0183 input without a checksum. Would a "ignore checksum" or "force checksum" be on the feature list for the NMEA0183 input dialog one day?

Another option for me is to generate a checksum in hardware but I would like to avoid that.

That would be a feature to be included on the signal k plugin which convert NMEA 0183 into signal k
https://github.com/SignalK/signalk-parser-nmea0183

Checksum is optional on kplex and opencpn
  Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)