Correction fonctions de gestion des icones. Ajout et modification des bitmaps d'icones. Ajout fonction de changement d'icone en cours de déroulement.
378 lines
12 KiB
C++
378 lines
12 KiB
C++
/*-----------------------------------------------------------------------
|
|
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
|
|
* Sleep mode not stable, forum at :
|
|
"https://github.com/earlephilhower/arduino-pico/issues/345"
|
|
-----------------------------------------------------------------------
|
|
Mod: 2026/05/27 added 2 bitmap to sreen saver
|
|
-----------------------------------------------------------------------*/
|
|
#define BUTTONPLUS 14 // PullUp 10K I=.33 mA
|
|
#define BUTTONMINUS 15 // PullUp 10K I=.33 mA
|
|
#define RELAY 27 // Must be < 4mA
|
|
#define PIEZO 8 // 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 SENSOR_HALL
|
|
#define S_HALL 7 // Sense Hall sensor
|
|
//#define ESSAIS
|
|
enum screen_t {sLOGO,sTITRE,sCHOIX,sEXPOS,sREGLE,sDUREE,sINCRE,sSAUVE,sVEILLE,sNONE};
|
|
#ifdef ESSAIS
|
|
int16_t defaultTime=80, stepTime=5, timeOut=3; // expo & setting time
|
|
int16_t snoozeTimeOut=6;
|
|
#else
|
|
int16_t defaultTime=180, stepTime=10, timeOut=4;
|
|
int16_t snoozeTimeOut=60; //60
|
|
#endif
|
|
int16_t greetTime=2000;
|
|
// display limit to 999s => 16mn 39s
|
|
volatile uint16_t setTime=defaultTime;
|
|
volatile uint16_t downTime; // count down time
|
|
volatile uint16_t lastSetTime, lastStepTime, time2save=0;
|
|
volatile boolean plusPushed=false; volatile boolean minusPushed=false;
|
|
char sMsg[16];
|
|
screen_t screen=sNONE;
|
|
#include <EEPROM.h>
|
|
#include "displays.h" // Oled functions & led RGB
|
|
#include "pt.h" // proto threads
|
|
//#include "scroll.h" // circular buffer for displays
|
|
#define h42 0x2A
|
|
#define h43 0x2B
|
|
#define add42 254
|
|
#define add43 255
|
|
|
|
/*----------------- CPU 0 ---------------------------------*/
|
|
void die() {ledRGB(RED); for(;;); }
|
|
bool isRamSet() {
|
|
byte val1,val2;
|
|
EEPROM.begin(256);
|
|
//clearRAM();
|
|
val1 = EEPROM.read(add42);
|
|
val2 = EEPROM.read(add43);
|
|
if (val1==h42 && val2==h43) return true; // allready writed
|
|
EEPROM.write(add42, h42); // 42
|
|
EEPROM.write(add43, h43); // 43
|
|
EEPROM.put(0, setTime);
|
|
EEPROM.put(4, stepTime);
|
|
EEPROM.commit(); // WIP? if (EEPROM.commit()) { do something ? }
|
|
return false;
|
|
}
|
|
void SetTime2RAM() {
|
|
EEPROM.put(0, setTime); EEPROM.commit();
|
|
}
|
|
void StepTime2RAM() {
|
|
EEPROM.put(4, stepTime); EEPROM.commit();
|
|
}
|
|
void clearRAM() {
|
|
for(int addr = 0; addr < 256; addr++) {
|
|
EEPROM.write(addr, 0);
|
|
}
|
|
EEPROM.commit();
|
|
}
|
|
void setup() {
|
|
showInit();
|
|
sprintf(sMsg,"Value");
|
|
// read memory
|
|
if (isRamSet()) { // setting values to be found in memory
|
|
EEPROM.get(0, setTime);
|
|
EEPROM.get(4, stepTime);
|
|
#ifdef ESSAIS
|
|
char l1[16], l2[16], l3[16];
|
|
sprintf(l1,"RAM time values");
|
|
sprintf(l2,"set: %3ds",setTime);
|
|
sprintf(l3,"step: %3ds",stepTime);
|
|
showInfo(l1, l2, l3);
|
|
delay(5000);
|
|
#endif
|
|
}
|
|
// EEPROM.end();
|
|
lastSetTime=setTime;
|
|
lastStepTime=stepTime;
|
|
showLOGO(greetTime);
|
|
minusPushed=false; plusPushed=false; // in case button pushed while LOGO
|
|
screen=sTITRE;
|
|
}
|
|
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;
|
|
case sSAUVE : showSAUVE(time2save,sMsg); break;
|
|
case sVEILLE : delay(100); break; // snooze screen
|
|
case sNONE : delay(100); break; // nothing to change yet, waiting for next screen
|
|
default : ledRGB(RED); delay(6000); break;// Code error
|
|
}
|
|
delay(100);
|
|
}
|
|
/*----------------- CPU 1 ---------------------------------*/
|
|
// ProtoThreads local continuation structure
|
|
static pt_t pMINUS,pPLUS,pALARM,pTITRE,pCHOIX,pEXPOS,
|
|
pREGLE,pDUREE,pINCRE,pSAUVE,pVEILLE;
|
|
|
|
void setup1() { // CPU 1 to manage buttons
|
|
// ProtoThreads continuation structure is set to 0
|
|
PT_INIT(&pMINUS); PT_INIT(&pPLUS); PT_INIT(&pALARM);
|
|
PT_INIT(&pTITRE); PT_INIT(&pCHOIX); PT_INIT(&pEXPOS);
|
|
PT_INIT(&pREGLE); PT_INIT(&pINCRE); PT_INIT(&pDUREE);
|
|
PT_INIT(&pSAUVE); PT_INIT(&pVEILLE);
|
|
// IO
|
|
pinMode(BUTTONMINUS, INPUT_PULLUP); pinMode(BUTTONPLUS, INPUT_PULLUP);
|
|
pinMode(RELAY, OUTPUT); digitalWrite(RELAY, LOW);delay(500);
|
|
|
|
#ifdef SENSOR_HALL
|
|
pinMode (S_HALL, INPUT_PULLUP); // Enable pull-up as sensor output is open collector
|
|
#endif
|
|
}
|
|
|
|
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(pAlarm(pt_t *lc)) { //WIP
|
|
PT_BEGIN(lc);
|
|
// PT_WAIT_UNTIL(lc, (screen==sEXPOS) );
|
|
if (digitalRead(S_HALL))
|
|
ledRGB(RED);
|
|
else
|
|
ledRGB(GREEN);
|
|
PT_DELAY(lc, 400); // reading hall sensor
|
|
// PT_WAIT_UNTIL(lc, digitalRead(S_HALL));// Pullup pin: switch <=> magnet
|
|
// digitalWrite(RELAY, LOW ); }
|
|
PT_END(lc);
|
|
}
|
|
static PT_THREAD(pTitre(pt_t *lc)) {
|
|
PT_BEGIN(lc);
|
|
PT_WAIT_UNTIL(lc, (screen==sTITRE));
|
|
ledRGB(GREEN);
|
|
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
|
|
static unsigned long ttl,to= snoozeTimeOut * 1000;
|
|
PT_BEGIN(lc);
|
|
PT_WAIT_UNTIL(lc, (screen==sCHOIX));
|
|
ledRGB(ORANGE);
|
|
minusPushed=false; plusPushed=false;
|
|
ttl=millis()+to;
|
|
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed || (millis() > ttl) ) );
|
|
if (minusPushed) { minusPushed=false; screen=sEXPOS; }
|
|
if (plusPushed) { plusPushed=false; screen=sREGLE; }
|
|
if (millis() > ttl) screen=sVEILLE; //screen=sTITRE; //
|
|
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
|
|
if (plusPushed) {
|
|
plusPushed=false;
|
|
if (downTime < 1000 - stepTime) downTime += stepTime;
|
|
}
|
|
PT_DELAY(lc, 600);
|
|
downTime -=1;
|
|
if (minusPushed) { minusPushed=false; downTime = 0; }
|
|
PT_DELAY(lc, 310);
|
|
playClk(); // this take ~100ms
|
|
} while ( downTime > 0);
|
|
digitalWrite(RELAY, LOW );
|
|
screen=sCHOIX;
|
|
ledRGB(ORANGE);
|
|
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);
|
|
lastStepTime = stepTime;
|
|
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=sNONE;
|
|
} while (screen==sINCRE);
|
|
if (lastStepTime == stepTime) screen=sREGLE;
|
|
else { sprintf(sMsg,"Step:"); screen=sSAUVE; }
|
|
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);
|
|
lastSetTime = setTime;
|
|
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=sNONE;
|
|
} while (screen==sDUREE);
|
|
if (lastSetTime == setTime) screen=sREGLE;
|
|
else { sprintf(sMsg,"Time:"); screen=sSAUVE; }
|
|
PT_END(lc);
|
|
}
|
|
static PT_THREAD(pSauve(pt_t *lc)) { //
|
|
static unsigned long ttl, to;
|
|
to = (timeOut+4) * 1000;
|
|
PT_BEGIN(lc);
|
|
PT_WAIT_UNTIL(lc, (screen==sSAUVE) );
|
|
if (lastSetTime != setTime) time2save=setTime; // value for screen sSAUVE
|
|
else if (lastStepTime != stepTime) time2save=stepTime;
|
|
ledRGB(ROSE);
|
|
PT_DELAY(lc, 1000);
|
|
ttl=millis()+to;
|
|
do {
|
|
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed || (millis() > ttl)) );
|
|
if (plusPushed) {
|
|
if (lastSetTime != setTime) SetTime2RAM();
|
|
if (lastStepTime != stepTime) StepTime2RAM();
|
|
sprintf(sMsg,"done");
|
|
PT_DELAY(lc, 2000);
|
|
screen=sREGLE;
|
|
}
|
|
if (millis() > ttl || minusPushed) screen=sREGLE;
|
|
} while (screen==sSAUVE );
|
|
time2save=0;
|
|
PT_END(lc);
|
|
}
|
|
|
|
static PT_THREAD(pVeille(pt_t *lc)) { // OK and avoid bounces
|
|
const int nbSprites = 10;
|
|
static t_iconMvt icons[nbSprites];
|
|
static t_sprite sprite;
|
|
static uint16_t nbpass=0;
|
|
PT_BEGIN(lc);
|
|
PT_WAIT_UNTIL(lc, (screen==sVEILLE));
|
|
ledRGB(NONE);
|
|
|
|
initSprite(&sprite,nbSprites,16,16, flake_bmp, icons); // load values to sprite
|
|
do {
|
|
drawSprite(&sprite);
|
|
PT_DELAY(lc, 40);
|
|
if (!(plusPushed || minusPushed)) {
|
|
oled.display();
|
|
PT_DELAY(lc, 40);
|
|
updateSprite(&sprite); // update coordinates of each sprite
|
|
}
|
|
nbpass = changeSprite(&sprite, nbpass);
|
|
} while (!(plusPushed || minusPushed ));
|
|
|
|
minusPushed=false; plusPushed=false;
|
|
oled.clearDisplay();
|
|
PT_DELAY(lc, 200);
|
|
screen=sTITRE; // sCHOIX;//
|
|
PT_END(lc); // to try: exit & return flag ?
|
|
}
|
|
|
|
void loop1() { // CPU 1 dedicated to run threads
|
|
pMinus (&pMINUS); // process minus button
|
|
pPlus (&pPLUS); // process plus button
|
|
// pAlarm (&pALARM); // WIP
|
|
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
|
|
pSauve (&pSAUVE); // process screen SAUVE
|
|
pVeille(&pVEILLE); // process screen saver
|
|
}
|
|
/*
|
|
* code debug
|
|
Serial.begin(115200); delay(500); Serial.printf("CPU 0 on\n");
|
|
Serial.printf("CPU 1 on\n");
|
|
*/
|