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.

  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Also send I2C sensor data to Node-Red so ALL instruments show on the dashboard
Hello all, long overwhelming message coming up.. Hopefully Node-Red is my way out

(If you feel like TL-DR, the important questions are in bold)

So in the past few weeks, I have read so many websites about concepts, communication protocols, documentation and I still don't understand 90% of what people are talking about on this forum, or what OP does "exactly".. I don't get it, I'm a software engineer and I feel stupid haha! Everybody seems to understand perfectly what spaghetti all these protocols and terms build togheter: MQTT, i2C, NMEA0183, NME2000, 1W, SPI, Signal K, Serial, GPIO, kplex. They all seem interconnected but I fail to see the big picture, where all the data passes by, even with the documentation workflow image, plus many of the pages about the things I don't understand like MQTT and SPI are empty in both old and new docs.

So anyways, I managed to make our analog oil pressure sensors work with an Arduino Uno board I had lying around and send it over I2C to OpenPlotter, until I realized that you can only add sensors that were pre-configured in OpenPlotter, not custom sensors. So I cloned the OP repo and searched in the code where that list was to configure my own I2C sensor in the files (,, the .pypilot/RTIMULib files) until I realized that thers's no way the devs wanted it to be that complicated.

Then I read this thread about someone trying to send data via I2C from Arduino Uno to RPi with the same problem as mine:
And most people seem to say that Node-Red is the solution (I avoided it until now since I thought it was a programming language for kids like scracth hahaha). Is there a way however to send the I2C data to Node-Red somehow? If I can get the oil pressure on a dashboard there, AND other I2C (like the BMP180) sensors to all display there without having to use the Signal K instruments panel, it would be awesome! If there's an obvious solution to only use Node-red for everything, please point me in the right direction and I'll do my homework and read the docs, as long as I stop going in circles!

I've seen amazing Code-Red dashboard in the forums like these:
And this one (Unfortunately using MQTT that I don't undersand):
and now I really want to use it, I got some great tutorial videos and links so I'll go read this tomorrow.

In the meantime, can someone also answer these questions please:
-Is it possible to send I2C data to Node-Red? I liked i2C because I can just connect the Arduino Uno to SCL and SDA, without needing a level shifter or resistance + no need for a USB hub (as I can't get one now far from a decent town). Not sure if I'm supposed to use something like this:

-Am I supposed to send the i2C sensor data over NMEA using the generator somehow? It seems like it's only pre-generated sentences with specific sensors, nothing custom.

-Can OpenCPN display other data than NMEA? For example i2C, Serial or GPIO sensors, I guess by using plugins like "Dashboard"?

Thanks for reading all this and enduring my confusing post XD I feel like I can't see the easy way out in front of me, just like this picture XD
example import clipboard opencpn is limited to a few things it can display you can use dashboard in NR

[{"id":"d75f9eeb.e9af2","type":"websocket in","z":"82321e4.b0af8e","name":"ws","server":"41d6b650.f16a38","client":"","x":50,"y":620,"wires":[["83969d8.a84d66","c5c9eb43.d8f238","38780251.f951ae","ba58bc65.7efb9","e81cb99d.1966d8"]]},{"id":"83969d8.a84d66","type":"jsonpath","z":"82321e4.b0af8e","expression":"$.updates..values[*]","split":false,"name":"Signal K delta values","x":240,"y":620,"wires":[["770e578d.94a6d8"]]},{"id":"770e578d.94a6d8","type":"function","z":"82321e4.b0af8e","name":"merge values","func":"var paths={};\nvar arrayLength = msg.payload.length;\nfor (var i = 0; i < arrayLength; i++) {\n    paths[msg.payload[i].path]=msg.payload[i].value;\n}\nmsg.payload = paths;\nreturn msg;","outputs":1,"noerr":0,"x":440,"y":620,"wires":[["abaad182.6b541","4647605c.f27e1","94c51894.715fe8","b2490678.59dba8","a2c7a150.6c2af","963a6ecd.eb9f2","b1b1f8ee.678498","8e6844de.9733a8","28f5b60f.9eb77a","1d6e8fe5.f399d","4b42071a.e35c88","a26efae0.3bb758","ec450371.3822a"]]},{"id":"11507251.ffafbe","type":"ui_template","z":"82321e4.b0af8e","group":"1e14c235.4fc26e","name":"Tempin","order":3,"width":"3","height":"6","format":"<script src=\"/myjs/tween-min.js\"></script>\n<script src=\"/myjs/steelseries-min.js\"></script>\n<script>\nvar tempout;\n    (function(scope){ \n        scope.$watch('msg', function(msg) {\n           if (typeof(msg.value) != \"undefined\") tempout.setValueAnimated(msg.value);\n           //if (typeof(msg.threshold) != \"undefined\") radial4.setThreshold(msg.threshold);\n          // if (typeof(msg.odo) != \"undefined\")radial4.setOdoValue(msg.odo);  \n           //if (typeof(msg.userLed) != \"undefined\") radial4.setUserLedOnOff(msg.userLed);  \n          // if (typeof(msg.trend) != \"undefined\")\n            {\n               // if (msg.trend==1)     radial4.setTrend(steelseries.TrendState.UP);\n                //if (msg.trend==0)     radial4.setTrend(steelseries.TrendState.STEADY);\n               // if (msg.trend==-1)    radial4.setTrend(steelseries.TrendState.DOWN);\n               // if (msg.trend==-2)    radial4.setTrend(steelseries.TrendState.OFF);\n            }\n        });\n    })(scope);\n\n    var sections = [steelseries.Section(0, 25, 'rgba(0, 0, 220, 0.3)'),\n                        steelseries.Section(25, 50, 'rgba(0, 220, 0, 0.3)'),\n                        steelseries.Section(50, 75, 'rgba(220, 220, 0, 0.3)') ],\n\n            // Define one area\n    areas = [steelseries.Section(75, 100, 'rgba(220, 0, 0, 0.3)')],\n\n    tempout = new steelseries.Linear('tempout', {\n            gaugeType: steelseries.GaugeType.TYPE2,\n            width: 140,\n            height: 300,\n            //size: 292,\n            section: sections,\n            area: areas,\n            titleString: \"Inside\",\n            unitString: \"Degrees F\",\n            threshold: 80,\n            lcdVisible: true,\n           \n            //thresholdRising: false,\n           // userLedVisible: true,\n           // useOdometer: true,\n          //  lcdVisible: true,\n           // trendVisible: true\n        });\n                        \n    tempout.setFrameDesign(steelseries.FrameDesign.BRASS);\n    tempout.setValueAnimated(0);\n    tempout.setPointerType(steelseries.PointerType.TYPE9);\n   // radial4.setThreshold(50);\n    //radial4.blinkUserLed(0);\n   // radial4.setOdoValue(0);\n\n\n</script>\n\n<canvas id=\"tempout\" width=\"140\" height=\"300\"></canvas>\n","storeOutMessages":true,"fwdInMessages":true,"x":1198.0003967285156,"y":588.0000686645508,"wires":[[]]},{"id":"28f5b60f.9eb77a","type":"function","z":"82321e4.b0af8e","name":"Water Temp","func":"var signalk_key=\"environment.water.temperature\";\n\nif(msg.payload.hasOwnProperty(signalk_key)){\n    msg.payload=msg.payload[signalk_key];\n    return msg;\n    \n\n}","outputs":1,"noerr":0,"x":639,"y":563.000002861023,"wires":[["ece38a60.7f99c8"]]},{"id":"ee83bd35.bdac9","type":"function","z":"82321e4.b0af8e","name":"","func":"msg.value=msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":976.000057220459,"y":588.0000066757202,"wires":[["11507251.ffafbe"]]},{"id":"ece38a60.7f99c8","type":"function","z":"82321e4.b0af8e","name":"K to F","func":"var temp = msg.payload;\n\nvalue = (temp * 9.0) / 5.0 - 459.67; \nmsg.payload=value;\nreturn msg; ","outputs":1,"noerr":0,"x":779,"y":563.000002861023,"wires":[[]]},{"id":"1d6e8fe5.f399d","type":"function","z":"82321e4.b0af8e","name":"cabin pres","func":"var signalk_key=\"environment.outside.pressure\";\n\nif(msg.payload.hasOwnProperty(signalk_key)){\n    msg.payload=msg.payload[signalk_key];\n    return msg;\n    \n\n}","outputs":1,"noerr":0,"x":639,"y":603.000002861023,"wires":[["cffed0ba.ba82b"]]},{"id":"cffed0ba.ba82b","type":"ui_chart","z":"82321e4.b0af8e","name":"","group":"1e14c235.4fc26e","order":2,"width":0,"height":0,"label":"cabin pres","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"604800","cutout":0,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"x":799,"y":603.000002861023,"wires":[[],[]]},{"id":"4b42071a.e35c88","type":"function","z":"82321e4.b0af8e","name":"cabin temp","func":"var signalk_key=\"environment.inside.mainCabin.temperature\";\n\nif(msg.payload.hasOwnProperty(signalk_key)){\n    msg.payload=msg.payload[signalk_key];\n    return msg;\n    \n\n}","outputs":1,"noerr":0,"x":639,"y":643.000002861023,"wires":[["ee81c52e.60bd18"]]},{"id":"5f3ba447.cc53ec","type":"ui_chart","z":"82321e4.b0af8e","name":"cabin temp","group":"1e14c235.4fc26e","order":1,"width":0,"height":0,"label":"cabin temp","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"x":1075.1666870117188,"y":643.0000114440918,"wires":[[],[]]},{"id":"ee81c52e.60bd18","type":"function","z":"82321e4.b0af8e","name":"K to F","func":"var temp = msg.payload;\n\nvalue = (temp * 9.0) / 5.0 - 459.67; \nmsg.payload=value;\nreturn msg; ","outputs":1,"noerr":0,"x":781,"y":643.3333387374878,"wires":[["5f3ba447.cc53ec","ee83bd35.bdac9"]]},{"id":"a26efae0.3bb758","type":"function","z":"82321e4.b0af8e","name":"float","func":"var signalk_key=\"sensors.floatswitch\";\n\nif(msg.payload.hasOwnProperty(signalk_key)){\n    msg.payload=msg.payload[signalk_key];\n    return msg;\n    \n\n}","outputs":1,"noerr":0,"x":630,"y":681,"wires":[["c19bf413.43a098"]]},{"id":"41d6b650.f16a38","type":"websocket-listener","z":"","path":"ws://localhost:3000/signalk/v1/stream","wholemsg":"false"},{"id":"1e14c235.4fc26e","type":"ui_group","z":"","name":"ENVIRONMENT","tab":"8b452ef1.b3d38","order":1,"disp":true,"width":"6"},{"id":"8b452ef1.b3d38","type":"ui_tab","z":"","name":"Tab 2","icon":"dashboard","order":2}]
mare liberum
(11-07-2018, 10:31 AM)NaturalBornCamper Wrote: So anyways, I managed to make our analog oil pressure sensors work with an Arduino Uno board I had lying around and send it over I2C to OpenPlotter, until I realized that you can only add sensors that were pre-configured in OpenPlotter, 

You can send the data direct to signalk over serial from the arduino, like this - 
#include "ArduinoJson.h"
int LED_pin = 2;

void setup() {
 // put your setup code here, to run once:

// Serial.println("Starting Up, Please Wait...");
 // initialize digital pin LED_BUILTIN as an output.
 pinMode(LED_pin, OUTPUT);

void loop() {
 // put your main code here, to run repeatedly:

 int randon_num = random(1, 300);
 sendSigK("mytest.test.test", randon_num);
 int state = digitalRead(LED_pin);
 digitalWrite(LED_pin, !state);


void sendSigK(String sigKey, float data) {    //    send SigK

 DynamicJsonBuffer jsonBuffer;
 String deltaText;

 //  build delta message
 JsonObject& delta = jsonBuffer.createObject();

 //updated array
 JsonArray& updatesArr = delta.createNestedArray("updates");
 JsonObject& thisUpdate = updatesArr.createNestedObject();   //Json Object nested inside delta [...
 JsonArray& values = thisUpdate.createNestedArray("values"); // Values array nested in delta[ values....
 JsonObject& thisValue = values.createNestedObject();
 thisValue["path"] = sigKey;
 thisValue["value"] = data;

 thisUpdate["Source"] = "ESP11";

Then you need to add this to   /home/pi/.signalk/settings.json - underneath the lines >
  "loggingDirectory": "/home/pi/Logs",
  "mdns": false,
  "pipedProviders": [
      "enabled": true,
     "id": "nmeaFromFile",
     "pipeElements": [
         "type": "providers/serialport",
         "options": {
           "device": "/dev/ttyUSB2",
           "baudrate": 4800,
           "toStdout": ["nmea0183out1", "nmea0183out2"]
         "optionMappings": [
             "fromAppProperty": "argv.nmeadevice",
             "toOption": "device"

             "fromAppProperty": "argv.nmeabaudrate",
             "toOption": "baudrate"
         "type": "providers/from_json",
         "options": {
           "sentenceEvent": "nmea0183in1"
         "optionMappings": [
             "fromAppProperty": "selfId",
             "toOption": "selfId"
             "fromAppProperty": "selfType",
             "toOption": "selfType"

Then it should be added as signalk. Opencpn only see NMEA data so you'll need to convert it to NMEA it you want to see the data in that prog.

Forum Jump:

Users browsing this thread: 1 Guest(s)