Bonjour a tous,
Voila longtemps que j’espérai prendre le temps pour mon petit projet Arduino 2WD car.
Je suis développeur LABVIEW depuis de nombreuses années mais je suis une bille en C, il est temps de remédier un peu à ça.
Mon projet c'est une 2Wd car , avec asservissement surun arduino UNO.
Un arduino MEGA qui traîne dans le placard ainsi qu'un shield WIFI R3 de deuxième génération le seconderont pour gérer le wifi et les capteurs
Un Algorithme A* sur PC , sous labview me renvois des coordonnées de déplacement prévu du véhicule dans l'appartement.
J'ai déjà implémenté, la connexion WIFI entre le PC et le MEGA .
Le MEGA me retourne des infos /lumière/température/capteur Ultra son....
Le MEGA transférera ces coordonnées au UNO qui ne gérera que ça(asservissement distance/angle)
Bien entendu, il faut bien commencer quelques part et je vais essayé de le faire dans l'ordre.
J'ai assemblé le robot et effectivement, pour le prix , on a se qu'on a...
J'en suis au asservissement PID, j'en ai déja réalisé sous LABVIEW mais a coder ça a été une autre histoire.
J'ai donc commencé simplement par un asservissement PID ligne droite.
J'arrive à quelque chose de "potable" ou a 1.7 tours/seconde, le robot se déplace a peu prêt droit.
Mais je reste confronté à une serieuse interrogation.
Mes roues codeuses dispose de 20 fentes et je me retrouvais à compter constamment 80 ticks pour 1 tour de roue, j'ai résolu un peu de ce problème en rajoutant un tampon sur l'interruption mais il m'en reste toujours 40, que j'utilise les fonction FALLING/RISING/HIGH ou LOW, rien n'y fait , 40 ticks par tour de roue.....
Avez vous une idée?
1er essai d'insertion de code.....dsl
#include <SimpleTimer.h>
/* VARIABLES MOTEUR & ROUES CODEUSES-----------------------------------------------------------------------*/
//Timer t;
SimpleTimer PIDTimer; //variable Timer pour le controle des PID
const int FrqEchantillonnage = 30; // Fréquence du pid 50
float ConsigneNbTourSecondeG = 1.7; // Nombre de tours de roue par seconde gauche
float ConsigneNbTourSecondeD = 1.7; // Nombre de tours de roue par seconde droite
float Erreur_precedenteG = ConsigneNbTourSecondeG;
float Erreur_precedenteD = ConsigneNbTourSecondeD;
float somme_erreur_MoteurG = 0; // Somme des erreurs pour l'intégrateur gauche
float somme_erreur_MoteurD = 0; // Somme des erreurs pour l'intégrateur droite
unsigned long tickG = 0; // Compteur de tick de la codeuse gauche
unsigned long tickD = 0; // Compteur de tick de la codeuse droite
const int RapportReducteur = 1; // Rapport entre le nombre de tours de l'arbre moteur et de la roue 29
const int Tick_par_tour_codeuse = 40; // Nombre de tick codeuse par tour de l'arbre moteur
int CommandMoteurG = 0; // valeur de la commande du moteur gauche
int CommandMoteurD = 0; // valeur de la commande du moteur droit
long Temps_Antirebond = 3; // temps anti rebond d'interruption
volatile unsigned long last_microG; // derniere valeur du timer ou a eu lieu une interuptionG
volatile unsigned long last_microD; // derniere valeur du timer ou a eu lieu une interuptionD
/* VARIABLES PID MOTEURS------------------------------------------------------------------------------------*/
float kp = 44; // Coefficient proportionnel 50 44
float ki = 10; // Coefficient integrale 10 2
float kd = 20; // Coefficient dérivé 20 8
/* PIN ---const = ROM---------------------------------------------------------------------------------------*/
const int EnA = 11; // analogique PWM pilotage moteur Droit
const int EnB = 5; // analogique PWM pilotage moteur Gauche
const int In1 = 9; // moteur Droit LOW=avancer/HIGH=reculer
const int In2 = 8; // moteur Droit HIGH=avancer/LOW= reculer
const int In3 = 7; // moteur Gauche LOW=avancer/HIGH=reculer
const int In4 = 6; // moteur Gauche HIGH=avancer/LOW= reculer
/* SETUP *****************************************************************************************************/
void setup() {
pinMode(EnA, OUTPUT); //toutes les sorties Moteur en OUTPUT
pinMode(EnB, OUTPUT);
pinMode(In1, OUTPUT);
pinMode(In2, OUTPUT);
pinMode(In3, OUTPUT);
pinMode(In4, OUTPUT);
analogWrite(EnB, 125);
analogWrite(EnA, 125);
digitalWrite(In1, LOW); //marche Avant
digitalWrite(In2, HIGH);
digitalWrite(In3, LOW);
digitalWrite(In4, HIGH);
attachInterrupt(0,AntirebondG , CHANGE); // Interruption sur tick de la codeuse PIN 2 moteur droit (9.6)
attachInterrupt(1,AntirebondD , CHANGE); // Interruption sur tick de la codeuse PIN 3 moteur gauche (11.10)
PIDTimer.setInterval(1000/FrqEchantillonnage, asservissement); // Interruption(20ms) pour calcul du PID et asservissement par dans asservissement à cette fonction
Serial.begin(115200);
}
/* LOOP ************************************************************************************************************/
void loop() {
PIDTimer.run();
}
/*ANTI REBOND AVANT INTERRUPTION ***********************************************************************************/
void AntirebondG(){
if ((long)(micros() - last_microG) >= Temps_Antirebond * 1000){
CompteurtickG();
last_microG = micros();
}
}
void AntirebondD(){
if ((long)(micros() - last_microD) >= Temps_Antirebond * 1000){
CompteurtickD();
last_microD = micros();
}
}
/*COMPTEUR ROUES TICKD ET TICKG ***********************************************************************************/
void CompteurtickG() { // Interruption sur tick de la codeuse gauche
tickG++; // On incrémente le nombre de tick de la codeuse gauche
}
void CompteurtickD() { // Interruption sur tick de la codeuse droite
tickD++; // On incrémente le nombre de tick de la codeuse droite
}
/* CALCUL DES ASSERVISSEMENTS ROUES G & D ************************************************************************/
void asservissement()
{
// Calcul de l'erreur
int FrqCodeuseG = FrqEchantillonnage*tickG;
int FrqCodeuseD = FrqEchantillonnage*tickD;
float TourSecondeG = (float)FrqCodeuseG/(float)Tick_par_tour_codeuse/(float)RapportReducteur;
float TourSecondeD = (float)FrqCodeuseD/(float)Tick_par_tour_codeuse/(float)RapportReducteur;
float ErreurG = ConsigneNbTourSecondeG - TourSecondeG;
float ErreurD = ConsigneNbTourSecondeD - TourSecondeD;
somme_erreur_MoteurG += ErreurG;
somme_erreur_MoteurD += ErreurD;
float delta_erreur_MoteurG = ErreurG-Erreur_precedenteG;
Erreur_precedenteG = ErreurG;
float delta_erreur_MoteurD = ErreurD-Erreur_precedenteD;
Erreur_precedenteD = ErreurD;
// PI : calcul de la commande
CommandMoteurG = kp*ErreurG + ki*somme_erreur_MoteurG + kd*delta_erreur_MoteurG;
CommandMoteurD = kp*ErreurD + ki*somme_erreur_MoteurD + kd*delta_erreur_MoteurD;
// Normalisation et contrôle du moteur gauche
if(CommandMoteurG < 00) CommandMoteurG=00;
else if(CommandMoteurG > 255) CommandMoteurG = 255;
analogWrite(EnB, CommandMoteurG);
// Normalisation et contrôle du moteur droit
if(CommandMoteurD < 00) CommandMoteurD=0;
else if(CommandMoteurD > 255) CommandMoteurD = 255;
analogWrite(EnA, CommandMoteurD);
tickG=0; // Réinitialisation du nombre de ticks de roue codeuse G
tickD=0; // Réinitialisation du nombre de ticks de roue codeuse D
}