PWM à heure fixe

Bonjour,
voila le petit exercice du jour :wink: pour la gestion de mon aquarium.

Voila le code que j’utilise pour l’allumage et l’extinction de ma rampe à l’aide d’un relais, donc allumage non progressif.

ETAT_BP1=digitalRead(BP1);
  if((ETAT_BP1==APPUI1) && (lights_on_time > temps_perso ||  lights_off_time <= temps_perso))
  {
    digitalWrite(day_light, LOW);
  }
  else
  {
    digitalWrite(day_light, HIGH);
  }

Voila le code que j’utilise pour l’allumage et l’extinction progressif (allumage en une heure et extinction en une heure) :

for (i=0; i<=255;i++){ // boucle for compte de 0 à 255
analogWrite(LED,i); // génère une impulsion sur la broche de largeur i = la luminosité augmente
delay(14000); // pause de 14000 ms entre chaque "cran"
} 
for (i=0; i<=255;i++){ // boucle for compte de 0 à 255
analogWrite(LED,255-i); // génère une impulsion sur la broche de largeur 255-i la luminosité baisse
delay(14000); // pause de 14000 ms entre chaque "cran"
}

Maintenant ce que je voudrais faire :

  1. début de l’allumage progressif à 12h00
  2. allumage complet à 13h00
  3. début d’extinction à 22h00
  4. extinction complète à 23h00

Merci pour votre aide.

Tu utilises quoi pour mesurer le temps, l'horloge interne de l'arduino, ou un composant externe ?

j'utilise un ds1307

void loop(){
time = lecture du ds1307;
if (time >12.00 && time < 13.00){
allumage();
}
if else (time > 22.00 && time < 23.00){
extinction();
}

Void allumage(){
ta fonction allumage progressif
}

void extinction(){
ta fonction d'extinction progressive
}

A adapter avec ta fonction de lecture de ton ds1307.

Dans tes fonctions, utilise plutôt millis() à la place de delay(), ça permet de libérer l’arduino pour qu’il fasse autre chose pendant ces 14 secondes.
Regarde ici :
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1290209709

Par exemple:

if (hour() == 12) { // entre 12:00 et 12:59:59
   analogWrite (day_light, map (minute() * 60 + second(), 0, 3600, 0, 1024));
}
else if (hour() == 22) { // entre 22:00 et 22:59:59
   analogWrite (day_light, map (minute() * 60 + second(), 0, 3600, 1024, 0));
}

Ceci va augmenter ou réduire la lumière progressivement pendant une heure d'une manière linéaire en dépendance du nombre de secondes depuis l'heure complète. Si tu veux une variation exponentielle qui pourrait paraître plus naturelle, échange map par une fonction qui te convient mieux.

Korman

J'ai essayé le code de Korman et j'ai un le message d'erreur suivant :

test_prog.cpp: In function 'void loop()':
test_prog.cpp:91: erreur: 'hour' cannot be used as a function
test_prog.cpp:92: erreur: 'minute' cannot be used as a function
test_prog.cpp:92: erreur: 'second' cannot be used as a function
test_prog.cpp:94: erreur: 'hour' cannot be used as a function
test_prog.cpp:95: erreur: 'minute' cannot be used as a function
test_prog.cpp:95: erreur: 'second' cannot be used as a function
#include <Time.h>

Ces fonctions viennent de la librairie Time.

Korman

super ça fonctionne avec la librairie time

Je vous propose mon code pour savoir si ça vous parait correct car je ne peux pas faire de test car j’ai oublié mon arduino au boulot et que aujourd’hui je garde mes deux enfants malades (sacrée gastro…)

#include <Time.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

int day_light = 3;           // sortie PWM
int lights_on_time = 1200;  //allume les day lights à cette heure (en temps_perso)
int lights_off_time = 2200; //éteint les day lights à cette heure (en temps_perso)

void setup() {
  RTC.stop();
  RTC.set(DS1307_SEC,01);        //réglage secondes
  RTC.set(DS1307_MIN,59);        //réglage minutes
  RTC.set(DS1307_HR,11);         //réglage heures (military)
  RTC.set(DS1307_DOW,2);         //réglage jour de la semaine
  RTC.set(DS1307_DATE,30);       //réglage date
  RTC.set(DS1307_MTH,11);         //réglage mois
  RTC.set(DS1307_YR,10);          //réglage année
  RTC.start();
  pinMode(day_light, OUTPUT);  // digital pin pour day light en sortie
}

void loop() {
  int minut, heure, seconde, date, mois, annee, temps_perso;
  //Récupérer l'heure du DS1307**********************************************************************************************
  heure = RTC.get(DS1307_HR,true);  
  minut = RTC.get(DS1307_MIN,false);
  seconde = RTC.get(DS1307_SEC,false);
  date = RTC.get(DS1307_DATE,false);
  mois = RTC.get(DS1307_MTH,false);
  annee = RTC.get(DS1307_YR,false);
  temps_perso = (heure * 100) + minut;  //creation temps_perso
  //Affichage heure******************************************************************************************
  Serial.print(RTC.get(DS1307_HR,true));
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));
  delay(1000);
  //****************Day Lights
  if (hour() == 12) { // entre 12:00 et 12:59:59
    analogWrite (day_light, map (minute() * 60 + second(), 0, 3600, 0, 1024));
  }
  else if (hour() == 22) { // entre 22:00 et 22:59:59
    analogWrite (day_light, map (minute() * 60 + second(), 0, 3600, 1024, 0));
  } 
  else if ((hour() > 12 ) && (hour() < 22)) {
    digitalWrite(day_light, HIGH);
  }
  else if (((hour() > 22 ) && (hour() < 00)) || ((hour() > 0 ) && (hour() < 12))){
    digitalWrite(day_light, LOW);  
  }
}

Donc allumage progressif entre 12h00 et 13h00
puis allumage continue entre 12h00 et 22h00
puis extinction progressif entre 22h00 et 23h00
le reste du temps donc entre 23h00 et 12h00 rampe éteinte

J’ai bon ???

J’ai bon ???

En principe oui, seulement tu vas te rendre compte, que la dernière demi-heure de l’allumage, l’intensité de la lumière ne change presque pas. Ceci n’est pas un problème du programme, mais vient de la perception. Si ça te gènes, ils est assez simple de changer la progression linéaire en une progression exponentielle.

if (hour() == 12) { // entre 12:00 et 12:59:59
    analogWrite (day_light, (1 << map (minute() * 60 + second(), 0, 3600, 0, 10)) -1);
}
else if (hour() == 22) { // entre 22:00 et 22:59:59
    analogWrite (day_light, (1 << map (minute() * 60 + second(), 0, 3600, 10, 0)) -1);
}

Peut-être cet effet de lumière te plais mieux.

Korman

Salut à tous,

j'utilise ce code pour l'allumage progressif

if (heure == 15) { // entre 15:00 et 15:59:59
    analogWrite (pwm1, map (minute() * 60 + second(), 0, 3600, 0, 1024));
}

et j'ai quelques problèmes. A 15h44 ma rampe s'eteint et se rallume en l'espace de 1 seconde. Puis à 15h59 la rampe s'éteint pendant une minute et s'allume à fond à 16h00 (allumage programmé à fond dans le prog à 16h00)

Des idées ???

1023 á la place de 1024 devrait résoudre le problème de 15:59. Pour l'autre vérifie le résultat de la fonction map.

Korman

Merci mais que veux tu dire par vérifie le résultat de la fonction map ??

Je voulais dire, de vérifier si la fonction map te donne 0 ou une autre valeur qui parait fausse autour de 15:44. Si oui, le problème est à chercher dans ce coin, si non quelque part d'autre.

Korman

Voila, le problème est presque résolu.

L'allumage progressif se fait correctement . Il y a juste un petit problème au démarrage de l'allumage progressif.

Voile le code utilisé

if (heure == 15) { // entre 15:00 et 15:59:59
    analogWrite (pwm, map ((minut * 60), 0, 3540, 0, 255));
}

Pour voir ou se trouvaient les bugs j'utilise un écran LCD sur lequel j'affiche le resultat de (minut *60) et le résultat complet de la fonction map ((minut * 60), 0, 3540, 0, 255). De plus j'affiche l'heure récupérée de mon DS1307.

Le problème est que à 15h00 l'éclairage s'allume à fond pendant une demi-seconde avant de s'éteindre pour commencer alors l'allumage progressif.

Voici ce qui apparait sur l'écran : - à 14h59 3540 255 (mais rampe éteinte car il n'est pas 15 heures - à 15h00 0 0

Cela parait correct mais il y a un problème de rafraichissement. Lorsque l'heure 15h00 apparait sur l'afficheur il est encore affiché la valeur 3540 qui correspond à 14h59. Donc la fonction analogWrite prend pour valeur 255 donc éclairage à fond. L'éclairage s'éteint au bout de la demi seconde qui passe pour afficher 0 qui correspond à 15h00.

J'espère avoir été assez clair dans mes explications.

Une solution :

if (heure == 15 && minut==1) { // entre 15:01 et 15:59:59 analogWrite (pwm, map ((minut * 60), 0, 3540, 0, 255)); }

Comme çà tu ne démarres qu'à 15h01, et problème résolu. Par contre je suis curieux quand même de savoir pourquoi ton code ne marche pas.

tu me dis que :

(heure == 15 && minut==1) : entre 15:01 et 15:59:59

ça ne fait pas : entre 15:01:00 et 15:01:59 ???

Pourquoi ne pas plutot mettre : (heure == 15 && minut >= 1) ???

Oui pardon exact !!

Sinon, as-tu essayé :

heure = RTC.get(DS1307_HR,true); minut = RTC.get(DS1307_MIN,true);

Il est peut-être la ton problème de rafraichissement.

je pense avoir trouvé mon problème

Un peu avant dans le void() j'ai un delay(1000) je pense le supprimer ou le diminuer

j'essairais ce midi

Il faudrait que tu posts ton code car apparemment il a pas mal changé ^^