HI,
In trying to make my second robot, I have purchased a Pololu metal gear motor with encoder but learning the encoder was a bit much. So I purchased a stand alone rotary encoder (looks like a pot), read up on the arduino site and found a program where I can read the output of the rotary encoder utilizing the Arduino. I had previously purchased the low voltage dual serial motor controller for my 1st tank robot.
The motor controller takes a 4 byte hex code to operate it however the rotary encoder gives decimal numbers positive (0,1,2,3…) for Clockwise and negative for CC.
I would like to control the small 3 volt tamiya motor using the rotary encoder to understand how it works. After much searching I just couldn’t find an example.
Question:
Since the rotary encoder gives a sequential plus or minus decimal output I am assuming all I need to do is change the decimal output of the rotary encoder to hex, make it a variable and insert it into the 4 byte hex code for speed and direction? Is this correct. If so, then how would I go about doing this?
My next step… what motor controller would you recommend for the 50:1 Metal Gearmotor 37Dx54L with 64 CPR encoder. I plan to buy 3 more and make a 4 wheel drive basic robot.
Thank you.
Scott
Hi, Scott.
I am not really sure what you are trying to accomplish, so it is difficult to give you specific advice. Ultimately, you need to find a way to map your encoder readings to motor speeds, which you will then send to the motor controller using the appropriate commands. Typically, this is done using some kind of closed-loop feedback algorithm like PID. The way you do it depends on what behavior you want (e.g. are you trying to do speed control or position control?).
If you want to control four 50:1 37D metal gearmotors, I recommend using two Simple Motor Controller 18v15s.
Specifically, you would use one controller per side of the robot, connecting both motors on that side in parallel to the same SMC. You would need to use the Arduino to read and process the encoder signals directly, but we have an Arduino library that can help you with that. Note that you probably only want to use two motors with encoders (one on each side of the robot); the other motors can be versions without the encoder. Having encoder feedback on all four motors is probably overkill (and difficult to process).
-Derrill
Hi Derrill,
Thank you for replying. On your advice, I just ordered 1 Simple Motor Controller 18v15s.
I am trying to learn how to program and use an encoder with a motor to determine position or speed. Then use this knowledge to direct a robot. To start with, I only have the low voltage motor controller so I have to use the small tamiya motor for now.
I found this code to get an output from a rotary encoder and I actually understand it. Do you have any ideas on how to map this to the 4 byte hex required for the low voltage motor controller? I have no specific use other than learning how.
Would I be correct that it will be easier with the new simple motor controller?
//From bildr article: http://bildr.org/2012/08/rotary-encoder-arduino/
//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
void setup() {
Serial.begin (9600);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop(){
//Do stuff here
Serial.println(encoderValue);
delay(100); //just here to slow down the output, and show it will work even during a delay
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}
This gives numers 0,1,2,3… or -0,-1,-2,-3… depending on direction. I am using a arduino Mega and wonder if the inturrupts are working so fast that there may not be enough time left over for mapping. Or could you give me an idea on how to map the rotary encoder output to the hex input required for the rotary encoder?
Thank you,
Scott
Hi, Scott.
I recommend you start out by just printing position and speed information based on your encoder output. Once you have that, you can more easily decide how you want control your motors based on that information. You might find this Wikipedia article on PID control helpful.
-Derrill