Première version du code du minuteur et schéma d'implantation.

This commit is contained in:
2026-05-08 00:37:26 +02:00
parent da3fa03aff
commit 71753703e8
9 changed files with 825 additions and 0 deletions

252
minuteur/minuteur.ino Normal file
View File

@@ -0,0 +1,252 @@
/*-----------------------------------------------------------------------
Project: InsoL@b
Author : user@B0 mail@nowhere.void
File : minuteur.ino 2026-04-19
This work is copyrighted under the CERN Open Hardware Licence Version 2.
-------------------------------------------------------------------------
Serial port not available ? sudo fuser -k /dev/ttyACM0 & RST or Boot
-------------------------------------------------------------------------
* Power on: Greeting screen LOGO waits for timout and go to screen TITRE
- Show InsoL@b logo
* screen TITRE
- Show title & wait for any button to continue to Screen CHOIX
* Screen CHOIX
- displays default/curent exposure time
- minus button go to screen EXPO exposure timing sequence
- plus button go to setting screen REGLE
* Screen EXPO
- UV exposure
- display count down, minus button to stop, plus to increment time
- when done exit back to screen CHOIX
* Screen REGLE
- minus button go to screen INCRE
- plus button go to screen DUREE
- return to caller on time out
* Screen DURE
- minus decrement exposure time
- plus increment exposure time
- return to caller on time out
* Screen INCRE
- minus decrement step value
- plus increment step value
- return to caller on time out
-----------------------------------------------------------------------*/
#define BUTTONPLUS 14 // PullUp 10K I=.33 mA
#define BUTTONMINUS 15 // PullUp 10K I=.33 mA
#define RELAY 27 // Must be < 4mA
#define PIEZO 28 // Used by anyrtttl.h in bitmaps.h
/* I2C SDA & CLK PullUp 2*10K I=.66 mA
Sur le RP2040 le défaut du courant de sortie est limité à 4mA/broche IO,
C'est configurable par logiciel pour atteindre 2mA, 8mA ou 12mA.
Le courant maximal combiné que toutes les broches GPIO peuvent sourcer ou
absorber est limité à 50 mA. Au total le courant total doit être < à 50mA.
*/
//#define ESSAIS
enum screen_t {sLOGO,sTITRE,sCHOIX,sEXPOS,sREGLE,sDUREE,sINCRE,sNONE};
#ifdef ESSAIS
int16_t defaultTime=80, stepTime=5, timeOut=3; // expo & setting time
#else
int16_t defaultTime=180, stepTime=10, timeOut=2;
#endif
int16_t greetTime=1000;
// display limit to 999s => 16mn 39s
volatile uint16_t setTime=defaultTime;
volatile uint16_t downTime; // count down time
screen_t screen=sTITRE;
#include "displays.h" // Oled functions & led RGB
#include "pt.h" // proto threads
//#include "scroll.h" // circular buffer for displays
/*----------------- CPU 0 ---------------------------------*/
void die() {ledRGB(RED); for(;;); }
void setup() { showInit(); showLOGO(greetTime); ledRGB(GREEN);
}
void loop() { // CPU 0 dedicated to refresh display
// TODO not recall screen if values did not change
switch(screen) {
case sTITRE : showTITRE(); break;
case sCHOIX : showCHOIX(setTime); break;
case sEXPOS : showEXPOS(downTime,stepTime); break;
case sREGLE : showREGLE(); break;
case sDUREE : showDUREE(setTime); break;
case sINCRE : showINCRE(stepTime); break;
default : ledRGB(RED); delay(3000); break; // Code error
}
delay(100);
}
/*----------------- CPU 1 ---------------------------------*/
// ProtoThreads local continuation structure
static pt_t pMINUS, pPLUS, pTITRE, pCHOIX, pEXPOS, pREGLE, pDUREE, pINCRE;
volatile boolean plusPushed=false; volatile boolean minusPushed=false;
void setup1() { // CPU 1 to manage buttons
// ProtoThreads continuation structure is set to 0
PT_INIT(&pMINUS); PT_INIT(&pPLUS);
PT_INIT(&pTITRE); PT_INIT(&pCHOIX); PT_INIT(&pEXPOS);
PT_INIT(&pREGLE); PT_INIT(&pINCRE); PT_INIT(&pDUREE);
// IO
pinMode(BUTTONMINUS, INPUT_PULLUP); pinMode(BUTTONPLUS, INPUT_PULLUP);
pinMode(RELAY, OUTPUT); digitalWrite(RELAY, LOW);delay(500);
}
static PT_THREAD(pPlus(pt_t *lc)) { // OK and avoid bounces
PT_BEGIN(lc); // lc=local continuation byte, here set to previous call value
while (1) {
PT_WAIT_UNTIL(lc, digitalRead(BUTTONPLUS) == LOW); // lc set to __LINE__
plusPushed=true;
}
PT_END(lc); // to try: exit & return flag ?
}
static PT_THREAD(pMinus(pt_t *lc)) {
PT_BEGIN(lc);
while (1) {
PT_WAIT_UNTIL(lc, digitalRead(BUTTONMINUS) == LOW);
minusPushed=true;
}
PT_END(lc);
}
static PT_THREAD(pTitre(pt_t *lc)) {
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sTITRE));
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed ));
minusPushed=false; plusPushed=false;
screen=sCHOIX;
PT_DELAY(lc, 100);
PT_END(lc);
}
static PT_THREAD(pChoix(pt_t *lc)) { // TODO sleep & wake up
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sCHOIX));
ledRGB(ORANGE);
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed ) );
if (minusPushed) { minusPushed=false; screen=sEXPOS; }
if (plusPushed) { plusPushed=false; screen=sREGLE; }
PT_DELAY(lc, 100);
PT_END(lc);
}
static PT_THREAD(pExpos(pt_t *lc)) { // run count down UV light OK
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sEXPOS) );
ledRGB(PINK);
downTime = setTime;
playRTTTL(sCHOIX);
digitalWrite(RELAY, HIGH);
minusPushed=false; plusPushed=false;
do { // count down loop
// playRTTTL(sCOUNT); send flag to CPU 0 ? or non blocking RTTTL
if (plusPushed) {
plusPushed=false;
if (downTime < 1000 - stepTime) downTime += stepTime;
}
PT_DELAY(lc, 800);
downTime -=1;
if (minusPushed) { minusPushed=false; downTime = 0; }
PT_DELAY(lc, 200);
} while ( downTime > 0);
digitalWrite(RELAY, LOW );
screen=sCHOIX;
playRTTTL(sEXPOS);
PT_END(lc);
}
static PT_THREAD(pRegle(pt_t *lc)) { // OK
static unsigned long ttl,to=500 + timeOut * 1000;
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sREGLE) );
ledRGB(YELLOW);
minusPushed=false; plusPushed=false;
ttl=millis()+to;
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed || (millis() > ttl) ) );
if (plusPushed) { plusPushed=false; screen=sDUREE; }
else if (minusPushed) { minusPushed=false; screen=sINCRE; }
if (millis() > ttl) screen=sCHOIX;
PT_DELAY(lc, 100);
PT_END(lc);
}
static PT_THREAD(pIncre(pt_t *lc)) { // OK
static unsigned long ttl, to=timeOut * 1000;
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sINCRE) );
ledRGB(BLUE);
PT_DELAY(lc, 1000);
ttl=millis()+to;
minusPushed=false; plusPushed=false;
do {
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed || (millis() > ttl)) );
if (plusPushed) {
plusPushed=false;
if (stepTime < 999) stepTime += 1 ;
ttl=millis()+to;
} else
if (minusPushed) {
minusPushed=false;
if (stepTime >1) stepTime-= 1 ;
ttl=millis()+to;
}
if (millis() > ttl) screen=sREGLE;
} while (screen==sINCRE);
PT_END(lc);
}
static PT_THREAD(pDuree(pt_t *lc)) { // OK
static unsigned long ttl, to=timeOut * 1000;
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sDUREE) );
ledRGB(FUCHS);
PT_DELAY(lc, 1000);
ttl=millis()+to;
do {
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed || (millis() > ttl)) );
if (plusPushed) {
plusPushed=false;
if (setTime < 1000 - stepTime) setTime += stepTime ;
ttl=millis()+to;
}
if (minusPushed) {
minusPushed=false;
if (setTime > stepTime) setTime -= stepTime ;
ttl=millis()+to;
}
if (millis() > ttl) screen=sREGLE;
} while (screen==sDUREE);
PT_END(lc);
}
void loop1() { // CPU 1 dedicated to run threads
pMinus (&pMINUS); // process minus button
pPlus (&pPLUS); // process plus button
pTitre (&pTITRE); // process screen TITRE
pChoix (&pCHOIX); // process screen CHOIX
pExpos (&pEXPOS); // process screen EXPOS
pRegle (&pREGLE); // process screen REGLE
pIncre (&pINCRE); // process screen INCRE
pDuree (&pDUREE); // process screen DUREE
}
/*
* provisions
#include <EEPROM.h>
v
void setup() {
EEPROM.begin(512);
// write a 0 to all 512 bytes of the EEPROM
for (int i = 0; i < 512; i++) {
EEPROM.write(i, 0);
}
// turn the LED on when we're done
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
EEPROM.end();
}
void loop() {
static int x = 0;
Serial.printf("C1: Stay on target...\n");
val++;
if (++x < 10) {
EEPROM.begin(512);
EEPROM.write(0,x);
EEPROM.commit();
}
delay(1000);
}
* code debug
Serial.begin(115200); delay(500); Serial.printf("CPU 0 on\n");
Serial.printf("CPU 1 on\n");
*/