From 4d399627e6f97a42f46185463f96108660d5edcc Mon Sep 17 00:00:00 2001 From: Kristof Robot Date: Sun, 1 Sep 2013 21:16:08 +0200 Subject: [PATCH] Added direct support for wheel encoders (Arduino Uno) Added support for wheel encoder counting directly on the main Arduino board. This allows connecting wheel encoders directly to the Arduino board, without the need for any additional wheel encoder counter equipment. For speed, the code is directly addressing the specific Atmega328p ports and interrupts, making this implementation Atmega328p (Arduino Uno) dependent. It should be easy to adapt for other boards/AVR chips though. --- .../ROSArduinoBridge/ROSArduinoBridge.ino | 24 +++++++++++ .../ROSArduinoBridge/encoder_driver.h | 12 ++++++ .../ROSArduinoBridge/encoder_driver.ino | 41 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/ros_arduino_firmware/src/libraries/ROSArduinoBridge/ROSArduinoBridge.ino b/ros_arduino_firmware/src/libraries/ROSArduinoBridge/ROSArduinoBridge.ino index 77322d2..ff8bfe1 100644 --- a/ros_arduino_firmware/src/libraries/ROSArduinoBridge/ROSArduinoBridge.ino +++ b/ros_arduino_firmware/src/libraries/ROSArduinoBridge/ROSArduinoBridge.ino @@ -58,6 +58,9 @@ /* The RoboGaia encoder shield */ #define ROBOGAIA + + /* Encoders directly attached to Arduino board */ + //#define ARDUINO_ENC_COUNTER #endif //#define USE_SERVOS // Enable use of PWM servos as defined in servos.h @@ -236,6 +239,27 @@ void setup() { // Initialize the motor controller if used */ #ifdef USE_BASE + #ifdef ARDUINO_ENC_COUNTER + //set as inputs + DDRD &= ~(1<> 2; //read the current state into lowest 2 bits + + left_enc_pos += ENC_STATES[(enc_last & 0x0f)]; + } + + /* Interrupt routine for RIGHT encoder, taking care of actual counting */ + ISR (PCINT1_vect){ + static uint8_t enc_last=0; + + enc_last <<=2; //shift previous state two places + enc_last |= (PINC & (3 << 4)) >> 4; //read the current state into lowest 2 bits + + right_enc_pos += ENC_STATES[(enc_last & 0x0f)]; + } + + /* Wrap the encoder reading function */ + long readEncoder(int i) { + if (i == LEFT) return left_enc_pos; + else return right_enc_pos; + } + + /* Wrap the encoder reset function */ + void resetEncoder(int i) { + if (i == LEFT){ + left_enc_pos=0L; + return; + } else { + right_enc_pos=0L; + return; + } + } #else #error A encoder driver must be selected! #endif