PWM, fréquence et contrôle

Bonjour,

Dans le but d'implémenter un signal PWM sur une Arduino UNO, je me suis demandé quel était l'impact de la fréquence de ce signal (bruit, nuissances sur le signal...) ? En effet j'ai lu que par défaut cette fréquence est d'environ 500Hz Ajuster le Fréquence PWM sur un Arduino - MCHobby - Le Blog mais qu'elle était réglable. Quel est l’intérêt de régler la fréquence ?

Enfin si je souhaite faire un système destiné à contrôler l'intensité lumineuse des LEDs qui fonctionnerait dans ce style là : alternance de 8h d'éclairage à 100% puis 2 heures de nuit (0%). Comment programmer ce genre de système ?
Si j'ai bien compris la fonction "analogWrite( broche, valeur)", permet de définir le duty cycle. Ainsi si je tape analogwrite(sortieLed,255) j'obtiens une intensité lumineuse de 100% sur la sortie des LEDs. Mais pendant combien de temps je conserve ce 100% ?
Est ce que l'instruction analogwrite(sortieLed,128) donne 50% de la période (T=1/f=1/500=2ms) de nuit puis 2ms de pleine intensité lumineuse ?

Merci pour votre aide !

etrange : pourquoi utiliser pwm si led a 100% pendant 8h puis 0% pendant 2h

enfin c'est ce que je comprends (mal sans doute)

non c'est bien cela ! Du moins dans la première phase de l'étude ça sera comme cela après l'idée est de pouvoir gérer l'intensité à partir du programme donc éventuellement mettre 80% pendant 4h puis 20%pendant 3h etc.

La valeur écrite le reste tant qu'on n'en écrit pas une nouvelle.
Donc pour éteindre la led 1s après l'avoir allumée par ex, il faut stocker la valeur de millis() dans une variable dans la fonction setup().
Dans loop(), si millis()-valeur d'origine > 1000 alors éteindre la led, sinon l'allumer.

Concernant la fréquence du PWM, ça dépend des usages qu'on veut en faire mais pour piloter une LED j'ai toujours laissé la fréquence par défaut.

cela donnerait quelque chose comme ça pour 1 heure allumée - 1h eteinte?

void setup(){
Serial.begin(9600);

origine = millis(); //donc origine == 0 ??
}

void loop(){
analogwrite(sortieLED,255); //LED à 100%

if((millis()-origine)>3 600 000){
analogwrite(sortieLED,0); //éteindre LED au bout d'une heure
origine2=millis();
}

if((millis()-origine2)>3 600 000){
analogwrite(sortieLED,255); //rallumer LED au bout d'une heure
}
}

Mais comment enchainer ensuite sans devoir saisir autant de if que l'on veut de période ?

Non pas vraiment.
Plutôt un truc du genre (non testé mais c’est l’idée):

int origine=0;
void setup(){
  origine = millis();                   //donc origine == 0 ??
}

void loop(){

if((millis()-origine) <3 600 000){
analogwrite(sortieLED,255);  //allumée la première heure
}else{
analogwrite(sortieLED,0);  //eteinte la seconde heure
}

if((millis()-origine)>7 200 000){
 origine = millis(); // au bout de 2h, on boucle -> on rallume la led 
  }
}

desacant:
Mais comment enchainer ensuite sans devoir saisir autant de if que l'on veut de période ?

tu stock dans un tableau les point qui t'intérése (horraire) et tu ne fait qu'une boucle if qui prend comme parametre les valeur de ton tableau par exemple.

Heloderma-kris:

desacant:
Mais comment enchainer ensuite sans devoir saisir autant de if que l'on veut de période ?

tu stock dans un tableau les point qui t'intérése (horraire) et tu ne fait qu'une boucle if qui prend comme parametre les valeur de ton tableau par exemple.

Oui, un tableau à 2 dimensions: une colonne par "pas" et 2 lignes: l'heure (nb de secondes) et la valeur PWM associée.

C'est a dire l'heure ?
Et les paramètres de la boucle if ce sont les conditions de réalisation de cette boucle, comment cela peut-il être des points du tableaux ?

