Loop issue with Adafruit IO

Hello !
Let me introduce first, I’m Romain, begining in arduino programming.

I’m having an issue while trying to program an ESP8266 module.
I’m trying to use it to trigger differents light modes on my WS2811 led strip with Adafruit IO.

Here is the code:

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define WLAN_SSID       "Freebox-1CE573"
#define WLAN_PASS       "arrhis-adsumetur38-venenose.@-adpingit"
 
#define AIO_SERVER      "io.adafruit.com"                                                        //Definition des paramètres IO
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "Kdcius"
#define AIO_KEY         "aio_WvIm53NbJpTXfvuJXcUfRkbSjlVM"
#define LED_animations D0



#include <FastLED.h>
FASTLED_USING_NAMESPACE

#define DATA_PIN    0
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB                                                                          //Definition des paramètres FastLED
#define NUM_LEDS    245
CRGB leds[NUM_LEDS];

#define BRIGHTNESS         150
#define FRAMES_PER_SECOND  120
 
 
WiFiClient client;
 
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);          //Connecetion au serv mqtt

Adafruit_MQTT_Subscribe LED_animations= Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/LED_animations");    //Ajout du feed
Adafruit_MQTT_Subscribe LED_off= Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/LED_off"); 
 

void MQTT_connect();
 
void setup() {
  Serial.begin(115200);
  delay(10);
 
  Serial.println(F("Adafruit MQTT demo"));
 
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);
                                                                                                //Connection au WiFi
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
 
  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());
  mqtt.subscribe(&LED_animations);
  mqtt.subscribe(&LED_off);



  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); 
                                                                                                              //SetUp FastLED
  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);

  
}



uint32_t x=0;                                                                                            //J'ai pas compris mais truc IO


// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns



void loop() {
  MQTT_connect();
 
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    
    if (subscription == &LED_animations) {
    Serial.print(F("Got: "));
    Serial.println((char *)LED_animations.lastread);                                                   //Differentes action à réaliser
    uint16_t state0 = atoi((char *)LED_animations.lastread);
    while (state0 ==1)
    {
       // Call the current pattern function once, updating the 'leds' array
       gPatterns[gCurrentPatternNumber]();

       // send the 'leds' array out to the actual LED strip
       FastLED.show();                                                                        //My issue is here !
       // insert a delay to keep the framerate modest
       
       FastLED.delay(1000/FRAMES_PER_SECOND); 

       // do some periodic updates
       EVERY_N_MILLISECONDS( 10 ) { gHue++; } // slowly cycle the "base color" through the rainbow
       EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
    }
   }

   if (subscription == &LED_off) {
    Serial.print(F("Got: "));
    Serial.println((char *)LED_off.lastread);
    uint16_t state1 = atoi((char *)LED_off.lastread);
    if (state1 ==1)
    {
     for(int led = 0; led < 245; led++) {
      leds[led] = CRGB::Black ; 
      FastLED.show();
      delay (8);
     }
    }
   }
   
  }
}
void MQTT_connect() {
  int8_t ret;
if (mqtt.connected()) {
    return;
  }
 
  Serial.print("Connecting to MQTT... ");
 
  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) {
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();                                                                    //Boucle de connection au serv mqtt
       delay(5000);
       retries--;
       if (retries == 0) {
         while (1);
         
       }
  }
  Serial.println("MQTT Connected!");
}





                          //Là c'est les differents paterns des animations
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
  }
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}
            //Et là c'est la fin de la liste des paterns

The issue I have is marked with comment it’s in the middle of the code.
Let me explain.
I’m trying to trigger the first mode which contains 6 animations.
But with the while control structure, the state of the IO feed won’t be checked so I will be stuck in the animation.
Unable to trigger any other mode.

I appologize if my English isn’t perfect ^^’

So if you mind a good way of doing what I’m trying to do since hours and hours, let me know !

PS: The code I used isn’t mine, It’s based on an other maker one.

I’m working on a similar project at the moment.

A few things that I have done to make my animations run successfuly -

  • Compared millis(), rather than using any sort of delay() function
  • Used the AdafruitIO library, and then used a callback function to handle new MQTT messages
  • Used the yield() function before FastLED.show(), this vastly improved the animation.

Here’s my code as it might be of use. It’s riddled with bad practice, but it works. It’s also poorly commented.

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

unsigned long ledStarted = 0;
const long interval = 10;

int hue = 0;
int sat = 255;
String text_colour = "0";

#define NUM_LEDS 30
#define DATA_PIN D2

int xmasLights[NUM_LEDS];
int total_time = 100;
int start_up_time = total_time / 4;

// set up the Adafruit IO feeds
AdafruitIO_Feed *colour = io.feed("colour_button");

CRGBArray<NUM_LEDS> leds;



void setup() {
  Serial.begin(115200);
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
  RGB > (leds, NUM_LEDS); // BGR ordering is typical
  io.connect();

  colour->onMessage(colourHandler);

  // // wait for a connection
  while (io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  ////  // we are connected
  Serial.println();
  Serial.println(io.statusText());

  //  create an array to hold the current animation frame of each LED
  for (int k = 0; k < NUM_LEDS; k++) {
    xmasLights [k] = random(1, total_time);
  }
  //  strip.show();
  //  strip.setBrightness(255);
  delay(500);

}

void loop() {
  io.run();


  unsigned long currentMillis = millis();
  if (currentMillis - ledStarted >= interval) {
    ledStarted = currentMillis;
    // Update the LEDS depending where they are in the animation cycle
    for (int k = 0; k < NUM_LEDS; k++) {

      if (xmasLights[k] <=  start_up_time) {

        int light_level = (255 * xmasLights[k] / start_up_time);
        leds[k] = CHSV(hue, sat, light_level);
        //      strip.setPixelColor(k, 0, 0, light_level);

      }
      else if (xmasLights[k] == 0) {

        xmasLights[k] = 1;
      }
      else {
        int light_level = (255 + (255 * start_up_time / (total_time - start_up_time))) - (255 * xmasLights[k] / (total_time - start_up_time));
        leds[k] = CHSV(hue, sat, light_level);
        //      strip.setPixelColor(k, 0, 0, light_level);
      }
      xmasLights[k]++;
    }
    yield();
    FastLED.show();
    //  strip.show();
  }
  //delay(10);
}

void colourHandler(AdafruitIO_Data * data) {
  Serial.print("-> outdoor light HEX: ");
  Serial.println(data->value());
  if (data->value() == "0") {

  }
  else {
    text_colour = data->value();
  }
    if (text_colour == "1") { // red
    hue = 0;
    sat = 255;
  }
  else if (text_colour == "2") { //green
    hue = 120*255/360;
    sat = 255;
  }
  else if (text_colour == "3") {//yelow
    hue = 60*255/360;
    sat = 255;
  }
  if (text_colour == "4") { //blue
    hue = 240*255/360;
    sat = 255;
  }
  else if (text_colour == "5") { //purple
    hue = 271*255/360;
    sat = 73*255/100;
  }
  else if (text_colour == "6") { //orange
    hue = 33*255/360;
    sat = 255*82/100;
  }
  else if (text_colour == "7") { //white
    hue = 160*255/360;
    sat = 0;
  }
  else {
    hue = hue;
    sat = sat;
  }
}