Aide à la programmation sur arrêt et relance d'un véhicule

Bonjour à tous,

Mon projet consiste à arrêter et relancer un véhicule via un émetteur / récepteur.

Dans le étapes du programme, je dois simuler des valeurs d'une pédale d'embrayage qui est équipé d'un potentiomètre "PWM" et d'une électrovanne qui vient freiner le véhicule lorsqu'il est débrayé et qui relâche l'électrovanne lorsque l'on relance le véhicule.

Lorsque j'actionne un bouton de ma radiocommande, le véhicule doit se débrayer et s'arrêter jusqu'à ce que j’appuie de nouveau sur le bouton ou il doit se libérer du frein et ré-embrayer.

Voici comment j'ai procédé dans le code :


/*  -----------------------------------------------  Déclaration du débrayage  ---------------------------------------------*/

const int inter_debrayage = 11;  // Poussoir de relais du récepteur n°1 en haut
int Etat_inter_debrayage;

const int Relais_electro_frein = 3;
const int Relais_canal_A_B_debrayage = 12;


const int Valeur_canal_B = 5;
const int Valeur_canal_A = 6;


/* _______________________________________________________  SETUP  ___________________________________________________________*/

void setup() {

  Serial.begin(9600);


  /*  ---------------------------------------------  Initialisation du débrayage  ----------------------------------------*/

  pinMode(inter_debrayage, INPUT);

  pinMode(Relais_electro_frein, OUTPUT);
  

  pinMode(Relais_canal_A_B_debrayage, OUTPUT);
  digitalWrite(Relais_canal_A_B_debrayage, HIGH);

  pinMode(Valeur_canal_A, OUTPUT);
  pinMode(Valeur_canal_B, OUTPUT);
  

    
    analogWrite(Valeur_canal_A, 190);                       // Première temporisation de débrayage de la pédale 
    analogWrite(Valeur_canal_B, 65);
   
    analogWrite(Valeur_canal_A, 150);                       
    analogWrite(Valeur_canal_B, 155);
   
    analogWrite(Valeur_canal_A, 115);                       
    analogWrite(Valeur_canal_B, 140);
    
    analogWrite(Valeur_canal_A, 85);                       
    analogWrite(Valeur_canal_B, 170);
    
    analogWrite(Valeur_canal_A, 55);                       
    analogWrite(Valeur_canal_B, 200);


    digitalWrite(Relais_electro_frein, HIGH);
}

/* ___________________________________________________________  LOOP  _______________________________________________________________________*/


void loop() {
  

 /*  ------------------  Routine de débrayage  ---------------------------------*/


  Etat_inter_debrayage = digitalRead(inter_debrayage);                 // Routine de relance du tracteur en marche avant

if ( Etat_inter_debrayage == LOW ) {

       for ( int i=0; i<2; i++){ 

    digitalWrite(Relais_electro_frein, LOW);

    analogWrite(Valeur_canal_A, 55);                       
    analogWrite(Valeur_canal_B, 200);
    
    analogWrite(Valeur_canal_A, 85);                       
    analogWrite(Valeur_canal_B, 170);
    
    analogWrite(Valeur_canal_A, 115);                       
    analogWrite(Valeur_canal_B, 140);
    
    analogWrite(Valeur_canal_A, 150);                       
    analogWrite(Valeur_canal_B, 155);
   
    analogWrite(Valeur_canal_A, 190);                      
    analogWrite(Valeur_canal_B, 65);


       }

 } else { 

 }

if ( Etat_inter_debrayage == HIGH ) {

       for ( int i=0; i<2; i++){ 

digitalWrite(Relais_electro_frein, HIGH);

    
    analogWrite(Valeur_canal_A, 190);                       
    analogWrite(Valeur_canal_B, 65);
   
    analogWrite(Valeur_canal_A, 150);                       
    analogWrite(Valeur_canal_B, 155);
   
    analogWrite(Valeur_canal_A, 115);                       
    analogWrite(Valeur_canal_B, 140);
   
    analogWrite(Valeur_canal_A, 85);                      
    analogWrite(Valeur_canal_B, 170);
   
    analogWrite(Valeur_canal_A, 55);                       
    analogWrite(Valeur_canal_B, 200);
   

  }
 }
}

Après essai, ça ne fonctionne pas, comment voyez vous la syntaxe des boucles for pour que la comparaison fonctionne une seul fois et s'arrête tant que l'on ne change pas de condition ?

Et es ce que la valeur de i++ revient à zéro après plusieurs appuis sur le bouton ?

Merci par avance pour votre aide.
Ludo

C''est-à-dire?


  • Il faut avoir une variable qui contient l'état actuel embrayé/débrayé et une variable qui contient le fait que l'on a effectué une action.
  • Il faut tester le bouton en permanence et comparer son état actuel avec son état précédent pour détecter un appui.
  • si le bouton était au repos au cycle précédent et actuellement au repos effacer la variable qui contient le fait que l'on a effectué une action
    -si le bouton était au repos au cycle précédent et actuellement activé et que l'action n'a pas été effectuée il faut:
    • changer l'état de la variable qui contient l'état embrayé/débrayé.
    • effectuer l'action embrayage/débrayage
    • mémorisé le fait que l'on a effectué l'action
    • faire un petit delay() pour masquer les éventuels rebonds du bouton

Ce genre de chose peut être traitée assez facilement avec une machine à état. Il y a un tuto ici


À chaque fois que l'on commence la boucle for, la variable est initialisée à 0 (c'est ce qu'indique le premier argument de la fonction)


A noter

Les sorties PWM génère un signal relativement lent (sur les broche 5 et 6 c'est 980Hz, soit un peu plus de 1ms) or le temps d'exécution de la boucle for doit être inférieur à 1ms donc les 5 pas de ta boucle doivent être complètement masqués.

Merci pour ces infos, j'ai suivi le tuto ( super bien construit ) sur les machines à état donc j'ai pour le coup réédité le code :

#include "OneButton.h"

#define PIN_INPUT 11
OneButton button;

enum {etatfreiner, etatRelancer} etatDuVehicule;

/*  -----------------------------------------------  Déclaration du débrayage  ---------------------------------------------*/

//const int inter_debrayage = 11;  // Poussoir de relais du récepteur n°1 en haut
//int Etat_inter_debrayage;

const int Relais_electro_frein = 3;
const int Relais_canal_A_B_debrayage = 12;


const int Valeur_canal_B = 5;
const int Valeur_canal_A = 6;

void mettreAuRepos() { // Mise à l'arrêt du véhicule au démarrage du systeme

  analogWrite(Valeur_canal_A, 190);
  analogWrite(Valeur_canal_B, 65);
  delay(50);
  analogWrite(Valeur_canal_A, 150);
  analogWrite(Valeur_canal_B, 155);
  delay(50);
  analogWrite(Valeur_canal_A, 115);
  analogWrite(Valeur_canal_B, 140);
  delay(50);
  analogWrite(Valeur_canal_A, 85);
  analogWrite(Valeur_canal_B, 170);
  delay(50);
  analogWrite(Valeur_canal_A, 55);
  analogWrite(Valeur_canal_B, 200);
  delay(50);
  digitalWrite(Relais_electro_frein, HIGH);

  etatDuVehicule = etatfreiner;

}

void simpleclick() {

  switch (etatDuVehicule) {

    case etatfreiner :

      delay(100);

      for ( int i = 0; i < 2; i++) {
        digitalWrite(Relais_electro_frein, LOW);
        delay(100);
        analogWrite(Valeur_canal_A, 55);
        analogWrite(Valeur_canal_B, 200);
        delay(50);
        analogWrite(Valeur_canal_A, 85);
        analogWrite(Valeur_canal_B, 170);
        delay(50);
        analogWrite(Valeur_canal_A, 115);
        analogWrite(Valeur_canal_B, 140);
        delay(50);
        analogWrite(Valeur_canal_A, 150);
        analogWrite(Valeur_canal_B, 155);
        delay(50);
        analogWrite(Valeur_canal_A, 190);
        analogWrite(Valeur_canal_B, 65);
        delay(100);
      }
      break;

    case etatRelancer :

      for ( int i = 0; i < 2; i++) {
        delay(100);
        digitalWrite(Relais_electro_frein, HIGH);
        analogWrite(Valeur_canal_A, 190);
        analogWrite(Valeur_canal_B, 65);
        delay(50);
        analogWrite(Valeur_canal_A, 150);
        analogWrite(Valeur_canal_B, 155);
        delay(50);
        analogWrite(Valeur_canal_A, 115);
        analogWrite(Valeur_canal_B, 140);
        delay(50);
        analogWrite(Valeur_canal_A, 85);
        analogWrite(Valeur_canal_B, 170);
        delay(50);
        analogWrite(Valeur_canal_A, 55);
        analogWrite(Valeur_canal_B, 200);
        delay(100);
      }
      break;
  }
}
/* _______________________________________________________  SETUP  ___________________________________________________________*/

void setup() {

  Serial.begin(9600);

  button.setup(PIN_INPUT, INPUT);   // J'ai installé une PullUp sur le pin 11

  /*  ---------------------------------------------  Initialisation du débrayage  ----------------------------------------*/

  // pinMode(inter_debrayage, INPUT);

  pinMode(Relais_electro_frein, OUTPUT);


  pinMode(Relais_canal_A_B_debrayage, OUTPUT);
  digitalWrite(Relais_canal_A_B_debrayage, HIGH);

  pinMode(Valeur_canal_A, OUTPUT);
  pinMode(Valeur_canal_B, OUTPUT);

  mettreAuRepos();

  button.attachClick(simpleclick);

}

/* ___________________________________________________________  LOOP  _______________________________________________________________________*/


void loop() {

  button.tick();

}

Tout marche bien quand j'allume la carte Uno par contre je n'ai pas de détection du bouton, il ne se passe rien.
J'ai lancé une lecture du pin 11 dans la loop et voici ce que j'obtiens dans le moniteur série :

J'ai bien une détection de changement d'état. Je précise que se contacteur est une lamelle de relais présente dans mon récepteur. Lorsque j’appuie sur ma radiocommande, le relais intégré à mon récepteur s’excite et je récupère mon pin 11 de se contact. Le relais est en maintient donc il change d'état à chaque appui de ma radiocommande.

Je devrais quand même réussir à avoir un fonctionnement avec le switch / case non ?

N'as-tu pas oublié de mettre etatDuVehicule à jour dans ton switch-case ?

EDIT : Par ailleurs, tu devrais ajouter des Serial.print() dans les différentes branches de ton switch pour savoir quelle partie du programme est parcourue.
Passe aussi Serial.begin(9600); à 115200 (ainsi que côté terminal) pour plus de réactivité.

Merci à toi, effectivement, il n'y avait pas le changement d'état à la fin de mes deux case , je retente demain pour le test.