Advertisement
dlwestab

Rotary Encoder Code

Aug 8th, 2011
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.64 KB | None | 0 0
  1. /*
  2. Copyright 2011 Dustin L. Westaby
  3. WARNING: Not Debugged
  4.  
  5. ----------------------------------------------------------------------
  6.         Rotary Encoder Code for ATtiny2313
  7. ----------------------------------------------------------------------
  8. Title:      pb.c
  9. Author:     Dustin Westaby
  10. Date Created:   08/08/11
  11. Last Modified:  08/08/11
  12. Purpose:  Decodes two Rotary Encoders and three Pushbutton input controls
  13.           simultaniously.
  14.  
  15. Compiled with AVR-GCC WinAVR
  16.  
  17. Revisions List:
  18.  August 8th, 2011 - Draft code written
  19.  
  20. ----------------------------------------------------------------------
  21. ----------------------------------------------------------------------
  22.  
  23. Operating notes from the Rotary Encoder Datasheet
  24. A = A channel, B = B Channel
  25.  
  26. Clockwise      Counter-Clockwise
  27. AB             AB
  28. 00             00
  29. 10             01
  30. 11             11
  31. 01             10
  32. 00             00
  33. 10             01
  34. 11             11
  35. 01             10
  36. 00             00
  37.  
  38. ---------------------------------------------------------------------- */
  39.  
  40.  
  41. //--------------------------------------
  42. //          Global Variables           |
  43. //--------------------------------------
  44. /* 8 MHz Internal Oscillator */
  45. #define F_CPU 8000000UL
  46.  
  47. //Init some enumerated constants
  48. enum { knobA, knobB, wheelA, wheelB };
  49. enum { NONE, FORWARD, BACKWARD };
  50. enum { KNOB, WHEEL, LEDS };
  51. enum { PRESSED, NOTPRESSED };
  52. enum { LEDA, LEDB, LEDC };
  53.  
  54. #define ON 0
  55. #define OFF 1
  56.  
  57. //--------------------------------------
  58. //              Includes               |
  59. //--------------------------------------
  60. #include <avr/io.h>
  61. #include <util/delay.h>
  62. #include <avr/sleep.h>
  63. #include <avr/interrupt.h>
  64. #include <inttypes.h>
  65.  
  66. //--------------------------------------
  67. //          Delay Subroutines          |
  68. //--------------------------------------
  69. void delay_ms(uint16_t ms) {
  70.     while ( ms )
  71.     {
  72.         _delay_ms(1);
  73.         ms--;
  74.     }
  75. }
  76.  
  77. void delay_us(uint16_t us) {
  78.     while ( us )
  79.     {
  80.         _delay_us(1);
  81.         us--;
  82.     }
  83. }
  84.  
  85.  
  86. //--------------------------------------
  87. //              Functions              |
  88. //--------------------------------------
  89.  
  90. void TurnOnOffLEDs(Selection)
  91. {
  92.     //Exit function if no Light change needed
  93.     if (Selection == NONE) return;
  94.  
  95.     //placeholder
  96.  
  97.     //turn on the selected LED, turn off others
  98. }
  99.  
  100. void startkeypress_timer(KnobWheelLED, TurnDirection)
  101. {
  102.     //Exit function if no movement detected
  103.     if (TurnDirection == NONE) return;
  104.  
  105.     //Determine what keypress is needed (ONE AT A TIME PLEASE!!!)
  106.     if (KnobWheelLED == KNOB)
  107.     {
  108.         if (TurnDirection == FORWARD)
  109.         {
  110.             // Knob Forward
  111.             // Set Keypress and Debug LED
  112.         PORTD = (OFF<<0)|(OFF<<1)|(OFF<<2)|(ON<<3)|(ON<<4)|(OFF<<5)|(OFF<<6)|(OFF<<7);
  113.         }
  114.         else
  115.         {
  116.             // Knob Backward
  117.             // Set Keypress and Debug LED
  118.         PORTD = (OFF<<0)|(OFF<<1)|(ON<<2)|(OFF<<3)|(OFF<<4)|(ON<<5)|(OFF<<6)|(OFF<<7);
  119.         }
  120.     }
  121.     else if (KnobWheelLED == WHEEL)
  122.     {
  123.         if (TurnDirection == FORWARD)
  124.         {
  125.             // Wheel Forward
  126.             // Set Keypress and Debug LED
  127.         PORTD = (OFF<<0)|(ON<<1)|(OFF<<2)|(OFF<<3)|(OFF<<4)|(OFF<<5)|(ON<<6)|(OFF<<7);
  128.         }
  129.         else
  130.         {
  131.             // Wheel Backward
  132.             // Set Keypress and Debug LED
  133.         PORTD = (ON<<0)|(OFF<<1)|(OFF<<2)|(OFF<<3)|(OFF<<4)|(OFF<<5)|(OFF<<6)|(ON<<7);
  134.         }
  135.     }
  136.     else //Must be LED input
  137.     {
  138.         if (TurnDirection == LEDA)
  139.         {
  140.             // LED A
  141.             // Set Keypress and Debug LED
  142.         PORTC = (ON<<0)|(OFF<<1)|(OFF<<2)|(OFF<<3)|(OFF<<4)|(ON<<5)|(OFF<<6)|(OFF<<7);
  143.         }
  144.         else if  (TurnDirection == LEDB)
  145.         {
  146.             // LED B
  147.             // Set Keypress and Debug LED
  148.         PORTC = (OFF<<0)|(ON<<1)|(OFF<<2)|(OFF<<3)|(ON<<4)|(OFF<<5)|(OFF<<6)|(OFF<<7);
  149.         }
  150.         else
  151.         {
  152.             // LED C
  153.             // Set Keypress and Debug LED
  154.         PORTC = (OFF<<0)|(OFF<<1)|(ON<<2)|(ON<<3)|(OFF<<4)|(OFF<<5)|(OFF<<6)|(OFF<<7);
  155.     }
  156.     }
  157.  
  158.   //Hold key down for a while (Debug LED will blink)
  159.   delay_ms(100);
  160.  
  161.   //Clear all Keypresses and blank Debug LEDs
  162.   PORTA = 0b11111111;
  163.   PORTC = 0b11111111;
  164.  
  165.   //Don't allow another keypress for a while
  166.   delay_ms(100);
  167.  
  168. }
  169.  
  170. void init()
  171. {
  172.     //placeholder
  173.     //setup I/O
  174.  
  175.     //Port D is output for Keypress
  176.     DDRD =  0b11111111;
  177.     PORTD = 0b00000000;
  178. }
  179.  
  180. //--------------------------------------
  181. //               Main                  |
  182. //--------------------------------------
  183. void main()
  184. {
  185.  
  186.     int OldState[7]; //Old Status
  187.     int NewState[7]  //New Status
  188.     int TurnDirectionKnob;
  189.     int TurnDirectionWheel;
  190.     int LED_Select;
  191.  
  192.     //Setup IO
  193.     init();
  194.  
  195.     //Get First Input State
  196.     OldState[knobA]  = bit_is_clear(PINB, PB0);
  197.     OldState[knobB]  = bit_is_clear(PINB, PB1);
  198.     OldState[wheelA] = bit_is_clear(PINB, PB2);
  199.     OldState[wheelB] = bit_is_clear(PINB, PB3);
  200.     OldState[LEDA] = bit_is_clear(PINA, PA0);
  201.     OldState[LEDB] = bit_is_clear(PINA, PA1);
  202.     OldState[LEDC] = bit_is_clear(PINA, PA2);
  203.  
  204.     //Setup LED lights
  205.     TurnOnOffLEDs(LEDA);
  206.  
  207.     while(1)
  208.     {
  209.         //--------------------------------------------------------------------------
  210.         // Setup for next Input State Change
  211.         //--------------------------------------------------------------------------
  212.  
  213.         NewState = GetStates();
  214.         TurnDirectionKnob = NONE;
  215.         TurnDirectionWheel = NONE;
  216.         LED_Select = NONE;
  217.  
  218.         //Wait for Input State Change
  219.         while(NewState == OldState)
  220.         {
  221.             NewState[knobA]  = bit_is_clear(PINB, PB0);
  222.           NewState[knobB]  = bit_is_clear(PINB, PB1);
  223.           NewState[wheelA] = bit_is_clear(PINB, PB2);
  224.           NewState[wheelB] = bit_is_clear(PINB, PB3);
  225.           NewState[LEDA] = bit_is_clear(PINA, PA0);
  226.           NewState[LEDB] = bit_is_clear(PINA, PA1);
  227.           NewState[LEDC] = bit_is_clear(PINA, PA2);
  228.         }
  229.  
  230.         //--------------------------------------------------------------------------
  231.         // Check for Knob movement and determine direction
  232.         //--------------------------------------------------------------------------
  233.  
  234.         if((OldState[knobA]==0 && NewState[knobA]==1 &&
  235.             OldState[knobB]==0 && NewState[knobB]==0)|| //PHASE1
  236.            (OldState[knobA]==1 && NewState[knobA]==1 &&
  237.             OldState[knobB]==0 && NewState[knobB]==1)||     //PHASE2
  238.            (OldState[knobA]==1 && NewState[knobA]==0 &&
  239.             OldState[knobB]==1 && NewState[knobB]==1)||     //PHASE3
  240.            (OldState[knobA]==0 && NewState[knobA]==0 &&
  241.             OldState[knobB]==1 && NewState[knobB]==0)||     //PHASE4
  242.            (OldState[knobA]==0 && NewState[knobA]==1 &&
  243.             OldState[knobB]==0 && NewState[knobB]==0))  //PHASE5
  244.         {
  245.             TurnDirectionKnob = FORWARD;
  246.         }
  247.         else if((OldState[knobA]==0 && NewState[knobA]==0 &&
  248.             OldState[knobB]==0 && NewState[knobB]==1)|| //PHASE1
  249.                 (OldState[knobA]==0 && NewState[knobA]==1 &&
  250.             OldState[knobB]==1 && NewState[knobB]==1)||     //PHASE2
  251.                 (OldState[knobA]==1 && NewState[knobA]==1 &&
  252.             OldState[knobB]==1 && NewState[knobB]==0)||     //PHASE3
  253.                 (OldState[knobA]==1 && NewState[knobA]==0 &&
  254.             OldState[knobB]==0 && NewState[knobB]==0)||     //PHASE4
  255.                 (OldState[knobA]==0 && NewState[knobA]==0 &&
  256.             OldState[knobB]==0 && NewState[knobB]==1))  //PHASE5
  257.         {
  258.             TurnDirectionKnob = BACKWARD;
  259.         }
  260.         else //No movement detected for Knob
  261.             TurnDirectionKnob = NONE;
  262.  
  263.         //Send Keypress
  264.         startkeypress_timer(KNOB, TurnDirectionKnob);
  265.  
  266.         //--------------------------------------------------------------------------
  267.         // Check for Wheel movement and determine direction
  268.         //--------------------------------------------------------------------------
  269.  
  270.         if((OldState[wheelA]==0 && NewState[wheelA]==1 &&
  271.             OldState[wheelB]==0 && NewState[wheelB]==0)||   //PHASE1
  272.            (OldState[wheelA]==1 && NewState[wheelA]==1 &&
  273.             OldState[wheelB]==0 && NewState[wheelB]==1)||   //PHASE2
  274.            (OldState[wheelA]==1 && NewState[wheelA]==0 &&
  275.             OldState[wheelB]==1 && NewState[wheelB]==1)||   //PHASE3
  276.            (OldState[wheelA]==0 && NewState[wheelA]==0 &&
  277.             OldState[wheelB]==1 && NewState[wheelB]==0)||   //PHASE4
  278.            (OldState[wheelA]==0 && NewState[wheelA]==1 &&
  279.             OldState[wheelB]==0 && NewState[wheelB]==0))    //PHASE5
  280.         {
  281.             TurnDirectionWheel = FORWARD;
  282.         }
  283.         else if((OldState[wheelA]==0 && NewState[wheelA]==0 &&
  284.             OldState[wheelB]==0 && NewState[wheelB]==1)||   //PHASE1
  285.                 (OldState[wheelA]==0 && NewState[wheelA]==1 &&
  286.             OldState[wheelB]==1 && NewState[wheelB]==1)||   //PHASE2
  287.                 (OldState[wheelA]==1 && NewState[wheelA]==1 &&
  288.             OldState[wheelB]==1 && NewState[wheelB]==0)||   //PHASE3
  289.                 (OldState[wheelA]==1 && NewState[wheelA]==0 &&
  290.             OldState[wheelB]==0 && NewState[wheelB]==0)||   //PHASE4
  291.                 (OldState[wheelA]==0 && NewState[wheelA]==0 &&
  292.             OldState[wheelB]==0 && NewState[wheelB]==1))    //PHASE5
  293.         {
  294.             TurnDirectionWheel = BACKWARD;
  295.         }
  296.         else //No movement detected for Wheel
  297.             TurnDirectionWheel = NONE;
  298.  
  299.         //Send Keypress
  300.         startkeypress_timer(WHEEL, TurnDirectionWheel);
  301.  
  302.         //--------------------------------------------------------------------------
  303.         // Check for LED Button Press
  304.         //--------------------------------------------------------------------------
  305.  
  306.         if(OldState[LEDA]==NOTPRESSED && NewState[LEDA]==PRESSED)
  307.             LED_Select = LEDA;
  308.         else if (OldState[LEDB]==NOTPRESSED NewState[LEDB]==PRESSED)
  309.             LED_Select = LEDB;
  310.         else if (OldState[LEDC]==NOTPRESSED NewState[LEDC]==PRESSED)
  311.             LED_Select = LEDC;
  312.         else //No button press detected for LEDs
  313.             LED_Select = NONE;
  314.  
  315.         //Send Keypress & Change Lights
  316.         startkeypress_timer(LEDS, LED_Select);
  317.         TurnOnOffLEDs(LED_Select);
  318.  
  319.         //--------------------------------------------------------------------------
  320.         // Setup for next Input State Change
  321.         //--------------------------------------------------------------------------
  322.  
  323.         //Save the current state as the old state
  324.         OldState = NewState;
  325.  
  326.         //Debouncing Delay
  327.         delay_us(200);
  328.  
  329.     }
  330.  
  331.  
  332.  
  333.     //This should not be reachable
  334.     while(1);
  335.  
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement