This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pypilot control ideas
#8
(2020-02-21, 08:31 PM)kp.sov69 Wrote: So if i understand correctly you are able to control all the autopilot functions through the arduino serial connection sending messages back and forth through signalk? That seems like a very elegant solution for a helm based control and display interface. 32u4 based arduinos have an extra hardware uart and high speed built in usb serial.
Would love to see the code and implementation as well.

Here it is wiring diagram:
   

and arduino sketch is attached as well

.zip   sketch_nov11b.zip (Size: 90.73 KB / Downloads: 228)

arduino is USB connected to Raspberry Pi as /dev/ttyUSB1

Recently i have changed implementation on Raspberry Pi side. Now it is only using  Node-Red dashboard in SignalK server without using Kplex (so, now it is working in Openplotter2 too)

the arduino and node-red code in the testing and debugging state... (just as proof of concept, but working at table perfectly : )

Here is is node-red flow
Code:
[
    {
        "id": "9a419ebb.65893",
        "type": "switch",
        "z": "ba70a55e.0d29a8",
        "name": "Filter XXX to pypilot and another NMEA's to signalk",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "regex",
                "v": "^(?=...*XXX)",
                "vt": "str",
                "case": false
            },
            {
                "t": "regex",
                "v": "^\\$",
                "vt": "str",
                "case": false
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 527,
        "y": 388,
        "wires": [
            [
                "195f2de4.b63742"
            ],
            [
                "fdd29b96.b7f2a8"
            ],
            []
        ],
        "inputLabels": [
            "Input"
        ],
        "outputLabels": [
            "XXX",
            "Otherwise",
            ""
        ]
    },
    {
        "id": "9f6be0e6.5389b",
        "type": "tcp out",
        "z": "ba70a55e.0d29a8",
        "host": "localhost",
        "port": "21311",
        "beserver": "client",
        "base64": false,
        "end": false,
        "name": "",
        "x": 1184,
        "y": 362,
        "wires": []
    },
    {
        "id": "195f2de4.b63742",
        "type": "function",
        "z": "ba70a55e.0d29a8",
        "name": "Parse to Pypilot internal Signalk",
        "func": "var th = msg.payload.replace(\"\\$APXXX,\",\"\").slice(0, -5).split(\",\");\n\nmsg.payload = '{\\\"name\\\": \\\"'+th[0]+'\\\", \\\"method\\\": \\\"set\\\", \\\"value\\\": '+th[1]+'}\\n'\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 875,
        "y": 328,
        "wires": [
            [
                "9f6be0e6.5389b"
            ]
        ]
    },
    {
        "id": "ebba1cdb.316b6",
        "type": "tcp request",
        "z": "ba70a55e.0d29a8",
        "server": "localhost",
        "port": "21311",
        "out": "sit",
        "splitc": " ",
        "name": "",
        "x": 350,
        "y": 68,
        "wires": [
            [
                "dcd047b9.925a68"
            ]
        ]
    },
    {
        "id": "ebddce32.852eb",
        "type": "inject",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "topic": "",
        "payload": "[123,34,110,97,109,101,34,58,32,34,105,109,117,46,104,101,97,100,105,110,103,95,108,111,119,112,97,115,115,34,44,32,34,109,101,116,104,111,100,34,58,32,34,103,101,116,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,104,101,97,100,105,110,103,95,99,111,109,109,97,110,100,34,44,32,34,109,101,116,104,111,100,34,58,32,34,103,101,116,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,101,110,97,98,108,101,100,34,44,32,34,109,101,116,104,111,100,34,58,32,34,103,101,116,34,125,13,10,123,34,110,97,109,101,34,58,32,34,115,101,114,118,111,46,115,116,97,116,101,34,44,32,34,109,101,116,104,111,100,34,58,32,34,103,101,116,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,109,111,100,101,34,44,32,34,109,101,116,104,111,100,34,58,32,34,103,101,116,34,125,13,10,123,34,110,97,109,101,34,58,32,34,105,109,117,46,104,101,97,100,105,110,103,95,108,111,119,112,97,115,115,34,44,32,34,109,101,116,104,111,100,34,58,32,34,119,97,116,99,104,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,104,101,97,100,105,110,103,95,99,111,109,109,97,110,100,34,44,32,34,109,101,116,104,111,100,34,58,32,34,119,97,116,99,104,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,101,110,97,98,108,101,100,34,44,32,34,109,101,116,104,111,100,34,58,32,34,119,97,116,99,104,34,125,13,10,123,34,110,97,109,101,34,58,32,34,115,101,114,118,111,46,115,116,97,116,101,34,44,32,34,109,101,116,104,111,100,34,58,32,34,119,97,116,99,104,34,125,13,10,123,34,110,97,109,101,34,58,32,34,97,112,46,109,111,100,101,34,44,32,34,109,101,116,104,111,100,34,58,32,34,119,97,116,99,104,34,125,13,10]",
        "payloadType": "bin",
        "repeat": "30",
        "crontab": "",
        "once": true,
        "onceDelay": "1",
        "x": 140,
        "y": 69,
        "wires": [
            [
                "ebba1cdb.316b6"
            ]
        ]
    },
    {
        "id": "dcd047b9.925a68",
        "type": "function",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "func": "msg.payload = msg.payload.toString();\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "x": 533,
        "y": 68,
        "wires": [
            [
                "42c84588.bc3fdc"
            ]
        ]
    },
    {
        "id": "8075876f.6fb518",
        "type": "json",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 1005,
        "y": 68,
        "wires": [
            [
                "51e6b603.327568"
            ]
        ]
    },
    {
        "id": "d0d13719.18e238",
        "type": "change",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "rules": [
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "name",
                "fromt": "str",
                "to": "id",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 835,
        "y": 68,
        "wires": [
            [
                "8075876f.6fb518"
            ]
        ]
    },
    {
        "id": "51e6b603.327568",
        "type": "function",
        "z": "ba70a55e.0d29a8",
        "name": "Form $APDBG NMEA",
        "func": "var heading = context.get(\"heading\") || 0; \nvar heading_command = context.get(\"heading_command\") || 0; \nvar ap_enabled = context.get(\"ap_enabled\") || \"\";\nvar ap_mode = context.get(\"ap_mode\") || \"\"; \nvar servo_state = context.get(\"servo_state\") || \"\"; \n\nif (msg.payload.hasOwnProperty(\"imu.heading_lowpass\")) {\n    heading = msg.payload[\"imu.heading_lowpass\"].value; \n    context.set(\"heading\", heading); \n}\n\nif (msg.payload.hasOwnProperty(\"ap.heading_command\")) {\n    heading_command = msg.payload[\"ap.heading_command\"].value; \n    context.set(\"heading_command\", heading_command); \n}\n\nif (msg.payload.hasOwnProperty(\"ap.enabled\")) {\n    if (msg.payload[\"ap.enabled\"].value===false) ap_enabled=\"False\";\n    if (msg.payload[\"ap.enabled\"].value===true) ap_enabled=\"True\";    \n    context.set(\"ap_enabled\", ap_enabled); \n}\n\nif (msg.payload.hasOwnProperty(\"ap.mode\")) {\n    ap_mode = msg.payload[\"ap.mode\"].value; \n    context.set(\"ap_mode\", ap_mode); \n}\n\nif (msg.payload.hasOwnProperty(\"servo.state\")) {\n    servo_state = msg.payload[\"servo.state\"].value; \n    context.set(\"servo_state\", servo_state); \n}\nvar today = new Date();\n\nfunction addZeroBefore(n) {\n  return (n < 10 ? '0' : '') + n;\n}\n\n\n\nmsg.payload=\"$APDBG,\"+Math.trunc(heading)+\",M,\"+ap_enabled+\",\"+heading_command+\",\"+servo_state+\",\"+ap_mode+\",\"+addZeroBefore(today.getHours())+addZeroBefore(today.getMinutes())+\"*00\"+'\\r\\n';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1195,
        "y": 68,
        "wires": [
            [
                "1cf49820.97cf98"
            ]
        ]
    },
    {
        "id": "42c84588.bc3fdc",
        "type": "split",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": true,
        "addname": "",
        "x": 665,
        "y": 68,
        "wires": [
            [
                "d0d13719.18e238"
            ]
        ]
    },
    {
        "id": "1cf49820.97cf98",
        "type": "delay",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "pauseType": "rate",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "2",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": true,
        "x": 581,
        "y": 150,
        "wires": [
            [
                "441c49c4.6c2d68"
            ]
        ]
    },
    {
        "id": "441c49c4.6c2d68",
        "type": "serial out",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "serial": "e7818a0.af4be78",
        "x": 885,
        "y": 228,
        "wires": []
    },
    {
        "id": "b02a0a9a.5d0a18",
        "type": "serial in",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "serial": "e7818a0.af4be78",
        "x": 169,
        "y": 389,
        "wires": [
            [
                "9a419ebb.65893"
            ]
        ]
    },
    {
        "id": "58ec5d5a.5bdc04",
        "type": "tcp in",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "server": "client",
        "host": "localhost",
        "port": "10110",
        "datamode": "stream",
        "datatype": "utf8",
        "newline": "\\n",
        "topic": "",
        "base64": false,
        "x": 155,
        "y": 228,
        "wires": [
            [
                "27887b9f.7527d4"
            ]
        ]
    },
    {
        "id": "27887b9f.7527d4",
        "type": "switch",
        "z": "ba70a55e.0d29a8",
        "name": "Filter RMC NMEA only",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "regex",
                "v": "^(?=...*RMC)",
                "vt": "str",
                "case": false
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 375,
        "y": 228,
        "wires": [
            [
                "441c49c4.6c2d68"
            ],
            []
        ],
        "inputLabels": [
            "Input"
        ],
        "outputLabels": [
            "OK",
            ""
        ]
    },
    {
        "id": "fdd29b96.b7f2a8",
        "type": "udp out",
        "z": "ba70a55e.0d29a8",
        "name": "",
        "addr": "localhost",
        "iface": "",
        "port": "10110",
        "ipv": "udp4",
        "outport": "",
        "base64": false,
        "multicast": "false",
        "x": 908,
        "y": 438,
        "wires": []
    },
    {
        "id": "e7818a0.af4be78",
        "type": "serial-port",
        "z": "",
        "serialport": "/dev/ttyUSB1",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": false
    }
]


[Image: 158255641864669890.jpg]
The principle is to form and send to arduino fake NMEA with information from pypilot and receive fake NMEA from arduino with commands that are passing for pypilot...



Please don't judge the quality of code, i am not so familiar with node-red
Reply


Messages In This Thread
Pypilot control ideas - by beholder77 - 2020-02-19, 02:28 PM
RE: Pypilot control ideas - by Saqqara - 2020-02-19, 04:51 PM
RE: Pypilot control ideas - by Saqqara - 2020-02-19, 07:56 PM
RE: Pypilot control ideas - by seandepagnier - 2020-02-20, 07:38 PM
RE: Pypilot control ideas - by beholder77 - 2020-02-21, 05:16 AM
RE: Pypilot control ideas - by kp.sov69 - 2020-02-21, 08:31 PM
RE: Pypilot control ideas - by beholder77 - 2020-02-24, 04:36 PM
RE: Pypilot control ideas - by Zakko89 - 2020-02-24, 12:05 PM
RE: Pypilot control ideas - by seandepagnier - 2020-02-25, 02:35 AM
RE: Pypilot control ideas - by kp.sov69 - 2020-02-25, 11:34 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)