Hem, j'avais pas vu le graphique.
Pour s'en sortir avec un programme, il faut d'abord établir les données nécessaires. Une fois les données nécessaires déterminées, le code vient (presque) tout seul. Ton appli n'est pas des plus simples car tu as plusieurs intervalles de temps à gérer et qui plus est 2 chronomètre, un pour compter les durées des rampes d'augmentation et de diminution et un pour compter les intervalles de temps entre deux augmentations ou diminutions de la PWM.
Il faut tout d'abord exprimer le temps en unités qui correspondent à ton application. Par exemple, le tick est la seconde. Le mieux est de faire une fonction qui te renvoie dans le nombre de ticks :
const unsigned long dureeDuTick = 1000;
unsigned long temps()
{
return millis()/dureeDuTick;
}
Pour gérer tes éclairages, tu as besoin, en plus du temps, de gérer l'état de chacun des éclairages. Comme tu as certains éclairages qui accomplissent 2 cycles par 24h, la led verte et la led rouge, il faut 8 états. À savoir :
ETEINT1, AUGMENTATION1, ALLUME1, DIMINUTION1, ETEINT2, AUGMENTATION2, ALLUME2 et DIMINUTION2.
Je te propose de représenter cela par un enum
enum { ETEINT1, AUGMENTATION1, ALLUME1, DIMINUTION1, ETEINT2, AUGMENTATION2, ALLUME2, DIMINUTION2 };
Ensuite il te faut un chronomètre par éclairage pour compter le temps écoulé avant de passer d'un état au suivant et il te faut également les durées, en nombre de ticks, des états. Il te faut aussi le nombre de tick entre 2 augmentations de valeur de PWM. C'est donné par la durée de l'augmentation ou de la diminution divisée par 255.
Et enfin la pin PWM concernée et la valeur de la PWM.
Je te propose de représenter cela par une structure :
struct eclairage {
const byte pin; /* pin de PWM */
byte etat;
byte valeurPWM;
byte intervallePWM; /* nombre de ticks entre 2 changement de PWM */
unsigned long chronometre;
const int dureeEteint1;
const int dureeAugmentation1;
const int dureeAllume1;
const int dureeDiminution1;
const int dureeEteint2;
const int dureeAugmentation2;
const int dureeAllume2;
const int dureeDiminution2;
};
Ensuite il faut instancier une struct par éclairage. Si je reprends ton graphique, on a ledVerte, ledRouge, ledBleue, ledBlancChaud et halogene.
Je n'arrive pas bien à voir les date exactes sur ton graphique mais on va dire que la led verte reste éteinte pendant 8h30 = 27000s. Puis elle augmente pendant 2h = 7200. Puis elle reste allumée pendant 0. Puis elle diminue pendant 3h = 10800. Puis elle reste éteinte pendant 5h = 18000s puis elle augmente pendant 2h = 7200 puis reste allumée 1h30 = 5400s puis diminue pendant 2h = 7200s. Total = 30600 + 7200 + 0 + 10800 + 18000 + 7200 + 5400 +7200 = 86400 / 3600 = 24. On est bon
Les temps sont en seconde car le tick est à la seconde. Ce qui donne pour ledVerte :
struct eclairage ledVerte = { pinLedVerte, ETEINT1, 0, 25200, 30600, 7200, 0, 10800, 18000, 7200, 6400, 7200 };
Le chronomètre est initialisé à une durée de 7h car au 0 de ton cycle, on a déjà consommé 1h30.
La gestion du cycle de lumière :
void gereEclairage(struct eclairage& lumiere)
{
unsigned long dateCourante = millis();
switch (lumiere.etat) {
case ETEINT1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAugmentation1;
lumiere.etat = AUGMENTATION1;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeAugmentation1 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case AUGMENTATION1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAllume1;
lumiere.etat = ALLUME1;
lumiere.valeurPWM = 255;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM++;
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
break;
case ALLUME1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeDiminution1;
lumiere.etat = DIMINUTION1;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeDiminution1 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case DIMINUTION1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeEteint2;
lumiere.etat = ETEINT2;
lumiere.valeurPWM = 0;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM--;
}
break;
case ETEINT2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAugmentation2;
lumiere.etat = AUGMENTATION2;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeAugmentation2 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case AUGMENTATION2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAllume2;
lumiere.etat = ALLUME2;
lumiere.valeurPWM = 255;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM++;
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
break;
case ALLUME2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeDiminution2;
lumiere.etat = DIMINUTION2;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeDiminution2 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case DIMINUTION2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeEteint1;
lumiere.etat = ETEINT1;
lumiere.valeurPWM = 0;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM--;
}
break;
}
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
Dans setup :
void setup() {
pinMode(ledVerte.pin, OUTPUT);
}
Dans loop :
void loop() {
// put your main code here, to run repeatedly:
gereEclairage(ledVerte);
}
Le code complet, ça compile mais ce n'est absolument pas testé.
const unsigned long dureeDuTick = 1000;
const byte pinLedVerte = 3;
unsigned long temps()
{
return millis()/dureeDuTick;
}
enum { ETEINT1, AUGMENTATION1, ALLUME1, DIMINUTION1, ETEINT2, AUGMENTATION2, ALLUME2, DIMINUTION2 };
struct eclairage {
const byte pin; /* pin de PWM */
byte etat; /* etat : ETEINT, AUGMENTATION, ALLUME, DIMINUTION */
unsigned long chronometre;
unsigned long dateChargementChronometre;
unsigned long dateChargementIntervallePWM;
unsigned long intervallePWM; /* nombre de ticks entre 2 changement de PWM */
byte valeurPWM;
const int dureeEteint1;
const int dureeAugmentation1;
const int dureeAllume1;
const int dureeDiminution1;
const int dureeEteint2;
const int dureeAugmentation2;
const int dureeAllume2;
const int dureeDiminution2;
};
struct eclairage ledVerte = { pinLedVerte, ETEINT1, 25200, 0, 0, 0, 0, 30600, 7200, 0, 10800, 18000, 7200, 6400, 7200 };
void gereEclairage(struct eclairage& lumiere)
{
unsigned long dateCourante = millis();
switch (lumiere.etat) {
case ETEINT1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAugmentation1;
lumiere.etat = AUGMENTATION1;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeAugmentation1 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case AUGMENTATION1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAllume1;
lumiere.etat = ALLUME1;
lumiere.valeurPWM = 255;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM++;
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
break;
case ALLUME1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeDiminution1;
lumiere.etat = DIMINUTION1;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeDiminution1 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case DIMINUTION1:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeEteint2;
lumiere.etat = ETEINT2;
lumiere.valeurPWM = 0;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM--;
}
break;
case ETEINT2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAugmentation2;
lumiere.etat = AUGMENTATION2;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeAugmentation2 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case AUGMENTATION2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeAllume2;
lumiere.etat = ALLUME2;
lumiere.valeurPWM = 255;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM++;
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
break;
case ALLUME2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeDiminution2;
lumiere.etat = DIMINUTION2;
lumiere.valeurPWM = 0;
lumiere.intervallePWM = lumiere.dureeDiminution2 / 255;
lumiere.dateChargementIntervallePWM = dateCourante;
}
break;
case DIMINUTION2:
if (lumiere.dateChargementChronometre + lumiere.chronometre > dateCourante)
{
lumiere.dateChargementChronometre = dateCourante;
lumiere.chronometre = lumiere.dureeEteint1;
lumiere.etat = ETEINT1;
lumiere.valeurPWM = 0;
}
else if (lumiere.dateChargementIntervallePWM + lumiere.intervallePWM > dateCourante)
{
lumiere.dateChargementIntervallePWM = dateCourante;
lumiere.valeurPWM--;
}
break;
}
analogWrite(lumiere.pin, lumiere.valeurPWM);
}
void setup() {
pinMode(ledVerte.pin, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
gereEclairage(ledVerte);
}