Asservissement en vitesse / Probleme de code

Salut a tous

Comme Hardware j’utilise un robot car avec 4 DC moteurs identiques . Pour le contrôle de mes moteurs j’utilise un Motorschield L298N : Puisque le Motorschield a deux entrées pour les moteurs, j’ai donc jumelé deux à deux les moteurs . De ce fait j’obtiens deux moteurs que je peux contrôler ou asservir.

J’aimerais faire un asservissement en vitesse. le Programme suivant l’explique.

#include "TimerOne.h"


#include <SimpleTimer.h>

SimpleTimer timer; 

// définition des pins de l'Arduino qui contrôlent le  moteur droit (jaune)
#define pinIN1 8
#define pinIN2 12
#define pinENA 6 // doit être une pin PWM     le 9 devient 6 

// définition des pins de l'Arduino qui contrôlent le  moteur gauche(Bleue)
#define pinIN3 13
#define pinIN4 4
#define pinENB 5 // doit être une pin PWM   le 10 devient 5
volatile long comptageImpulsion_link=0; // variable accessible dans la routine interruption externe 0
volatile long comptageImpulsion_right=0;

volatile int i;
volatile int j ;
volatile int vitMoteur = 0;      
unsigned long lastPulseTime1 ,lastPulseTime2;

volatile float vit1 = 0;
volatile float vit2 = 0;
const int pas= 20 ;// nombre d espacements sur le disque codeur

const int radius = 3.325  ; //  rayon de la roue ;





double consigne_moteur= 50; // 

// init calculs asservissement PID
double erreur_precedente= consigne_moteur; ; // (en tour/s)
double somme_erreur = 0;

//Definition des constantes du correcteur PID
double kp = 0.2;           // Coefficient proportionnel    choisis par tatonnement sur le moniteur. Ce sont les valeurs qui donnaient les meilleures performances
double ki = 2;             //5.5;      // Coefficient intégrateur
double kd = 0;           // Coefficient dérivateur

// duree d asservissement en millisseconde
double time_asservissement = 500 ;  

// periode en seconde pour le calcul de rotation_link et rotation_right voir asservissement()
double dt = time_asservissement /1000 ; 

unsigned long duree ;
void setup() {

  Serial.begin(9600);


  // Moteur Gauche
  pinMode(pinIN1, OUTPUT);
  pinMode(pinIN2, OUTPUT);
  pinMode(pinENA, OUTPUT);
  analogWrite(pinENA, 0);  // Initialisation sortie moteur à 0 
  delay(300);                // Pause de 0,3 sec pour laisser le temps au moteur de s'arréter si celui-ci est en marche
// Moteur droit
  pinMode(pinIN3, OUTPUT);
  pinMode(pinIN4, OUTPUT);
  pinMode(pinENB, OUTPUT);
  analogWrite(pinENB, 0);  // Initialisation sortie moteur à 0 
  delay(300);                // Pause de 0,3 sec pour laisser le temps au moteur de s'arréter si celui-ci est en marche


//Timer1.initialize(1000000); 

//Timer1.initialize(500000); 


attachInterrupt(1, speedright, RISING );
attachInterrupt(0, speedlink, RISING);

 //Timer1.attachInterrupt( asservissement);
timer.setInterval(time_asservissement, asservissement);


}

void loop() {

//duree= millis();
//asservissement();
//duree =millis()-duree;
//Serial.print("duree");
//Serial.print(duree);  
//Serial.println();
////  

timer.run(); 


}

void asservissement(){

  double rotation_link = (comptageImpulsion_link / pas)/dt ;// calculate RPS for Motor 1 tour/s   [b]// Je ne sais pas si c 'est correct[/b]
  double speed_link = ( 2*3.14*radius)*rotation_link;
  double rotation_right = (comptageImpulsion_right / pas)/dt ;// calculate RPS for Motor 1 tour/s
  double speed_right = (2*3.14*radius)*rotation_right;

 
  double vit = (speed_right+speed_link)/2;        [b]// Je ne sais pas si c 'est correct[/b]
  double erreur = consigne_moteur-vit;
  somme_erreur=somme_erreur+ erreur ;
  double delta = erreur− erreur_precedente;
  erreur_precedente = erreur;

  comptageImpulsion_link= 0; //  reset counter to zero
  comptageImpulsion_right= 0;
  
  vitMoteur = kp*erreur + ki*somme_erreur + kd*delta;

  if (vitMoteur > 255) {
    vitMoteur = 255;  // sachant que l'on est branché sur un pont en H L298
  } 
  else if (vitMoteur <50) {
    vitMoteur = 0;
  }

  Avancer(vitMoteur);


Serial.print("vit:");
Serial.print(vit);  
Serial.println();

Serial.print("Istzustand:");
  Serial.print(vit,8);  
  Serial.println();
  
  Serial.print("Erreur:");
  Serial.print(erreur,4);
  Serial.println();
//
  Serial.print("Commande:");
  Serial.print(vitMoteur);
  Serial.println();
    Serial.println();
  }


void Avancer( int powerRate ){
  // Moteur a gauche
  analogWrite( pinENA, powerRate );
  digitalWrite( pinIN1, false );
  digitalWrite( pinIN2, true );
  

  // Moteur droit 
   analogWrite( pinENB, powerRate );
  digitalWrite( pinIN3, LOW );
  digitalWrite( pinIN4, HIGH );
  
}

void speedlink() {// la fonction appelée par l'interruption externe n°0

comptageImpulsion_link=comptageImpulsion_link+1; // Incrémente la variable de comptage

}

void speedright() {// la fonction appelée par l'interruption externe n°1

comptageImpulsion_right=comptageImpulsion_right+1; // Incrémente la variable de comptage

}

j’ai plusieurs soucis /Préoccupations

  • En compilant le programme code ne reconnaît pas delta pour le coefficient Dérivateur je ne sais pas pourquoi ?
  • Le temps d’asservissement a-t-elle une influence sur les valeurs Kp,Ki, Kd? Si oui quel temps d’asservissement vous me conseillerez et pourquoi? (Actuellement j’ai choisi 500 ms)
  • Ici j’ai travaillé avec “double” comme type de données pour l’asservissement je ne sais pas si cela influence la valeur de ma commande "VitMoteur’?
  • Le calcul de mes vitesses “Link’” et “right” sont-elle corrects ?
  • Ai-je mal implémenté mon timér ?
  • Pour chaque moteur devrait-je utiliser des facteurs d’asservissement différents ?

Merci d’avance de vos Feed-back