Code PWM pour contrôler intensité lumineuse de LED

Bonjour,

Je cherche à coder un programme permettant de générer 3 signaux PWM qui me permettront de régler l’intensité lumineuse de 3 modules de LED différent (3 couleurs : rouge, rouge foncé et blanc). Ces LED sont destinées à éclairer des plantes.
Ce signal PWM varie (donc l’intensité lumineuse des LED aussi) en fonction de l’heure. Pour cela j’utilise un capteur DS1307.

Le schéma du montage est présent ci-joint (capture) ainsi que le montage permettant de passer d’un PWM à une tension (pour information).
Egalement présent en pièce jointe l’image illustrant le schéma Philips (capture2). La partie entourée en rouge est la partie qui gère l’intensité lumineuse et que je souhaite faire sous la forme du schéma présenté dans “Capture”.

J’ai donc réalisé ce code :

#include <Wire.h>
#include “RTClib.h”

// définir les 3 pins de sorties PWM
const int sortieLEDrouge = 11;
const int sortieLEDblanche = 9;
const int sortieLEDrouge_fonce = 10;

RTC_DS1307 rtc; // variable RTC pour récupérer l’heure depuis le RTC DS1307

void setup(){
Serial.begin(9600);
//Définir les pins 9 10 et 11 en sortie
pinMode(sortieLEDrouge, OUTPUT);
pinMode(sortieLEDblanche, OUTPUT);
pinMode(sortieLEDrouge_fonce, OUTPUT);
}

void loop(){

long horairesRouge [2][2]={{0,255},{20,0}};// {heures, intensité de fonctionnement} = allumé de 0 a 20h , éteint à 20h
long horairesRouge_fonce [2][2]={{0,255},{18,0}};// allumé de 0 a 18h , éteint à 18h
long horairesBlanche [2][2]={{0,255},{22,0}};// allumé de 0 a 22h , éteint à 22h
int idx=0; //index pour se déplacer dans les tableaux

DateTime now = rtc.now();
int hours = now.hour(); //récuperer le chiffre des heures

// **************** LED ROUGE **********************
//s’il est entre 0 et 20h
if((hours>= horairesRouge[0][0]) && (hours<horairesRouge[1][0])){
analogWrite(sortieLEDrouge,horairesRouge[idx][1]); //allumé la LED rouge à 100%
}
//s’il est passé 20h
else if(hours>horairesRouge[1][0]){
idx=1; //changer l’index
analogWrite(sortieLEDrouge,horairesRouge[idx][1]); //éteindre
}

//**************** LED ROUGE FONCE ********************
//s’il est entre 0 et 18h
if((hours>= horairesRouge_fonce[0][0]) && (hours<horairesRouge_fonce[1][0])){
analogWrite(sortieLEDrouge,horairesRouge_fonce[idx][1]); //allumé la LED rouge foncé à 100%
}
//s’il est passé 18h
else if(hours>horairesRouge_fonce[1][0]){
idx=1; //changer l’index
analogWrite(sortieLEDrouge,horairesRouge_fonce[idx][1]); //éteindre
}

//**************** LED BLANCHE ********************
//s’il est entre 0 et 22h
if((hours>= horairesBlanche[0][0]) && (hours<horairesBlanche[1][0])){
analogWrite(sortieLEDrouge,horairesBlanche[idx][1]); //allumé la LED rouge blanche à 100%
}
//s’il est passé 22h
else if(hours>horairesBlanche[1][0]){
idx=1; //changer l’index
analogWrite(sortieLEDrouge,horairesBlanche[idx][1]); //éteindre
}

}

Je tiens à préciser que je n’ai pas encore reçu les éléments (carte, rtc) me permettant de tester ce code en visualisant le signal de sortie sur un oscillo. Je tenais quand même à avoir votre avis sur les parties à améliorer/modifier.

J’ai en effet conscience que le code n’est pas optimisé quand je vois toutes ces boucles if qui s’enchaînent je me dis qu’il doit y avoir un meilleur moyen de le faire mais je ne trouve pas !

