# KY040 rotary encoder - counting within NR

**URL:** <https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548>\
**Category:** General\
**Created:** [25 August 2018 00:43 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548 "2018-08-25T00:43:43Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![RKF](https://avatars.discourse-cdn.com/v4/letter/r/cdc98d/32.png) [@RKF](https://discourse.nodered.org/u/RKF)\
**Post date:** [25 August 2018 00:43 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/1 "2018-08-25T00:43:43Z")

</div>

I have been using a KY040 rotary encoder within Node Red for a while, but my solution is a little clunky. I have attached it to an ESP8266 loaded with ESP-Easy, which outputs the count via MQTT to my Pi. This works, but it involves two pieces of controlling hardware.  
Node Red captures the MQTT flow and I use the Pi GPIO nodes to make my PWM solution dance. Easy.

But in my quest to make a standalone Pi / KY040 / Node Red setup I've attempted a number of methods to read the encoder without success. After trawling the web for a couple of days I have not found another person trying to accomplish the same as me.

First I installed the Python Function node, installed a few Python files, and tried to run their scripts (like [https://guy.carpenter.id.au/gaugette/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/](https://guy.carpenter.id.au/gaugette/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/)) without success.  
Then I tried to capture the bitstream using the serial node, which can see /dev/tty/AMA0 but the Pi denies me access. Using the browse function in the node itself, this is the only choice available)  
I installed the NPM libraries for serial port, which offered no further advancement.

Whilst I'm really comfortable working in the NR environment, I'm a bonehead at writing Python.

So feeling a little defeated, I thought I would see if anybody here was able to share their success story.

---

<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:** [25 August 2018 07:55 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/2 "2018-08-25T07:55:52Z")

</div>

To help those who do not know about the KY040 it might be useful if you told us what the encoder interface looks like.

---

<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:** [25 August 2018 08:17 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/3 "2018-08-25T08:17:13Z")

</div>

Sorry, I should have looked at the link you posted first. It seems fairly clear from that, assuming the device there is the same as yours. Initially I suggest forgetting about node red and get the code there working from the command line as is shown in the link. Once that is working then you can think about getting the data into node red.  
One thing to think about though. He is using polling to read the encoder, which means that if the processor is doing something while the encoder is moving and it is not able to poll for a period greater than 1/96th of a revolution then you will loose position. Personally I would probably stick with the dedicated hardware for the encoder position.

---

<div class="post-metadata">

**Author:** ![RKF](https://avatars.discourse-cdn.com/v4/letter/r/cdc98d/32.png) [@RKF](https://discourse.nodered.org/u/RKF)\
**Post date:** [25 August 2018 12:45 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/4 "2018-08-25T12:45:57Z")

</div>

@Colin -  
It's a 2 bit encoder - Aside from the power +/- and a switch, the interface has two pins arbitrarily named clk and data. Each pin (clk and data) provides a square wave output that is 90 degrees out of phase with one-another. One can determine the rotation direction based on this phase difference.  
I can get the code in the link to work more or less in a "pythonshell" node. Unless I'm mistaken, the code seems to only identify the rotation direction but not the all important counting element. The _less elegant_ solution I detailed above has the smarts to add (or subtract), making it ideal for PWM or stepper motor projects.

In this specific case I'm not after the encoder position, but rather a number between 1 and 100

Knowing that a node for a stepper motor exists, I'm hoping someone has managed to implement the rotary encoder in Node-Red while being contained solely within the hardware confines of the Raspberry Pi  
Rod

---

<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:** [25 August 2018 13:42 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/5 "2018-08-25T13:42:57Z")

</div>

> [@RKF](#):
>
> Knowing that a node for a stepper motor exists

What node, I don't think you mentioned that, or did I miss it?  
You can't use a serial port as you have to monitor both pins and compare current with last to determine whether it has moved or not.  
I think the link you posted tells you whether it has moved since last time, and which way.  
A simple way to get something going would be to execute that script in an exec node triggered by an Inject once at startup. Configure the exec node to return the output from the command as it appears. Then you would get a sequence of messages containing 1 or -1 to tell you whether it has moved. Then you just need to add those up to get the position relative to the start position.

---

<div class="post-metadata">

**Author:** ![RKF](https://avatars.discourse-cdn.com/v4/letter/r/cdc98d/32.png) [@RKF](https://discourse.nodered.org/u/RKF)\
**Post date:** [26 August 2018 07:17 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/6 "2018-08-26T07:17:39Z")

</div>

Hello Colin - Sorry I didn't mention the stepper motor node - it was an afterthought.

Anyway I'm pleased to say that the node **_pythonshell_** and a neat little piece of python code ([https://www.raspberrypi.org/forums/viewtopic.php?t=140250](https://www.raspberrypi.org/forums/viewtopic.php?t=140250)) has solved my problem. I now have the rotary encoder connected directly to the Raspberry Pi with a limit of 0-100 (perfect for PWM control on a _ **rpi\_gpio\_out** _ node.

I appreciate your suggestions and will see if I can make that a more suitable solution.

Rod

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [26 May 2019 21:58 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/7 "2019-05-26T21:58:10Z")

</div>

I know it's damned-near a year later, but this post put me on track for something that drove me crazy for 12 hours straight. There will be need for modifications, but this will be a major part of the feedback mechanism of a garage door controller I'm working on.

---

<div class="post-metadata">

**Author:** ![RogierQ](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rogierq/32/3211_2.png) [@RogierQ](https://discourse.nodered.org/u/RogierQ)\
**Post date:** [29 October 2019 16:01 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/8 "2019-10-29T16:01:12Z")

</div>

So what is the best way to connect the encoder?  
So i should use an arduino as interface between encoder and PI with NR?

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [29 October 2019 18:10 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/9 "2019-10-29T18:10:46Z")

</div>

You can do it using the PI's GPIO pins.

---

<div class="post-metadata">

**Author:** ![RogierQ](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rogierq/32/3211_2.png) [@RogierQ](https://discourse.nodered.org/u/RogierQ)\
**Post date:** [29 October 2019 18:41 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/10 "2019-10-29T18:41:30Z")

</div>

Ok and waht is the best way to handle the input then?  
I was thinking about first input sets a marker and second input sends that.  
I did not find a special node for this

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [29 October 2019 18:46 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/11 "2019-10-29T18:46:57Z")

</div>

I'm confused as to what you mean. Have you followed the links on the thread?

---

<div class="post-metadata">

**Author:** ![RogierQ](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rogierq/32/3211_2.png) [@RogierQ](https://discourse.nodered.org/u/RogierQ)\
**Post date:** [29 October 2019 18:48 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/12 "2019-10-29T18:48:19Z")

</div>

Yes, so i need the external library?  
There is no other or better way to do it?

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [29 October 2019 18:49 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/13 "2019-10-29T18:49:41Z")

</div>

You can use the pi GPIO nodes too, though tuning the debounce might be tough depending on your speeds.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [29 October 2019 18:51 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/14 "2019-10-29T18:51:28Z")

</div>

the Pi is not running a realtime operating system - so anything that needs critical timing I would use something like an offboard arduino, esp chip or other microcontroller to do the heavy lifting and just pass over readings using a higher level protocol.

---

<div class="post-metadata">

**Author:** ![RogierQ](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rogierq/32/3211_2.png) [@RogierQ](https://discourse.nodered.org/u/RogierQ)\
**Post date:** [29 October 2019 18:53 UTC](https://discourse.nodered.org/t/ky040-rotary-encoder-counting-within-nr/2548/15 "2019-10-29T18:53:19Z")

</div>

haha again the timing topic starts 😉  
Clear thanks @dceejay
