Montée progressive de l'éclairage avec pwm

Bonjour

Je voudrais réaliser un éclairage led, pour mon aquarium, piloté par Arduino Mega 2560.
J'ai consulté beaucoup de forums. C'est ici que j'ai trouvé quelque chose de pas trop compliqué et surtout de très clair. Merci à Swetohm :wink:
Je souhaite que la durée de l''éclairage soit comprise entre 14h00 et 22h00. Jusque là, pas de problème, tout fonctionne parfaitement. Voilà l'extrait du code qui gère cette fonction :

 if (now.hour() >= TabEvt [0][0] && now.minute() >= TabEvt [0][1] &&  now.hour() <= TabEvt [0][2] && now.minute() < TabEvt [0][3] ) 
              {
                analogWrite (PinSorties[0], 0);
              }
              else {
                analogWrite (PinSorties[0], 255);
              }

Les heures sont extraites d'une table qui a la forme suivante :

// {Heure départ, minute départ, heure arrêt, minute arrêt}          
{14,0,22,0},  // voie 1 - Pin 8

Ce que je voudrais, c'est que, pour passer de 0 à 255, il y ait une temporisation qui fasse que l'éclairage ne soit pas tout ou rien, mais progressif sur une quinzaine de minutes, aussi bien pour l'allumage que pour l'extinction. C'est ce qui explique analogWrite et non digitalWrite.
J'ai bien essayé de remplacer 0 par i, avec :

for (i = 0; i <= 255; i++)

Mais il ne se passe rien.

Je ne sais pas si j'ai été très clair dans mes explications… J'espère que oui… et que l'un ou l'une d'entre vous pourra m'aider.

Bonne journée à toutes et tous

bonjour,

Si j'ai bien compris, tu veux un éclairage entre 14h et 22h.

A 14h, tu ne veux pas passer de nuit à jour en une demi seconde mais plutôt en une demi heure (par exemple), si j'ai toujours bien compris ...

Donc pour le code que tu as fait :

else {
analogWrite (PinSorties[0], 255);
}

Je propose de le remplacer par :

