Go Down

Topic: Erreur de programmation [programme simple, mais newbee inside] (Read 4585 times) previous topic - next topic

n1c0l45

Nov 01, 2011, 06:09 pm Last Edit: May 16, 2012, 09:47 am by n1c0l45 Reason: 1
bonjour a tous

je suis en train de bosser sur un programme assez bête ou il y a des entrées tout ou rien (capteurs ou simplement boutons poussoirs) et qui contrôle des sorties en tout ou rien également! Pour faire simple tout est en O ou 1 ;)

le but de se programme est de faire fonctionner un petit groupe hydraulique.

Lorsque je testais tout semblait marcher, mais la je viens de tester sur le système réel et je n'ai pas du tout le même fonctionnement ...

en fait rien de fonctionne mise à part la sonnette!!!. La plupart des sorties se mettent à 1 et plus rien!

Je pense que mon problème vient des remises à zéro des variables, mais je ne maitrise pas suffisamment le langage pour trouver mon erreur.

Merci de me filer un petit coup de main

Nico


Super_Cinci

Tu fais une série de tests avec if qui mettent en route des actions selon quel bouton ou capteur est activé. Jusque là, ok.

mais voilà, tout se remet à zéro si le dernier test (if (!et_bt_hm && !et_bt_dben && !et_ct_ben_bas)) n'est pas vérifié (ton else à la fin ne concerne que le dernier test).

Alors simplement, revois tes tests comme suit :

Code: [Select]

if (test_variables) {
 action();
} else {
 pas_action();
}


Comme ça, pour chaque BP activé, on fait l'action, sinon on l'arrête.

Ensuite, tu passera pro en remplaçant chaque test juste par la ligne suivante et en virant toutes tes void d'action :

Code: [Select]

 digitalWrite(pin_où_faut_agir, test_variables);

skywodd

#2
Nov 01, 2011, 08:05 pm Last Edit: Nov 01, 2011, 08:08 pm by skywodd Reason: 1
Bonjour,

Je pense que ton erreur est purement "syntaxique", tu fait une tripoté de if et à la fin on voit un else qui tombe d'on ne sait ou telle un cheveux sur la soupe.

Je te (re)post ton code, c'est exactement le même que le tient à la différence prés que j'ai respecté une mise en forme lissible :
Code: [Select]

/*
 Atmega 644p
*/

// adressage des pins:  // pin dispo  0,8,9,16,22)   8,9 ==> bt
// en utilisant un #define à la place d'un const int tu gagne presque 200octets de flash et presque 40octets de ram
#define bt_hm       31  // pins d'entrée Pupitre
#define bt_mben     30
#define bt_dben     29
#define bt_pell1    28
#define bt_pell2    27
#define bt_sonnette 25
#define ct_ben_bas  20  // pins d'entrée capteurs
#define ps_beq_rent 18  // bequilles completement rentrées    1 quand rentré
#define ps_beq_sort 17  // bequilles sorties et en pression   1 quand sortie
#define embra       15  // pins de sortie
#define cl_para     14
#define benne       12
#define pell1       6
#define pell2       4
#define dc_beq      3
#define sonnet      2
#define mo_beq      1


void setup() {
 pinMode(embra, OUTPUT);        // initialisation des E/S
 pinMode(cl_para, OUTPUT);
 pinMode(benne, OUTPUT);
 pinMode(pell1, OUTPUT);
 pinMode(pell2, OUTPUT);
 pinMode(dc_beq, OUTPUT);
 pinMode(sonnet, OUTPUT);
 pinMode(mo_beq, OUTPUT);

 pinMode(bt_hm, INPUT);
 pinMode(bt_mben, INPUT);
 pinMode(bt_dben, INPUT);
 pinMode(bt_pell1, INPUT);
 pinMode(bt_pell2, INPUT);
 pinMode(bt_sonnette, INPUT);
 pinMode(ct_ben_bas, INPUT);  
 pinMode(ps_beq_rent, INPUT);
 pinMode(ps_beq_sort, INPUT);  
}


void loop(){
 int et_bt_hm = digitalRead(bt_hm);  // attribution des etats des variables
 int et_bt_mben = digitalRead(bt_mben);
 int et_bt_dben = digitalRead(bt_dben);
 int et_bt_pell1 = digitalRead(bt_pell1);
 int et_bt_pell2 = digitalRead(bt_pell2);
 int et_bt_sonnette = digitalRead(bt_sonnette);
 int et_ct_ben_bas = digitalRead(ct_ben_bas);
 int et_ps_beq_rent = digitalRead(ps_beq_rent);
 int et_ps_beq_sort = digitalRead(ps_beq_sort);



 // Sonnette alarme
 if (!et_bt_sonnette || et_ps_beq_rent == HIGH)          // sonnette si appui bouton ou bequilles non rentrées
 {
   digitalWrite(sonnet, HIGH);   // activation sonnette
 }

 // Pelle sens1
 if (!et_bt_hm && !et_bt_pell1)                          // vérification de l'homme mort et du BP pelle sens 1
 {
   digitalWrite(embra, HIGH);    // activation embrayage // il y avait une erreur de nom de fontion ici ;)
   digitalWrite(pell1, HIGH);    // pelle sens 1
 }                

 // Pelle sens2
 if (!et_bt_hm && !et_bt_pell2)                          // vérification de l'homme mort et du BP pelle sens 2
 {
   digitalWrite(embra, HIGH);    // activation embrayage
   digitalWrite(pell2, HIGH);    // pelle sens 2
 }

 // Sortir bequilles et montée benne
 if (!et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH) //vérification  de l'homme mort et BP monte benne et pressostat bequilles non sorties
 {
   digitalWrite(embra, HIGH);    // activation embrayage
   digitalWrite(dc_beq, HIGH);   // sortir bequilles
 }

 if (!et_bt_hm && !et_bt_mben && !et_ps_beq_sort)        //vérification  de l'homme mort et BP monte benne et pressostat bequilles sorties
 {
   digitalWrite(embra, HIGH);    // activation embrayage
   digitalWrite(benne, HIGH);    // monter benne
   digitalWrite(cl_para, HIGH);  // ouvrir clapet parachute
 }

 // Descente benne et remonter bequilles
 if (!et_bt_hm && !et_bt_dben && et_ct_ben_bas == HIGH)  //vérification  de l'homme mort et BP descente benne et capteur benne basse non activé
 {
   digitalWrite(cl_para, HIGH);   // ouvrir clapet parachute
 }

 if (!et_bt_hm && !et_bt_dben && !et_ct_ben_bas)         //vérification  de l'homme mort et BP descente benne et capteur benne basse activé
 {
   digitalWrite(embra, HIGH);     // activation embrayage
   digitalWrite(mo_beq, HIGH);    // rentrer bequilles
 }
 else // erreur ?
 { // remise des varibles à zero
   digitalWrite(embra, LOW);
   digitalWrite(pell1, LOW);
   digitalWrite(pell2, LOW);
   digitalWrite(cl_para, LOW);
   digitalWrite(mo_beq, LOW);
   // il y avait un ; qui ce baladé, faire de gros patté d'instructions n'apporte rien de bien ;)
   digitalWrite(dc_beq, LOW);
   digitalWrite(benne, LOW);
   digitalWrite(sonnet, LOW);
 }
}


J'ai mis des commentaires sur les passages "étranges".

Aprés lecture de ton code je peut te dire que ton arduino fait très exactement ce que tu lui demande, il place tout les sorties à HIGH selon les conditions qui lui sont donnée mais pour qu'il les repassent à LOW il faut que (!et_bt_hm && !et_bt_dben && !et_ct_ben_bas) == false, est ce que cela est volontaire ou non ? toi seul peut nous le dire ;)

Edit: Super_Cinci tu est un vrai ninja, le temps que rende le code lisible tu post déjà une réponse :)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

n1c0l45

merci bcp pour votre aide!!

donc tous les deux, vous pensez que faire" des void action n'est pas une bonne idée? je l'avait rajouter car cela me semblait plus lisible!

Merci de votre aide, je vais potassé tout cela ;)



Merci! merci! Merci !!!


skywodd


donc tous les deux, vous pensez que faire" des void action n'est pas une bonne idée? je l'avait rajouter car cela me semblait plus lisible!

faire une fonction n'est vraiment utile que quand on doit faire quelque chose (un calcul, ...) plusieurs fois dans un même code, une fonction utilisé une seul fois est inutile et entraine des erreurs (comme l'appel de pell_sens1 méchamment copier/coller en pell_sens2 ;))
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Super_Cinci