Concernant l’heure je suis conscient que s’il est 19h59min59s le programme retiendra 19h et laissera la lampe rouge allumée alors qu’entre temps il sera surement 20h passé de quelques secondes. Seulement ce décalage n’est que provisoire car quand la boucle loop se réexécutera, la lampe rouge s’éteindra car le programme indiquera alors 20h.
Donc il n’y à un problème de fonctionnement que le temps d’exécuter la boucle (qq secondes maximum non ?). Ce qui vu l’utilisation finale des LED (éclairage pour des plantes) ne posent pas un réel soucis !
Néanmoins si quelqu’un possède la solution pour optimiser cette partie je suis toujours preneur de conseils évidement.

Merci d’avance pour votre temps!

Capture2.JPG

Salut,

Un moyen qui simplifierai les choses et l’emploi de structure :

struct LED {
byte depart;
byte fin;
byte intensiteDepart;
byte intensiteFin;
int pinLED;
};

LED mesLED[3]={{0,20,0,255,11},{0,18,0,255,9},{0,22,0,255,10}};

void setup(){

  Serial.begin(9600);

  //Définir les pins 9 10 et 11 en sortie
for(int i=0;i<3;i++)   pinMode(mesLED[i].pinLED, OUTPUT);

}

void loop() {

DateTime now = rtc.now();
int hours = now.hour(); //récuperer le chiffre des heures

for(int i=0;i<3;i++) {

if(mesLED[i].depart>=hours && mesLED[i].fin<hours) {

analogWrite(mesLED[i].pinLED,mesLED[i].intensiteDepart);

} else {

analogWrite(mesLED[i].pinLED,mesLED[i].intensiteFin);

}

}

Et pour ton souci de passe d’une heure à l’autre je ne vois pas pourquoi tu penses perdre des secondes

Je ne savais pas qu'on pouvait créer ses types de variables comme en Java grâce au structure merci !

Pourquoi "byte" et pas "int" pour départ, fin , intensiteDepart et intensiteFin ?

Concernant l'heure je pensais que si à 19h59min59s je relève l'heure alors je vais laisser la LED rouge allumée mais le temps que je re relève l'heure il sera peut être 20h00min02s et dans ce cas la LED rouge sera allumée 2s de "trop".

  pinMode(mesLED[i].pinLED, OUTPUT); plutôt que

  pinMode(mesLED[i], OUTPUT);

Corrigé :wink:

desacant:
Concernant l'heure je pensais que si à 19h59min59s je relève l'heure alors je vais laisser la LED rouge allumée mais le temps que je re relève l'heure il sera peut être 20h00min02s et dans ce cas la LED rouge sera allumée 2s de "trop".

Le temps que tu relève l'heure soit quelque byte à 100 khz => quelques dizaines de µs

Donc ton relevage d'heure, tel qu'il est tu en fait plusieurs milliers / s, donc le retard sera plus qu'insignifiant ...

et est-ce un problème pour le programme de tourner autant de fois par seconde ?

Et tu utilises une variable byte parce que cela utilise moins de mémoire (2 fois moins que int) ?

une heure représenter en heure tiend dans un byte qui va de 0 a 255, pour stocké 18-20 ou autre de 0 a 23 c’est plus que sufisant

tu peut definir tes heures sous forme de structure comme ils viennent de te le montrer et meme inclure ces heures dans d’autre structure :

struct Heure{
byte h; //les heure
byte m;//les minutes
byte s;// les seconde si besoin ;-)
};

struct LED {
Heure depart;
Heure fin;
byte intensiteDepart;
byte intensiteFin;
int pinLED;
};

//pour y acceder c'est pareil que précédent :
 LED.depart.h = variable;// par exemple pour les heure de depart de LED

desacant:
et est-ce un problème pour le programme de tourner autant de fois par seconde ?

Pas du tout, il n'y a rien "qui s'use" :wink:

desacant:
Et tu utilises une variable byte parce que cela utilise moins de mémoire (2 fois moins que int) ?

Oui, c'est une bonne habitude à prendre que de faire les choix judicieux quand au choix des types de variable, et c'est valable dans les deux sens : pas prendre des types plus grand que necessaire, mais pas trop petit non plus pour éviter les débordement.

Bon après qui peut le plus peut le moins évidemment, mais un jour ou l'autre on finit aussi par remplir sa RAM, même si ici évidemment on en est très loin ^^

Ok merci je me disais que plus on faisait tourner le programme plus ça demandait "d'efforts" à la carte.