Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
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
  • 94 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
  • 110 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 © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.