Saturday, April 04, 2015

JAVA Rotray Encoder with Raspberry Pi

Hello there thanks for reading,

Well well well. This was fun hard thing to play with, the exercises of lesson 09 from the Sunfounder super kit for the Raspberry pi for model B.

The source code of all Ex09 variations are here.   

I learnt that this kit comes with the cheapest components in the market, they look good, but they are missing some capabilities for the very good reason of being cheap. For example the rotary encoder of this kit is the Keyes module . This sensor is missing some capacitors to reduce the debouncing of the signal and while its perfectly working for a polling solution, it is not really accurately working well when using State Listeners and Interrupt Service Routine ISR. At not very fast rotation speed some of the state changes are lost which makes produces some event state slips every now and then.

Do not get me wrong, the original code in C from the lesson 9 works well and any other solution in Python or Java using polling will work fine with this encoder. The exercise "Ex09_RotaryEncoder" its a direct translation from the C code. The drawback of this solution is that the CPU of the Pi is at 100% and I was worried about over cooking the Pi someday while using this code in some future crazy creation. So I did my research to try to save the life of my little Pi. 

I end up with four other variants of this exercise. The first one is "Ex09_RotaryEncoder_Interrupt". This is a sample code about how to connect call back ISR in a Raspberry Pi pin. As this is equivalent "more or less for this exercise" as using state changing listeners I did not implement all the full exercise again. I used this code for testing and better understanding about ISR and the rotary encoder events. Check this video below to see how to wire up the encoder and then with this exercise you should see on the console each one of the state changes in both channels A and B of the rotary encoder.




The second exercise is "Ex09_RotaryEncoder_RoEncListener". This is an attempt to use the RotaryEncoder solution from Mark de Reeper. This did not work very well with my R.E from keyes. But the code is very neat and it should work with better R.Encoders.

The next exercise is "Ex09_RotaryEncoder_SMPC". This is an adaptation to JAVA from the grate post of Ben Buxton on the Rotary library for Arduino. This is an State Machine solution which controls very well many of the issues that arise when working with R.Ecoders. Ben explains all full details in his post. In the JAVA code though the event processing was slow and I just added a Producer - Consumer threaded solution to prevent missing state changing events. At very fast rotation speed of the dial still few events are lost. However I think its good enough solution to use in a real application. The counting up and down is smooth and quite accurate.

The last exercise is "Ex09_RotaryEncoder_TemporalPollingThread" . This exercise is a cocktail mixes with polling, Listener and Threads. This solution may not be very efficient but it works quite well. The only issue is that it will do heavy polling during few seconds after moving the dial.

For full details about how to set up your Raspberry Pi and how to run these exercises please check out my old post Raspberri Pi with Pi4j and Junit testing mockups. Or leave me a comment if you have any issue or question.

I hope this helps,
Thanks for reading.

Posted by Marc Andreu.

No comments: