Bonjour à tous ! Je m'appelle valentin et dans le cadre d'un projet de groupe scolaire (niveau bac+2) nous avons récupéré un vieux robot que nous devions remettre en état. Nous possédons une télécommande RC (RC4GS) nous permettant de le contrôler à distance. Il s'agit d'un robot de pulvérisation de précision, il est donc muni d'une pompe que nous activons avec la télécommande. Le robot possède deux roues motrices et une roue folle à l'arrière.
Concernant l'avancement du robot, nous sommes équipés d'une carte Arduino Mega, de deux contrôleurs moteurs de type BTS 7960. Chaque BTS contrôle un moteur. Le tout est alimenté par une batterie 12V
(photo du robot)
Nous avons identifié 6 cas de figure pour l'avancement (avant tout droit, avant à gauche, avant à droite, arrière tout droit, arrière à gauche, arrière à droite).
La gachette de la télécommande (dite RC_CH2) permet d'avancer tout droit (avant ou arrière) et la roue (dite RC_CH1) permet de déterminer droite ou gauche.
Etant débutant et autodidacte en arduino j'ai voulu la jouer simple avec l'utilisation de boucles if permettant d'identifier nos 6 cas de figure repérés pour l'avancement et en utilisant un signal digital pour les contrôleurs moteurs.
#define SERIAL_PORT_SPEED 9600
// Set the size of the arrays (increase for more channels)
#define RC_NUM_CHANNELS 4
// Set up our receiver channels - these are the channels from the receiver
#define RC_CH1 0 // Right Stick LR
#define RC_CH2 1 // Right Stick UD
#define RC_CH3 2 // Left Stick UD
#define RC_CH4 3 // Left Stick LR
int etat_relais = 10;
int GR_ENA = 2;
int GL_ENA = 3;
int GR_PWM = 4;
int GL_PWM = 5;
int DR_ENA = 6;
int DL_ENA = 7;
int DR_PWM = 8;
int DL_PWM = 9;
// Set up our channel pins - these are the pins that we connect to the receiver
#define RC_CH1_INPUT 18 // receiver pin 1
#define RC_CH2_INPUT 19 // receiver pin 2
#define RC_CH3_INPUT 20 // receiver pin 3
#define RC_CH4_INPUT 21 // receiver pin 4
// Set up some arrays to store our pulse starts and widths
uint16_t RC_VALUES[RC_NUM_CHANNELS];
uint32_t RC_START[RC_NUM_CHANNELS];
volatile uint16_t RC_SHARED[RC_NUM_CHANNELS];
// Setup our program
void setup() {
// Set the speed to communicate with the host PC
Serial.begin(SERIAL_PORT_SPEED);
// Set our pin modes to input for the pins connected to the receiver
pinMode(RC_CH1_INPUT, INPUT);
pinMode(RC_CH2_INPUT, INPUT);
pinMode(RC_CH3_INPUT, INPUT);
pinMode(RC_CH4_INPUT, INPUT);
pinMode(etat_relais, OUTPUT);
digitalWrite(etat_relais, LOW);
// Attach interrupts to our pins
attachInterrupt(digitalPinToInterrupt(RC_CH1_INPUT), READ_RC1, CHANGE);
attachInterrupt(digitalPinToInterrupt(RC_CH2_INPUT), READ_RC2, CHANGE);
attachInterrupt(digitalPinToInterrupt(RC_CH3_INPUT), READ_RC3, CHANGE);
attachInterrupt(digitalPinToInterrupt(RC_CH4_INPUT), READ_RC4, CHANGE);
pinMode(GR_ENA, OUTPUT);
pinMode(GR_PWM, OUTPUT);
pinMode(GL_ENA, OUTPUT);
pinMode(GL_PWM, OUTPUT);
digitalWrite(GR_ENA, HIGH);
digitalWrite(GL_ENA, HIGH);
pinMode(DR_ENA, OUTPUT);
pinMode(DR_PWM, OUTPUT);
pinMode(DL_ENA, OUTPUT);
pinMode(DL_PWM, OUTPUT);
}
void loop() {
// read the values from our RC Receiver
rc_read_values();
// output our values to the serial port in a format the plotter can use
Serial.print(RC_VALUES[RC_CH1]);
Serial.print(",");
Serial.print(RC_VALUES[RC_CH2]);
Serial.print(",");
Serial.print(RC_VALUES[RC_CH3]);
Serial.print(",");
Serial.println(RC_VALUES[RC_CH4]);
//pompe
if ((RC_VALUES[RC_CH4]) > 1200)
digitalWrite(etat_relais, HIGH);
if ((RC_VALUES[RC_CH4]) < 1200)
digitalWrite(etat_relais, LOW);
//retour au neutre
if (((RC_VALUES[RC_CH2]) <= 1570) && ((RC_VALUES[RC_CH2]) >= 1484) && ((RC_VALUES[RC_CH1]) >= 1484) && ((RC_VALUES[RC_CH1]) <= 1570)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, LOW);
}
//avancement tout droit arrière
if (((RC_VALUES[RC_CH2]) > 1570) && (RC_VALUES[RC_CH1] > 1484) && (RC_VALUES[RC_CH1] < 1570)) {
digitalWrite(GR_PWM, HIGH);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, HIGH);
digitalWrite(DL_PWM, LOW);
}
//tourner à gauche arrière
if (((RC_VALUES[RC_CH2]) > 1570) && (RC_VALUES[RC_CH1] < 1400)) {
digitalWrite(GR_PWM, HIGH);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, LOW);
}
//tourner à droite arrière
if (((RC_VALUES[RC_CH2]) > 1570) && (RC_VALUES[RC_CH1] > 1570)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, HIGH);
digitalWrite(DL_PWM, LOW);
}
//avancement tout droit avant
if (((RC_VALUES[RC_CH2]) < 1484) && (RC_VALUES[RC_CH1] > 1484) && (RC_VALUES[RC_CH1] < 1570)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, HIGH);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, HIGH);
}
//tourner à droite avant
if (((RC_VALUES[RC_CH2]) < 1484) && (RC_VALUES[RC_CH1] > 1570)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, HIGH);
}
//tourner à gauche avant
if (((RC_VALUES[RC_CH2]) < 1484) && (RC_VALUES[RC_CH1] < 1400)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, HIGH);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, LOW);
}
//retour au neutre
if (((RC_VALUES[RC_CH2]) <= 1570) && ((RC_VALUES[RC_CH2]) >= 1484) && ((RC_VALUES[RC_CH1]) >= 1484) && ((RC_VALUES[RC_CH1]) <= 1570)) {
digitalWrite(GR_PWM, LOW);
digitalWrite(GL_PWM, LOW);
digitalWrite(DR_PWM, LOW);
digitalWrite(DL_PWM, LOW);
}
}
// Thee functions are called by the interrupts. We send them all to the same place to measure the pulse width
void READ_RC1() {
Read_Input(RC_CH1, RC_CH1_INPUT);
}
void READ_RC2() {
Read_Input(RC_CH2, RC_CH2_INPUT);
}
void READ_RC3() {
Read_Input(RC_CH3, RC_CH3_INPUT);
}
void READ_RC4() {
Read_Input(RC_CH4, RC_CH4_INPUT);
}
// This function reads the pulse starts and uses the time between rise and fall to set the value for pulse width
void Read_Input(uint8_t channel, uint8_t input_pin) {
if (digitalRead(input_pin) == HIGH) {
RC_START[channel] = micros();
} else {
uint16_t rc_compare = (uint16_t)(micros() - RC_START[channel]);
RC_SHARED[channel] = rc_compare;
}
}
// this function pulls the current values from our pulse arrays for us to use.
void rc_read_values() {
noInterrupts();
memcpy(RC_VALUES, (const void *)RC_SHARED, sizeof(RC_SHARED));
interrupts();
}
Le problème : une fois que tout est branché seule une roue tourne.
Nous avons essayé d'inverser les pins correspondants et c'est l'autre moteur qui tourne.
En essayant un autre code ne faisant qu'indiquer aux deux moteurs de fonctionner à fond (signal analogique) les deux fonctionnent :
int GR_EN=2;
int GR_PWM=3;
int GL_EN=4;
int GL_PWM=5;
int DR_EN=6;
int DR_PWM=7;
int DL_EN=8;
int DL_PWM=9;
void setup() {
pinMode(GR_EN,OUTPUT);
pinMode(GR_PWM,OUTPUT);
pinMode(GL_EN,OUTPUT);
pinMode(GL_PWM,OUTPUT);
pinMode(DR_EN,OUTPUT);
pinMode(DR_PWM, OUTPUT);
pinMode(DL_EN,OUTPUT);
pinMode(DL_PWM,OUTPUT);
// put your setup code here, to run once:
}
void loop() {
digitalWrite(DR_EN, HIGH);
digitalWrite(DL_EN, HIGH);
digitalWrite(GR_EN, HIGH);
digitalWrite(GL_EN, HIGH);
analogWrite(DR_PWM,0);
analogWrite(DL_PWM,255);
analogWrite(GR_PWM,255);
analogWrite(GL_PWM,0);
}
On suspecte peut-être une mauvaise utilisation des BTS 7960 ou une problème avec l'utilisation de digitalWrite. Auriez-vous une idée pour que nous réussissions à faire marcher nos deux roues ensemble ? (et que nous ayons une bonne note aussi ahah)
J'espère m'être bien exprimé sur cette question. Ca fait plusieurs mois qu'on bosse sur le projet c'est assez complexe à résumer en quelques lignes. N'hésitez pas à demander des renseignements et à nous faire des remarques constructives.
Valentin