Augmenter et réduire la luminosité d'une LED

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

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.

#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

  }
}

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

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?

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?

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?

LXXL:
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.

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.

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

Bonjour
utilise la structure switch / case:

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);

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

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.

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

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+

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

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.

Bonjour
excuse-moi, mais je dois partir (c'est dimanche)
je reviendrai vers 19 h.
A+

Aucuns problèmes, j'essaie de travailler avec ce que tu m'as envoyer en attendant.
A très bientôt.

thib : pourrais tu me dire si ma programmation est correcte? J'ai suivis comme j'ai pu tes indications.
J'arrive et à allumer et à eteindre avec analog. Quand à la variation de lumière : je ne la vois pas !
Sa m'a l'air de fonctionner car j'appuie sur 1 pour allumer,

Quand j'appuie sur 1 pour allumer, la led s'allume.
En guise de test j'appuie sur 0 pour éteindre, elle s'éteint.
Je l'a rallume avec 1, et j'essaye de réduire l'intensité lumineuse.
Après un certain nombre de pressions du bouton bas pour baisser (les boutons sont usés on dirait bien)
la led s'éteint mais je n'ai vu aucune variation.
Après un certain nombre de pressions du bouton haut pour augmenter
la led s'allume mais je n'ai vu aucune variation.

Pourrais tu me dire si la programmation est correcte au moin?

#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) {
ledlevel=255; // led ON
analogWrite(13, 255);
}
irrecv.resume(); // Receive the next value
}
if (irrecv.decode(&results)) {
if(results.value == 0x205D48B7) {
ledlevel=0; // led OFF
analogWrite(13, 0);
}
irrecv.resume(); // Receive the next value

}
if (irrecv.decode(&results)) {
if(results.value == 0x205DC03F) {

ledlevel=ledlevel+51; // led luminosité +
analogWrite(13, ledlevel);

}
irrecv.resume(); // Receive the next value
}
if (irrecv.decode(&results)) {
if(results.value == 0x205D40BF) {

ledlevel=ledlevel-51; // led luminosité -
analogWrite(13, ledlevel);

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

Quel carte arduino utilise tu ? Par ce que sur la Uno par exemple la pin 13 ne permet pas de sortir du PWM, seul les pin: 3, 5, 6, 9, 10,11.

donc a mon avis, ton code est fonctionnel mais comme la pin 13 ne peut faire que 0 ou 255, si ledlevel a une valeur comprise entre les deux, l'Uno ne change rien. C'est surement pour ça qu'il se passe rien entre ON et OFF.

Ne change pas ton code mais juste la pin d'alimentation de la led, utilise la 11, sans oublier les analogWrite(11, ledlevel);
ça devrai marcher beaucoup mieux. Désolé de ne pas avoir remarqué ça avant...
oublie pas de mettre la bonne résistance avec la led, seul la pin 13 en a une intégré.

Sinon tu peux supprimer les analogWrite dans les conditions if(results.value ==.... , et n'en mettre qu'un seul a la fin de la void loop. Comme ça dans les if(results.value ==... tu n'as besoin de changer que la valeur de ledlevel.

Autre chose, j'ai rassemblé toute les if(results.value ==.... dans une seul fonction if.

#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)) //attend un commande du recepteur IR
    {

    //teste condition bouton ON
    if(results.value == 0x205D906F) {
       ledlevel=255; // led ON

    //teste condition bouton OFF
    if(results.value == 0x205D48B7) {
      ledlevel=0; // led OFF
      }
    
   ////teste condition bouton + 
   if(results.value == 0x205DC03F && ledlevel < 255) {

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

   //teste condition bouton - 
   if(results.value == 0x205D40BF && ledlevel>0) {

      ledlevel=ledlevel-51; // led luminosité -
      

    } 
    irrecv.resume(); // Receive the next value
 
 
analogWrite(11, ledlevel);
}