engine RPM with pigpio library (edit: forget about pigpio)
Need help with an idea.
The idea is to get engine RPM data into SignalK via a python script and the pigpio library.
https://abyz.me.uk/rpi/pigpio/index.html
https://abyz.me.uk/rpi/pigpio/code/read_RPM_py.zip
The raw signal comes from the alternator and the script already has functionality to multiply to get from pulses to RPM and also for averaging. A piece of hardware is needed to connect to a GPIO pin, preferably using an opto.
I’ve got it working on my Pi which is also running SignalK-server, outputting a number. Where I’m stuck is with not knowing how to tie these two pieces together.
Edit: the use of pigpiod made the Pi reboot within a minute. No error or logging at all. I continued with writing my own solution (read: copy/paste snippets from the internet)
25 Replies
I think the easiest ways are
- via UDP
- wrap the python code as a plugin
For UDP create a server data connection as Signal K, UDP. Then from python send sk delta messages
For plugin use as base https://github.com/SignalK/sk-plugin-python-demo
Output sk deltas to stdout
You don’t need to publish the plugin, you can install from github or using npm pack
Just a heads up that the pigpio library isn't working with RPi 5.
I believe the Openplotter team are looking at libgpiod - gpiomon instead of pigpio
or an esp32>> https://www.youtube.com/watch?v=I12NdvRQNxY&t=33s
I’ve looked at both options but sadly have no idea how to tackle this. I’m not a developer. Leaves me no other option than to use SensESP, which is overkill because the needed connection is very near the RPi. And an ESP32 with powersupply and sending over WiFi seems crazy.
Oh well, it was just an idea.
If you have working python example then it should be doable. Share your code?
Oh, it is not my code, I wish I could do that. It is what I linked in my original post:
https://abyz.me.uk/rpi/pigpio/code/read_RPM_py.zip
So I do have above mentioned python script working with pigpio (outputs rpm on CLI) and also got your sk-plugin-python-demo working. But I have no idea how to combine those two.
can you modify the script so that it outputs signalk delta format messages? they look like
{"updates": [{"values": [{"path": "environment.airPressure","value": 1013}]}]}
after that you configure manually (by editing settings.json) sk server to launch the script and use its output as a data connection per the example at https://github.com/SignalK/signalk-server/blob/master/settings/commandline-provider-settings.json
GitHub
signalk-server/settings/commandline-provider-settings.json at maste...
An implementation of a Signal K central server for boats. - SignalK/signalk-server
The script is now modified and outputs:
{"updates": [{"values": [{"path": "propulsion.main.revolutions", "value": "0"}]}]}
{"updates": [{"values": [{"path": "propulsion.main.revolutions", "value": "0"}]}]}
{"updates": [{"values": [{"path": "propulsion.main.revolutions", "value": "0"}]}]}
(on my desk so no input from tacho to GPIO)
The editing of
settings.json
also succeeded and am now seeing:Cool!
Should the python script output just a single result and exit? Atm it is looping and producing output constantly every 2 secs (definable).
Looks like the script is constantly restarted every minute:
And in the Web-UI 'Server Logs' it shows as an error:
it should run forver and output data, one message per line
Ok, so that part is fine. Leaves the (error?) messages in the log. Any idea why it writes to the log like that? Almost there!
Your script is exiting instead of running continuously
Yes, you were right. The script I adopted had a nifty
while
loop. Beyond me why anybody would have a RPM counter running for a minute and stop, but now it runs infinite.
Thanks @Teppo Kurki for the help 👍
I've amended server.json with mentioned example.
This works as expected. But because I want to do more than just write a static number I've amended the line for command into "command": "/home/pi/read_RPM.py".
This also works, but not immediately. I first have to kill -9
the started process /usr/bin/python3 /home/pi/read_RPM.py
From that point SignalK-server starts producing the path and value. So question is: Why does it not work from the (re)start of SignalK?
It does get started right away, but doesn't do anything. No errors either.
I've tried postponing the start of the script like this:
"command": "sleep 10; /home/pi/read_RPM.py"
but that didn't help.
Oh, and when left alone, so no killing of the process, it does kinda start after two minutes or so but produces sporadic output.i've never used pigpio myself, but afai understand it has a background daemon process and the code that uses it. my guess is that when sk server is stopped it and stops your script also that leaves something lingering
you can try adding
sudo killall pigpiod && sudo pigpiod &&
before your command to restart the daemon ( from https://abyz.me.uk/rpi/pigpio/download.html)My script is now completely without pigpio; it made the Pi very unstable.
So pure your example for
settings.json
where command is starting a very simple python script.
The script (don't laugh, I'm a beginner):
I have another python script that generates a frequency on a GPIO.output pin connected to GPIO17 for above script. For bench testing; works great.
When signalk starts it starts the script but nothing happens until I kill the script.kill what script?
My python script named (see settings.json) /home/pi/read_RPM.py
It looks like the script is started twice from settings.json:
Seen with
htop
:When I completely stop signalk there is no such script left. Then I start signalk again and the scripts are back. One too many it seems.
There really is only one such line in settings.json
@Teppo Kurki Have you ever tried to use a python script by defining like:
"command": "/home/pi/script.py"
in settings.json?
Even a minimalistic script with a conversion of the bash command:
while true; do echo '{\"updates\": [{\"source\": {\"label\": \"dummy data\",\"timestamp\":\"'
date +'%Y-%m-%dT%H:%M:%S''\"},\"values\": [{\"path\": \"environment.airPressure\",\"value\": 1013}]}]}'; sleep 1; done
to python doesn't work. I've made sure the continues output is exactly the same when run from the command line.sorry about missing your comments above
i just tried running
it is launched once on my Mac and works as expected
you can try adding debug key
signalk:streams:execute
in Server Log, activate Persist debug settings and restart. you should be getting debug logging about launching the script
then you can use ps
or pstree
to see the process hierarchy: is the sk node process really launching to instances of your script
are you sure you are looking at the correct settings.json? break the json by removing for example a { and restart, does the server start?Thank you Teppo. Still don't know what I did wrong but your example helped me out.
Might anyone be following; with below code a rudimentary RMP counter reads pulses from GPIO without the need of any daemon running. Do take care of proper (voltage, spikes) protection of the port though!
Last time updating this topic:
Although above does work, it is inaccurate. Usable but the RPM-gauge (KIP) will never be stable but constantly moving back- and forth a little.
This is due to the RPi running a full OS which is not real time processing. So an ESP32 (SensESP) is probably best option for me (no room for HALMET)