Go Down

Topic: Augmenter et réduire la luminosité d'une LED (Read 8427 times) previous topic - next topic

LXXL

Bonjour.
Voici mon problème, J'aimerai avec ma télécommande rc5 allumer, éteindre, ainsi qu'augmenter ou réduire la luminosité de ma LED.
J'arrive à allumer et éteindre ma LED mais je ne sais pas comment faire pour augmenter et réduire la luminosité malgré de nombreuses recherches. Tout ce que je trouve je ne le comprends pas car je suis un néophyte.

Voici mon programme :

#include <IRremote.h>

int RECV_PIN = 10;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {
    if(results.value == 0x205D906F) {
      digitalWrite(13, HIGH);
    }
    irrecv.resume(); // Receive the next value
  }
  if (irrecv.decode(&results)) {
    if(results.value == 0x205D48B7) {
      digitalWrite(13, LOW);
    }
    irrecv.resume(); // Receive the next value

  }
}

Quelqu'un pourrait t-il me dire quoi mettre pour parvenir à mon objectif ?
Merci d'avance, LXXL

thib974

salut, si la led est sur une pin PWM, tu peux faire varier la luminosité en utilisant un analogWrite avec une valeur comprise entre 0 et 255. En changeant les valeur tu fait varier la luminosité, en prenant une incrémentation par 51 tu as 5 niveaux.

si l'arduino ne gère que la télécommande tu peux utiliser une boucle while pour que le programme ne commence que s'il y a des infos venant du récepteur ir. je ne connais pas la programmation des récepteur ir, donc il faudra vérifier le code qui suit, au pire j'espère qu'il te mettra sur la voie.


 
Code: [Select]

#include <IRremote.h>

