KY040 rotary encoder - counting within NR

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/) 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.

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

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.

@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

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.

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) 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

1 Like

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.

1 Like

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

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

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

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

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

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

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.

haha again the timing topic starts :wink:
Clear thanks @dceejay