Divers ajouts et correctifs

ajout sauvegarde en flash
et ajout écran de veille
This commit is contained in:
2026-05-22 00:35:39 +02:00
parent 71753703e8
commit 41fdaaa1ae
8 changed files with 357 additions and 108 deletions

View File

@@ -63,6 +63,9 @@ const char * _finish_=
const char * _logo_ = "Star Trek:o=5,d=16,b=63,b=63:8f.,a#,4d#6.,8d6,a#.,g.,c6.,4f6";
const char * _neon_ =
"Neonligh:d=4,o=5,b=100:8e#7,16p,16d#7,8d#7,8p,16c#7,8c#6,16a#6,8e#7,16p,16d#7,8d#7,8p,8c#7,16a#6,8e#7,16p,16a#6,8a#6,8p,16c#7,8d#7,16e#7,8e#7,16p,8d#7";
const char * _com_ = "Communic:d=4,o=5,b=100:16g#7,8a#7,16a#7,16a#7,8f#7";
const char * _pop_ = "Popcorn:d=1,o=5,b=800:8c6,8a#,8c6,8g,8d#,8g,c6";
const char * _clk_ = "clock:d=16,o=8,b=420:b7,32p,c";
void playRTTTL (screen_t itune){
//#ifdef SOUND_ON
@@ -71,32 +74,42 @@ void playRTTTL (screen_t itune){
return;
case sLOGO : anyrtttl::blocking::play(PIEZO, _logo_); break;
case sTITRE : ; break; //rtune = _missip1_
case sCHOIX : anyrtttl::blocking::play(PIEZO, _neon_); break;
case sCHOIX : anyrtttl::blocking::play(PIEZO, _com_); break;
case sEXPOS : anyrtttl::blocking::play(PIEZO, _finish_); break;
case sREGLE : ; break; //tune = _count_
default : ; break;
}
}
void playPop(){ anyrtttl::blocking::play(PIEZO, _pop_);}
void playClk(){ anyrtttl::blocking::play(PIEZO, _clk_);}
// Snooze screen saver
#define SNOOZE_HEIGHT 16
#define SNOOZE_WIDTH 16
#define XPOS 0 // Indexes into the 'icons' array in function below
#define YPOS 1
#define DELTAY 2
#define _DISPLAYWIDTH 128
#define _DISPLAYHEIGHT 32
#define FLOCONS 4 // snowflakes in animation
const unsigned char flake_bmp [] PROGMEM = {
0x01, 0x80, 0xc3, 0xc3, 0xe3, 0xc7, 0xfb, 0xdf, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0,
0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0xfb, 0xdf, 0xe3, 0xc7, 0xc3, 0xc3, 0x01, 0x80
};
// 'smiley', 16x16px
const unsigned char smiley_bmp [] PROGMEM = {
0x07, 0xc0, 0x1f, 0xf0, 0x3f, 0xf8, 0x7f, 0xfc, 0x63, 0x8c, 0xdd, 0x76, 0xd3, 0x96, 0xe7, 0xce,
0xff, 0xfe, 0xfd, 0x7e, 0x6f, 0xec, 0x73, 0x9c, 0x3c, 0x78, 0x1f, 0xf0, 0x07, 0xc0, 0x00, 0x00
};
// 'frown', 16x16px
const unsigned char frown_bmp [] PROGMEM = {
0x07, 0xc0, 0x1f, 0xf0, 0x3f, 0xf8, 0x67, 0xcc, 0x53, 0x94, 0xdd, 0x76, 0xd9, 0x36, 0xe1, 0x0e,
0xff, 0xfe, 0xff, 0xfe, 0x78, 0x3c, 0x73, 0x9c, 0x37, 0xd8, 0x1f, 0xf0, 0x07, 0xc0, 0x00, 0x00
};
//sprite_t smiley = { 6, 16, 16, 0, 1, 2, smiley_bmp };
//sprite_t frown = { unsigned short c6, 16, 16, 0, 1, 2, frown_bmp };
/*
// flower
static const unsigned char PROGMEM flower_bmp[] = {
0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 };
*/
#endif // _INSOLAB_BITMAP_H_

View File

@@ -10,17 +10,17 @@ digraph InsoLab {
graph [
rankdir=TB, // Top Bottom, BT,LR,Rl
overlap=false, splines=true, sep="+0.5",
ranksep=1.4, // in top down mode => Vert distance between nodes
nodesep=1.4, // in top down mode => horz distance between nodes
ranksep=1.8, // in top down mode => Vert distance between nodes
nodesep=1.6, // in top down mode => horz distance between nodes
fontname="Arial", fontsize=50,
style=filled, fillcolor="#FFC0A0", color = "#FFC0A0"
];
size="7,6"; // h,l
size="7,8"; // h,l
pad=1; // margins / clusters
label="\nDiagramme d'enchaînement des écrans.";
subgraph cluster_ecrans {
fontsize=60;
fontsize=70;
style=filled; fillcolor="#FFFFFF";
label="Le minuteur de l'InsoL@b\n";
color = "#FFFFFF";//"#FFC0A0";//"#FFFFFF";
@@ -29,49 +29,57 @@ subgraph cluster_ecrans {
node [ shape=box,style="filled,setlinewidth(2)",fontsize=30,
afixedsize=true, height=2.5, width=3.8 ];
edge [style="filled,setlinewidth(8)" fontsize=30 arrowsize=2 ]
CHOIX [label="CHOIX\nBoutton avec:\n- exposer UV\n+ régler durées",
CHOIX [label="CHOIX\nBouton avec:\n- exposer UV\n+ régler durées",
fillcolor="#FFA550"];
EXPOS [label="EXPOS\nDécompte de\nla durée avec\nexposition UV",
EXPOS [label="EXPOS\nDécompte durée UV\n- abandon\n+ ajout incrément",
fillcolor="#FFC0CB:#FF69B4", style=radial];
REGLE [label="REGLE\nRéglages avec:\n- changer le pas\n+ changer la durée",
fillcolor="#FFF080"] ;
SAUVE [label="SAUVE\n- non quitter\n+ oui sauver en\nFlash & quitter", fillcolor="#ffcec4"];
node [ shape=box,style="filled,setlinewidth(2)",fontsize=30,
afixedsize=true, height=1.8, width=3.8 ];
LOGO [label="LOGO\nÉcran d'accueil\naffiché 4s", fillcolor="#FFFFFF"];
TITRE [label="TITRE\nAttente appui\nd'un boutton", fillcolor="#7CFC60"];
LOGO [label="LOGO\nAccueil & lecture\nréglages en Flash", fillcolor="#FFFFFF"];
TITRE [label="TITRE\nAttente appui\nd'un bouton", fillcolor="#7CFC60"];
DUREE [label="DUREE\nChange la\ndurée sous UV", fillcolor="#FF98FF"] ;
INCRE [label="INCRE\nChange le pas\nréglant la durée", fillcolor="aqua"];
{ rank = same LOGO TITRE INCRE }
{ rank = same EXPOS CHOIX REGLE } //node [group = "R"] //REGLE; DUREE; INCRE;
{ rank = same EXPOS CHOIX REGLE SAUVE} //node [group = "R"] //REGLE; DUREE; INCRE;
node [shape=box, afixedsize=true, height=.7, width=3.8];
Réveil ; Veille;//[shape=box, afixedsize=true, height=.8, width=3.8];
/* ================================ Arcs ================================*/
VCC:s -> LOGO:n [ taillabel ="Mise\nsous\ntension " ];
Réveil:s -> TITRE:n [ taillabel= "\nSortie \nde veille ",label=" Bouton +" ];
Réveil:s -> TITRE:n [ taillabel= "\nSortie \nde veille ",label=" Bouton + ou -",
taillabel= "\nSortie \nde veille "];
LOGO:e -> TITRE:w [ taillabel =" Fin délai\n" ];
TITRE:e -> INCRE:w [ style=invis];
TITRE:s -> CHOIX:n [ taillabel ="\nBoutton + " ] ;
CHOIX:w -> EXPOS:e [ taillabel ="\nBoutton - " ];
CHOIX:e -> REGLE:w [ taillabel =" Boutton +" ] ;
TITRE:s -> CHOIX:n [ taillabel ="\nBouton + ou - " ] ;
CHOIX:nw -> EXPOS:ne [ label ="Bouton -" ];
CHOIX:ne -> REGLE:nw [ label ="Bouton +" ] ;
CHOIX:s -> Veille:n [
taillabel= "\nMise en veille au\ndélai d'activité expiré " ];
EXPOS:n -> CHOIX:nw [ taillabel ="Fin du\ndécompte\n" ];
headlabel= "\nDélai\nsans activité \n expiré " ];
EXPOS:se -> CHOIX:sw [ headlabel ="Fin\ndécompte \n\n" ];
EXPOS:n -> LOGO:s [ style=invis];
REGLE:n -> INCRE:s [ taillabel=" - \n\n" ];
REGLE:s -> CHOIX:se [ taillabel ="\nFin délai inactif " ];
REGLE:sw -> CHOIX:se [ headlabel ="\n Fin délai\n inactif" ];
REGLE:s -> DUREE:n [ taillabel="\n + " ];
INCRE:w -> INCRE:nw [ taillabel="- " ];
INCRE:e -> INCRE:ne [ taillabel=" +" ];
INCRE:se -> REGLE:ne [ headlabel="\n\n Fin\n délai" ];
DUREE:w -> DUREE:sw [ taillabel="- \n\n" ];
DUREE:e -> DUREE:se [ taillabel=" +\n\n" ];
DUREE:ne -> REGLE:se [ headlabel=" Fin\n délai" ];
INCRE:w -> INCRE:w [ label="- " ];
INCRE:n -> INCRE:n [ label="+" ];
INCRE:se -> REGLE:ne [ label=" Fin délai" ];
DUREE:w -> DUREE:w [ label="- " ];
DUREE:s -> DUREE:s [ taillabel="\n +" ];
DUREE:ne -> REGLE:se [ label=" Fin délai" ];
INCRE:ne -> SAUVE:n [ label=" Fin délai\n & modif" ];
DUREE:se -> SAUVE:s [ label=" Fin délai\n & modif" ];
SAUVE:w -> REGLE:e [ taillabel="- \nou \n+ " ];
{ rank = same Veille DUREE };
EXPOS -> Veille [ style=invis];
Veille:e -> DUREE:w [ style=invis];
REGLE:e -> SAUVE:w [ style=invis];
// n e s w = top right bottom left decorate=true =>line between label & edge
} // cluster_ecrans
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -16,7 +16,6 @@
#include <Wire.h>
#include <Adafruit_GFX.h>
// Declaration for SSD1306 display on I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// Default on RP2040 Zero: SDA GPIO 4 SCL GPIO 5
@@ -26,17 +25,28 @@
#ifdef ESSAIS
#define OLED_HEIGHT 64 // OLED display height, in pixels
#define OLED_ADR 0x3D //Address 0x3D/0x3C to 128x64, 0x3C to 128x32
#define OLED_ADR 0x3C //0x3D //Address 0x3D/0x3C to 128x64, 0x3C to 128x32
#else
#define OLED_HEIGHT 32 // OLED display height, in pixels
#define OLED_ADR 0x3C
#define OLED_ADR 0x3C // 0x3C
#endif
Adafruit_SSD1306 oled(OLED_WIDTH, OLED_HEIGHT, &Wire, OLED_RST);
char _oledmsg[32]; // general purpose character buffer
void showInfo(char* l1, char* l2, char* l3) {
oled.clearDisplay();
oled.setTextSize(1); oled.setTextColor(SSD1306_WHITE);
oled.setCursor(0,0);
sprintf(_oledmsg,"%s",l1);
oled.println(_oledmsg);
sprintf(_oledmsg,"%s",l2);
oled.println(_oledmsg);
sprintf(_oledmsg,"%s",l3);
oled.println(_oledmsg);
oled.display();
}
void showTxt1(uint8_t x, uint8_t y, char* txt) {
oled.clearDisplay();
oled.setTextSize(1); oled.setTextColor(SSD1306_WHITE);
oled.setCursor(x,y); // O,0 at top-left corner
sprintf(_oledmsg,"CR:%s",txt);
@@ -51,23 +61,27 @@ void showText(String l1, String l2) {
}
void showInit() {
ledInit(); ledRGB(BLANK); //ledRGB(RED);
ledInit(); ledRGB(BLANK);// ledRGB(BLANK); //ledRGB(RED);//
if(!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADR)) {
Serial.begin(115200); delay(100);
Serial.println(F("SSD1306 allocation failed"));
ledRGB(RED);
for(;;); // Don't proceed, loop forever
}
// setRotation(0)->point(0,0) is close to pin SDA
oled.clearDisplay();
oled.setRotation(2); // 2->point(0,0) is opposite of pins, 1&3 are vertical
//sprintf(_oledmsg, "SSD1306 @ %2d OK", OLED_ADR); oledTxt1(0,0,_oledmsg);
delay(100); // Serial.println(_oledmsg);
}
void showLOGO(int16_t gt) { /*--------- logo on SSD1306 -------------*/
oled.clearDisplay();
oled.clearDisplay(); oled.invertDisplay(true);
oled.drawBitmap(
LOGO_X0, LOGO_Y0,logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, LOGO_COLOR);
oled.display();
playRTTTL(sLOGO);
delay(gt);
delay(gt);
oled.invertDisplay(false);
}
void showTITRE() { // TextSize(2)=>10char, TextSize(1)=>22char,
oled.clearDisplay();
@@ -98,9 +112,9 @@ void showEXPOS(uint16_t t, int16_t m) {
void showREGLE() {
oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE);
oled.setCursor(0,0); oled.setTextSize(2);
oled.println(F("Set values"));
oled.println(F("Set times"));
oled.setCursor(0,18); oled.setTextSize(1);
sprintf(_oledmsg,"- UVtime, + step time"); oled.println(_oledmsg);
sprintf(_oledmsg," - step, + expo UV"); oled.println(_oledmsg);
oled.display();
}
void showDUREE(uint16_t t) {
@@ -119,4 +133,55 @@ void showINCRE(uint16_t t) {
sprintf(_oledmsg,"- less, + more"); oled.println(_oledmsg);
oled.display();
}
void showSAUVE(uint16_t t, char* txt) {
oled.clearDisplay(); oled.setTextColor(SSD1306_WHITE);
oled.setCursor(0,0); oled.setTextSize(2);
sprintf(_oledmsg,"%s %3ds",txt,t); oled.println(_oledmsg);
oled.setCursor(0,18); oled.setTextSize(1);
sprintf(_oledmsg,"- quit, + save"); oled.println(_oledmsg);
oled.display();
}
typedef struct s_iconMvt {
int xp,yp,dy;
} t_iconMvt;
typedef struct s_sprite {
int count, h, w, x, y, dy;
const unsigned char *bmp;
t_iconMvt *iconsMvt;
} t_sprite ;
void initSprite(t_sprite *s, int c, int h, int w, int x, int y, int dy, const unsigned char *bmp,t_iconMvt *iconsMvt) {
//t_iconMvt iconsMvt[c]; //WIP malloc ?? || Arg
s->count=c; s->h=h; s->w=w; s->x=x; s->y=y; s->dy=dy;
for(int i=0; i< s->count; i++) {
iconsMvt[i].xp = random(1 - s->w, OLED_WIDTH);
iconsMvt[i].yp = -s->h;
iconsMvt[i].dy = random(1, 6);
}
s->bmp=bmp;
s->iconsMvt= iconsMvt;
}
void drawSprite(t_sprite *s, Adafruit_SSD1306 d) {
//int8_t iconsMvt[FLOCONS][3];
d.clearDisplay();
for(int i=0; i < s->count; i++) {
d.drawBitmap(
s->iconsMvt[i].xp, s->iconsMvt[i].yp, s->bmp, s->w, s->h, SSD1306_WHITE);
}
//d.display(); // Show the display buffer on the screen
}
void updateSprite(t_sprite *s) {
for(int i=0; i < s->count; i++) {
s->iconsMvt[i].yp += s->iconsMvt[i].dy;
// If sprite is off the bottom of the screen...
if (s->iconsMvt[i].yp >= OLED_HEIGHT) {
// Reinitialize to a random position, just off the top
s->iconsMvt[i].xp = random(1 - s->w, OLED_WIDTH);
s->iconsMvt[i].yp = -s->h; // HEIGHT
s->iconsMvt[i].dy = random(1, 6);
}
} // f=0; f< sprites.count; f++)
}
#endif // _INSOLAB_DISPLAYS_H_

View File

@@ -19,9 +19,9 @@ Purple #800080 50% 0% 50% 300° 100% 25% 100% 50% 05 (low magenta)
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(
NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
enum {NONE, RED, YELLOW, ORANGE, GREEN, BLUE, PINK, FUCHS, BLANK};
enum {NONE, RED, ROSE, YELLOW, ORANGE, GREEN, BLUE, PINK, FUCHS, BLANK};
int ledColor = NONE;
int ledMax=2;
int ledMax=6;
void ledInit() {
pixels.begin();
@@ -33,19 +33,21 @@ void ledRGB(int rgb) {
switch (rgb) {
case RED: pixels.setPixelColor(0, pixels.Color(ledMax, 0, 0));
break;
case ROSE: pixels.setPixelColor(0, pixels.Color(ledMax, 2, 2));// #ffa2a2
break;
case YELLOW: pixels.setPixelColor(0, pixels.Color(ledMax, ledMax, 0));
break;
case ORANGE: pixels.setPixelColor(0, pixels.Color(ledMax, 1, 0));
case ORANGE: pixels.setPixelColor(0, pixels.Color(ledMax, 3, 0));
break;
case GREEN: pixels.setPixelColor(0, pixels.Color(0, ledMax, 0));
break;
case BLUE: pixels.setPixelColor(0, pixels.Color(0, ledMax, ledMax)); // AQUA
break;
case PINK: pixels.setPixelColor(0, pixels.Color(1,0,3)); // (1,0,2));
case PINK: pixels.setPixelColor(0, pixels.Color(6,0,8)); // (1,0,2));
break; // pink color (255, 192, 203) deep pink (255, 20, 147)
case FUCHS: pixels.setPixelColor(0, pixels.Color(ledMax,0,ledMax)); // FUCHSIA
break;
case BLANK: pixels.setPixelColor(0, pixels.Color(1, 1, 1));
case BLANK: pixels.setPixelColor(0, pixels.Color(4, 4, 4));
break;
case NONE: pixels.setPixelColor(0, pixels.Color(0, 0, 0));
break;
@@ -58,17 +60,13 @@ void ledScale(int rgb, int first, int aim, int inc, int period) {
i = i + inc;
switch (rgb) {
case RED:
pixels.setPixelColor(0, pixels.Color(i, 0, 0));
break;
pixels.setPixelColor(0, pixels.Color(i, 0, 0)); break;
case GREEN:
pixels.setPixelColor(0, pixels.Color(0, i, 0));
break;
pixels.setPixelColor(0, pixels.Color(0, i, 0)); break;
case BLUE:
pixels.setPixelColor(0, pixels.Color(0, 0, i));
break;
pixels.setPixelColor(0, pixels.Color(0, 0, i)); break;
case BLANK:
pixels.setPixelColor(0, pixels.Color(i, i, i));
break;
pixels.setPixelColor(0, pixels.Color(i, i, i)); break;
}
pixels.show(); delay(period);
} while (i != aim );

View File

@@ -30,36 +30,97 @@
- 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"
-----------------------------------------------------------------------*/
#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
#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,sNONE};
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=2;
int16_t defaultTime=180, stepTime=10, timeOut=4;
int16_t snoozeTimeOut=60; //60
#endif
int16_t greetTime=1000;
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 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=sTITRE;
#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(;;); }
void setup() { showInit(); showLOGO(greetTime); ledRGB(GREEN);
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
ledRGB(GREEN);
}
void loop() { // CPU 0 dedicated to refresh display
// TODO not recall screen if values did not change
@@ -70,23 +131,31 @@ void loop() { // CPU 0 dedicated to refresh display
case sREGLE : showREGLE(); break;
case sDUREE : showDUREE(setTime); break;
case sINCRE : showINCRE(stepTime); break;
default : ledRGB(RED); delay(3000); break; // Code error
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, pTITRE, pCHOIX, pEXPOS, pREGLE, pDUREE, pINCRE;
volatile boolean plusPushed=false; volatile boolean minusPushed=false;
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(&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
@@ -105,9 +174,22 @@ static PT_THREAD(pMinus(pt_t *lc)) {
}
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));
PT_WAIT_UNTIL(lc, (screen==sTITRE));
ledRGB(GREEN);
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed ));
minusPushed=false; plusPushed=false;
screen=sCHOIX;
@@ -115,36 +197,41 @@ static PT_THREAD(pTitre(pt_t *lc)) {
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);
PT_WAIT_UNTIL(lc, (plusPushed || minusPushed ) );
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) );
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);
PT_DELAY(lc, 600);
downTime -=1;
if (minusPushed) { minusPushed=false; downTime = 0; }
PT_DELAY(lc, 200);
PT_DELAY(lc, 310);
playClk(); // this take ~100ms
} while ( downTime > 0);
digitalWrite(RELAY, LOW );
screen=sCHOIX;
ledRGB(ORANGE);
playRTTTL(sEXPOS);
PT_END(lc);
}
@@ -167,6 +254,7 @@ static PT_THREAD(pIncre(pt_t *lc)) { // OK
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sINCRE) );
ledRGB(BLUE);
lastStepTime = stepTime;
PT_DELAY(lc, 1000);
ttl=millis()+to;
minusPushed=false; plusPushed=false;
@@ -182,8 +270,10 @@ static PT_THREAD(pIncre(pt_t *lc)) { // OK
if (stepTime >1) stepTime-= 1 ;
ttl=millis()+to;
}
if (millis() > ttl) screen=sREGLE;
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
@@ -191,6 +281,7 @@ static PT_THREAD(pDuree(pt_t *lc)) { // OK
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sDUREE) );
ledRGB(FUCHS);
lastSetTime = setTime;
PT_DELAY(lc, 1000);
ttl=millis()+to;
do {
@@ -205,47 +296,121 @@ static PT_THREAD(pDuree(pt_t *lc)) { // OK
if (setTime > stepTime) setTime -= stepTime ;
ttl=millis()+to;
}
if (millis() > ttl) screen=sREGLE;
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
static int8_t f, icons[FLOCONS][3];
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sVEILLE));
ledRGB(NONE);
for(f=0; f< FLOCONS; f++) {
icons[f][XPOS] = random(1 - SNOOZE_WIDTH, oled.width());
icons[f][YPOS] = -SNOOZE_HEIGHT;
icons[f][DELTAY] = random(1, 6);
}
do {
oled.clearDisplay();
for(f=0; f< FLOCONS; f++) { // ~ 10 ok for this screen
oled.drawBitmap(
icons[f][XPOS], icons[f][YPOS], flake_bmp,
SNOOZE_WIDTH, SNOOZE_HEIGHT, SSD1306_WHITE);
}
PT_DELAY(lc, 80);
if (!(plusPushed || minusPushed)) {
oled.display();
PT_DELAY(lc, 80);
// Then update coordinates of each icon
for(f=0; f< FLOCONS; f++) {
icons[f][YPOS] += icons[f][DELTAY];
// If snowflake is off the bottom of the screen...
if (icons[f][YPOS] >= oled.height()) {
// Reinitialize to a random position, just off the top
icons[f][XPOS] = random(1 - SNOOZE_WIDTH, oled.width());
icons[f][YPOS] = -SNOOZE_HEIGHT;
icons[f][DELTAY] = random(1, 6);
}
//PT_DELAY(lc, 100);
} // f=0; f< NUMFLAKES; f++)
}
} while (!(plusPushed || minusPushed ));
minusPushed=false; plusPushed=false;
oled.clearDisplay();
PT_DELAY(lc, 200);
screen=sTITRE; //sCHOIX;//
PT_END(lc); // to try: exit & return flag ?
}
#define ICONS 4
t_iconMvt icons[ICONS];
t_sprite sprite;
static PT_THREAD(pBugVeille(pt_t *lc)) { // OK and avoid bounces
PT_BEGIN(lc);
PT_WAIT_UNTIL(lc, (screen==sVEILLE));
ledRGB(NONE);
initSprite(&sprite,ICONS,16,16,0,1,2, flake_bmp, icons); // load values to sprite
do {
drawSprite(&sprite, oled);
PT_DELAY(lc, 80);
if (!(plusPushed || minusPushed)) {
oled.display();
PT_DELAY(lc, 80);
updateSprite(&sprite); // update coordinates of each sprite
}
} while (!(plusPushed || minusPushed ));
minusPushed=false; plusPushed=false;
oled.clearDisplay();
PT_DELAY(lc, 200);
screen=sCHOIX;// sTITRE; //
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
}
/*
* 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");