en fait, son erreur est très simple, je fais un code de bas correspondant au sien :

Code: [Select]

loop(){
  if (condition1){
    actionner_1();
  }
  if (condition2){
    actionner_2();
  }
  if (condition3){
    actionner_3();
  }
  if (condition4){
    actionner_4();
  } else {
    tout_arrêter();
  }
}


Donc si on remplit la condition1, alors on fait actionner1(); mais quelque petites µs après, comme condition4 n'est pas remplie, alors on fait tout_arrêter(); Le résultat est qu'on verra une impulsion de qq µs sur les bonnes pins, mais pas assez pour actionner un vérin.

l'erreur est là, c'est tout aussi simple que de se mettre un doigt dans le nez (ou ailleurs...)

Je suis pas un ninja, mais on a trouvé l'erreur en même temps... :)

n1c0l45

#6
Nov 01, 2011, 09:56 pm Last Edit: May 16, 2012, 09:49 am by n1c0l45 Reason: 1
encore merci

Super_Cinci

Bon, rien que ces deux tests se contredisent :

Code: [Select]

// Sortir bequilles et monter benne
  if (!et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH&& et_ps_beq_sort == HIGH )//vérification  de l'homme mort et BP monte benne et pressostat bequilles non sorties
             {
               digitalWrite(embra, HIGH);                   // activation embrayage
               digitalWrite(dc_beq, HIGH);                  // sortir bequilles
             }
  else      {
               digitalWrite(embra, LOW);           
               digitalWrite(dc_beq, LOW);       
            }           

  if (!et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort)     //vérification  de l'homme mort et BP monte benne et pressostat bequilles sorties
             {
               digitalWrite(embra, HIGH);                   // activation embrayage
               digitalWrite(benne, HIGH);                   // monter benne
               digitalWrite(cl_para, HIGH);                 // ouvrir clapet parachute
             }
  else      {
               digitalWrite(embra, LOW);               
               digitalWrite(benne, LOW);                 
               digitalWrite(cl_para, LOW);               
           }           

Effectivement, si le premier est vérifié, alors embra sera mis à 1, mais comme le second n'est pas vérifié, embra est remis à 0.

Comme chaque sortie dépend un peu de plusieurs entrées. si je ne prends que ces deux tests, ça donne ça :

Code: [Select]

embra = dc_beq = et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH && et_ps_beq_sort == HIGH;
embra = benne = cl_para = et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort

On voit que deux conditions agissent sur embra, donc il faut les réunir. On a donc juste à écrire ça :
Code: [Select]

digitalWrite(dc_beq, et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH&& et_ps_beq_sort == HIGH);
digitalWrite(embra, (et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH&& et_ps_beq_sort == HIGH)||(et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort));
digitalWrite(benne , et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort);
digitalWrite(cl_para, et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort);


Pour faire plus simple, essaie ce code là : c'est le tien, mais il doit marcher, sinon je ne suis pas un ninja :D

La modif que j'ai faite : c'est remplacer chaque if par un calcul boolean. puis digitalWrite (sortie, t_xxx);. Quand une sortie dépend de plusieurs tests, alors on a des OR dans le digitalWrite. Ca a pour effet que les tests IF ne s'annulent plus les uns les autres...

Code: [Select]

/*

  Atmega 644p

*/



// adressage des pins:           // pin dispo  0,8,9,16,22)   8,9 ==> bt
#define bt_hm        31         // pins d'entrée Pupitre
#define bt_mben      30
#define bt_dben      29
#define bt_pell1     28
#define bt_pell2     27
#define bt_sonnette  25

// pins d'entrée capteurs
#define ct_ben_bas   20
#define ps_beq_rent  18         // bequilles completement rentrées    1 quand rentré
#define ps_beq_sort  17         // bequilles sorties et en pression   1 quand sortie

#define embra        15         // pins de sortie
#define cl_para      14
#define benne        12
#define pell1         6
#define pell2         4
#define dc_beq        3
#define sonnet        2
#define mo_beq        1


