I am using an Arduino Uno R3 to control four motors with built-in encoders. At the moment, I am just doing some basic tests and I am having trouble with reading the encoders from pins 2 and 3. The problem is that they only read 0, -1, or +1 when I manually rotate the motor, while the other digital input pins give me integer readings proportional to the motor position as I would expect. Because I am using several motors, I don't really have spare pins I can use instead, so I would like to get these working. I am an Arduino newbie, so it's possibly I am making a silly mistake somewhere.
My hardware:
- Arduino Uno R3
- Pololu DRV8825 stepper motor drivers x4
- CUI Devices NEMA17-13-04PD-AMT112S motors x4
The relevant pin connections are as follows. Pins A2 and A3 are connected to the DRV8825 motor driver to control the motor direction and steps. Arduino GND and +5 V are powering the logic of the DRV8825 and also power the encoders. Encoder A+ is connected to pin 2 and B+ is connected to pin 3.
Here is the connection diagram for one motor ("motor 2" below). The others have been left off for clarity.
Here is my connection diagram for a single motor encoder only (other motors disconnected, DRV8825 disconnected):
I have tried connecting different encoders to different pins and verified that the problem is with the pins and not a fault in the encoder, as all four motor encoders have the same behaviour.
My test code is below. The code loops through the four motors and reads the encoder value. Motor 2 is using pins 2 and 3. Note that in the above schematics, I am only showing one motor for clarity, but the pin behaviour is the same regardless if one motor is connected or several. Note that the DRV8825 is disconnected for this test, so I am working with the encoders and Arduino only.
// Tests the encoders. Leave motor power supply disconnected and run Arduino only. Turn the motor and look at the encoder values on the Serial Monitor.
#include <Encoder.h>
const int encPin1[4] = {11, 9, 3, A0};
const int encPin2[4] = {10, 8, 2, A1};
long encPos[] = {-999, -999, -999, -999};
Encoder encoders[] = {Encoder(encPin1[0], encPin2[0]), Encoder(encPin1[1], encPin2[1]), Encoder(encPin1[2], encPin2[2]), Encoder(encPin1[3], encPin2[3])};
//Setup the serial connection
void setup() {
Serial.begin(115200);
Serial.println("Motor encoder test: ");
}
void loop() {
long newPos;
for (int i = 0; i < 4; i++) {
newPos = encoders[i].read();
if (newPos != encPos[i]) {
Serial.print("Motor ");
Serial.print(i);
Serial.print(" = ");
Serial.print(newPos);
Serial.println();
}
}
}
This is an example of my output in the Serial Monitor when I randomly rotate the knobs:
Motor 0 = 90
Motor 1 = 14
Motor 2 = 0
Motor 3 = -35
Motor 2 is reading 0, but it can also be -1 or 1. As you can see, motors 0, 1, and 3 give higher values, with the sign indicating if the motor has been turned clockwise or counter-clockwise.
Any ideas about what's going on? I have tried setting the pinmode of pins 2 and 3 to INPUT and INPUT_PULLUP, but the behaviour was the same. I understand that pins 2 and 3 are interrupt pins on Arduino Uno, so does this mean I have to handle them differently in the code?