Fading color to color Fastled

Hi all,

I’m searching for a way to fade from color to color with FastLED, I’ve read quite a lot about it,
But, my colors are not in the loop, and during the fade the code needs to continue and if necessary change the color already to the new color…

Here is my complete code, basically, the device receives a UDP packet, which tells the device which mode/color it the LED should show (modeIdle(), modeAvailable(), modeOrdered(), modeOff())

Best would be if I could crossfade from Current Color to New Color…

Not sure how to do this, without using loop

/*
  THEBULB.
  TERRASLAMP

  V1.0
  08-2020

*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <FastLED.h>

#include "arduino_secrets.h"

#define LED_PIN     9
#define COLOR_ORDER GRB
#define CHIPSET     WS2812B
#define NUM_LEDS    3
CRGB leds[NUM_LEDS];

/* Unique ID AND IP */
IPAddress ip(192, 168, 0, 101);
//int tableID = 01;   <--- to be added in later, packetbuffer should contain variable tableID
/* END */

int status = WL_IDLE_STATUS;

/* BOOLEANS */
bool candleAllowance = false;
bool connectionLive = false;
/* END */

/* BLINK LED VARIABLES */
const int ledPin =  LED_BUILTIN;// the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long interval = 5000;           // interval at which to blink (milliseconds)
/* END */

/* WiFi TESTER VARIABLES */
unsigned long startTime;
unsigned long comparisonTime = 0;
/* END */

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned int localPort = 7001;      // local port to listen on

char packetBuffer[256]; //buffer to hold incoming packet
//char  ReplyBuffer[] = "table 01: acknowledged";       // a string to send back

WiFiUDP Udp;

void setup() {

  pinMode(ledPin, OUTPUT);
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.clear(true);
  // FastLED.setBrightness( BRIGHTNESS );

  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  /*
    while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
    }
  */

  Serial.println("THE BULB. terraslamp -- V01 2020");
  Serial.println("Setting up network now, hold your drinks high..!");
  Serial.println();

  WiFi.config(ip);

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with the WiFi module failed!");
    connectionLive = false;
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:  **updated later to 1s -- so far no issues to report.
    delay(1000);
  }

  Serial.println("Connected to wifi");
  connectionLive = true;
  printWifiStatus();
  Serial.println();

  //Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);


}

void loop() {

  connectionStatus();
  //CHECK CONNECTION EVERY 10S
  startTime = millis();
  if ((startTime - comparisonTime) > 10000) //every 10s
  {
    comparisonTime = startTime;
    TestWiFiConnection(); //test connection, and reconnect if necessary
  }
  // END


  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.print("Command: ");
    Serial.print(packetBuffer);
    Serial.println();

    if ( !strcmp(packetBuffer, "01_available")) {
      modeAvailable();
    }
    else if ( !strcmp(packetBuffer, "01_ordered")) {
      modeOrdered();
    }
    else if ( !strcmp(packetBuffer, "01_idle")) {
      modeIdle();
    }
    else if ( !strcmp(packetBuffer, "all_off") || (packetBuffer, "01_off")) {
      modeOff();
    }
    else if ( !strcmp(packetBuffer, "01_ping")) {
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write("01 PING");
      Udp.endPacket();
    }
    /*
        HERE SHOULD COME SOME LINES THAT WILL MEASURE THE BATTERY VOLTAGE
        IF THE BATTERY IS RUNNING LOW THEN RUN:
        also see notes

        run this void: lowBattery();
    */
    FastLED.show();
  }
}

/*  ==== LIGHT MODES =====  */

void modeIdle() {
  candleEffect();
  FastLED.show();

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write("01 RECEIVED; Table 01 is IDLE now");
  Udp.endPacket();
}

void modeAvailable() {
  candleAllowance = false;
  leds[1].setRGB(0, 255, 0);
  FastLED.show();

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write("01 RECEIVED; Table 01 is AVAILABLE now");
  Udp.endPacket();
}

void modeOrdered() {
  candleAllowance = false;
  leds[1].setRGB(0, 0, 255);
  FastLED.show();

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write("01 RECEIVED; Table 01 is ORDERED now");
  Udp.endPacket();
}

void modeOff() {
  candleAllowance = false;
  FastLED.clear(true);

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write("01 RECEIVED; Table 01 is OFF now");
  Udp.endPacket();
}

void lowBattery() {

  // no light effects here, check notes

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write("01 WARNING: Low battery! Please charge me..!");
  Udp.endPacket();
}

void candleEffect() {
  /*
      Here should come a real cool candle effect
  */

  if (candleAllowance == true) {
    leds[0].setRGB(150, 60, 0);
    leds[1].setRGB(150, 60, 0);
    leds[2].setRGB(150, 60, 0);
    leds[3].setRGB(150, 60, 0);
  }
}

/* _______ADDITIONAL SYSTEM SETTINGS_______ */

/*  ==== LOG WIFI STATUS ==== */

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

/*  ==== CHECK CONNECTION ==== */



void connectionStatus() {
  unsigned long currentMillis = millis();

  if (connectionLive == true) {
    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW) {
        ledState = HIGH;
        interval = 50;        //give a short flash to show there is a connection [power-reduction]
      } else {
        ledState = LOW;
        interval = 10000;      //stay off for 10s [power-reduction]
      }

      // set the LED with the ledState of the variable:
      digitalWrite(ledPin, ledState);
    }
  }
  else {
    connectionLive = false;
    digitalWrite(ledPin, LOW);
  }
}

void TestWiFiConnection()
//test if always connected
{
  int StatusWiFi = WiFi.status();
  if (StatusWiFi == WL_CONNECTION_LOST || StatusWiFi == WL_DISCONNECTED) //if no connection
  {
    connectionLive = false;
    FastLED.clear(true);
    Serial.println("Lost connection.. trying to reconnect");
    WiFiConnect(); //if my SSID is present, connect
  }
}

void WiFiConnect()
//connect to my SSID
{
  status = WL_IDLE_STATUS;
  while (status != WL_CONNECTED)
  {
    status = WiFi.begin(ssid, pass);
    if (status == WL_CONNECTED) {
      connectionLive = true;
      Serial.println("We're back!");
    }
    else {
      TestWiFiConnection();
    }
  }
}

/* ==== ADDRESSING TERRASLAMP ==== */
/*
    In a later version here we will program RFID possibilities to change device IP and ID
*/

Rather than doing something with the leds ONLY when you receive a UDP packet, instead set a variable to indicate the effect you want to display.

Then, in loop(), depending on the value of that variable perform one step of whatever effect you want.

You might consider an enum for the state...

enum Effect {
  NONE,
  AVAILABLE,
  ORDERED,
  IDLE,
  OFF
};

Effect currentEffect = NONE;

switch (currentEffect)
{
  case AVAILABLE:
    //Do one step of available effect
    break;
  case ORDERED:
    //Do one step of ordered effect
    break;
  case IDLE:
    //Do one step of idle effect
    break;
  case OFF:
    //Do one step of off effect
    break;
}

You may want a timer (similar to how you perform your TestWiFiConnection) to control how fast the effects execute.

Yes, I was rethinking it, I was thinking to use booleans to set all situations to true or false and then execute.

I did not think of a struct, so I like your suggestion.
Will try this tomorrow!

darthvader072:
I did not think of a struct, so I like your suggestion.

That's not a struct, it's an enum.