Important notes for servo library, servos as hw and rotary encoders.

Library Servo.h

writeMiliseconds() - doesnt to anything with values 0-400 to our servo HD-1370A as well as values over 2400. Documentation is silent.

write() - values 0-200 are angle, 200-99999 are position. Very unwise design guys :(

God knows why the interfaces doesnt have three functions

  • setAngle()
  • setAbsolutePos() or setStep()
  • writeMagic() - yes, here you can do you magic values like 0-200,201+ and so on :)

Your servos – like mine HP-1370A – could have rotation range only +/- 60 degrees

Rotary encoders

There are three (3) ways how to read it

  • digitalRead from pinA and pinB in an infinite loop, keyword: active checking
  • direct attach to two (2) interrupt pins, keyword: passive waiting
  • using external IO with counter, keyword: any time baby, any time :)

Huge note: dont forget 10k pull up resistors.

ad 1) The easiest and most straight forward method. The idea is: we are actively detecting falling edge of pinA

Once we have it, we check pinB. If pinB is high → clockwise rotation, pinB is high → counter-clock.

    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low 
      if(encoder_B) {
        // B is high so clockwise

      }   
      else {
        // B is low so counter-clockwise      
    
      }   
    }   

An example with active checking but only 200x per second. Sample rate 200x per second (200Hz → 5ms, T = 1/f). Useful only if you know exactly which rotary encoder you have! Some starts with 24 pulses per revolution, some have 1024.

#define  TIMESLOT  5
currentTime = millis();
if ((currentTime - loopTime) > TIMESLOT)){
   [....some code....]
  lastTime=currentTime;
}

So you dont have to read it like an idiot 1000000x times per second.

ad 2) Using interrupts to read a rotary encoder is a perfect job for interrupts because the interrupt service routine (a function) can be short and quick, because it doesn't need to do much.

#define encoderPinA  2
#define encoderPinB  4

volatile int encoderPos = 0;

void setup() {
 attachInterrupt(0, MyInterrupt, CHANGE);
}

MyInterrupt() {
if (digitalRead(encoderPinA) == digitalRead(encoderPinB)) {
    encoderPos++;
  } else {
    encoderPos--;
  }
}

You can print the value outside not inside the MyIntterupt() routine, which should be as fast&small as possible.

void loop() {
   Serial.println (encoderPos, DEC);
}

the word volatile is very important :-).

 
hardware/arduino.txt · Last modified: 2015/03/04 18:07 by admin