Eclairage Leds par Arduino pour diorama

Télécommandé par infrarouge.

a marqué ce sujet comme résolu.

Hello hello

Je débute tout juste sur une arduino uno R3 (je l’ai reçu hier…) et je bute sur un programme.

Je souhaite faire un éclairage évolutif sur un diorama, piloté pas un Arduino (uno pour commencé, mais surement nano par la suite) et télécommandé (pour changer de mode)

Mais je bute sur un soucis. voila mon code (mélange de code repris un peu partout)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* YourDuino.com Example Software Sketch
 IR Remote Kit Test
 Uses YourDuino.com IR Infrared Remote Control Kit 2
 http://arduino-direct.com/sunshop/index.php?l=product_detail&p=153
 based on code by Ken Shirriff - http://arcfn.com
 Get Library at: https://github.com/shirriff/Arduino-IRremote
 Unzip folder into Libraries. RENAME folder IRremote
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/

#include "IRremote.h"

/*-----( Declare Constants )-----*/
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11
int pinLed=3; // pin de la led de test

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);           // create instance of 'irrecv'
decode_results results;            // create instance of 'decode_results'
/*-----( Declare Variables )-----*/


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Raw Data + Button Decode Test");
  irrecv.enableIRIn(); // Start the receiver
  pinMode(pinLed,OUTPUT); // led en sortie de courant

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if (irrecv.decode(&results)) // have we received an IR signal?

  {
//    Serial.println(results.value, HEX);  UN Comment to see raw values
    translateIR(); 
    irrecv.resume(); // receive the next value
  }  
}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/
void translateIR() // takes action based on IR code received

// describing Car MP3 IR codes 

{

  switch(results.value)

  {

  case 0xFF30CF:  
    Serial.println(" 1              "); 
    digitalWrite(pinLed,HIGH); // on passe le pin à +5V
    delay (1000);
    digitalWrite(pinLed,LOW); // on passe le pin à 0V
    break;

  case 0xFF18E7:  
    Serial.println(" 2              "); 
    digitalWrite(pinLed,HIGH); // on passe le pin à +5V
    delay (2000);
    digitalWrite(pinLed,LOW); // on passe le pin à 0V
    break;

  case 0xFF7A85:  
    Serial.println(" 3              "); 
    digitalWrite(pinLed,HIGH); // on passe le pin à +5V
    delay (3000);
    digitalWrite(pinLed,LOW); // on passe le pin à 0V
    break;

  default: 
    Serial.println(" other button   ");

  }

  delay(500);


} //END translateIR



/* ( THE END ) */

La c’est un test avec une led qui s’allume en fonction du bouton utilisé, pour faire un code plus complexe par la suite. Le code n’est pas forcement complet, j’ai enlevé les boutons qui ne servent a rien.

En gros, chaque cas aura un bout de code, plus ou moins complexe suivant le cas, et n’utilisera pas forcement les mêmes pins de l’arduino. Pour gérer par exemple, les réverbères, l’éclairage des maisons, les feux tricolores, une barrière électrique…

Seulement j’aimerais pouvoir changer de mode (par un appuie sur la télécommande) en cours de mode. Si j’appuie sur 3, je suis obligé d’attendre que le code se fasse, et ensuite d’attendre que l’arduino attende que j’appuie, pour que l’appuie se fasse détecté. (je sais pas si je suis clair ^^).

Ce que je voudrais, c’est passer du cas 3 au cas 2, sans avoir besoin d’attendre que le code du cas 3 soit fini en entier…

La fonction delay() ne me semble pas approprié, et je pensais utiliser millis(), mais j’ai pas trop compris comment ça fonctionnait…

y’a aussi surement moyen, d’optimiser le tout, mais c’est pas d’actualité pour le moment… déjà faire en sorte que ça marche ^^

merci d’avance pour vos précieux conseils…

+0 -0

Salut !

Alors oui, c’est bien la fonction millis() qu’il faudra utiliser dans ton cas.
Cette fonction renvoie le nombre de millisecondes depuis le lancement de ton programme sur la carte, donc pour avoir le nombre de millisecondes écoulés depuis un temps t, tu enregistre juste ce temps dans une variable puis au moment t+1, tu fais la soustraction pour connaitre l’intervalle.

En code ça donne:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int time = 0;
int delay = 0;

void loop() {
  if (digitalRead(3) == HIGH) { // Par exemple si appuie d'un bouton
    time = millis(); // On stocke le temps qu'il s'est écoulé depuis le début
    digitalWrite(5, HIGH); // On allume la led
  }

  delay = millis() - time; // On soustrait le temps présent à l'ancien temps pour avoir l'intervalle entre l'appuie du bouton et "maintenant"

  if (delay > 1000)
    digitalWrite(5, LOW); // On l'éteint au bout d'1 seconde

}

Après je te laisse adapter pour l’utiliser dans ton code ;)

En fait, j’y ai réfléchi toute la nuit (la nuit porte conseil comme on dit ^^)

Et je n’ai pas trouvé de solution pour faire lire a tout moment le code ir reçu…

Du coup, ayant trouvé des clones de Nano pour moins de 2€, je pensais en prendre plusieurs, en utiliser un par fonction (éclairages, réverbères, feux…) et les commander via un dernier qui reçoit les code IR.

Ce serait moins simple a caser, mais plus simple a programmer non ? En bricolant un grand hub usb, et calant un relais sur chaque port, et le Nano master commande ces relais. Nano esclave allumée, programme lancée… et inversement.

Non, y’a plus simple ?

SAlut , si tu penses que faire communiquer plusieurs cartes , envoyer et recevoir des données , puis gerer la fonction de commande sur une autre carte qui doit tout analyser recevoir et renvoyer les infos aux autres est plus simple que de changer juste une fonction de ton code , ben je t ’ assure que tu te trompes graaaaavvvve !!!!

Ardakaniz t ’ as donné la solution sur un plateau …

la fonction delay() stoppe completement le prog d ’ ou ton pb . la fonction millis() declenche un timer en gros qui stoppe rien du tout , ce qui resout donc ton pb . il ne reste plus qu ’ a adapter ton code et remercier Ardakaniz pour t ’ avoir donner la solution .

PS : delay() est une fonction ; delay=xxxxxx est une variable ; ca n ’ a plus rien a voir .

+0 -0

Yop

J’ai refait un essai avec millis, ca retourne bien a la detection infrarouge, mais le bout de code dans les "case" ne se font qu’une seule fois, et je fais un boucle dedans, je peux pas en sortir…

Il faudrait alors que je puisse stocker la valeur de la commande infrarouge, pour la faire repeter et la changer si une nouvelle revient…

Le switch ne devrait aps se faire sur la valeur de la telecommande, mais sur une valeur qui reste en memoire (la valeur de la telecomande change une fois le "case" fait

Pas simple…

Un exemple de comment tu pourrais faire sans avoir à acheter une Arduino pour chaque mode (ce qui est pas très économique on va dire) serait de virer le delay et le digitalWrite(pinLed, LOW) dans chaque cas, mais à la place de mettre l’équivalent de ma variable time dans l’exemple à la valeur de millis, puis vérifier l’interval.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
int mode1_starttime = -1;

void translateIR() {
  switch (results.value) {
    case 0xFF30CF:
      Serial.println("Mode: 1");
      digitalWrite(pinLed, HIGH); // Active la LED
      mode1_starttime = millis(); // 
      break;

    // [...]
  }
}

void disable_modes() {
  if (mode1_starttime >= 0 && (millis() - mode1_starttime) >= 1000) { // Va tester la première condition avant
    digitalWrite(pinLed, LOW);
    mode1_starttime = -1; // Evite d'avoir un boolean en plus pour dire si le mode a été activé ou pas : -1 = désactivé, quand une valeur de millis (>= 0) = activé 
  }

  // [...]
}

ça reste un code "assez" simple tout en évitant d’avoir à acheter de nombreuses cartes, le seul inconvénient c’est que ça peux vite finir long, donc l’utilisation de tableaux pourrais généraliser tout ça.
Si jamais tu veux que quand un mode est activé, tu veux désactiver les autres, tu as juste à modifier la condition de disable_modes pour que quand modeX_starttime vaille -1, ça désactive, ou -2 pour éviter de boucle et d’éxécuter des digitalWrite inutiles

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte