Led controlée par module RTC, petit problème de code

Bonjour à tous,

Actuellement je suis un cours en ligne sur les objets connectés, donc je suis toute novice en Arduino. Jusqu'à présent j'ai réussi à m'en tirer avec le forum pour trouver des bouts de code et des réponses mais là je bloque sur quelques chose qui je le pense est tout bête...

Pour le cours je dois créer mon propre objet connecté. J'ai donc opté pour une veilleuse qui s'allume à une plage horaire définit (avec un module RTC) et lorsque la luminosité de la pièce est faible (photorésistance).
Lorsque c'est deux conditions sont réunies ma led s'allume et un servo moteur change le visuel de ma veilleuse.

Jusque là pour l'allumage tout marche!

Mais après je me rends compte que si je mets la photorésistance à la lumière, la veilleuse ne s'éteint pas...

Voici mon code:

#include <Servo.h>
#include <Wire.h>
#include "RTClib.h"

Servo servoM;
RTC_DS1307 RTC; //Classe RTC_DS1307

int val = 0;
int sensorPin = 0;
int ledPin = 13;
int cdeServo = 9;
 
void setup() {
  Serial.begin(9600); //Démarrage de la communication
  Wire.begin(); //Démarrage de la librairie wire.h
  RTC.begin(); //Démarrage de la librairie RTClib.h
  
  //Si RTC ne fonctionne pas
  if (! RTC.isrunning()) {
    Serial.println("RTC ne fonctionne pas !"); 
  }
  
  servoM.attach(cdeServo);
  delay(200);
  servoM.writeMicroseconds(600);
  pinMode(ledPin, OUTPUT);
}
 
void loop() {
  
//Heure actuel
  DateTime now = RTC.now();
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);  
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  delay(3000);
  
  val = analogRead(sensorPin); //Prise de valeur de la photorésistance
  Serial.println("luminosité : "); Serial.println(val); //Ecriture de la valeur
  
  // Valeur équivalente à la nuit
  if (now.hour() > 19 && now.hour() < 23) { // Si on est dans la plage horaire entre 19h et 23h
  if (val > 500) { // Si la résistance est dans l'obscurité
    digitalWrite(ledPin, HIGH);// veilleuse s'allume
    servoM.writeMicroseconds(2200);// moteur tourne sur le visuel nuit
    Serial.println("Bonne nuit");
   }
 } 
 
 else {  
  //Valeur équivalente au jour
    digitalWrite(ledPin, LOW); //veilleuse s'éteint
    servoM.writeMicroseconds(600); //moteur tourne sur le visuel jour
    Serial.println("Bonjour");
  }
  
  delay(10000);
}

Merci pour votre aide :slight_smile:

bonjour,
la valeur de val change si tu mets ton doigt dessus?
ca affiche quoi?

AMHA, ca doit être inférieur et non supérieur à 500

Oui ma valeur augmente quand je mets le doigt dessus, jusqu'à 700 environ (quand elle est cachée complètement) sinon à la lumière normale je suis au alentour de 100.

Merci de ton aide.

int sensorPin = 0;

tu es certains de cette pin?

Oui, j'avais pris le code de mon cours sur la photorésistance qui fonctionne très bien. De plus si je supprime cette ligne, j'ai ce message d'erreur "'sensorPin' was not declared in this scope".

Je pense que le problème vient des conditions qui doivent pas être top.

Lorsque je démarre mon programme dans la bonne plage horaire mais avec de la lumière, la led est éteinte. Puis je cache la photorésistance pour la mettre dans l'obscurité, la led s'allume. Seulement quand je remets la photorésistance quelques secondes après. J'ai bien la bonne valeur dans le moniteur série au démarrage de la nouvelle boucle mais la led reste allumée.

Et je pense que la manière dont j'ai écris la plage horaire n'est pas très stable. Je m'explique, si je mets une plage horaire 1h d'intervale ça ne fonctionne pas.
exemple :

if (now.hour() > 13 && now.hour() < 14) {}

mais dans ce cas là

if (now.hour() > 13 && now.hour() < 15) {}

ça fonctionne

salut

ça ne s'éteint pas tout simplement car tu ne vérifie pas si il faut éteindre. Dans ton code tu as bien deux conditions (les deux if) pour vérifer, d'abord si tu es dans la plage horaire, puis si c'est le cas si la luminosité correspond.
par contre ensuite le else ne s'applique que sur le premier if, donc seulement à la plage horaire. rien ne vérifie si il faut éteindre si la luminosité change.

tu as je pense deux solutions pour que ça fonctionne sans changer trop de code :

soit rajouter un digitalWrite(ledPin,LOW) juste avant les deux if, de sorte que avant de vérifier tes conditions la led soit toujours éteinte, et dans ce cas le else est inutile et tu peux le supprimer

soit imbriquer les deux conditions des deux if dans une seule (avec && ) de manière à supprimer le second if, de sorte que le else s'appliquera alors aux deux.

moi dans un cas comme ça j'utilise la première solution, car si ça doit rester allumer de toutes manières l'extinction sera tellement courte que l'oeil ne le voit pas

hello

si je mets une plage horaire 1h d'interval ça ne fonctionne pas.

if (now.hour() > 13 && now.hour() < 14) {}

if (now.hour() > 13===> il faut donc qu'il soit au moins 14h

&& now.hour() < 14===> il faut également qu'il soit 13 h maxi

Merci beaucoup, c'était ça qui clochait! Je sentais qu'il y avait un problème dans les conditions mais je voyais pas où :slight_smile:

bien vu dfgh pour la condition qui ne fonctionne pas

pour revenir à ce que je disais, si la micro-coupure sur la led pose problème avec ma solution 1, il est possible de s'en affranchir en ajoutant une variable int tamponLed. C'est cette variable qui prendra la valeur LOW juste avant le if, qui sera mise à HIGH dans le if si besoin
et ensuite seulement après le if tu fais ton digitalWrite(ledPin, tamponLed); comme ça même si la valeur change momentanément pendant la vérif des conditions, la sortie elle ne changera pas. Et meme chose pour ton servo, dans le if tu vire ce qui le commande, et à la fin à la suite du digitalWrite tu met également la commande du servo basée sur la valeur de tamponLed par exemple

digitalWrite(ledPin, tamponLed);
if (tamponLED==HIGH) servoM.writeMicroseconds(2200);
else servoM.writeMicroseconds(600);