For some reason when I comment out the Serial print section in the main loop() the motors just keep running.
while (counter1<200){
counter3 = counter3 + 1; // dummy action
// Serial.print(counter1);
// Serial.print(" ");
// Serial.println(counter2);
}
With them in the while loop the motors turn the fixed number of times and then pause as expected.
while (counter1<200){
counter3 = counter3 + 1; // dummy action
Serial.print(counter1);
Serial.print(" ");
Serial.println(counter2);
}
One thing that has improved is the motors now seem to be turning at the nearly the same speed when given the same pulse rates and the robot base travels in nearly a straight line.
Forgotten how to insert code. The {:} pop up window didn't produce the desired result and I have forgotten where is was explained.
// Motor A pin assignments to L298N motor controller
const int enA = 11;
const int in1 = 10;
const int in2 = 9;
// Motor B pin assignments to L298N motor controller
const int enB = 5;
const int in3 = 6;
const int in4 = 7;
// motor A encoder counter
int counter1 = 0;
// motor B encoder counter
int counter2 = 0;
// button pins assignments
const int btn0 = 25;
const int btn1 = 24;
const int btn2 = 23;
const int btn3 = 22;
int counter3 = 0;
void forwardA(int rate){
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, rate);
}
void forwardB(int rate){
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, rate);
}
void reverseA(int rate){
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, rate);
}
void reverseB(int rate){
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, rate);
}
void turnOffMotorA(){
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
analogWrite(enA, 0);
}
void turnOffMotorB(){
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
analogWrite(enB,0);
}
// inputs to motors control
void allInputsOff()
{
analogWrite( enA, 0 );
analogWrite( enB, 0 );
digitalWrite( in1, LOW );
digitalWrite( in2, LOW );
digitalWrite( in3, LOW );
digitalWrite( in4, LOW );
}
void setup()
{
// Set all buttons as inputs
pinMode(btn0,INPUT);
pinMode(btn1,INPUT);
pinMode(btn2,INPUT);
pinMode(btn3,INPUT);
// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(3,INPUT); // set as input
digitalWrite(3,HIGH); // enable internal pullup resister
attachInterrupt(digitalPinToInterrupt(3), encoder1, RISING); // interrupt initialization
pinMode(2,INPUT); // set as input
digitalWrite(2,HIGH); // enable internal pullup resister
attachInterrupt(digitalPinToInterrupt(2), encoder2, RISING); // interrupt initialization
counter1 = 0;
counter2 = 0;
Serial.begin( 9600 );
Serial.println("Starting up");
}
// interrrupt server routines for reading encoder
void encoder1()
{
counter1 = counter1 + 1;
}
void encoder2()
{
counter2 = counter2 + 1;
}
void loop()
{
// set encoder counters to zero
counter1 = 0;
counter2 = 0;
// start up motors
forwardA(200);
forwardB(200);
while (counter1<200){
counter3 = counter3 + 1; // dummy action
Serial.print(counter1);
Serial.print(" ");
Serial.println(counter2);
}
turnOffMotorA();
turnOffMotorB();
delay(3000);
}
1.Declare counter 1 and counter 2 as VOLATILE INT
This is required to ensure proper assignments to these variables from the interrupt service functions.
2. Make sure that encoder 2 fires properly.
hj
hj
Thank you hstaam, it works fine now.
Glad to have helped.
hj
Just for clarity for the rest of us. What exactly did you need to do? Did you only need to modify the following two lines in the void setup() routine?
From
// set encoder counters to zero
counter1 = 0;
counter2 = 0;
To
// set encoder counters to zero
volatile int counter1 = 0;
volatile int counter2 = 0;
Is that all you needed to do to fix this?
I'm trying to learn and understand too. Thanks.
DroneBot Workshop Robotics Engineer
James
https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword
Define them as volatile integers ,
// motor A encoder counter
volatile int counter1 = 0;
// motor B encoder counter
volatile int counter2 = 0;
Later in the code you can set them to whatever value you want in the loop.
The program below starts up both motors and then waits for counter1 to become equal to or greater then 291 (or whatever number of counts you want). During the while loop the interrupt server routines are being called whenever the value from the encoder goes from LOW to HIGH.
void loop()
{
// set encoder counters to zero for next count up to 200
counter1 = 0;
counter2 = 0;
// start up motors
forwardA(200);
forwardB(200);
'wait for counter1 to reach 291 counts
while (counter1 < 291){
}
turnOffMotorA();
turnOffMotorB();
delay(3000); 'wait for a while before starting the motors again
}