int RECV_PIN = 10;
IRrecv irrecv(RECV_PIN);
decode_results results;
int ledpin=13; 
int ledlevel=0;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {
    if(results.value == 0x205D906F && ledlevel)
    {
      ledlevel=255; //led on
    }
    if(results.value == //mettre la valeur pour luminosité ++// && ledlevel <255)
    {
      ledlevel=ledlevel+51; //luminosité led ++
    }
     if(results.value == //mettre la valeur pour luminosité --// && ledlevel >0)
    {
      ledlevel=ledlevel-51; //luminosité led --
    }
   if(results.value == 0x205D48B7 )
    {
      ledlevel=0; //led off
    }
    analogWrite(13, ledlevel);
    irrecv.resume(); // Receive the next value

  }
}

LXXL

Je te remercie pour ta réponse Thib.
Je vais essayer tout sa dès que je pourrais.

LXXL

Je n'ai pas penser à dire quelle matériel j'ai.
Je fais l'émission avec une télécommande rc5.
La réception avec un TFMS 38kHz.
Une petite LED et une résistance 330ohms.
Je n'ai pas de photo du montage mais c'est le même que Ken Shirrif à peu près. Et je n'ai pas de potentiomètre.
J'ai essayer le programme malgré tout mais bon.
Est-ce au moins possible de jouer sur l'intensité sans potentiomètre?

thib974

je vois pas ce que tu veux dire par jouer sur l'intensité sans potentiomètre. Tu parle de la partie IR ou de la partie éclairage? 

LXXL

Je me suis mal exprimé peut être.
Mon objectif : Si j'appuie sur "1" ( avec ma télécommande) ma led s'allume.
                    Si j'appuie sur "0" ma led s'éteint.
                    Si j'appuie sur "+" l'intensité lumineuse de ma led augmente.
                    Si j'appuie sur "-"  l'intensité lumineuse de ma led diminue.

Le programme que j'ai collé au début me permettait d'allumer et d'éteindre sans problème.
Maintenant je ne sais pas comment faire pour jouer sur cet éclairage.
Je pense ( et j'espère vu mon niveau de programation) qu'il faut que je garde la mème mise en forme c'est à dire :

if (irrecv.decode(&results)) {
    if(results.value == 0x205D906F) {
      digitalWrite(13, HIGH);
    }
    irrecv.resume(); // Receive the next value
  }

Je ne pourrai pas remplacer le HIGH par autre chose qui me permettrai d'augmenter/ réduire la luminosité de la led?


 


micol



if (irrecv.decode(&results)) {
    if(results.value == 0x205D906F) {
      digitalWrite(13, HIGH);
    }
    irrecv.resume(); // Receive the next value
  }

Je ne pourrai pas remplacer le HIGH par autre chose qui me permettrai d'augmenter/ réduire la luminosité de la led?


Avec digitalWrite() tu ne peux mettre que HIGH ou LOW.
Comme te l'a dit Thib974, il te faut utiliser analogWrite sur une broche PWM et là tu peux mettre une valeur progressive de 0 à 1023.

exemple :  analogWrite(led, 512)  allumera la led avec la moitié de l'intensité max.
*** Micol *** resolutly politically NOT correct

thib974

En faite c'est très simple, il te suffit d'alimenter la led depuis une des pins notée PWM (pulse with modulation). Ces pin te permette de d'avoir une tension de sortie variable, de 0 à 5v pour un Uno, dans le codage ces valeurs vont de 0 à 255 pour une résolution de 256bit et 0 1023 pour 1024bit. La variation de tension fera changer la luminosité de la led.

La commande digitalWrite n'a que 2 état comme tu le sais déjà, donc remplace la par un analogWrite et tu pourra demander une tension de sortie variable.
Donc au lieu de digitalWrite(13, HIGH);,    utilise analogWrite(13, 255);
Et au lieu de digitalWrite(13, LOW);,     utilise analogWrite(13, 0);

pour l'instant si tu ne change que cela dans le codage, il devrai fonctionner de la même manière. Mais pour ajouter la variation de tension le plus simple est de déclarer un int avant ton setup{}, que tu nome ledlevel. Et tu remplace la valeur de l'analogWrite par ledlevel, comme ceci analogWrite(13, ledlevel);

En suite, au lieu de faire un  analogWrite dans la fonction if, qui compare results.value, tu vas lui demandé de changer la valeur de ledlevel.

if (irrecv.decode(&results)) {
   if(results.value == 0x205D906F) {
     ledlevel=255; // led ON
   }
   irrecv.resume(); // Receive the next value
 }



Et ce n'est qu'en dernière ligne de ta void loop que tu demandera analogWrite(13, ledlevel);. Comme ça, quand tu appuis sur un bouton de la télécommande ça ne fera que changer la valeur de ledlevel et l'analogWrite ce contentera de mettre a jour la tension de sortie si elle a était modifié.

Pour faire varier la tension tu ajoute ou retranche une valeur a ledlevl, par exemple 51 (255/5=51).
par exemple pour augmenter la luminosité

if (irrecv.decode(&results)) {
   if(results.value == mettre le code pour le bouton +) {

     ledlevel=lelevel+51; // led luminosité +

   }
   irrecv.resume(); // Receive the next value
 }

Maintenant je pense que tu peux mettre toute tes fonction if pour les boutons dans la même if (irrecv.decode(&results)) . Je ne suis pas sure qu'il soit obligatoire de la remettre pour chaque bouton. Normalement tu obtiens un code comme celui que je t'ai montré plus haut.



LXXL

Merci beaucoup pour vos réponses très claires.
Je vais essayer de compiler.

lve123

Bonjour
utilise la structure switch / case:

Code: [Select]
switch(result.value){
case 0x205d906f:
ledlevel =255;

case 0x205d48b7
ledlevel = 0;

case 0x205dzzzz //code touche+
--- //instructions pour augmenter ledlevel
case 0x205dyyyy // code touche -
--- //instructions pour diminuer ledlevel
}
analogueWrite(sortie,ledlevel);

---

lve123

oups j'ai oublier les : aux lignes case.
cette façon de faire te permet de rajouter d'autres fonctions (touches) facilement.
A+

LXXL

thib : j'essaye de suivre tes instructions à la lettre, j'ai remplacer par un analog write et effectivement sa fonctionne comme avant. aucuns problèmes de ce coté.
je déclare le int ledlevel mais ensuite je ne comprends plus à partir d'ici.
Qu'entends tu par remplacer la valeur de l'analogWrite par ledlevel ? je ne sais jamais où et quand il faut remplacer des mots par des codes. J'ai déjà lu la suite pour mieux essayer de comprendre et que veux tu dire par "Et ce n'est qu'en dernière ligne de ta void loop que tu demandera analogWrite(13, ledlevel);" ? où devrais-je mettre ce analog write(13,ledlevel) exactement?

J'ai actuellement ceci :

#include <IRremote.h>

int ledlevel=0;
int RECV_PIN = 10;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {
    if(results.value == 0x205D906F) {
       analogWrite(13, 255);
    }
    irrecv.resume(); // Receive the next value
  }
  if (irrecv.decode(&results)) {
    if(results.value == 0x205D48B7) {
      analogWrite(13, 0);
    }
    irrecv.resume(); // Receive the next value

  }
}

lve123 : Merci pour tes indications mais je préfère rester sur du if, j'ai déjà des difficultés avec ceux là donc je préfère ne pas commencer autre chose, par contre si je suis longuement bloqué j'essaierai en parallèle.



lve123

Bonjour je me permet d'insister sur switch / case, c'est tellement plus simple !
Par exemple :
Code: [Select]

switch(result.value){

case 0x205d48b7: //bouton off
ledlevel = 0;

case 0x205d906f: // bouton on
ledlevel = 255;

case 0x205dzzzz: // bouton +
  if (ledlevel != 255) { // si on n'est pas allumé à fond
    if (TP == 0) { // on incrémente toutes les 0,5 secondes si on laisse le doigt sur le bouton
       ledlevel ++;
       TP = 5;
     }
  }

case 0x205dyyyy: // bouton -
  if (ledlevel != 0) { // si on est pas éteint
    if(TM == 0) { // on décrémente toutes les 0,5 secondes
       ledlevel --;
       TM = 5;
     }
  }
}
irrecv.resume();

duree = millis(); // calcul temporisation de 100 millisecondes
if((duree%100)>=50){
  if (FT == true) {
   if (TP != 0) {
      TP--;
    }
   if (TM != 0){
       TM --;
    }
}
FT == false;
}
else {
FT = true;
}


Il faut déclarer :
byte TP = 0;
byte TM = 0;
boolean FT = false;
long duree = 0;
A+

lve123

oups j'ai encore oublier à la fin (c'est l'alcool) analogueWrite(sortie, ledlevel);

LXXL

Puisque tu insistes c'est que tu es sur de ce que tu dis !
Cela dit pourrais tu m'indiquer ce qu'il faut signaler tout au début, ce qu'il faut mettre dans void set up et dans void loop . car je ne sais pas du tout où mettre tout sa. Tout ce que j'ai pu voir dans mes recherches infructueuses et Toutes ces parenthèses me perturbe.
merci.

Go Up