Netduino home hardware projects downloads community

Jump to content


Photo

Rotary Encoder Example


  • Please log in to reply
2 replies to this topic

#1 Greg Mason

Greg Mason

    New Member

  • Members
  • Pip
  • 1 posts
  • LocationPortland, OR, US

Posted 11 July 2011 - 11:17 PM

Started working a temperature controller project of my own a little while ago and now that I think I am starting to get this Netduino stuff, I am going to start posting chunks of our project in hopes of peer review and project advice. I am fairly new to the Netduino but am really liking it as I am enjoying learning .NET a lot more than using C++.

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.

Attached Files



#2 Miha

Miha

    Advanced Member

  • Members
  • PipPipPip
  • 93 posts

Posted 05 November 2011 - 09:00 PM

Hey Greg!

Just wanted to say thanks and that I'm lifting a beer up to you! It works great with an encoder a friend of mine unsoldered from a pcb of god knows what... :)

Kind regards,
Miha.

Started working a temperature controller project of my own a little while ago and now that I think I am starting to get this Netduino stuff, I am going to start posting chunks of our project in hopes of peer review and project advice. I am fairly new to the Netduino but am really liking it as I am enjoying learning .NET a lot more than using C++.

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:



#3 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 81 posts

Posted 27 October 2013 - 12:48 AM

Greg,

 

Thanks for posting this! I got it working with little trouble and I'm confirming that it works with the rotary encoder from sparkfun: https://www.sparkfun...s/TW-700198.pdf

 

I really appreciate the time you spent to document your code as well. Very helpful to me and a great example on interrupts. Thanks!

 

Btw, how is the rest of your project progressing? 






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2010-2014 Secret Labs LLC  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.