il suffit, au lieu d’utiliser une heure sexagésimale, que tu utilises le nombre de secondes écoulées depuis minuit.

long horaires [10][2] = {{6328,7875},{15687,18247} ... }; // {horaire début,horaire fin}

...

unsigned long time = millis();
for(int i=0;i<10;i++){
if(millis() >=horaire[i][0]) analogWrite(sortieLed,255);
if(millis() >=horaire[i][1]) analogWrite(sortieLed,0);
}

Après on peut même étoffer avec les variations de lumière :

long horaires [10][3] = {{6328,7875,128},{15687,18247,56} ... }; // {horaire début,horaire fin, consigne}

...

unsigned long time = millis();
for(int i=0;i<10;i++){
if(millis() >=horaire[i][0]) analogWrite(sortieLed,horaire[i][2]);
if(millis() >=horaire[i][1]) analogWrite(sortieLed,0);
}

On peut faire plus simple en ne stockant que "l'heure" (nb de secondes) du changement de consigne, et la consigne associée. A moins de considérer que si une heure de fin et la prochaine heure de début ne sont pas la même, la consigne doit être 0 entre ces deux heures.

Si le sketch doit tourner en permanence il faut aussi tenir compte du fait que le compteur de millis() repasse à zéro tous les 49j et 17h environ.

En réalité utilisé millis() est à proscrire pour la simple et bonne raison que sa précision est incompatible avec un système temps réel (dérive de plusieurs secondes / minute).

regarde du coté des RTC ou horloge temps reel type DS1307 qui te permetron d'avoir une vrai horloge.
les tiny RTC peuvent tres bien faire l'afaire et ne coute pas cher, de plus il existe des librairie deja toute fait pour les utilisé et cela ce branche en i2c .

Et quel est le problème de simplement utiliser la fonction delay() ?

Quelque chose du genre :

void loop(){
analogwrite(sortieLED,255);  //allumer LED
delay(3600000); // attendre une heure 
analogwrite(sortieLED,0); //eteindre LED
delay(3600000); //attendre une heure avant de rallumer

}

C'est toi qui voulait un réglage suivant des horaires, pas nous ....

desacant:
Et quel est le problème de simplement utiliser la fonction delay() ?

Quelque chose du genre :

void loop(){

analogwrite(sortieLED,255);  //allumer LED
delay(3600000); // attendre une heure
analogwrite(sortieLED,0); //eteindre LED
delay(3600000); //attendre une heure avant de rallumer

}

Delay bloque l'exécution du programme.
Si ton Arduino ne doit rien faire d'autre, c'est faisable.
Mais le besoin n'était pas clairement exprimé. Utiliser delay() pour une temporisation est généralement une mauvaise pratique, sauf dans des cas triviaux.

le probleme de delay() c'est que ton programe estcomme figé par cette fonction et il ne peut plus effectuer d'autre tache pendant ce temps la !

D'accord donc solution écartée, ma carte doit également gérer des capteurs de climats en simultané.

Je n'ai pas compris le fonctionnement du tableau :

long horaires [10][2] = {{6328,7875},{15687,18247} ... }; // {horaire début,horaire fin}

dans ce tableau est stocké les secondes écoulées depuis minuit ? Donc dans le cas précédent le système s'allume à 1h45 environ (6328s après minuit) puis s'éteind vers 2h11 (7875s après minuit) ? Et ainsi de suite je programme sur une période de 24h ?

Dans ce cas :

long horaires [10][3] = {{6328,7875,128},{15687,18247,56} ... }; // {horaire début,horaire fin, consigne}

A quoi correspond la consigne ?

La consigne c'est la valeur de PWM de la led.
Si tu utilises une horloge RTC, alors l'heure peut être le nb de secondes après minuit en effet.
A voir si tu as besoin d'une heure de début et de fin ou si les consignes s'enchainent directement (heure d'application de la consigne)

Non les consignes vont s’enchaîner directement :
Par exemple : 2h d'éclairage a 100%, suivi d'une heure à 80%, puis 1h à 60%...

Mais du coup sans RTC à quoi correspondent les valeurs de ton tableau ?