nicolasdb / nicolasdb.github.io

My portfolio website as a maker and fabmanager
https://nicolasdb.github.io/
Other
1 stars 4 forks source link

[Badge] - Learning Arduino finite state machine #115

Open nicolasdb opened 5 years ago

nicolasdb commented 5 years ago

So, j'ai déjà une base d'arduino. Je sais comment installer les drivers, comment on le structure, comment uploader du code, le blink, collecter des data via le serial,

Aujourd'hui, j'aimerai et j'ai besoin d'aller plus loin parce que j'ai un job qui va faire appel à du code simple, mais bcp de fois.

image

Il s'agit de 3 grandes catégories:

  1. la surveillance du niveau d'une réserve d'eau et l'activation d'une pompe si le niveau baisse. Code à mettre en boucle.
  2. Focus sur l'échelle de la maquette. Des boutons comme trigger manuel. Un bouton est un déclencheur de scénario qui va ouvrir une suite prédéfinie d' électro-valve, avec l'option d'une led pour attirer l'oeil sur où l'action se passe. 2.1 définir X boutons et leur suite d'actions et timing. 2.2 définir les actions séparément. L'action est dans la maison, et son alentour
  3. La ville et une vie extérieur à la maquette. un Random à la place des bouton, pour simuler une activité extradiégétique du quartier, de la ville. Action principalement dans les collecteurs de rues.

J'ai donc besoin de mieux comprendre le code modulaire et les librairies. Pour faire appel à l'un ou l'autre sans devoir refaire ce qui est fait. https://youtu.be/fE3Dw0slhIc

nicolasdb commented 5 years ago

https://youtu.be/fsMg6F6yYlo

2 Files:

  1. .cpp = source code (fonction)
  2. .h = header file, liste des fonctions, une table des matières en sorte. (data)

+ 2 optionnels keywords.txt et un folder examples

nicolasdb commented 5 years ago

Class = module composé de

nicolasdb commented 5 years ago

cette vidéo était en fait plus claire. Et correspond mieux à ce que je cherche comme exemple concret. https://www.youtube.com/watch?v=HvGJlIKOLoI

Ensuite

La machine à état / finite state machine

nicolasdb commented 5 years ago

ok, donc dans mon cas, si je veux déclencher une suite logique d'évènements/fonction, je pourrais lister mes actions avec enum comme dans

enum {lundi, mardi, mercredi, jeudi, vendredi, samedi, dimanche} jour;

void setup() {
  Serial.begin(115200);
  jour = jeudi;
  Serial.println(jour);
}

void loop() {}
nicolasdb commented 5 years ago

En fait, celui ci en français est parfait.

un bouton, pour controler l'état de 4 leds. 3 excercices pour bien comprendre

nicolasdb commented 5 years ago

A-Level Comp Sci: Finite State Machine https://www.youtube.com/watch?v=4rNYAvsSkwk

nicolasdb commented 5 years ago

OK, ça marche.

2 fonctions différentes.

  1. lecture de l'état du switch REED pour le niveau d'eau. https://circuitdigest.com/microcontroller-projects/arduino-reed-switch-interfacing Si off, alors allumer la pompe via relai.
  2. bouton actif, machine à état. à chaque click, on change l'état d'une variable et suit un programme.

include // on inclut la librairie

const byte reedSwitch = 2; const byte buttonPin = 4; // on définit un nom pour la pin associée au bouton OneButton buttonh(buttonPin, true); // true pour dire qu'on est en INPUT_PULLUP, // donc actif LOW, connecté à GND

// les pins utilisées pour les LEDs const byte pinPump = 12; const byte pinLedRouge = 8; const byte pinLedBleue = 9; const byte pinLedJaune = 10; const byte pinLedBlanche = 11;

// la liste des états possible de notre système // ainsi qu'une variable etatCourant prenant une de ces valeurs enum {REPOS, ETAT_Bl, ETAT_BlJ, ETAT_BlJB, ETAT_BlJBR} etatCourant; int reedStat;

// ------------------------------------------------------ // Cette fonction installe l'état initial // ------------------------------------------------------ void pumpOff() { digitalWrite(pinPump, LOW); etatPump = OFF; } void mettreAuRepos() { digitalWrite(pinLedRouge, LOW); digitalWrite(pinLedBleue, LOW); digitalWrite(pinLedJaune, LOW); digitalWrite(pinLedBlanche, LOW); etatCourant = REPOS; }

// ------------------------------------------------------ // La fonction de call back, appellée automatiquement quand on clique // ------------------------------------------------------ void level() { switch (etatPump) { case OFF: digitalWrite(pinPump, HIGH); etatPump = ON; break;

case ON:
digitalWrite(pinPump, LOW);
etatPump = OFF;
break;

} }

void simpleclick() { switch (etatCourant) { case REPOS: // on était au repos et on a un appui, on allume la verte digitalWrite(pinLedBlanche, HIGH); // LED verte alimentée etatCourant = ETAT_Bl; // on note le nouvel état de notre système break;

case ETAT_Bl: // on était led verte allumée et on a un appui, on allume la jaune
  digitalWrite(pinLedJaune, HIGH); // LED jaune alimentée
  etatCourant = ETAT_BlJ;// on note le nouvel état de notre système
  break;

case ETAT_BlJ: // vert et jaune allumées, on a un appui, on allume la orange
  digitalWrite(pinLedBleue, HIGH); // LED orange alimentée
  etatCourant = ETAT_BlJB;// on note le nouvel état de notre système
  break;

case ETAT_BlJB:// vert, orange et jaune allumées, on a un appui, on allume la rouge
  digitalWrite(pinLedRouge, HIGH); // LED rouge alimentée
  etatCourant = ETAT_BlJBR;// on note le nouvel état de notre système
  break;

case ETAT_BlJBR: // tout était allumé, on a un appui, on retourne au repos
  mettreAuRepos(); // on retourne à l'état initial
  break;

} }

// ------------------------------------------------------ // On initialise notre système dans le setup // ------------------------------------------------------ void setup() { Serial.begin(9600);

pinMode (reedSwitch, INPUT); pinMode (pinLedRouge, OUTPUT); pinMode (pinLedBleue, OUTPUT); pinMode (pinLedJaune, OUTPUT); pinMode (pinLedBlanche, OUTPUT); pinMode (pinPump, OUTPUT);

//conditions Initiales mettreAuRepos(); pumpOff();

// On attache la fonction simpleClick() comme callBack buttonh.attachClick(simpleclick);

}

void loop() { // On vérifie l'état des boutons, ce qui déclenche l'appel de la fonction callBack si nécessaire buttonh.tick();

reedStat = digitalRead(reedSwitch); if (reedStat == 1) etatPump = ON; else etatPump = OFF; Serial.print(reedStat); level(); delay(100); // ici on peut faire autre chose du moment que ça ne prend pas trop longtemps

}

nicolasdb commented 5 years ago
  1. sensor reed IN, loop IF reed = 0; then turn on Pump.

  2. LED! case allX = all OFF, case allO = ready for entry, waiting for action, case push = turn off other button, buton scénario blink, no action till return to allO,

    end scénario = stop blink, switch to allO

  3. bouton 1 IF PUSH; start sceno = 1 sceno 1= valve A ON, wait, OFF, wait; valve C ON, wait, OFF, wait; valve E ON, wait, OFF, wait; valve F ON, wait, OFF, wait;