c'est le programme que j'utilise pour l'instant  asservissement.ino   3,95 Ko
  56 téléchargement(s)
 asservissement.ino   3,95 Ko
  56 téléchargement(s)
#include <FlexiTimer2.h>
#include <digitalWriteFast.h> 
 
// Codeur incrémental
#define codeurInterruptionA 0
#define codeurInterruptionB 1
#define codeurPinA 2
#define codeurPinB 3
volatile long ticksCodeur = 0;
 
// Moteur CC
#define directionMoteur  4
#define pwmMoteur  5
 
// Cadence d'envoi des données en ms
#define TSDATA 100
unsigned long tempsDernierEnvoi = 0;
unsigned long tempsCourant = 0;
 
// Cadence d'échantillonnage en ms
#define CADENCE_MS 10
volatile double dt = CADENCE_MS/1000.;
volatile double temps = -CADENCE_MS/1000.;
 
volatile double omega;
volatile double commande = 0.;
volatile double vref = 6.5;
 
// PID
volatile double Kp = 0.29;
volatile double Ki = 8.93;
volatile double P_x = 0.;
volatile double I_x = 0.;
volatile double ecart = 0.;
 
// Initialisations
void setup(void) {
 
  // Codeur incrémental
  pinMode(codeurPinA, INPUT);      // entrée digitale pin A codeur
  pinMode(codeurPinB, INPUT);      // entrée digitale pin B codeur
  digitalWrite(codeurPinA, HIGH);  // activation de la résistance de pullup
  digitalWrite(codeurPinB, HIGH);  // activation de la résistance de pullup
  attachInterrupt(codeurInterruptionA, GestionInterruptionCodeurPinA, CHANGE);
  attachInterrupt(codeurInterruptionB, GestionInterruptionCodeurPinB, CHANGE);
 
  // Moteur CC
  pinMode(directionMoteur, OUTPUT);
  pinMode(pwmMoteur, OUTPUT);
 
  // Liaison série
  Serial.begin(9600);
  Serial.flush();
 
  // Compteur d'impulsions de l'encodeur
  ticksCodeur = 0;
 
  // La routine isrt est exécutée à cadence fixe
  FlexiTimer2::set(CADENCE_MS, 1/1000., isrt); // résolution timer = 1 ms
  FlexiTimer2::start();
 
}
 
// Boucle principale
void loop() {
 
  // Ecriture des données sur la liaison série
  ecritureData();
 
}
 
void isrt(){
 
  int codeurDeltaPos;
  double tensionBatterie;
 
  // Nombre de ticks codeur depuis la dernière fois
  codeurDeltaPos = ticksCodeur;
  ticksCodeur = 0;
 
  // Calcul de la vitesse de rotation
  omega = ((2.*3.141592*((double)codeurDeltaPos))/1632.)/dt;  // en rad/s
 
  /******* Régulation PID ********/
  // Ecart entre la consigne et la mesure
  ecart = vref - omega;
 
  // Terme proportionnel
  P_x = Kp * ecart;
 
  // Calcul de la commande
  commande = P_x + I_x;
 
  // Terme intégral (sera utilisé lors du pas d'échantillonnage suivant)
  I_x = I_x + Ki * dt * ecart;
  /******* Fin régulation PID ********/
 
  // Envoi de la commande au moteur
  tensionBatterie = 7.2;
  CommandeMoteur(commande, tensionBatterie);
 
  temps += dt;
}
 
void ecritureData(void) {
 
  // Ecriture des données en sortie tous les TSDATA millisecondes
  tempsCourant = millis();
  if (tempsCourant-tempsDernierEnvoi > TSDATA) {
    Serial.print(temps);
 
    Serial.print(",");
    Serial.print(omega);
 
    Serial.print("\r");
    Serial.print("\n");
 
    tempsDernierEnvoi = tempsCourant;
  }
}
 
void CommandeMoteur(double tension, double tensionBatterie)
{
    int tension_int;
 
    // Normalisation de la tension d'alimentation par
        // rapport à la tension batterie
    tension_int = (int)(255*(tension/tensionBatterie));
 
    // Saturation par sécurité
    if (tension_int>255) {
        tension_int = 255;
    }
    if (tension_int<-255) {
        tension_int = -255;
    }
 
        // Commande PWM
    if (tension_int>=0) {
        digitalWrite(directionMoteur, LOW);
        analogWrite(pwmMoteur, tension_int);
    }
    if (tension_int<0) {
        digitalWrite(directionMoteur, HIGH);
        analogWrite(pwmMoteur, -tension_int);
    }
}
 
// Routine de service d'interruption attachée à la voie A du codeur incrémental
void GestionInterruptionCodeurPinA()
{
  if (digitalReadFast2(codeurPinA) == digitalReadFast2(codeurPinB)) {
    ticksCodeur--;
  }
  else {
    ticksCodeur++;
  }
}
 
// Routine de service d'interruption attachée à la voie B du codeur incrémental
void GestionInterruptionCodeurPinB()
{
  if (digitalReadFast2(codeurPinA) == digitalReadFast2(codeurPinB)) {
    ticksCodeur++;
  }
  else {
    ticksCodeur--;
  }
}