# Calculating RPM? Arduino & Firmata

**URL:** https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352
**Category:** General
**Created:** [18 January 2021 21:09 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352 "2021-01-18T21:09:10Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![lizzardguki](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lizzardguki/32/103637_2.png) [@lizzardguki](https://discourse.nodered.org/u/lizzardguki)
#### Post date: [18 January 2021 21:09 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/1 "2021-01-18T21:09:11Z")

</div>

I have a hall sensor that is right next to the shaft that haves two magnets (see the image below), and it is connected to the Arduino and Firmata...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/3/6321191008d27d06714d51447a222de7d268e563.png)  
I am curious how could I calculate the RPM of the shaft precisely...  
So far I am only able to calculate up to 1ms between input by saving the timestamp of the input and then calculating the difference  
I set up a sample flow with the inject node for emulating:

```auto
[{"id":"b1a8ffac.b96598","type":"group","z":"b075400f.e51258","name":"hall sensor input*","style":{"label":true},"nodes":["6bc358e5.ba1db8","a64fb2d8.015dc","9dab4746.7abac","c84255da.b00238","e7b1b3d2.1e802","abb9acb8.8a5188","5a1304af.505a94","248efa47.ad776e"],"x":94,"y":39,"w":1102,"h":122},{"id":"6bc358e5.ba1db8","type":"function","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"push time to array","func":"\nconst now = new Date() \nvar a = []\na = flow.get('timearray')\na.push(now.getTime())\nflow.set('timearray', a )\nmsg.payload = a\nreturn msg;","outputs":1,"noerr":0,"initialize":"flow.set('timearray', [])","finalize":"","x":490,"y":80,"wires":[["a64fb2d8.015dc"]]},{"id":"a64fb2d8.015dc","type":"function","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"array of halfrevs","func":"var a = msg.payload\nvar e = a.length\nvar r\nvar halfrevs = []\nhalfrevs = flow.get('halfrev')\n\nconsole.log ( (e-1) + ' ' + (e-2))\n r= a[e-1] - a[e-2]\nif (!isNaN(r)){\nmsg.payload = r\nhalfrevs.push(r)\nflow.set('halfrev',halfrevs)\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\nflow.set('halfrev',[])","finalize":"","x":720,"y":80,"wires":[["9dab4746.7abac"]]},{"id":"9dab4746.7abac","type":"function","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"calc RPM","func":"var arr = flow.get('halfrev')\nvar e = arr.length \nvar revms\n\nrevms = arr[e-1] + arr[e-2]\nif (!isNaN(revms)){\n\nmsg.payload = ((1000/revms) * 60)\nflow.set('rpm1', (Math.round((1000/revms) * 60) ))\nreturn msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":900,"y":80,"wires":[["248efa47.ad776e"]]},{"id":"c84255da.b00238","type":"delay","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":540,"y":120,"wires":[["abb9acb8.8a5188"]]},{"id":"e7b1b3d2.1e802","type":"function","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"restart if no input","func":"var i = context.get('i')\ni += 1 \ncontext.set('i',i)\nif (i == 1 ){\n msg.delay = 1000\n return msg;\n}\nelse {\n msg.reset =''\n node.send(msg)\n delete msg.reset\n msg.delay = 1000\n node.send(msg)\n}\n","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('i',0)","finalize":"","x":425,"y":120,"wires":[["c84255da.b00238"]],"l":false},{"id":"abb9acb8.8a5188","type":"function","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"empty arrays","func":"\nflow.set('timearray',[])\nflow.set('halfrev', [])","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('i',0)","finalize":"","x":635,"y":120,"wires":[[]],"l":false},{"id":"5a1304af.505a94","type":"inject","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"Set RPM","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"0.0001","topic":"","payload":"","payloadType":"date","x":200,"y":80,"wires":[["6bc358e5.ba1db8","e7b1b3d2.1e802"]]},{"id":"248efa47.ad776e","type":"debug","z":"b075400f.e51258","g":"b1a8ffac.b96598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1100,"y":80,"wires":[]}]

```

I know this is not the most efficient way, but I couldn't think of a better more precise way...  
Any thoughts on this, I tried creating a while loop inside a function, but it wasn't accurate, and values between inputs were never constant( i was debugging it with a delay node)...

I would potentially need the accuracy of 0.1 - 0.2 ms...

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [18 January 2021 21:22 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/2 "2021-01-18T21:22:39Z")

</div>

Could [node-red-contrib-msg-speed](https://flows.nodered.org/node/node-red-contrib-msg-speed) help you calculate the rpm?

---

<div class="post-metadata">

### Author: ![lizzardguki](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lizzardguki/32/103637_2.png) [@lizzardguki](https://discourse.nodered.org/u/lizzardguki)
#### Post date: [18 January 2021 21:37 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/3 "2021-01-18T21:37:17Z")

</div>

It is not quite precise, (1ms (inject node input repeat) = 930-940 inputs per second (should be 1000) )and it can also capture inputs low as 1 ms, but thanks for the share 😃

---

<div class="post-metadata">

### Author: ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)
#### Post date: [18 January 2021 21:43 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/4 "2021-01-18T21:43:03Z")

</div>

> [@lizzardguki](#):
>
> It is not quite precise

I would be very surprised if the contrib-node is not carrying out the calculation correctly. It's more likely to be caused by delays in the system as node-RED is single threaded, and is struggling to handle data at this frequency.

---

<div class="post-metadata">

### Author: ![lizzardguki](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lizzardguki/32/103637_2.png) [@lizzardguki](https://discourse.nodered.org/u/lizzardguki)
#### Post date: [18 January 2021 21:45 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/5 "2021-01-18T21:45:37Z")

</div>

I probably guess this is the main issue, and I know that I am trying something impossible, I think the far better solution for me is to connect another Arduino with the hall sensor and communicate with it through a serial node. But wanted to give node-red a try for this task...

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [18 January 2021 21:57 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/6 "2021-01-18T21:57:42Z")

</div>

It might be better to do the speed calc in the Arduino.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [19 March 2021 21:57 UTC](https://discourse.nodered.org/t/calculating-rpm-arduino-firmata/39352/7 "2021-03-19T21:57:45Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
