Would it be better to measure the time between the pulses? From that you can calculate the RPM of the shaft with the sensors. If the time between two samples is t seconds then the rpm of the shaft is 30/t.
so if you can measure the time for two pulses, you will know the RPS at that instance multiply it by 60 and you have the RPM. My concern is how accurate it has to be since (I believe) NR will not always run in real time.
I wonder if you could use an arduino to read the pulses, do the calculation and send it to NR to do the display
If that does not give sufficient accuracy then you could, for instance note the time which the accumulated value crosses each 10 counts boundary and calculate it over ten pulses. Or 20 or whatever, depending on how fast they are coming in.
Morning all. I've had a further look into this now and come up with the following:
- Our engine has a range from 0-100 Hz
- 100 Hz = 6000 RPM = 12000 Pulses per minute
From this it is possible to scale the pulses.
What I want to try to implement into Node-RED would then be a function that based on pulse readings over time can translate this info into rpm.
Say for instance that we have a counter receiving 20 pulses every 100 millisecond, this would translate into 6000 RPM (20 pulses * 10 counts per second * 60 second = 12000 pulses = 6000 RPM)
So we need a node which counts pulses over a short amount of time, then processes this information and sends it further on to the gauge in the form of an rpm reading.
Did this make any sense?
Since the device returns a running total (that is correct is it not?) You don't need to count pulses, you need to watch the running total. Have a look in the node red docs at the section on storing values in the node context so you can save the time and value of an earlier sample.
How will storing the total count help me convert the information to current rpm?
I'm using the Modbus-Response node which is working as a total counter / information storer.
How can I get information from a Function node with regards to save the time and value?
I read up on how to get a value from a context, but not sure how to further use the information provided.
Store the time and value, then at a later time you can compare current values with older ones. Lookup JavaScript Date for how to get the current time.
Here is a sample flow triggering every 20 milli seconds and displaying the result on a gauge.
You will notice that the RPM does not stay constant at 6000, I believe this is due to the fact that it is running on a mac that has other processes running so it is not real time.
There may be ways to tighten up the function code, but it is still not going to be running real time.
[{"id":"573fcfd.9a461b","type":"inject","z":"1020f0f0.11e4c7","name":"","topic":"","payload":"20","payloadType":"num","repeat":".1","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":80,"wires":[["e5ecad23.c3d3f8"]]},{"id":"e5ecad23.c3d3f8","type":"function","z":"1020f0f0.11e4c7","name":"","func":"var n = context.get(\"foo\")||{\n \"c\": 0,\n \"start_time\": Date.now(),\n \"start_count\": 0,\n \"end_time\": Date.now(),\n \"end_count\": 0\n}\nn.start_count = n.end_count\nn.end_count += msg.payload\n\nn.end_time = Date.now()\nvar elapsed_time = (n.end_time - n.start_time)/1000\nvar elapsed_count = (n.end_count - n.start_count)/2\n n.start_time = n.end_time\n n.start_count = n.end_count\n var rpm = elapsed_count / (elapsed_time/60)\n msg.payload = rpm.toFixed()\n\n n.c = 1\n context.set(\"foo\",n)\n\nreturn msg;\n\n","outputs":1,"noerr":0,"x":410,"y":80,"wires":[["641ccc9e.1cff84","39b3decb.e00752"]]},{"id":"641ccc9e.1cff84","type":"debug","z":"1020f0f0.11e4c7","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":80,"wires":[]},{"id":"39b3decb.e00752","type":"ui_gauge","z":"1020f0f0.11e4c7","name":"","group":"c3070762.41f66","order":4,"width":0,"height":0,"gtype":"gage","title":"gauge","label":"units","format":"{{value}}","min":0,"max":"20000","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":670,"y":140,"wires":[]},{"id":"c3070762.41f66","type":"ui_group","z":"","name":"Default","tab":"30a1a1f1.1aa7a6","disp":true,"width":"6","collapse":false},{"id":"30a1a1f1.1aa7a6","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
especially if it is reading over modbus. As long as you only use it as an indication over a decent time interval you may be ok - but really you ought to be doing the actual rpm measurement down on the sensor itself and reporting that back instead if you need any kind of accuracy.
Tried opening your string in order to be able to implement your function node. After importing it my gauge doesn't receive any number values, even thou I haven't added the function node to my flow.
Debug node connected to Modbus read node shows:
This is the info it receives from my Modbus read node.
Any idea what should I set up the Switch node to now?
Have tried to both Set msg.payload to msg.payload[0] and to Move msg.payload[0] to msg.payload, but it wont give any values to the gauge.
The Modbus-response node is still receiving pulses, so nothing has changed on that end.
Earlier you showed that msg.payload was an array with one element containing the total so far. Now you show something completely different. It is difficult to help unless we know exactly what your input data looks like.
Are you sure that your modbus device is not capable of providing you with the speed?
measures the time between each pulse with the interval length node then sends this payload to a function node:
if one revolution = 1 pulse then rpm = 1 / (msg.payload / 60000).
it is an inverse function the shorter the time the higher the value of the function will be if 1tour = 2 pulses then rpm = 1 / (msg.payload / 120000).
if the engine turns too fast the raspberry will not follow.
If you can live with a slow update use a 30 second interval timer block. Every 30 seconds subtract the last count from the current count and that will give you RPM since there are two counts per rev.