Inclusion d'un bout de code dans un autre...

Toutes les discussions sur l'Arduino !

Modérateur : MOD

Répondre
Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 06 janv. 2015, 11:16

Bonjour à tous.

Toujours en train de galérer avec cette petite carte qui me rend dingue, j'aimerai savoir comment on fait afin d'imbriquer des bouts de code les au aux autres.

En effet, quand on utilise une bibliothèque, c'est bien, mais après? On fait comment si l'on veut rajouter des fonctionnalités? Car à ce rythme, je vais avoir 30 cartes Arduino sur le réseau!! Alors à part des If et Cie qui ne règlent pas le problème, je ne trouve pas! Je suis très con ou alors je vais vraiment commencer à le croire :siffle: :siffle:

Voila un code qui fait fonctionner deux boutons poussoirs. J'aimerai, pour tester uniquement, faire une boucle clignotement sur la led 13. J'ai beau la placer n'importe où, cela ne fonctionne pas. Ou alors, lorsque cela fonctionne, du coup, il est impossible d'allumer une led via le bouton poussoir.

Merci encore de l'aide.

Code : Tout sélectionner

#include <Button.h>

/*
 * Deux boutons, b1 et b2. Le premier est sur la broche 5. Le second
 * sur la broche 6.
 * ils sont tous les deux en PULLUP (non pressé = HIGH). Quand le
 * bouton est pressé, la broche est LOW.
 */
Button Halle(15);
Button Pont_Secteur(16);

/*
 * 2 LED sur les broches 6 et 7. Anode au 5V via une résistance de 330 ohms
 * cathode sur la broche de l'Arduino. Pour allumer la LED il faut donc
 * que la broche soit LOW.
 */
const byte pinLED_Halle = 7;
const byte pinLED_PS = 6;
const byte pinLED = 13;
/*
 * Etat initial : LEDs éteintes
 */
byte etatLED_Halle = HIGH;
byte etatLED_PS = HIGH;

void setup()
{
  pinMode(pinLED_Halle, OUTPUT);
  pinMode(pinLED_PS, OUTPUT);
  pinMode (pinLED,OUTPUT);
  
    
  digitalWrite(pinLED_Halle, etatLED_Halle);
  digitalWrite(pinLED_PS, etatLED_PS);

 }
 

  
 void loop()
{
       
  Halle.scan();
  Pont_Secteur.scan();
  if (Halle.uniquePress()) 
  {
    etatLED_Halle = !etatLED_Halle;
  }
  if (Pont_Secteur.uniquePress()) 
  {
    etatLED_PS = !etatLED_PS;
  }
  
  digitalWrite(pinLED_Halle, etatLED_Halle);
  digitalWrite(pinLED_PS, etatLED_PS);
  
}




Avatar du membre
jlb
Fécond
Messages : 686
Enregistré le : jeu. 04 oct. 2012, 15:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Inclusion d'un bout de code dans un autre...

Message par jlb » mar. 06 janv. 2015, 11:46

Il faut gérer ce clignotement de LED dans loop. Mais tu ne peux pas utiliser delay.

En effet delay est bloquant. L'Arduino ne fait rien pendant ce temps et donc ta gestion de boutons poussoir ne fonctionnera plus.

Il faut donc gérer le clignotement de la LED en examinant le temps écoulé mais au lieu de rester planté devant la pendule à attendre que l'heure arrive, ce qui se passe avec delay, il faut jeter un oeil à la pendule, aller faire autre chose, revenir jeter un oeil, etc et quand la pendule indique l'heure voulue, changer l'état de la LED 13.

Pour cela, il faut utiliser la fonction millis()

Je te propose de faire une fonction pour gérer cette LED 13. Cette fonction va :
1 - regarder l'heure via millis
2 - calculer combien de temps s'est écoulé depuis la dernière fois ou l'état de la LED a été changé
3 - si il s'est écoulé un temps >= à l'interval de changement : noter la nouvelle heure de changement et changer l'état

L'intérêt de faire une fonction est d'isoler le code qui concerne cette led et de simplifier la lecture du programme.

Voici cette fonction

Code : Tout sélectionner

void clignoteLED13()
{
    static byte etatLED13 = LOW;
    static unsigned long date = 0;

    unsigned long nouvelleDate = millis();
    if (nouvelleDate - date > 500) {
        date = nouvelleDate;
        etatLED13 = !etatLED13;
        digitalWrite(13,etatLED13);
    }
}
Dans loop, tu appelles clignoteLED13(), voici le programme :

Code : Tout sélectionner

#include <Button.h>

/*
 * Deux boutons, b1 et b2. Le premier est sur la broche 5. Le second
 * sur la broche 6.
 * ils sont tous les deux en PULLUP (non pressé = HIGH). Quand le
 * bouton est pressé, la broche est LOW.
 */
Button Halle(15);
Button Pont_Secteur(16);

/*
 * 2 LED sur les broches 6 et 7. Anode au 5V via une résistance de 330 ohms
 * cathode sur la broche de l'Arduino. Pour allumer la LED il faut donc
 * que la broche soit LOW.
 */
const byte pinLED_Halle = 7;
const byte pinLED_PS = 6;
const byte pinLED = 13;
/*
 * Etat initial : LEDs éteintes
 */
byte etatLED_Halle = HIGH;
byte etatLED_PS = HIGH;

void clignoteLED13()
{
    static byte etatLED13 = LOW;
    static unsigned long date = 0;

    unsigned long nouvelleDate = millis();
    if (nouvelleDate - date > 500) {
        date = nouvelleDate;
        etatLED13 = !etatLED13;
        digitalWrite(pinLED,etatLED13);
    }
}

void setup()
{
  pinMode(pinLED_Halle, OUTPUT);
  pinMode(pinLED_PS, OUTPUT);
  pinMode (pinLED,OUTPUT);
  
    
  digitalWrite(pinLED_Halle, etatLED_Halle);
  digitalWrite(pinLED_PS, etatLED_PS);

 }
 

  
 void loop()
{
       
  Halle.scan();
  Pont_Secteur.scan();
  if (Halle.uniquePress()) 
  {
    etatLED_Halle = !etatLED_Halle;
  }
  if (Pont_Secteur.uniquePress()) 
  {
    etatLED_PS = !etatLED_PS;
  }
  
  digitalWrite(pinLED_Halle, etatLED_Halle);
  digitalWrite(pinLED_PS, etatLED_PS);
  
  clignoteLED13();
}

Je n'ai pas testé, j'ai peut-être fait des typos.

Concernant la signification de static, regarde ma réponse tout en bas de http://www.locoduino.org/spip.php?article64 (avant dernier message)

Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Re: Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 06 janv. 2015, 11:56

Merci pour cette réponse rapide. Je n'ai plus le temps de tester mais je vais voir ça dès que possible.

Ce qui me rassure: pendant que j'attendais une réponse j'ai créer une fonction comme toi (void clignotement) que j'avais mis au bon endroit (avant le setup). par contre, j'utilisai toujours "delay" et je n'appelai pas la fonction dans la "loop".
Je commence un peu à voir comment tout cela peut s'enchaîner. Pas simple mais je vais bien arriver à quelquechose.
Maintenant, il faut que je décode un peu mieux tout ça en particulier les histoires de "nouvelledate - date". Encore du mal avec ça.

Je suis très long à comprendre mais quand j'aurai tout appris cela devrait aller plus vite. Ha, si seulement j'avais encore 10 ans pour tout bien comprendre!! :mdr:

Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Re: Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 06 janv. 2015, 13:04

C'est bon, je viens de tester. Cela fonctionne nickel.

Merci.

Avatar du membre
jlb
Fécond
Messages : 686
Enregistré le : jeu. 04 oct. 2012, 15:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Inclusion d'un bout de code dans un autre...

Message par jlb » mar. 06 janv. 2015, 14:15

sash28 a écrit : Maintenant, il faut que je décode un peu mieux tout ça en particulier les histoires de "nouvelledate - date". Encore du mal avec ça.
millis() donne la date courante. La date commence à 0 quand on allume l'Arduino. Les dates sont en millisecondes.

le static unsigned long date permet de mémorisé la date du dernier changement de l'état de la LED 13. On décide arbitrairement qu'il y a eu un changement à la date 0. Le static fait que date n'est initialisé qu'une seul fois au démarrage et conserve sa valeur entre deux appels à clignoteLED13.

Donc on met la date courante dans nouvelleDate.

nouvelleDate — date donne donc le temps écoulé depuis le dernier changement d'état de la LED.

Dès que ça dépasse 500 ms, l'état de la LED est changé et nouvelleDate est copié dans date pour préparer la prochaine mesure de temps.

Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Re: Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 13 janv. 2015, 16:30

Merci jlb pour ces précisions .
Par contre, j'ai relu le code. Il n'y a pas de temps de clignotement comme l'on peut faire avec (delay). Donc comment la led "sait" qu'elle doit clignoter 60 fois par seconde ou 25 ou 10?? Je pense que c'est du au fonctionnement du processeur non?

Merci.

Avatar du membre
jlb
Fécond
Messages : 686
Enregistré le : jeu. 04 oct. 2012, 15:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Inclusion d'un bout de code dans un autre...

Message par jlb » mar. 13 janv. 2015, 16:39

Bonjour,

C'est dans clignoteLED13. Tu as ceci, j'ai ajouté les commentaires.

Code : Tout sélectionner

    unsigned long nouvelleDate = millis(); // coup d'oeil à la pendule
    if (nouvelleDate - date > 500) { // il s'est écoulé 500ms depuis la dernière fois
        date = nouvelleDate; // mémorise la date de changement pour préparer les prochaines 500ms 
        etatLED13 = !etatLED13; // inverse l'état de la LED
        digitalWrite(13,etatLED13); // met à jour la LED
    }
En résumé, 500 est la valeur à changer.

Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Re: Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 13 janv. 2015, 17:27

Le 500 ne correspond pas à un temps depuis le début du programme?
Je pensais que cela signifiait que lorsque le programme avait débuté depuis 500ms, le clignotement commençait.

-----------------------------------------------------------------------------------------
Je viens de tester:

si je mets "12000" à la place de 500, la led clignote beaucoup plus lentement. Donc, si je veux que cette même led clignote à 60/secondes mais uniquement 2' après le lancement du programme, il faut que je rajoute une ligne "millis" non?

------------------------------------------------------------------------------------------
J'ai relu ton dernier message jlb sur le "static". Je viens de comprendre la nuance avec ce que je demande. Le même clignotement au bout de 2' et jusqu'à 5' par exemple.

Avatar du membre
jlb
Fécond
Messages : 686
Enregistré le : jeu. 04 oct. 2012, 15:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Inclusion d'un bout de code dans un autre...

Message par jlb » mar. 13 janv. 2015, 17:57

La ligne :

Code : Tout sélectionner

unsigned long nouvelleDate = millis();
met dans nouvelleDate le temps écoulé depuis le début du programme.

date est initialisé à 0. Donc la première fois que le if est exécuté et les fois suivante tant que nouvelleDate - date reste inférieur ou égal à 500 :

Code : Tout sélectionner

if (nouvelleDate - date > 500) {
on effectue la soustraction dateCourante - 0 et on compare le résultat à 500. Donc oui, on attends 500ms avant le premier allumage de la LED. Mais ensuite, dans le if, on change date :

Code : Tout sélectionner

date = nouvelleDate;
Donc la prochaine fois que la fonction sera exécutée et que l'on récupérera dans nouvelleDate la date courante, le if :

Code : Tout sélectionner

if (nouvelleDate - date > 500) {
nouvelleDate - date donnera la durée écoulée depuis la dernière fois ou date a été changée. Donc ce qui dans le if sera exécuté 500 ms après son exécution précédente.

L'effet est d'exécuter ce qui est dans le if tous les 500ms
Par contre, si je veux que le clignotement commence au bout de 2 minutes par exemple, si je mets "120000" le clignotement débutera au bout de 2' et si oui à quelle fréquence?
Si tu mets 120000, le clignotement commencera au bout de 2 minutes et l'état de la LED changera toutes les deux minutes.

Si tu veux commencer le clignotement au bout de 2 minutes et ensuite toutes les 500 ms, il faut ajouter du code : avoir une variable booléenne que nous appellerons demarrage et initialisée à true par exemple, qui permet de savoir qu'on est au début puis quand 2 minutes sont passées, mettre cette variable à false :

Code : Tout sélectionner

void clignoteLED13()
{
    static byte etatLED13 = LOW;
    static unsigned long date = 0;
    static boolean demarrage = true;

    unsigned long nouvelleDate = millis();

    if (demarrage && nouvelleDate > 120000) {
        demarrage = false;
        date = nouvelleDate;
    }
    else {
        if (nouvelleDate - date > 500) {
            date = nouvelleDate;
            etatLED13 = !etatLED13;
            digitalWrite(13,etatLED13);
        }
    }
}

Sash28
Causant
Messages : 211
Enregistré le : mer. 01 juil. 2009, 07:00
Âge : 45

Re: Inclusion d'un bout de code dans un autre...

Message par Sash28 » mar. 13 janv. 2015, 18:28

Ok ok.
Sans le savoir j'avais commencé à modifier le code en ajoutant justement un if...else. Mais je n'avais pas créé de "boolean" donc rien ne marchait.
Je progresse grâce à toi. Merci encore pour les précisions.
Ca commence à être un peu plus clair dans ma petite tête.

Avatar du membre
jlb
Fécond
Messages : 686
Enregistré le : jeu. 04 oct. 2012, 15:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Inclusion d'un bout de code dans un autre...

Message par jlb » mer. 14 janv. 2015, 15:07

Bonjour,

LOCODUINO vient de publier un article à ce sujet : Comment gérer le temps dans un programme ?

Répondre