Advertisement
dlwestab

Rotary Encoder Code v0.3

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