Thursday, 16 February 2012

NetDuino - fun with rotary encoders

I'm playing with a Netduino microcontroller with a view to making a digital readout for my lathe (using a linear encoder from machine-dro.co.uk). So I experimented with a couple of rotary controllers I had lying around which were pretty flaky. After quite a bit of googling and poking around, I found the following code gave me the most satisfactory results, so I thought I'd post it in case anybody else found it handy (feel free to suggest improvements):


public class RotaryEncoder
    {
        private InterruptPort PortA;
        private InterruptPort PortB;
        private uint prevA = 0;
        private uint prevB = 0;
        private uint prevPort = 0;

        public int Position{get; private set;}
        
        public RotaryEncoder(Cpu.Pin pinA, Cpu.Pin pinB)
        {

            PortA = new InterruptPort(
                    pinA, 
                    false, 
                    Port.ResistorMode.PullUp, 
                    Port.InterruptMode.InterruptEdgeBoth);

            PortB = new InterruptPort(
                    pinB, 
                    false, 
                    Port.ResistorMode.PullUp, 
                    Port.InterruptMode.InterruptEdgeBoth);

            PortA.OnInterrupt += OnInterrupt;
            PortB.OnInterrupt += OnInterrupt;
        }

        void OnInterrupt(uint port, uint state, DateTime time)
        {
            if (port == prevPort)
                return;

            prevPort = port;

            if (((uint)PortA.Id) == port){
                if (state > 0 && prevB > 0)
                    --Position;
                prevA = state;
            }
            else{
                if (prevA == 0 && state == 0)
                    ++Position;
                prevB = state;
            }    
        }  
    }

No comments:

Post a Comment