else {
for (int i = 0; i <= 255; i++) {
analogWrite (PinSorties[0], i);
delay(7000);
}

Explications :

Je suis parti d'un éclairage progressif sur 30 minutes (1800 secondes)
J'ai fait une petite boucle qui va de 0 à 255.

1800/255 = 7,05888 ....

Donc à chaque itération, je fais une pause de 7 secondes puis j'augmente de 1 la luminosité

Ca te donne une piste ?

HardWeKnow2017:
bonjour,

Si j'ai bien compris, tu veux un éclairage entre 14h et 22h.

A 14h, tu ne veux pas passer de nuit à jour en une demi seconde mais plutôt en une demi heure (par exemple), si j'ai toujours bien compris ...

C'est exactement ça!

Donc pour le code que tu as fait :

else {
analogWrite (PinSorties[0], 255);
}

Je propose de le remplacer par :

else {
for (int i = 0; i <= 255; i++) {
analogWrite (PinSorties[0], i);
delay(7000);
}

Ça fonctionne, mais la led s'éteint au bout de 30 minutes et recommence le cycle au début en se rallumant progressivement et ainsi de suite.

En tout cas, merci pour ton aide

Effectivement, j'avais pas vu l'essentiel !

ton test n'est pas bon ...

Par contre je te propose un autre bout de code :

le dernier post a été mal édité ....


if (now.hour() == TabEvt[0][0] && now.minute() >= TabEvt [0][1] ) // il est 14h passé
{
 for (int i = 0; i <= 255; i++) {
       analogWrite (PinSorties[0], i);
       delay(7000);
 } 
// Ici il s'est passé 1820 secondes (7 * 256)

// Duree en heure entre heure 1 et heure 2
float dureeHeure =  (TabEvt [0][2] + (TabEvt [0][3] /60)) - (TabEvt [0][0] + (TabEvt [0][1] /60));
int dureeMs = dureeHeure * 60 * 60 * 1000;
 delay(dureeMs - 1820); // (Pour arriver à 22h)
 analogWrite (PinSorties[0], 0);
}

bonjour,
utiliser des delay n'est pas la meilleure solution, surtout pour un aquarium qui a peut être besoin de faire d'autres opérations entre temps.
cela veut dire que pendant 30mn, rien ne pourra se faire.
calcul température, renouvellement eau, affichage sur écran non mis à jour, etc....

2 solutions

  • utiliser les secondes ou minutes RTC pour augmenter par tranches de 10 par exemple
  • utiliser millis()

infobarquee:
bonjour,
utiliser des delay n'est pas la meilleure solution, surtout pour un aquarium qui a peut être besoin de faire d'autres opérations entre temps.
cela veut dire que pendant 30mn, rien ne pourra se faire.
calcul température, renouvellement eau, affichage sur écran non mis à jour, etc....

2 solutions

  • utiliser les secondes ou minutes RTC pour augmenter par tranches de 10 par exemple
  • utiliser millis()

Bonjour et merci de votre aide.

En ce qui concerne les autres actions à mener en parallèle (calcul température, renouvellement eau,...) ce n'est pas un problème. Je pense dédier une carte spécifiquement pour l'éclairage. Cette carte (une Nano par exemple) n'aura donc qu'à gérer l'éclairage (jour, nuit, lune,...).

Je ne comprends pas les solutions que vous me donnez :

  • utiliser les secondes ou minutes RTC pour augmenter par tranches de 10 par exemple

Des tranches de 10 quoi ?

  • utiliser millis()

Où les utiliser ?

Je débute vraiment. Et là, j'avoue que je ne suis pas tout.

Et à propos de débutant, je me suis inscrit à un cours en ligne consacré à l'étude d'Arduino. Les cours (gratuits) sont dispensé par des profs d'université, de centre de recherche, etc... Les domaines abordés sont très très variés. Le site pour les inscriptions : https://www.fun-mooc.fr

Je pense que cela peut intéresser quelques uns d'entre nous.

Des tranches de 10 quoi ?

si tu fais l'exemple fader avec une led, tu verras que l'éclairage n'est pas régulier, tout dépend en fait avec quoi tu éclaire.
Par tranche de 10 (0-10-20-30-etc...) sur le pwm serait mieux AMHA ou de 5 en 5

Tu peux tout faire avec une seule carte, au lieu de mettre une carte pour l'éclairage, une autre pour la pompe, etc...
Ca évite de doubler du matériel, donc de l'argent aussi.

Le RTC pour être utilisé pour plusieurs choses en un seul exemplaire, pompe, éclairage, affichage heure sur lcd ou TFT etc....

La fonction millis() ne bloque pas le code comme le fait un delay.

Donc, avant de te lancer corps et ame dans un projet complexe, fait un module, puis un autre et après quand tout fonctionne, tu rassemble le tout.

Regarde les exemples dans projets finis pour les aquariums, ou celui de ma couveuse.
Je gère tout avec une mega, écran TFT touch screen, température, etc...

infobarquee:
La fonction millis() ne bloque pas le code comme le fait un delay.

Donc, avant de te lancer corps et ame dans un projet complexe, fait un module, puis un autre et après quand tout fonctionne, tu rassemble le tout.

C'est bien pour cela que, dans l'immédiat, je voudrais allumer, progressivement (15 minutes pour passer de 0 à 255) une led, à 14h00 et qu'elle s’éteigne, tout aussi progressivement à 22h00. Et que cela se répète tous les jours.

Quand j'en serai arrivé là, j'aurai fait un grand pas et alors seulement je continuerai mon projet. Mais là, je bute sérieusement. Je parviens à l'allumer et l'éteindre aux heures voulues, mais sans cette fichue progression :angry:

C'est bien pour cela que, dans l'immédiat, je voudrais allumer, progressivement (15 minutes pour passer de 0 à 255) une led, à 14h00 et qu'elle s'éteigne, tout aussi progressivement à 22h00. Et que cela se répète tous les jours.

ca nous fait 255/15 =17
donc pour chaque minutes a partir de 14h00, tu vas augmenter le pwm de 17

ca devrait donner un truc comme ca
pour chaque minute, on la multiplie par 17

int pwm = 0;


void loop(){

if (now.hour() == TabEvt[0][0] && now.minute() >= TabEvt [0][1] >= TabEvt [0][1] ) // il est 14h passé
{
   if (now.minute()  < 16 && pwm < 255 ){

      pwm = now.minute() * 17; 

     analogWrite(led,  pwm);
       
     }

}

Je pense avoir mieux :wink:

Je l'ai fait en pseudo code.

J'ai surtout corrigé le test pour les heures et minutes ; de plus l'allumage progressif est dynamique en fonction du temps qui te convient le mieux (en variable) ...

Plages horaires (Heure, minute)
H1, M1, H2, M2

h : now.hour()
m : m.minute()
nbMinutesTempsAllumageProgressif = 30

Loop
Si ((h = H1 && m >= M1) || (h > H1 )) && (h < H2 || (h=h2 && m <= M2)) {
	int nbMinutesEcouléesDepuisH1M1 = (60 * (h - H1) + (m - M1));
	Si nbMinutesEcouléesDepuisH1M1 < nbMinutesTempsAllumageProgressif {
		// Calcul ratio eclairage
		float ratio = nbMinutesEcouléesDepuisH1M1 / nbMinutesTempsAllumageProgressif;
		analogWrite(led,  ratio * 255);
	} Sinon {
		// on fait rien 
	}	
} Sinon {
	// On éteint !
	analogWrite(led,  0);
}

PS : Je n'avais pas vu que tu voulais également un éclairage qui s'abaisse graduellement ...

Tu me diras, si tu arrives a faire fonctionner le lever du jour, tu arriveras à décliner dans l'autre sens ...

Question annexe :

Comment gères-tu les heures et minutes réelles ?
Tu as un composant particulier pour connaitre ces informations ?

Bonjour,

Pour mon aquarium, je gère l'allumage et l'extinction progressives de leds bleues et blanches à l'aide de l'instruction map comme suit :

    valupLedBleue = (map (t.min, 0, 30, 0, 255));  // allumage des leds bleues sur 30 minutes
    valupLedBlanche = (map (t.min, 0, 30, 0, 255));  // allumage des leds blanches sur 30 minutes
    valdownLedBleue = (map (t.min, 0, 30, 255, 0)); // extinction des leds bleues sur 30 minutes
    valdownLedBlanche = (map (t.min, 0, 30, 255, 0)); // extinction des leds blanches sur 30 minutes

et cela fonctionne très bien, il suffit de lancer la fonction à l'heure souhaitée.

la solution du map est bonne aussi

Merci à vous tous qui cherchez à m'aider ! Et y'a du boulot !!!

@ Infobarquee : la solution que vous me proposiez me paraissait la plus simple, mais je ne parviens pas à la faire fonctionner.

@EGT59 :

valupLedBleue = (map (t.min, 0, 30, 0, 255));

t.min correspondent à quoi ? Je me sert d'un DS 1307 comme RTC.

HardWeKnow2017:
Je pense avoir mieux :wink:

Je l'ai fait en pseudo code.

(...)

Plages horaires (Heure, minute)

H1, M1, H2, M2



Faut-il déclarer les heures et minutes sous cette forme ou y-a-t-il une syntaxe différente ? Je suppose que l'on place ce code dans setup.



h : now.hour()
m : m.minute()
nbMinutesTempsAllumageProgressif = 30

Loop
Si ((h = H1 && m >= M1) || (h > H1 )) && (h < H2 || (h=h2 && m <= M2)) {
int nbMinutesEcouléesDepuisH1M1 = (60 * (h - H1) + (m - M1));
Si nbMinutesEcouléesDepuisH1M1 < nbMinutesTempsAllumageProgressif {
// Calcul ratio eclairage
float ratio = nbMinutesEcouléesDepuisH1M1 / nbMinutesTempsAllumageProgressif;
analogWrite(led,  ratio * 255);
} Sinon {
// on fait rien
}
} Sinon {
// On éteint !
analogWrite(led,  0);
}

J'imagine que "Si" et "Sinon" sont à remplacer par "if" et "else" . Je progresse, je progresse :wink: Mais je n'ai toujours pas réussi à trouver la solution :confused:

bonjour

pourquoi t'embeter avec des tableaux, tu crées une variable Hprog =( (now.heure * 100)+now.minute)et tu travailles avec ça.

Si Hprog >= 1200 (donc 12H00) faire ceci

sinon faire cela

Je te mets un bout de mon code en exemple

if (HProg >= 1100 && HProg <= 1130)  
        {
          analogWrite(LedBleue, valupLedBleue); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK"); c = 1; // Allumage progressif de l'éclairage Led Bleue et sa led témoin
        }
        
      else if (HProg > 1130 && HProg <= 1200)
        {
          analogWrite(LedBleue, 255); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK"); c = 1;
        }
      else if (HProg > 1200 && HProg <= 1230) 
        {
          analogWrite(LedBleue, valdownLedBleue); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK");  c = 1;  // Extinction progressive de l'éclairage Led Bleue
        }

Je suis débutant comme toi donc il y a certainement des trucs à améliorer mais bon ça fonctionne

Pur le t.min, c'est pour récupérer les minutes de ma RTC (DS3232), pour toi c'est now.minute je pense. Les pros te diront si je dis une bêtise......

Fait des tests tu vas y arriver

EGT59:
bonjour

pourquoi t'embeter avec des tableaux, tu crées une variable Hprog =( (now.heure * 100)+now.minute)et tu travailles avec ça.

Si Hprog >= 1200 (donc 12H00) faire ceci

sinon faire cela

Je te mets un bout de mon code en exemple

if (HProg >= 1100 && HProg <= 1130)  

{
         analogWrite(LedBleue, valupLedBleue); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK"); c = 1; // Allumage progressif de l'éclairage Led Bleue et sa led témoin
       }
       
     else if (HProg > 1130 && HProg <= 1200)
       {
         analogWrite(LedBleue, 255); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK"); c = 1;
       }
     else if (HProg > 1200 && HProg <= 1230)
       {
         analogWrite(LedBleue, valdownLedBleue); digitalWrite(LedEclLedBleue, HIGH); lcd.setCursor(9,1); lcd.print("OK");  c = 1;  // Extinction progressive de l'éclairage Led Bleue
       }




Je suis débutant comme toi donc il y a certainement des trucs à améliorer mais bon ça fonctionne


Fait des tests tu vas y arriver

Nous sommes dimanche, il est 19h35 et je kracccccc !

Impossible de faire marcher mon bazar >:(

Si tu peux me passer ton code, cela m'enlèverait une belle épine du pied. Je viens de passer quasiment tout le week-end sur mon projet et rien à faire avec la temporisation (pour la montée comme pour la descente) de l'intensité lumineuse.

Et ma femme commence à trouver que les poissons, ça prends de la place et que l'éclairage beaucoup trop de temps. Même mon chien me fait la gueule ! C'est dire :roll_eyes:

S'il y a une bonne âme charitable (et je suis persuadé qu'il y en a :wink: qui veut bien me donner le coup de pousse qui va bien, je lui en serai éternellement reconnaissant.

En tout cas, bonne semaine à toutes et tous !

Bonsoir,

Je vois que tu sais récupérer l'heure et la minute actuelle avec now.hour et minute, donc tu sais calculer une variable Hprog (par exemple) qui serait égale à now.hour * 100 + les minutes en cours. Par exemple si il est 11h39 ca donnerait hprog = 1139.

Après tu te sers de cette valeur pour faire des actions à l'heure que tu souhaites.

Pour allumer tes leds progressivement à 11h39 par exemple : si hprog >= 1139 alors instruction d'allumage progressive décrite dans mon post plus haut.

c'est pas très compliqué à tester......

// Calcul HProg 

{
  dateheure = t.hour;  // variable date_heure contient l'heure actuelle
  dateminute = t.min; // variable date_minute contient la minute actuelle
  HProg = (dateheure*100) + dateminute;
  
}
 
      // GESTION DU TRANSFO 15V
  {  
  if ((HProg >= 1058 && HProg <= 1302) || (HProg >= 2043 && HProg <= 2302))
    {
      digitalWrite(EclLed, LOW);  // alimente le relais 2-1 du transfo 15V
    }
  else
    {
      digitalWrite(EclLed, HIGH); // coupe le relais 2-1 du 15v
    }
  }

mon code pour le calcul de HProg : très simple et pour la gestion d'un relais qui alimente le transfo de mes leds.

Bon courage

Effectivement ! il faut remplacer Si par if :slight_smile:

c'est ça le pseudo code :slight_smile:

bin oui il y a un minimum quand même ...... :slight_smile: