Nano + FastLed

Bonjour à tous,
je m’amuse depuis peu avec des cartes arduino nano(chinoises il est vrai :-[ ) et un joli ruban WS2812B.

La librairie FastLed fait des miracles mais … je commande mon arduino qui gere les led par radio (433Mhz et rc-switch) en lui communiquant 4 valeurs : le N° de programme, la couleur, la luminosite et la vitesse.

Voici le code (soyez indulgent je débute, mais toute remarque sera bienvenue)

#include "FastLED.h"
#include <RCSwitch.h>


// How many leds in your strip?
#define NUM_LEDS 330
#define DATA_PIN 3

// Define the array of leds
CRGB leds[NUM_LEDS];

RCSwitch mySwitch = RCSwitch();
int val_prog = 100;
int val_vit = 100;
int val_lum = 127;
int val_cou =0;

uint8_t gHue = 0;
unsigned long previousMillis = 0;
const long interval = 500;

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
  if (mySwitch.available()) {
     
    int value = mySwitch.getReceivedValue();
    /* valeurs recues :
     *  entre 10000 et 10099 : n° de programme
     *  entre 11000 et 11200 : vitesse 
     *  entre 12010 et 12255 : luminosité
     *  entre 13000 et 13255 : couleur
    */
    if (value >= 11000 && value <= 11200) {val_vit = value-11000;}
    else if (value >= 12010 && value <= 12255) {val_lum = value-12000;}  
    else if (value >= 13000 && value <= 13255) {val_cou = value-13000;}
    else if (value >= 10000 && value <= 10099) {val_prog= value-10000;}  
           
    mySwitch.resetAvailable();    
    Serial.println (value);
    Serial.print ("prg ");
    Serial.println (val_prog);
    Serial.print ("lum ");
    Serial.println (val_lum);
    Serial.print ("cou ");
    Serial.println (val_cou);
    Serial.print ("vit ");
    Serial.println (val_vit);
  }
  
   if (val_prog == 0){  // blanc
        fill_solid(leds, NUM_LEDS, CRGB::White);
        FastLED.setBrightness( val_lum );
        FastLED.show();
        delay(100);
   }
  
   if (val_prog == 1 ){//couleur choisie
        fill_solid(leds, NUM_LEDS, CHSV(val_cou,255,255));
        FastLED.setBrightness( val_lum );
        FastLED.show();
        delay(100); 
   }  

   if (val_prog == 2 ){//arc en ciel
        unsigned long currentMillis = millis();
        if (val_vit != 0 && currentMillis - previousMillis >= interval*(100/val_vit)) {
          previousMillis = currentMillis;   
          gHue++;
        }
      fill_rainbow( leds, NUM_LEDS, gHue, 7);
      FastLED.setBrightness( val_lum );
      FastLED.show();
      delay(200);
   } 
   
  
}

la partie réception de donnée, seule, fonctionne très bien. C’est basique mais ca fonctionne, pas trop de parasite , pas trop d’erreur dans les valeurs recues. Mais dès que je rajoute les ‘if’, la reception est aléatoire voir quasi nulle. Seul le 1er envoi apres initialisation de la nano réceptrice est correcte, après … gros bazar … ou rien du tout >:(

Et c’est là que vos lumieres (leds ca va de soit :-D) m’aideraient a comprendre, car je seche !

Pour les ‘delay’ présent dans les ‘if’, qu’ils soient là ou pas, ce ne change rien.

Une petite idée du pourquoi de la chose ??

les WS2812B mettent la pression sur le système d'interruption car le timing est clé pour allumer les LEDs et donc la librairie FASTLed désactive les interruptions pendant qu'elle s'occupera de vos LEDs.. Le soucis que vous avez c'est que votre 433Mhz a aussi besoin des interruptions pour ne pas rater une transmission.... (dé mémoire je crois qu'il faut compter 30µs par LED donc si vous en avez une centaine par exemple, ça fait que les interruptions vont être désactivées pendant 3ms... super long pour votre communication sans fil)

les nouveaux bandeaux de LEDs type APA102 n'ont pas cette contrainte de timing strict et seraient donc plus adaptées ou une communication différente qui ne dépendrait pas des interruptions ou alors passer sur des processeurs bcp plus puissants comme sur un teensy 3.x ou un DUE. Dans ces architectures la librairie FastLed a le temps de ré-autoriser les interruptions entre 2 LEDs (pour des interruptions qui prennent moins de 5µs comme la lecture du port Série par exemple)

Haaaa ! Heureusement qu'il y a des pros pour instruire les newbies dont je fait partie :slight_smile: merci pour cette reponse claire et precise.

Du coup en attendant je suis allé voir le post 'Comment connecter plusieurs Arduino par RF avec FS1000A ?'
Pour finalement arriver sur les modules RF 'nRF24L01+' en 2.4Ghz.
Il y aurait donc cette possibilité.

Où, comme vous l’évoquez, passer sur une DUE.

Je n'ai pas encore compris ce que sont ces 'interruptions' (mais j'y travaille :-)) mais pour m'en affranchir complétement, deux nRF24L01 feraient l'affaire ? ou fonctionnent t'ils aussi de la même maniere que les FS1000A que j'utilise ?

le nRF24L01 utilisent SPI pour la transmission donc devrait être jouable. jamais essayé

Qu'il en soit ainsi ! Les NRF24L01+ sont commandés.
Entre 'interruption' et 'SPI' , j'ai de quoi chercher le temps qu'ils soient livrés !