Robotics Asked by Abdullah Ansari on November 30, 2021
I am making an Arduino-controlled differential drive robot, and I am having the following problems:
the encoders built into the motors are being used for measuring the rotary displacement, and while running they will randomly start counting the opposite direction of their rotation for a second then start counting the right direction again
What can I do in terms of differential and integral control that will lead to a consistent turn every time?
MY CODE:
'#'include <DueTimer.h>
'#'define MOT1 5 //right motor speed pin (PWM)
'#'define MOT2 6 //left motor speed pin (PWM)
'#'define DIR1 4 //right motor direction pin
'#'define DIR2 7 //left motor direction pin
'#'define EN1A 10 //right motor encoder phase A pin
'#'define EN1B 11 //right motor encoder phase B pin
'#'define EN2A 8 //left motor encoder phase A pin
'#'define EN2B 9 //left motor encoder phase B pin
volatile long right_enc = 0;
volatile long left_enc = 0;
volatile long left_enc1 = 0;
volatile long left_enc_diff = 0;
void setup() {
// put your setup code here, to run once:
//set pin mode, attach external interrupts to encoders with ISR vector, set initial direction and speed of motors.
pinMode(MOT1, OUTPUT); // Set ENC1 as output
pinMode(DIR1, OUTPUT); // Set DIR1 as output
pinMode(MOT2, OUTPUT); // Set ENC2 as output
pinMode(DIR2, OUTPUT); // Set DIR2 as output
attachInterrupt(digitalPinToInterrupt(EN1A), countRight, CHANGE);
attachInterrupt(digitalPinToInterrupt(EN2A), countLeft, CHANGE);
digitalWrite(DIR1, HIGH);
digitalWrite(DIR2, LOW);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
left_enc = 0;
//left_enc1 = left_enc;
while (-left_enc < 1023){
analogWrite(MOT2, 100);
analogWrite(MOT1, 50);
Serial.println("left_enc: ");
Serial.print(-right_enc);
Serial.println(" ");
Serial.print(" ");
}
analogWrite(MOT2, 0);
analogWrite(MOT1, 0);
for (;;) {
// statement block
}
}
void countRight(){
if (digitalRead(EN1A)){
if (digitalRead(EN1B)){right_enc++;}
else if (!digitalRead(EN1B)) {right_enc--;}
}
}
void countLeft(){
if (digitalRead(EN2A)){
if (digitalRead(EN2B)){left_enc++;}
else if (!digitalRead(EN2B)) {left_enc--;}
}
}
=======
What kind of motors are you using? Because the behaviour you describe makes me think of a brushless motor, due to the fact that you have a rotating magnetic field having the rotor spin. But in the beginning it will not necessary start on the right direction (during a very very little lapse of time).
Your program's frequency can also be related to this behaviour. So, have you tried with only one encoder (for this you need to comment all the code calling the interrupts you are not using)? If it occurs only when you have 2 encoders then your micro-controller may not be fast enough (or your motor is to fast).
Have you tried this library ? Usually this code is giving good results!
Answered by fcebron on November 30, 2021
This is just a guess, but I think that your measuring cycle is too slow (not enough measurements per time, therefore the phases get mixed up). Does this occur, when the motors turn slower?
Answered by Squelsh on November 30, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP