**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
{{:hardware:rotary_encoder_phase.jpg|}}
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 :-).