void setup() {

  pinMode(embra, OUTPUT);        // initialisation des E/S
  pinMode(cl_para, OUTPUT);
  pinMode(benne, OUTPUT);
  pinMode(pell1, OUTPUT);
  pinMode(pell2, OUTPUT);
  pinMode(dc_beq, OUTPUT);
  pinMode(sonnet, OUTPUT);
  pinMode(mo_beq, OUTPUT);

  pinMode(bt_hm, INPUT);
  pinMode(bt_mben, INPUT);
  pinMode(bt_dben, INPUT);
  pinMode(bt_pell1, INPUT);
  pinMode(bt_pell2, INPUT);
  pinMode(bt_sonnette, INPUT);

  pinMode(ct_ben_bas, INPUT);
  pinMode(ps_beq_rent, INPUT);
  pinMode(ps_beq_sort, INPUT);
}

boolean t_sonnette, t_pelle_s1, t_pelle_s2, t_beq_benne, t_hm_benne, t_benne_beq, t_hm_benne_beq;  // variables de tests capteurs et boutons

void loop(){


int et_bt_hm = digitalRead(bt_hm);               // attribution des etats des variables
int et_bt_mben = digitalRead(bt_mben);
int et_bt_dben = digitalRead(bt_dben);
int et_bt_pell1 = digitalRead(bt_pell1);
int et_bt_pell2 = digitalRead(bt_pell2);
int et_bt_sonnette = digitalRead(bt_sonnette);
int et_ct_ben_bas = digitalRead(ct_ben_bas);
int et_ps_beq_rent = digitalRead(ps_beq_rent);
int et_ps_beq_sort = digitalRead(ps_beq_sort);


// Sonnette alarme
  t_sonnette = (!et_bt_sonnette || et_ps_beq_rent == HIGH);        // sonnette si appui bouton ou bequilles non rentrées

// Pelle sens1
  t_pelle_s1 = (!et_bt_hm && !et_bt_pell1);                        // vérification de l'homme mort et du BP pelle sens 1

// Pelle sens2
  t_pelle_s2 = (!et_bt_hm && !et_bt_pell2);                        // vérification de l'homme mort et du BP pelle sens 2

// Sortir bequilles et monter benne
  t_beq_benne = (!et_bt_hm && !et_bt_mben && et_ps_beq_sort == HIGH&& et_ps_beq_sort == HIGH); //vérification  de l'homme mort et BP monte benne et pressostat bequilles non sorties
  t_hm_benne = (!et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort);     //vérification  de l'homme mort et BP monte benne et pressostat bequilles sorties

// Descente benne et remonter bequilles
  t_benne_beq = (!et_bt_hm && !et_bt_dben && et_ct_ben_bas == HIGH && et_ct_ben_bas == HIGH); //vérification  de l'homme mort et BP descente benne et capteur benne basse non activé
  t_hm_benne_beq = (!et_bt_hm && !et_bt_dben && !et_ct_ben_bas && !et_ct_ben_bas);      //vérification  de l'homme mort et BP descente benne et capteur benne basse activé


  digitalWrite(sonnet, t_sonnette);                  // activation sonnette
  digitalWrite(embra, t_pelle_s1 || t_pelle_s2 || t_beq_benne || t_hm_benne || t_hm_benne_beq);          // activation embrayage
  digitalWrite(pell1, t_pelle_s1);                   // pelle sens 1
  digitalWrite(pell2, t_pelle_s2);                   // pelle sens 2
  digitalWrite(dc_beq, t_beq_benne);                  // sortir bequilles
  digitalWrite(benne, t_hm_benne);                   // monter benne
  digitalWrite(cl_para, t_hm_benne || t_benne_beq);                 // ouvrir clapet parachute
  digitalWrite(mo_beq, t_hm_benne_beq);                  // rentrer bequilles

}

C'est le petit cadeau du matin...
Maintenant, si tu prends par exemple le digitalWrite suivant :
Code: [Select]

  digitalWrite(cl_para, t_hm_benne || t_benne_beq);                 // ouvrir clapet parachute

on trouve alors :
Code: [Select]

  cl_para = (t_hm_benne || t_benne_beq)
             = (!et_bt_hm && !et_bt_mben && !et_ps_beq_sort && !et_ps_beq_sort) || (!et_bt_hm && !et_bt_dben && et_ct_ben_bas == HIGH && et_ct_ben_bas == HIGH)
(...)

