Hello, I have been going in circles ( no pun intended) for two days with this and I am not getting anywhere.
I have a simple DC motor and encoder from here: Pololu - 131:1 Metal Gearmotor 37Dx57L mm 12V with 64 CPR Encoder (No End Cap)
I am using 3 pushbuttons to send the motor to 3 different positions – which are + 1 rev, + 2 rev and then reverse one rev.
I am counting encoder pulses in the serial monitor and I am trying to sum the all of the encoder moves to see how far off I am from my desired tick count. The motor overshoots the desired tick count, which is fine for now. My plan is to then to try and implement PID control to see if I can hit my encoder counts to the same number as the desired tick number.
My problem now is I can’t get the math right for summing encoder counts after each push button. I have a two second pause in the print command to let the motor reach its position before I print the counts to the monitor. As I understanding it the counts stay in memory until a new “move” command is run and then the count zeros and starts counting again until the motor stops.
So I push button 1, get a count, but then I am trying to zero the counter, push button 1 (or 2 or 3) then add the new count to the old count and get a total count. Simply put, I want to push any combination of forward and reverse buttons (pausing in-between to let the motor reach its destination) for 20 repetitions and be able to see how many counts I am off from my desired tick count.
I have tried zeroing the count in between button pushes, using the button to trigger a math function to add to the count (doesn’t work as it takes 1-2 seconds for the motor to reach its final count), looking at a change in counts using a compare function (works when the count is different but not when the same button is pushed over and over), and a couple of other methods.
I always get a constant summing of counts even when there are no button pushes, or I can’t get the count to increment at all.
Here is my non-working code, for now I have commented out push buttons 2 and 3.
I feel I am going about this incorrectly and I should take an entirely new approach - any guidance or suggestions are welcome, thank you
// MD03A_Motor_basic + encoder
//credit to: KAS http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282384853
// credit to JohnWasser
//
const int InA1 = 10; // Pin 10, goes to Pololu INA motor direction pin (low forward, high reverse)
const int InB1 = 11; // Pin 11, goes to Pololu INB motor direction pin (low reverse, high forward)
const int PWM1 = 6; // Pin 6, goes to Pololu PWM pin (speed)
const int encodPinA1 = 3; // Pin 3, reads encoder A signal (yellow)
//const int encodPinB1 = 8; // Pin 8, reads encoder B signal (White)
const int FORWARD = 1; //
const int BACKWARD = 2; //
const int buttonPin = A0; // Analog pin A0, reads Voltage of button 1, 2, or 3
unsigned long lastMilli = 0; // loop timing
unsigned long lastMilliPrint = 0; // loop timing
volatile long count = 0; // motion counter
volatile long ticks = 0; // motion end point
volatile boolean run = false; // motor moves
int buttonValue = 0; // defines switchValue as an interger, sets value at 0 (of 0 -1023)
long previousMillis = 0; // will store last time print was updated
long interval = 200; // interval at which to print
int lastCount = 0;
int totalCount = 0;
int lastMove = 0;
int oldCount = 0;
//
void setup() {
pinMode(InA1, OUTPUT); // direction to Pololu motor board
pinMode(InB1, OUTPUT); // direction to Pololu motor board
pinMode(PWM1, OUTPUT); // PWM output to Pololu motor board
pinMode(encodPinA1, INPUT); // input from encoder
//pinMode(encodPinB1, INPUT); // input from encoder
pinMode(buttonPin,INPUT); // pin A0, reads V input from buttons
digitalWrite(encodPinA1, HIGH); // turn on pullup resistor pin 10
//digitalWrite(encodPinB1, HIGH); // turn on pullup resistor pin 11
attachInterrupt(1, rencoder, FALLING);
Serial.begin(9600); // set up Serial library at 9600 bps
}
void loop()
{
buttonValue = analogRead(buttonPin); // Read Voltage on pin A0
{
if(buttonValue>940) // Button #1 470 resistor 992 max (1023=5v)
{
moveMotor(FORWARD, 250, 2000*1); // direction, PWM (speed), ticks number (2000=360°)
addCount; // calls math function to add current count
}
}
//buttonValue = analogRead(buttonPin);
//if(buttonValue>750 && buttonValue<800) // Button #2 4.7k resistor 790 max, min = less than bttn #1
//moveMotor(FORWARD, 250, 2000*2); // direction, PWM (speed), ticks number (2000=360°)
//buttonValue = analogRead(buttonPin);
//if(buttonValue>600 && buttonValue<630) // Button #3 10k resistor 620 max, min = less than bttn #2
//moveMotor(BACKWARD, 250, 2000*1); // direction, PWM (speed), ticks number (2000=360°)
printCount(2000); // prints count every 2 seconds
}
void moveMotor(int direction, int PWM_val, long tick) {
count = 0; // abs(count)
ticks = tick;
if(direction==FORWARD)
motorForward(PWM_val);
else
if(direction==BACKWARD)
motorBackward(PWM_val);
}
void rencoder() { // pulse and direction, direct port reading to save cycles
count++;
if(run && count >= ticks)
motorBrake();
}
void motorForward(int PWM_val) {
analogWrite(PWM1, PWM_val);
digitalWrite(InA1, LOW);
digitalWrite(InB1, HIGH);
run = true;
}
void motorBackward(int PWM_val) {
analogWrite(PWM1, PWM_val);
digitalWrite(InA1, HIGH);
digitalWrite(InB1, LOW);
run = true;
}
void motorBrake() {
analogWrite(PWM1, 0);
digitalWrite(InA1, HIGH);
digitalWrite(InB1, HIGH);
run = false;
}
void addCount()
{
lastMove = count;
}
void printCount(long interval) // function "blink", "interval" is a "long" parameter assigned to the "blink" function
// 1000 is passed into "interval" when "blink(1000)" is run
{
if (millis() - previousMillis > interval) // if (current time - below marked time > 1000) is true, then run below
{
previousMillis = millis(); // mark the time when the above is true (current time - previous time > 1000)
totalCount = (lastMove + oldCount);
oldCount = count;
Serial.print("total " );
Serial.println(totalCount);
}
}