This was my first project on Netduino: Trying to figure out events in .NET. I figured a Rotary Encoder was as good a starting place as any since I needed a driver later on for handling the UI to the LCD panel.
I am publishing this under Beerware license since my long term project is an automated brewing machine:
/// <summary> /// Rotary Encoder firmware for SurplusGizmos.com encoder /// part no. EC11B15243AY manufactured by Alps Electronics company /// http://www.surplusgizmos.com/Rotary-Encoder-w-Momentary-Switch_p_839.html /// /// This software is released as beerware under /// THE BEER-WARE LICENSE (Revision 42): As long as you retain this notice you /// can do whatever you want with this source code. If you think this code is worth it, /// you can raise a beer in return - Greg Mason /// </summary> public class Program { public static void Main() { RotaryEncoder_EC11B rotary = new RotaryEncoder_EC11B(Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D0); TestSubscriber sub = new TestSubscriber(rotary); Thread.Sleep(Timeout.Infinite); } } public class TestSubscriber { private static OutputPort led; public TestSubscriber(RotaryEncoder_EC11B rotary) { led = new OutputPort(Pins.ONBOARD_LED, false); rotary.RotationEventHandler += HandleRotation; rotary.MomentaryButtonEventHandler += (data1, data2, time) => { HandleMomentaryButton(led, time); }; } public static void HandleRotation(uint data1, uint data2, DateTime time) { Debug.Print("\nHandleRotation: " + time.TimeOfDay); Debug.Print("Rotation result: " + data2); } public static void HandleMomentaryButton(OutputPort led, DateTime time) { Debug.Print("\nMomentary Button Pressed: " + time.TimeOfDay); led.Write(!led.Read()); } }My intent was to make this as simple as possible to instantiate and use and I think I accomplished that and attempted to get the events to process as fast as we could.
/// <summary> /// Used to record a rotary result. If rotary result is initial, we enter an "in process" state. /// If we are already in process, then the results will be processed and an event raised from another method. /// </summary> /// <param name="pinA">Tested result of Pin A on Encoder</param> /// <param name="pinB">Tested result of Pin B on Encoder</param> private static void NewRotaryResult(bool pinA, bool pinB, ref bool InProcess, ref ResultSet[] results, NativeEventHandler RotationEventHandler) { // Set the appropriate result items results[InProcess.AsInt()].PinA = pinA; results[InProcess.AsInt()].PinB = pinB; // If already in process we need to process the rotation if (InProcess) { ProcessRotation(results, RotationEventHandler); } // Toggle the InProcess InProcess = !InProcess; } /// <summary> /// Processes a rotation event and raises an event to public interface with result /// </summary> /// <param name="results">pinA and PinB bool result set</param> private static void ProcessRotation(ResultSet[] results, NativeEventHandler RotationEventHandler) { // false result, cancel if (results[0].PinA == results[1].PinA && results[0].PinB == results[1].PinB) return; NativeEventHandler handler = RotationEventHandler; // if pin A high if (results[0].PinA == true) { // if pin B went down then counter-clockwise if (results[1].PinB == false) OnRaiseRotationEvent(RotaryEncoder_EC11B.COUNTERCLOCKWISE, handler); // else clockwise else OnRaiseRotationEvent(RotaryEncoder_EC11B.CLOCKWISE, handler); } // else pin A low else { // if pin B went up then counter-clockwise if (results[1].PinB == true) OnRaiseRotationEvent(RotaryEncoder_EC11B.COUNTERCLOCKWISE, handler); // else clockwise else OnRaiseRotationEvent(RotaryEncoder_EC11B.CLOCKWISE, handler); } }This handled all the rotation code and direction determination well enough. Using an o-scope we also determined proper debounce delay for the momentary button on this encoder. So far it works like a charm. I have included the project.
Any tips or glaring errors? I would love to get this rock solid.