Advertisement
Guest User

// THE HOLY ENCODER SERVO

a guest
Jun 29th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.28 KB | None | 0 0
  1. #include <Servo.h>
  2.  
  3. // PIN DEFINITIONS
  4. #define PIN_X_SERVO  9
  5. #define PIN_X_P1    21
  6. #define PIN_X_P2    20
  7. #define PIN_Y_SERVO 10
  8. #define PIN_Y_P1    19
  9. #define PIN_Y_P2    18
  10.  
  11. // ENCODER PIN STATES
  12. enum servo_flags_t {
  13.   P1     = 0x1,
  14.   P1_ON  = 0x1,
  15.   P1_OFF = 0x0,
  16.   P2     = 0x2,
  17.   P2_ON  = 0x2,
  18.   P2_OFF = 0x0
  19. }
  20.  
  21. // THE HOLY ENCODER SERVO
  22. class GudServo : public Servo {
  23. public:
  24.   // copy arguments, set initial position
  25.   GudServo(int16_t min, int16_t max, int16_t increment) {
  26.     this->min = min;
  27.     this->max = max;
  28.     this->increment = increment;
  29.     this->position = 0;
  30.   }
  31.  
  32.   // level change on line 1
  33.   void irq_pcint_p1() {
  34.     // line 2 is high
  35.     if ((state & P2) == P2_ON) {
  36.       // line 1 is now high (after this change)
  37.       if ((state & P1) == P1_OFF) {
  38.         // clockwise rotation
  39.         position -= increment;
  40.         // update line 1 status
  41.         state |= P1_ON;
  42.       // line 1 is now low (after this change)
  43.       } else {
  44.         // counter-clockwise rotation
  45.         position += increment;
  46.         // update line 1 status
  47.         state &= ~P1_ON;
  48.       }
  49.     // line 2 is low
  50.     } else {
  51.       // line 1 is now high (after this change)
  52.       if ((state & P1) == P1_OFF) {
  53.         // counter-clockwise rotation
  54.         position += increment;
  55.         // update line 1 status
  56.         state |= P1_ON;
  57.       // line 1 is now low (after this change)
  58.       } else {
  59.         // clockwise rotation
  60.         position -= increment;
  61.         // update line 1 status
  62.         state &= ~P1_ON;
  63.       }
  64.     }
  65.     // handle position overflow
  66.     irq_wrap();
  67.   }
  68.  
  69.   // level change on line 2
  70.   void irq_pcint_p2() {
  71.     // line 1 is high
  72.     if ((state & P1) == P1_ON) {
  73.       // line 2 is now high (after this change)
  74.       if ((state & P2) == P1_OFF) {
  75.         // counter-clockwise rotation
  76.         position += increment;
  77.         // update line 2 status
  78.         state |= P2_ON;
  79.       // line 2 is now low (after this change)
  80.       } else {
  81.         // clockwise rotation
  82.         position -= increment;
  83.         // update line 2 status
  84.         state &= ~P2_ON;
  85.       }
  86.     // line 1 is low
  87.     } else {
  88.       // line 2 is now high (after this change)
  89.       if ((state & P2) == P1_OFF) {
  90.         // clockwise rotation
  91.         position -= increment;
  92.         // update line 2 status
  93.         state |= P2_ON;
  94.       // line 2 is now low (after this change)
  95.       } else {
  96.         // counter-clockwise rotation
  97.         position += increment;
  98.         // update line 2 status
  99.         state &= ~P2_ON;
  100.       }
  101.     }
  102.     // handle position overflow
  103.     irq_wrap();
  104.   }
  105.  
  106.   // get accumulated position
  107.   int16_t getPosition() {
  108.     return position;
  109.   }
  110.  
  111.   // set accumulated position
  112.   void setPosition(int16_t pos) {
  113.     position = pos;
  114.   }
  115.  
  116. private:
  117.   // position overflow handler
  118.   inline void irq_wrap() {
  119.     if (position > max) {
  120.       position = max;
  121.     } else if (position < min) {
  122.       position = min;
  123.     }
  124.   }
  125.  
  126. private:
  127.   volatile int16_t position; // accumulated position
  128.   int16_t min, max;          // min & max bounds
  129.   int16_t increment;         // increment per signal
  130.   servo_flags_t state;       // input ticks
  131. }
  132.  
  133. // global variables
  134. GudServo x(0, 180, 1),
  135.          y(0, 180, 1);
  136.  
  137. // interrupts handlers
  138.  
  139. void irqX_pcint_p1() {
  140.   x.irq_pcint_p1();
  141. }
  142.  
  143. void irqX_pcint_p2() {
  144.   x.irq_pcint_p2();
  145. }
  146.  
  147. void irqY_pcint_p1() {
  148.   y.irq_pcint_p1();
  149. }
  150.  
  151. void irqY_pcint_p2() {
  152.   y.irq_pcint_p2();
  153. }
  154.  
  155. // wire everything together
  156. void setup() {
  157.   Serial.begin(9600);
  158.   x.Attach(PIN_X_SERVO);
  159.   attachInterrupt(digitalPinToInterrupt(PIN_X_P1), irqX_pcint_p1, CHANGE);
  160.   attachInterrupt(digitalPinToInterrupt(PIN_X_P2), irqX_pcint_p2, CHANGE);
  161.   y.Attach(PIN_Y_SERVO);
  162.   attachInterrupt(digitalPinToInterrupt(PIN_Y_P1), irqY_pcint_p1, CHANGE);
  163.   attachInterrupt(digitalPinToInterrupt(PIN_Y_P2), irqY_pcint_p2, CHANGE);
  164. }
  165.  
  166.  
  167. // print positions
  168.  
  169. int16_t x_last;
  170. int16_t y_last;
  171.  
  172. void loop() {
  173.   int16_t x_now = x.getPosition();
  174.   int16_t y_now = y.getPosition();
  175.  
  176.   if (x_last != x_now) {
  177.     Serial.print("X rot: ");
  178.     Serial.println(x_now);
  179.     x_last = x_now;
  180.   }
  181.   if (y_last != y_now) {
  182.     Serial.print("Y rot: ");
  183.     Serial.println(y_now);
  184.     y_last = y_now;
  185.   }
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement