diff --git a/arduino_proto_threads/tp_dragon/tp_dragon.ino b/arduino_proto_threads/tp_dragon/tp_dragon.ino new file mode 100644 index 0000000..c8c5c70 --- /dev/null +++ b/arduino_proto_threads/tp_dragon/tp_dragon.ino @@ -0,0 +1,155 @@ +/*--------------------------------------------------------------*/ +/* Projet: Atelier proto threads pour l'Arduino */ +/* File : tp_pt.ino */ +/* Author: jearz@HPP 30/07/21 */ +/*--------------------------------------------------------------*/ +/* + Animation de 4 leds suite à l'appui d'un boutton poussoir +*/ + +#define JAUNE 13 // +#define BLEUE 12 // +#define ROUGE 11 // +#define AUTRE 10 // provision +#define VERTE 9 // +#define POUSSOIR 8 // boutton + +#include "pt.h" // version modifiée de l'original +static struct pt ptP, ptR, ptRv, ptJ, ptB, ptVc, ptVd; // proto threads +bool cycle = false; uint16_t periode = 7000; // gestion du cycle +bool degrade = false; int nb_cycles = 0; const int deb_cycle_ko = 10; // 255; + +void initIO() { + pinMode(POUSSOIR, INPUT_PULLUP); + pinMode(ROUGE, OUTPUT); analogWrite(ROUGE, LOW); + pinMode(JAUNE, OUTPUT); digitalWrite(JAUNE, LOW); + pinMode(BLEUE, OUTPUT); digitalWrite(BLEUE, LOW); + pinMode(VERTE, OUTPUT); analogWrite(VERTE, 254); // gauge at max + pinMode(POUSSOIR, INPUT_PULLUP); +} +void setup() { + initIO(); // Setup: set LEDs & boutton + PT_INIT(&ptP); PT_INIT(&ptR); PT_INIT(&ptRv); PT_INIT(&ptJ); + PT_INIT(&ptB); PT_INIT(&ptVc); PT_INIT(&ptVd); +} +/*------------------------------------------------------------------*/ +void ledPWM(uint8_t led, int ratio) { + uint8_t val=constrain(ratio,0,254); // limité à [0..254] + analogWrite(led, val); +} +bool capterPoussoir() { // fonction anti rebonds + int nb=0; + for (int i=0;i<10;i++) { + delay(10); // utiliser un thread ? + nb+= digitalRead(POUSSOIR); // Pullup pin: HIGH <=> button off + } // & LOW <=> button on + return (nb<5) ; // +} +static int ptPoussoir(struct pt *pt) { + static unsigned long started =0; + PT_BEGIN(pt); + while(1) { + PT_WAIT_UNTIL(pt, capterPoussoir() ); // appel fonction anti rebonds + cycle=true; nb_cycles++; // c’est parti pour un tour + if (nb_cycles == deb_cycle_ko ) degrade = true; // mode dégradé actif + started=millis(); + PT_WAIT_UNTIL(pt, millis() - started > periode ); // test fin de cycle + cycle=false; // signale la fin aux autres PT + } + PT_END(pt); +} // ptPoussoir +static int ptVerteD(struct pt *pt, int duree) // Verte en mode dégradé +{ + static unsigned long ttl = 0; + PT_BEGIN(pt); + while ( degrade ) { + ttl = millis() + duree ; + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(VERTE, !digitalRead(VERTE)); + } + PT_END(pt); +} // VerteD +static int ptVerteC(struct pt *pt) // Verte en mode compte à rebours +{ + static uint16_t ratio = 0; + static unsigned long ttl = 0; + PT_BEGIN(pt); + while (! degrade && cycle ) { + ratio = map(nb_cycles, 0, 254, 254, 0); + ledPWM(VERTE, ratio); + ttl = millis() + periode ; + PT_WAIT_UNTIL(pt, millis() > ttl); + } + PT_END(pt); +} // VerteC +static int ptJaune(struct pt *pt, uint16_t offset, uint16_t duree ) +{ + static unsigned long ttl = 0; + PT_BEGIN(pt); + while( ! degrade && cycle ) { + ttl = millis() + offset ; + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(JAUNE, HIGH); + ttl = millis() + duree ; + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(JAUNE, LOW); + PT_WAIT_UNTIL(pt, ! cycle ); + } + PT_END(pt); +} // Jaune +static int ptBleue(struct pt *pt, uint16_t offset, uint16_t duree ) +{ + static unsigned long ttl = 0; + PT_BEGIN(pt); + while( ! degrade && cycle ) { + ttl = millis() + offset ; + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(BLEUE, HIGH); + ttl = millis() + duree ; + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(BLEUE, LOW); + PT_WAIT_UNTIL(pt, ! cycle ); + } + PT_END(pt); +} // bleue +static int ptVarRouge(struct pt *pt, int debut, int fin, int inc, int palier) +{ + static int i=0 ; // static unsigned long ttl = 0; + PT_BEGIN(pt); + ledPWM(ROUGE, debut) ; + do { + PT_DELAY(pt, palier); + i=i+inc; + ledPWM(ROUGE, i) ; + } while (i != fin ); + PT_END(pt); +} // gestion PWM rouge +static int ptRouge(struct pt *pt, uint16_t debut, uint16_t plafond, uint16_t fin) +{ + static unsigned long ttl = 0; + PT_BEGIN(pt); + while ( cycle ) { + ttl = millis() + debut ; + PT_WAIT_THREAD(pt, ptVarRouge(&ptRv,0,254,1,7)); + PT_WAIT_UNTIL(pt, millis() > ttl); + ttl = millis() + plafond ; + digitalWrite(ROUGE, HIGH); + PT_WAIT_UNTIL(pt, millis() > ttl); + ttl = millis() + fin ; + PT_WAIT_THREAD(pt, ptVarRouge(&ptRv,254,0,-1,7)); + PT_WAIT_UNTIL(pt, millis() > ttl); + digitalWrite(ROUGE, LOW); + PT_WAIT_UNTIL(pt, ! cycle ); + } + PT_END(pt); +} // rouge + +void loop() { + int r1=3000, r2=1000, r3=3000, j1=1500, j2=2000, b1=2000, b2=3000; + ptPoussoir(&ptP); // proto thread gestion appui poussoir + ptRouge(&ptR,r1,r2,r3); // proto thread cycle Rouge + ptJaune(&ptJ,j1,j2); // proto thread cycle jaune + ptBleue(&ptB,b1,b2); // proto thread cycle Bleue + ptVerteC(&ptVc); // proto thread Verte compte à rebours + ptVerteD(&ptVd,500); // proto thread Verte mode dégradé +}