Snippet - FEZ Cobra II and Rotary Encoder

I just posted FEZ Cobra II and Rotary Encoder on Codeshare. Feel free to discuss and make suggestions here.

Interesting


string B0 = "0", B1 = "0";                              // 
if (pinA.Read()) B1 = "1"; else B1 = "0";               // read pinA and convert to binary
if (pinB.Read()) B0 = "1"; else B0 = "0";               // read pinB and convert to binary
B0 = B1 + B0;
if (B0 == "01" || B0 == "10") encoderValue++;           //clockwise movement
if (B0 == "00" || B0 == "11") encoderValue--;           //counter-clockwise movement

Managing encoder state with strings is an “expensive” way of doing this. I would toggle bits in a byte instead;

I also have a version of this:

https://www.ghielectronics.com/community/codeshare/entry/723

@ Loy

There is an opportunity to improve your encoder code.

With the Micro Framework, hardware interrupts are placed on an internal queue, and then sequentially processed by a thread. The time from when the hardware interrupt was internally processed, and when it arrives at your handler can vary. At a minimum, on a Cobra II, it will be delay 1-2+ms.

In your handler, when you receive an interrupt, you are reading the values the ports, effectively ignoring any other interrupts that might be in the queue.

At very slow rates, you might not have a problem. But if you were to turn the encoder fast enough, you would lose changes.

When you get an interrupt, the data1 and data2 values contains the pin number and the current state of the associated port for the interrupt. You should persist the state of each port, between interrupts, in a member variable. If you receive an interrupt for input A, then you should use the data2 value for its state, and the saved value for the B interrupt.

Doing it this way, you would never lose a state change.

Sorry to hijack the thread here but if this is how the UART interrupt is also processed then you are going to get a big issue with this at anything above 9600 bps.

This can’t be the case for UART handling surely? I think I need to grab the porting kit and start having a look at this.

@ Dave McLaughlin - I believe it is.

When the UART gets a data ready interrupt, the core moves the data into a large internal buffer and places a DataReceived interrupt into the queue. The UART data received buffer is cleared out at hardware speeds.

@ Architect -

Excellent! I will try it if I have any performance issue further in the project. Thank you for a nice comment.

By the way, do you have any comment or sample code to measure the speed of the rotation?

@ Mike -

I’m so sorry, but I’m afraid I don’t really understand your comment.

Do you suggest that I should set pin A and B as the interrupt ports and cancel Pin.P0_0? If that’s the case, it would be a nice improvement.