- [Show page]
- [Old revisions]
- [[unknown link type]]
- []
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
|
hardware:arduino [2015/03/04 17:18] admin created |
hardware:arduino [2015/03/04 18:07] (current) admin [Rotary encoders] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| **Important notes for servo library, servos as hw and rotary encoders.** | **Important notes for servo library, servos as hw and rotary encoders.** | ||
| - | ====== Library Servo.h===== | + | ====== 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. | ''writeMiliseconds()'' - doesnt to anything with values 0-400 to our servo HD-1370A as well as values over 2400. Documentation is silent. | ||
| Line 13: | Line 12: | ||
| Your servos -- like mine HP-1370A -- could have rotation range only +/- 60 degrees | 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. | ||
| + | |||
| + | <code> | ||
| + | |||
| + | 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 | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | 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. | ||
| + | |||
| + | <code> | ||
| + | #define TIMESLOT 5 | ||
| + | currentTime = millis(); | ||
| + | if ((currentTime - loopTime) > TIMESLOT)){ | ||
| + | [....some code....] | ||
| + | lastTime=currentTime; | ||
| + | } | ||
| + | </code> | ||
| + | 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. | ||
| + | |||
| + | <code> | ||
| + | #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--; | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | You can print the value **outside** not inside the MyIntterupt() routine, which should be as fast&small as possible. | ||
| + | <code> | ||
| + | void loop() { | ||
| + | Serial.println (encoderPos, DEC); | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | the word //volatile// is **very** important :-). | ||
| + | |||
hardware/arduino.1425485933.txt.gz · Last modified: 2015/03/04 17:18 by admin


