Voici les résultas du sketch minimum avec uniquement les fonction du driveur moteurs et de lectures des encodeurs ( sans asservissement PID).
Les résultas sont identiques par rapport au programme complet du robot ( Deux motoréducteurs GM25-370CA avec encodeur en 3.3V )
- La roue droite ne tourne pas ( vibrations légères du moteur)
- la lecture de la vitesse des roues par les encodeurs est incohérente ( Encodeur A gauche faiblement incrémenté alors que la roue tourne , Encodeur B Droit incrémenté alors que la roue ne tourne pas ) = Corrigé dans fonction "void TimerIsr()" par inversion SpeedGauche et speedDroit dans les Serial.print )
- Le cablage des encodeurs a été vérifié
=> Je continue à réfléchir !!!
1) Les broches de commandes du driver moteur Arduino :
Function pins per Ch. A pins per Ch. B
Direction D12 D13
PWM D3 D11
Brake D9 D8
Current Sensing A0 A1
Motors Connection
Brushed DC motor. You can drive two Brushed DC motors by connecting the two wires of each one in the (+) and (-) screw terminals for each channel A and B. In this way you can control its direction by setting HIGH or LOW the DIR A and DIR B pins, you can control the speed by varying the PWM A and PWM B duty cycle values. The Brake A and Brake B pins, if set HIGH, will effectively brake the DC motors rather than let them slow down by cutting the power. You can measure the current going through the DC motor by reading the SNS0 and SNS1 pins. On each channel will be a voltage proportional to the measured current, which can be read as a normal analog input, through the function analogRead() on the analog input A0 and A1. For your convenience it is calibrated to be 3.3V when the channel is delivering its maximum possible current, that is 2A.
2) La trace debug du test :
<Arduino : Start Setup>
<Arduino : Setup Encoders>
<Arduino : Setup Motors>
<Arduino : AvancerRobot()>
<EncodA = 0.83 , EncodB = -196.50>
<Arduino : ReculerRobot()>
<EncodA = 0.83 , EncodB = -192.50>
<Arduino : ArreterRobot()>
<Arduino : End Setup>
<Arduino : Start loop
<Arduino : AvancerRobot()>
<EncodA = 0.17 , EncodB = -197.83>
<EncodA = 0.17 , EncodB = -232.17>
<EncodA = 0.00 , EncodB = -234.83>
<EncodA = 0.33 , EncodB = -235.00>
<EncodA = 0.33 , EncodB = -234.83>
<Arduino : ArreterRobot()>
<Arduino : ReculerRobot()>
<EncodA = 0.67 , EncodB = -193.83>
<EncodA = 0.17 , EncodB = -239.33>
<EncodA = 0.83 , EncodB = -239.67>
<EncodA = 1.33 , EncodB = -239.50>
<EncodA = 0.33 , EncodB = -239.67>
<Arduino : End loop
3) Le sketch de test :
/*************************************************************
Motor Shield Arduino - 2-Channel DC Motor with encodeurs
*************************************************************/
// ------- Bibiliothèques
#include <TimerOne.h> // Pour le timer
// ------ Pins MOTORS connectés à l'Arduino MEGA
#define PINMOTEURGAUCHEPWMA 3 // Arduino Shield motor gauche
#define PINMOTEURDROITPWMB 11 // Arduino Shield motor droit
#define PINBRAKEA 9 // Arduino Shield motor gauche
#define PINBRAKEB 8 // Arduino Shield motor droit
#define PINMOTEURGAUCHEDIRA 12 // Arduino Shield motor gauche
#define PINMOTEURDROITDIRB 13 // Arduino Shield motor droit
#define PINENCODGAUCHEA 18 // Encodeur A gauche
#define PINENCODGAUCHEB 19 // Encodeur B gauche
#define PINENCODDROITA 20 // Encodeur A droit
#define PINENCODDROITB 21 // Encodeur B droit
int SpeedMotor_A=123;
int SpeedMotor_B=123;
// volatile => pour toute variable qui sera utilise dans les interruptions
volatile int countDroit = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 0 */
volatile int countGauche = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 1 */
volatile double speedDroit = 0; // vitesse du moteur
volatile double speedGauche = 0; // vitesse du moteur
void setup() {
SerialSetup(); // initialize the serial communication
EncodersSetup(); // Init 2 encoders
MotorsSetup(); // Init 2 motors sans PID
}
void loop(){
Serial.println("<Arduino : Start loop");
AvancerRobot();
delay(10000);
ArreterRobot();
ReculerRobot();
delay(10000);
Serial.println("<Arduino : End loop");
}
////////////////////////////////////////////////////
// Encoder counter 1
void counterDroit()
{
byte state = PIND;
(((state >> PINENCODDROITA) & 1) ^ ((state >> PINENCODDROITB) & 1)) ? countDroit-- : countDroit++; // régler ++ et -- pour que faire avancer => +
}
// Encoder counter 2
void counterGauche()
{
byte state = PIND;
(((state >> PINENCODGAUCHEA) & 1 ) ^ ((state >> PINENCODGAUCHEB) & 1)) ? countGauche++ : countGauche--; // régler ++ et -- pour que faire avancer => +
}
// Timer pour calculer la vitesse grace aux encodeurs
void timerIsr()
{
// Lecture vitesse en tour / mn
speedDroit = countDroit;
countDroit = 0;
speedGauche = countGauche;
countGauche = 0;
Serial.println("<EncodA = ");
Serial.print(speedDroit/6); // 6 ticks par tour de roue
Serial.print(" , EncodB = ");
Serial.print(speedGauche/6);
Serial.print(">");
}
//////// Traitement ordres Robot
void ArreterRobot()
{
Serial.println("<Arduino : ArreterRobot()>");
analogWrite(PINMOTEURGAUCHEPWMA, 0); // Stop the motor by inertia , motor turn off
analogWrite(PINMOTEURDROITPWMB, 0);
digitalWrite(PINBRAKEA, HIGH); // set the brake pins LOW to turn them off:
digitalWrite(PINBRAKEB, HIGH);
}
void AvancerRobot()
{
// Move the motor forward
Serial.println("<Arduino : AvancerRobot()>");
digitalWrite(PINBRAKEA, LOW); // set the brake pins LOW to turn them off:
digitalWrite(PINBRAKEB, LOW);
digitalWrite(PINMOTEURGAUCHEDIRA, HIGH); // Set direction to High = Forward
digitalWrite(PINMOTEURDROITDIRB, LOW);
analogWrite(PINMOTEURGAUCHEPWMA, SpeedMotor_A);
analogWrite(PINMOTEURDROITPWMB, SpeedMotor_B);
}
void ReculerRobot()
{
// Reverse the motors
Serial.println("<Arduino : ReculerRobot()>");
digitalWrite(PINBRAKEA, LOW); // set the brake pins LOW to turn them off:
digitalWrite(PINBRAKEB, LOW);
digitalWrite(PINMOTEURGAUCHEDIRA, LOW); // Set direction to Low = Backward
digitalWrite(PINMOTEURDROITDIRB, HIGH); // Set direction to Low = Backward
analogWrite(PINMOTEURGAUCHEPWMA, SpeedMotor_A);
analogWrite(PINMOTEURDROITPWMB, SpeedMotor_B);
}
void MotorsSetup()
{
// set up all of the pins of the motor shield as outputs:
Serial.println("<Arduino : Setup Motors>");
pinMode(PINBRAKEA, OUTPUT);
pinMode(PINMOTEURGAUCHEDIRA, OUTPUT);
pinMode(PINMOTEURGAUCHEPWMA, OUTPUT);
pinMode(PINBRAKEB, OUTPUT);
pinMode(PINMOTEURDROITDIRB, OUTPUT);
pinMode(PINMOTEURDROITPWMB, OUTPUT);
// Move the motor forward
AvancerRobot();
delay(1000);
ReculerRobot();
delay(1000);
ArreterRobot();
}
void EncodersSetup()
{
Serial.println("<Arduino : Setup Encoders>");
// on initialise les entrées et sorties
pinMode(PINENCODGAUCHEA, INPUT_PULLUP);
pinMode(PINENCODGAUCHEB, INPUT_PULLUP);
pinMode(PINENCODDROITA, INPUT_PULLUP);
pinMode(PINENCODDROITB, INPUT_PULLUP);
// Encoder quadrature counter
attachInterrupt(digitalPinToInterrupt(18),counterGauche, CHANGE);
attachInterrupt(digitalPinToInterrupt(20),counterDroit, CHANGE);
Timer1.initialize(800000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz
Timer1.attachInterrupt( timerIsr );
}
void SerialSetup()
{
Serial.begin(19200); // initialize the serial communication
}