Projet de régulation Débit TIPE prépa

Bonjour,

Dans le cadre d’un projet étudiant en prépa scientifique, je réalise avec mon groupe un projet de régulation de débit à l’aide d’un pointeau motorisé .
On a construit une maquette avec des tuyaux dans lesquels nous faisons passer bcp d’eau avec un débit variable, et à l’aide d’un moto-réducteur contrôlé par arduino, nous faisons l’asservissement du débit en déplaçant dans le tuyau une pièce qui le bouche plus ou moins à un endroit. On a donc deux débitmètres (un en entrée et un en sortie) (http://www.seeedstudio.com/wiki/G3/4_Water_Flow_sensor), et à l’aide d’un programme qui doit récupérer le débit en sortie, le moteur doit tourner dans un sens ou dans l’autre pour s’adapter aux variations de débits.

Mon soucis:
Pour commencer, je doit étalonner des capteurs de fin de courses, et faire faire un aller retour complet à ma pièce avant de pouvoir commencer. Toute cette partie est dans le Setup. Et là, échec, il me fait la moitié du Setup, me zappe la fin et passe directement dans le loop. Voilà le setup, avec les commentaires pour indiquer le problème:

 CONSTANTES

Constantes sur lesquelles on joue:

// moteur:
int ka=50; 
float ta=0.05;
int kc=1; 

        
//  débit souhaité:
float consignedebit = 0;
float Qmin = 100;
int kqx = 0.05; 
int tq = 0.101;
// position et la vitesse:
int kp = 6 ; 
int kv = 0.25;
int Vmax=14; 

//moteur:
const int cod1 = 2;
const int cod2 = 3;
const int commandevitesse = 11;
const int commanderotation = 12;
float vitesse;
int rotation;
float Calrot; 
float vitrelle;
float consigne;
float integrale;
volatile float NbTopsFan;

//pour le débit
volatile float compteurdebit1;
volatile float compteurdebit2;
float Calc1;
float Calc2;                               
int hallsensor1 = 20;
int hallsensor2 = 21;

//pour le débit souhaité
float xc;
float deltaQ1;
float deltaQ2;
float integrale3;

//position et la vitesse
float xmax; 
float xmin; 
float integrale2; 

//capteurs de fin de course: photoresistance
int sensorvalue;
int sensorlow = 1023;
int sensorhigh = 0;
float pasdeled;
float limite;

int sensorvalue2;
int sensorlow2 = 1023;
int sensorhigh2 = 0;
float pasdeled2;
float limite2;

//diodes
const int Ledpin=13;
const int Led = 6;

 FONCTIONS D'ETALONNAGE 

void etalonnerPR1(){
    digitalWrite(Led, HIGH);
  unsigned long a = millis();
  while(millis()-a<5000){
    sensorvalue=analogRead(A0);
    if(sensorvalue>sensorhigh){
      sensorhigh=sensorvalue;
    }
    if(sensorvalue<sensorlow){
      sensorlow=sensorvalue;
    }
  }
  digitalWrite(Led,LOW);
  pasdeled=sensorhigh-sensorlow;
  limite= sensorhigh-(pasdeled/2);
}

void etalonnerPR2(){
    digitalWrite(Led, HIGH);
  unsigned long b=millis();
  while(millis()-b<5000){
    sensorvalue2=analogRead(A1);
    if(sensorvalue2>sensorhigh2){
      sensorhigh2=sensorvalue2;
    }
    if(sensorvalue2<sensorlow2){
      sensorlow2=sensorvalue2;
    }
  }
  digitalWrite(Led ,LOW);
  pasdeled2=sensorhigh2-sensorlow2;
  limite2= sensorhigh2-(pasdeled2/2);
}

Fonctions de test 

void verifierPR1(){
  sensorvalue=analogRead(A0);
  if(sensorvalue < limite && rotation == HIGH ){ 
    /* le LOW ou HIGH c'est pour pas l'empecher de repartir dans l'autre sens */
    analogWrite(commandevitesse, 0);
    digitalWrite(commanderotation, LOW );
    delay(50);
    digitalWrite(Ledpin, HIGH); //pour signaler le bloquage 
    Serial.println("Bug a droite");
    xmax=integrale2*kp;
  }
  digitalWrite(Ledpin,LOW);
}

void verifierPR2(){
  sensorvalue2=analogRead(A1);
  if(sensorvalue2 < limite2 && rotation == LOW /*ou HIGH, faudra voir le système*/){ 
    /* le LOW ou HIGH c'est pour pas l'empecher de repartir dans l'autre sens */
    analogWrite(commandevitesse, 0);
    digitalWrite(commanderotation, HIGH /* ou LOW faudra voir*/);
    delay(50);
    // Là il y a un truc qui bloque la lumière donc on arrête le moteur
    // Et on fait clignoter la led 13 pour dire qu'il y a bloquage
    digitalWrite(Ledpin, HIGH); //pour signaler le bloquage
    Serial.println("Bug a Gauche");
    xmin=0; 
  }
  digitalWrite(Ledpin,LOW);
}

Fonctions pour le moteur

  void vitessemoteur(){
  NbTopsFan = 0;
   sei ();
  delay (50);  
  cli();      
  Calrot = NbTopsFan*10/76;
}

void cmptmot (){ 
  NbTopsFan++; 
} 

void commande(){
  float eps=0;

  if(rotation==LOW){
    vitrelle=-Calrot;}
  else{
    vitrelle=Calrot;}

  eps=consigne-kc*vitrelle;
  integrale+=eps*ta*2;
  float eps2 = eps + integrale;
  eps2*=ka;
  
  if(eps2<=0 && rotation==LOW){
    vitesse=-eps2;
  }
  else if(eps2>=0 && rotation==HIGH){
    vitesse=eps2;    
  }
  else if(eps2<0 && rotation==HIGH){
    digitalWrite(commandevitesse,0);
    delay(50);
    vitesse=-eps2;
    rotation=LOW;}
  else{
    digitalWrite(commandevitesse,0);
    delay(50);
    vitesse=eps2;
    rotation=HIGH;}
  
  if(vitesse>=256){
    vitesse=255;
  }
  else if(50 < vitesse<100){
    vitesse=100;
  }
  else if(vitesse<50){
    vitesse=0;
  }
}
 Fonctions pour le débit 

void rpm1 ()
{ 
  compteurdebit1++;
} 

void rpm2 ()   
{ 
  compteurdebit2++;
}

void Debit(){
  compteurdebit1= 0;
  compteurdebit1= 0;  
  sei();      
  delay (50); 
  cli();      
  Calc1 = (compteurdebit1 * 1200 / 5.5); 
  Calc2 = (compteurdebit2 * 1200 / 5.5); 
}


//génération commande 


void positionpointeau(){
  if(rotation==LOW){
  integrale2+=-0.101*Calrot*kp; 
  }
  else{
  integrale2+=0.101*Calrot*kp;
  }
} 

void generer_consigne(){
  float epsQ=0;
  float xc1=0;
  deltaQ1 = Calc2 - consignedebit;
  if (abs(deltaQ1)<=Qmin){
    deltaQ2=0;
    }
  else if(deltaQ1>Qmin){
    deltaQ2=deltaQ1-Qmin;
  }
  else{
    deltaQ2=deltaQ1+Qmin;
  }
  
  integrale3+=tq*deltaQ2;
  
  epsQ=deltaQ2+integrale3;

  xc1=kqx*epsQ;
  
  if (abs(xc1)<=xmax/2){
  xc=xc1;
  }
  else if(xc1>xmax/2){
  xc=xmax/2;
  }
  else{
  xc=-xmax/2;
  }

  float Ex = 0;
  
  
  
  Ex= xc +xmax/2 - integrale2;
  Ex*=kv;
  
    if (abs(Ex)<=Vmax){
  consigne=Ex;
  }
  else if(Ex>Vmax){
  consigne=Vmax;
  }
  else{
  consigne=-Vmax;
  }
  

}  


  void setup(){

    //débit
  pinMode(hallsensor1, INPUT);
  pinMode(hallsensor2, INPUT); 
  attachInterrupt(3, rpm1, RISING); 
  attachInterrupt(2, rpm2, RISING); 
  deltaQ1=0;
  deltaQ2=0;
  integrale3=0;
  
  
  Serial.begin(9600); 
  
  //étalonner la photo résistance
  pinMode(Ledpin,OUTPUT);
  digitalWrite(Ledpin,HIGH);
  pinMode(Led, OUTPUT);
  etalonnerPR1();
  Serial.flush();
  digitalWrite(Led, HIGH);
  delay(200);
  digitalWrite(Led, LOW);
  delay(400);


  etalonnerPR2();
  
//Ce programme comme etalonnerPR1 permet d'étalonner mes capteurs de fins de courses. A 
//priori ils ne sont pas la source du problème car jusque là tout ce passe bien
  
  //Pour le moteur
  pinMode(commandevitesse,OUTPUT);
  pinMode(commanderotation,OUTPUT);
  pinMode(cod1,INPUT);
  pinMode(cod2,INPUT);
  pinMode(8, OUTPUT);
  attachInterrupt(0, cmptmot, CHANGE);
  attachInterrupt(1, cmptmot, CHANGE);
  
  Serial.flush();

  //Pour étalonner les distances:
  
  
  sensorvalue=analogRead(A0);
  digitalWrite(commanderotation, HIGH);
  analogWrite(commandevitesse, 200);
    
  while (sensorvalue > limite){
    Serial.println("TEST 1");
    sensorvalue=analogRead(A0);    
    vitessemoteur();
    integrale2+=0.05*Calrot*kp;
    sensorvalue=analogRead(A0);  
    Serial.println(Calrot,DEC);
  }

  analogWrite(commandevitesse, 0);
  delay(1000);
  
  
  digitalWrite(commanderotation, LOW);
  analogWrite(commandevitesse, 200);
  sensorvalue2=analogRead(A1);
  digitalWrite(Ledpin,LOW);

  while (sensorvalue2 > limite2){
    vitessemoteur();
    Serial.println("TEST 2");
    sensorvalue2=analogRead(A1);  
    Serial.println("TEST 3");
  }
  
  
  analogWrite(commandevitesse, 0);  

  // ICI: le moteur s’arrête comme demandé par la ligne précédente, mais, au lieu de faire 
  //clignoter la led comme demandé ensuite, le programme passe direct dans la loop

  delay(1000);
  
  digitalWrite(Ledpin,LOW);
  
  digitalWrite(Led, HIGH);
  delay(200);
  digitalWrite(Led, LOW);
  delay(400);
  digitalWrite(Led, HIGH);
  delay(200);
  digitalWrite(Led, LOW);
  delay(400);

  digitalWrite(commanderotation, HIGH);
  analogWrite(commandevitesse, 100);
  delay(2000);
  analogWrite(commandevitesse, 0);

  
}

void loop(){
  
  Serial.println("Loop");
  
  digitalWrite(commanderotation, rotation);
  analogWrite(commandevitesse, vitesse);
  verifierPR2();
  verifierPR1();
  Debit();
  generer_consigne();
  vitessemoteur();
  Serial.println(vitesse);
  
  positionpointeau();
  commande();
  

  //longueur d'une boucle : 101 ms
  
}

J’utilise un arduino méga

Merci d’avance

EDIT: Code complet

Amaury

bonjour, le code de etalonnerPR1(); etalonnerPR2(); ?

mets ton code complet entre balise code

le code de etalonnerPR1(); etalonnerPR2(); ?

mets ton code complet entre balise code

Fait;) Non sans difficultés avec la limite des 9000 caractères...

Amaury

déjà avec millis, c'est unsigned long et non int... ou const..... fais au moins des fonctions identiques

Oui en effet mais ça bug quand même ... j'ai réessayé en corrigeant et en éditant dans le premier post. Question: 1 les flushs sont-ils utiles? Un amis m'a recommandé d en mettre des que je mettais des serial.print mais j avoue ne pas savoir le fonctionnement... 2 Quand j'ouvre la fenêtre du serial sur mon ordi, le programme se relance sur l'arduino comme si j avais appuyé sur reset... C'est normal? J avais jamais remarqué avant...

déjà, là y a un blem

 unsigned longb=millis();

mets des serial print dans tes fonctions pour voir si elles fonctionnent

et qu’est ce qui ne marche pas?

oui, normal, tu ré initialise la carte en ouvrant la console