Nouveau dans ce forum et débutant Arduino, je poste mon premier message pour demander un avis, une orientation de recherche.
J’ai acheté un Kit Starter Arduino Elegoo chez Amazon qui comprend un Arduino Mega et j’ai aussi acheté des Nano.
J’essaye de créer une boîte lumineuse avec une bande de 40 LEDs RGB qui devra s’animer en continu et avec une télécommande IR qui me permettra de modifier l’intensité et le temps d’animation. Le projet me semble faisable et souvent abordé sur le Net. Mais cela ne semble pas si simple après mes lectures.
J’ai longuement cherché, j’ai beaucoup lu et essayé avec une bande blanche pour débuter (sans data) mais je me suis confronté au problème des boucles continue et des interruptions IR que je n’ai pas pu résoudre malgré mes copies de codes çà et là. Mon code recopié pour gérer l’IR fonctionne bien avec IRremote.h
J’ai peut-être compris qu’il fallait gérer des interruptions sur des pins identifiées. J’ai aussi vu qu’il existait un/des bibliothèques pour gérer les interruptions, exemple PinChangeInterrupt, et j’ai aussi découvert attachInterrupt().
Le problème est bien de capturer la commande IR quand elle arrive et sans interrompre les boucles qui gèrent l’animation des LED. Il me semble que l’instruction delay() par exemple est difficile à programmer s’il n’y a pas de notion d’interruption IR qui prendrait la priorité.
Si vous avez déjà fait ou vu ce genre de projet, je suis preneur. Je voudrais simplement un conseil pour orienter ma recherche :
1 – Savoir si on peut réellement le faire avec un Arduino et lequel (puissance ?)
2 – Si des interruptions peuvent être gérées et sur quels pins (pin de l’IR) ?
3 – L’utilisation d’une bibliothèque peut-elle résoudre ce problème : FastLed, Adafruit, OctoWS2812 etc ?
En vous remerciant par avance de vos conseils et de vos codes si possibles !
donc si vous avez un bandeau qui nécessite plus de 50µs pour faire son affichage et qui bloque les interruptions ça ne fonctionnera pas.
J'utilise des APA102 qui ne dépendent pas d'un timing précis (vous fournissez la clock), j'ai jamais essayé avec une télécommande mais je pense que ça devait marcher avec fastLed
Salut @pat-06
Je suis peut-être à côté de la plaque, mais bon... si c'est le cas, I'm sorry, je n'ai rien dis
Dans la donc GitHub de IRremote, il est marqué :
Si vous utilisez une bibliothèque qui nécessite le même timer qu'IRremote, vous avez un problème, puisque la ressource timer ne peut pas être partagée simultanément par les deux bibliothèques.
Changer la minuterie
La meilleure approche consiste à modifier la minuterie utilisée pour IRremote, ce qui peut être réalisé en spécifiant la minuterie avant #include <IRremote.hpp>.
Je ne pense pas... C'est un problème de confits entre timer, chacune (les LEDs et les interruptions) veux utiliser le même.
Bon code
R-P7
EDIT : c'est quoi votre code ? Pouvez vous le poster ici (entre balises <code/>, évidement) ?
imaginez que je vous dise "Si tu sais méditer, observer et connaître sans jamais devenir sceptique ou destructeur" et que chaque lettre arrive toutes les 50µs mais que après 550µs la lecture est bloquée pendant 37 ticks puis ça reprend
durant les 550µs vous aurez lu Si tu sais
puis vous ratez les 37 prochains caractères
puis la lecture reprend et vous lisez devenir sceptique ou destructeur et donc le message que vous pensez avoir reçu c'est "Si tu sais devenir sceptique ou destructeur" ==> vous avouerez que ça n'a pas le même sens...
pour une télécommande infrarouge c'est un peu la même chose.
la bibliothèque IRRemote a besoin de recevoir les trames infrarouges de commande, c'est un train d'onde qu'il faut échantillonner assez fréquemment pour comprendre la commande qui vient d'être envoyée. Pour cela la bibliothèque va utiliser une interruption toutes les 50µs pour aller prendre un échantillon sur la broche de réception de signal IR. Si l'interruption ne peut pas avoir lieu comme prévu, vous ratez des échantillons et le message devient impossible à décoder.
C'est ce qu'il se passe avec des Noepixels parce que pour transférer le tableau de couleurs des LEDs depuis la mémoire vers le bandeau il faut un timing précis et donc les bibliothèques gérant ces bandeaux de leds interrompent les interruptions afin de gérer finement le temps d'émission des bits sur le fil de data. ➜ pendant ce temps là, l'interruption infra-rouge ne fonctionne pas et vous perdez la trame
Si vous prenez les bandeaux type APA102, ils ont une broche de plus qui définit l'horloge d'envoi des données (à chaque impulsion un nouveau bit est dispo) et donc la bibliothèque n'a pas besoin de bloquer les interruptions, elle positionne le bit, puis crée un front sur l'horloge et si c'est interrompu un moment c'est pas grave, le bit suivant arrivera un peu plus tard. ➜ les pixels peuvent bien être transférés et à la vitesse que l'on veut (y compris très vite par exemple en utilisant le SPI matériel).
voici un petit exemple les boutons 0 à 9 choisissent la couleur de 3 leds qui défilent sur le bandeau. le bouton C éteint le bandeau et les boutons + ou - gèrent la vitesse de défilement
le code
#include <FastLED.h>
#include <IRremote.h>
// Hardware SPI - data 51, clock 53 pour la mega https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging
const byte nombreDeLeds = 40;
const byte dataPin = 51;
const byte clockPin = 53;
//
const byte IRPin = 9; // sur MEGA 5, 6, 9, 11, 46
CRGB leds[nombreDeLeds];
IRrecv receiver(IRPin);
const unsigned long deltaT = 10;
bool enPause = true;
unsigned long duree = 250;
uint8_t hue = 128;
void animation() {
static unsigned long chrono;
static byte currentLed = 0;
if (enPause) return;
if (millis() - chrono >= duree) {
if (currentLed > 1) leds[currentLed - 1] = CHSV( hue, 128, 100);
leds[currentLed] = CHSV( hue, 255, 200);
if (currentLed < nombreDeLeds - 1) leds[currentLed + 1] = CHSV( hue, 128, 100);
chrono = millis();
currentLed = (currentLed + 1) % nombreDeLeds;
FastLED.show();
FastLED.clear();
}
}
void interpretationCodeIR() {
switch (receiver.decodedIRData.command) {
case 162: Serial.println(F("POWER")); break;
case 226: Serial.println(F("MENU")); break;
case 34: Serial.println(F("TEST")); break;
case 194: Serial.println(F("BACK")); break;
case 224: Serial.println(F("PREV.")); break;
case 168: Serial.println(F("PLAY")); break;
case 144: Serial.println(F("NEXT")); break;
case 2: Serial.println(F("PLUS")); enPause = false; if (duree >= deltaT) duree -= deltaT; Serial.print(F("duree=")); Serial.println(duree); break;
case 152: Serial.println(F("MINUS")); enPause = false; duree += deltaT; Serial.print(F("duree=")); Serial.println(duree); break;
case 104: Serial.println(F("num: 0")); enPause = false; hue = 25; break;
case 48: Serial.println(F("num: 1")); enPause = false; hue = 50; break;
case 24: Serial.println(F("num: 2")); enPause = false; hue = 75; break;
case 122: Serial.println(F("num: 3")); enPause = false; hue = 100; break;
case 16: Serial.println(F("num: 4")); enPause = false; hue = 125; break;
case 56: Serial.println(F("num: 5")); enPause = false; hue = 150; break;
case 90: Serial.println(F("num: 6")); enPause = false; hue = 175; break;
case 66: Serial.println(F("num: 7")); enPause = false; hue = 200; break;
case 74: Serial.println(F("num: 8")); enPause = false; hue = 225; break;
case 82: Serial.println(F("num: 9")); enPause = false; hue = 255; break;
case 176: Serial.println(F("key: C")); //no break
default: enPause = true; FastLED.clear(); FastLED.show(); break;
}
}
void setup() {
Serial.begin(115200);
FastLED.addLeds<DOTSTAR, dataPin, clockPin >(leds, nombreDeLeds);
FastLED.setBrightness(50);
receiver.enableIRIn();
}
void loop() {
if (receiver.decode()) {
interpretationCodeIR();
receiver.resume();
}
animation(); // appel non bloquant
}
Merci Pandarox007
Hummm pas si simple donc...je ne sais pas encore si la bibliothèque FastLed par exemple utilise le même timer que celle IRremote (je ne sais pas comment le savoir pour le moment ! )
Merci beaucoup J-M-L c'est une information que je pense comprendre et qui explique ce qui n'était pas expliqué par ailleurs. Un tutoriel complet de votre part aurait un immense succès s'il était en anglais !
Je m'empresse de commander une bande APA102 pour tester...
Bien à vous
Un bon tutoriel Fastled peut être trouvé ICI. Le chapitre dédié aux interruptions est très intéressant.
Une petite astuce: consiste ne pas envoyer les "frames" en continu, mais à introduire un petit délay, si l'animation le permet. Pendant ce délay, iRremote reprend le contrôle des interruptions et est capable de lire un donné, entre 50 et 100 ms. est généralement suffisant.
Merci gonpezzi
J'étais tombé sur cet article sans en comprendre encore complément le sens, je vais donc le relire.
Quant au delay() cela me semble difficile d'attendre 50 à 100ms pour une animation en continu, je referai des tests pour confirmer...bonne journée
A condition que vous appuyez sur le bouton de la télécommande au bon moment… plus la pause entre deux affichages est longue et plus l’affichage lui même est court (peu de LEDs) et plus vous avez de chance de bien recevoir le message, mais ça reste un peu au hasard et frustrant pour l’utilisateur qui risque d’avoir à appuyer plusieurs fois pour le bouton pour qu’il soit pris en compte.
Bien sûr cher @J-M-L, comme je l'ai déjà dit : "si l'animation le permet".
Par exemple, si nous fabriquons un thermomètre, il n’est pas nécessaire d’animer continuellement la bande. Dans ce cas, un retard utilisant "delay" ou "millis" jusqu'à 10 secondes n'est pas pertinent et le contrôle IR fonctionnera correctement.
Cela dit, je ne vais pas donner mon avis avant d'avoir étudié et testé attentivement ce qui est recommandé dans le post précédent (#8), car je travaille actuellement sur un projet de ces led avec une télécommande IR et jusqu'à présent je n'ai pas eu ce problème.
sauf si par malchance vous appuyez sur le bouton juste pendant la mise à jour du thermomètre et que vous avez un nombre conséquent de LEDs. Certes, il suffira d'appuyer une seconde fois mais je trouve cela frustrant
Une LED met 30µs pour se mettre à jour - temps pendant lequel les interruptions sont bloquées. Si vous avez deux LEDs, vous bloquez donc les interruption pendant 60µs ce qui fait que vous décalez l'interruption IR qui se produit toutes les 50µs mais elle sera traitée et avec un peu de chance le signal sur la broche de réception sera toujours le même et donc il n'y a pas de perte. Mais si vous avez 4 Leds, ça prend 120µs et là vous avez eu 2 interruptions IR, la première est perdue et la seconde sera traitée ➜ vous commencez à déformer le message reçu.
Imaginez que vous ayez 100 Leds, là c'est carrément 3ms de perdues soit ~60 échantillons du message IR. C'est dns ce cas irrécupérable et l'utilisateur ne comprendra pas pourquoi ça n'a pas fonctionner.
Si l'utilisateur tient le bouton appuyé, certaines télécommandes ne renvoient pas le même code mais un code dit de répétition. ça sert à la réception pour comprendre ce que fait l'utilisateur (si je tiens le bouton "mettre le son plus fort" appuyé, on veut que le son continue d'augmenter. Le souci est que si j'ai raté la première réception du message, je ne sais pas ce qu'il faut continuer à répéter et donc ça ne fonctionne pas...
il en va de même avec de nombreuses bibliothèques qui dépendent des interruptions pour fonctionner correctement, c'est pour cela que je préfère les APA102, c'est un souci de moins à gérer.
Vous avez tout à fait raison, ce que vous dites est incontestable.
Dans un fil de discussion, il n'y a pas longtemps, vous avez recommandé ce type de LED et j'ai l'intention de les essayer.
Savez-vous s'ils existent au format 5 ou 10mm. ?. Autrement dit, comme une LED normale non SMD.
J'aimerais avoir votre avis J-M-L
Je voudrais commander une bande APA102 pour tester votre code d'hier, il apparait d'autres types de bandes peut-être plus récentes.
J'ai trouvé une synthèse ICI
Serait-il judicieux d'utiliser la HP107s par exemple ?
HD107s 5050 Pixel led is a update of apa102/apa102c, it is same protocel as apa102 ,same pcb,same controller HD107s: PWM refresh Rate 27 kHz PWM; transmission rate 30MHZ; 8bits)
Merci.
Pour le moment ils ne fonctionnent pas pour moi, j'en ai besoin au format 5mm pour un cube LED, il y aura une chance de les essayer.
Salutations.