Je pense qu'en décomposant l'expression, on doit pouvoir simplifier grandement, limite si tu t'es pas pris la tête pour calculer tes associations pour faire des tests, alors que ce n'était pas nécessaire, et que tu as déjà les formules de tes sorties genre
Code: [Select]
sortie = entrée1 || (!entrée2 && entrée3)

Si mon code marche, alors en échange, je te demande de le réécrire en simplifiant le tout, sinon c'est trop facile, c'est ton projet, pas le mien! :P

n1c0l45

Merci, je viens de comprendre mon erreur!

je vais modifier mon programme pour suivre tes indications (virer les if)

merci

n1c0l45

#9
Nov 02, 2011, 10:27 am Last Edit: May 16, 2012, 09:49 am by n1c0l45 Reason: 1
je suis en train de faire les modifs (le programme mis en ligne est en faait une version simplifiée de celui que j'utilise, il y a plus de fonctions)

encore merci de ton aide

skywodd


Quote
sketch_nov02a.cpp: In function 'void loop()':
sketch_nov02a:87: error: lvalue required as left operand of assignment



Redonne nous ton code complet pour qu'on puisse regarder ça chez nous ;)
Ps: je vois pas trop ce que tu nous prépare avec tes opérations logique pointant vers des variables ...
j'ai bien une petite idée de ce que tu compte essayer de faire mais j'attend de voir ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Super_Cinci

Les digitalWrite(), fallait les garder, car ce sont eux qui mettent 1 ou 0 en sortie hard... ce que tu as fait là ne ressemble plus à grand chose...

en attente du code complet...

skywodd


Les digitalWrite(), fallait les garder, car ce sont eux qui mettent 1 ou 0 en sortie hard... ce que tu as fait là ne ressemble plus à grand chose...
en attente du code complet...


Il a suivi ton code d'exemple Super_Cinci, perso je trouve cela totalement ignoble de faire un :
Code: [Select]
t_sonnette = (!et_bt_sonnette || et_ps_beq_rent == HIGH);
digitalWrite(sonnet, t_sonnette);

et encore plus :
Code: [Select]
digitalWrite(sonnet, (!et_bt_sonnette || et_ps_beq_rent == HIGH));
Un if "normal" ça mange pas de pain et ça rend le code bien plus lisible.

n1c0l45 si tu ne maitrise pas encore totalement la syntaxe "arduino" garde ma version avec des if + accolades,
d'un point de vu optimisation c'est pas top mais le core arduino en soi n'est pas optimisé alors pas la peine de chercher 12h à 14h.
Enfin bon fait comme tu le sens ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

osaka


Un if "normal" ça mange pas de pain et ça rend le code bien plus lisible.


Je plussoie, une grosse partie des erreurs en programmation viennent de la lisibilité du code.
Ca permet aussi d'avoir plus de "repères".

Super_Cinci

#14
Nov 02, 2011, 07:39 pm Last Edit: Nov 02, 2011, 07:41 pm by Super_Cinci Reason: 1

Il a suivi ton code d'exemple Super_Cinci, perso je trouve cela totalement ignoble de faire un :
Code: [Select]
t_sonnette = (!et_bt_sonnette || et_ps_beq_rent == HIGH);
digitalWrite(sonnet, t_sonnette);

et encore plus :
Code: [Select]
digitalWrite(sonnet, (!et_bt_sonnette || et_ps_beq_rent == HIGH));
Un if "normal" ça mange pas de pain et ça rend le code bien plus lisible.


Je sais que tu n'aimes pas trop mes idées, mais pourquoi faire un if sur des valeurs booléennes alors qu'il suffit d'un digitalWrite? je comprends pas du tout ta réaction, car je n'ai fait qu'une équation logique, comme on faisait en première année de BTS. De plus, si tu regardes bien, les sorties dépendent d'entrées mais pas toutes en même temps et pour l'embrayage, c'est assez compliqué. Tu n'as jamais fait d'équations genre "S1 = (!E1 + E2) . E3 + !E4"? c'est exactement ce dont il a besoin ici, et l'utilisation des if devient très compliquée pour résoudre une telle équation et encore moins lisible (à mon sens, à l'école d'il y a 15 ans ou le moindre octet de mémoire valait de l'or, ce qui est un peu le cas de nos arduinos)...

Go Up