RGB LED Strips control over Wifi

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include "certs.h"
#include <LEDStripDriver.h>

// DIN=GPIO16, CIN=GPIO14
LEDStripDriver led = LEDStripDriver(16, 14);
char messageBuffer[50];

WiFiClient espClient;
PubSubClient client(espClient);

unsigned long currentTime;
unsigned long startTime;

String lastledcolor;
String ledcolor;
bool command=false;
void setup_wifi()
{
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    pause(500);
  }
  Serial.println();
  Serial.print("WiFi connected to ");
  Serial.println(ssid);
  Serial.print("IP address : ");
  Serial.println(WiFi.localIP());
  pause(2000);
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  led.setColor(0, 0, 0);
}

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
  if (command == true)
  {
    Rainbow();
  }
  else if (command == false)
  {
    lastledcolor = ledcolor;
    stopRainbow();
  }
}

void reconnect()
{
  while (!client.connected())
  {
    if (client.connect("Reception"))
    {
      Serial.println("connected");
      client.subscribe("RGB/Output");
    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again");
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  //Serial.println();
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  Serial.print("length : ");
  Serial.println(length);
  memcpy(messageBuffer, payload, length);
  messageBuffer[length] = '\0';
  Serial.print("the payload is : ");
  Serial.println(messageBuffer);
  if (strcmp(messageBuffer, "change") == 0)
  {
    Serial.println(strcmp(messageBuffer, "change"));
    command= true;

  }
  else if (strcmp(messageBuffer, "freeze") == 0)
  {
    Serial.println(strcmp(messageBuffer, "freeze"));
    command= false;

  }
}

void stopRainbow()
{
  if (lastledcolor == "red")
    led.setColor(255, 0, 0);
  else if (lastledcolor == "green")
    led.setColor(0, 255, 0);
  else if (lastledcolor == "blue")
    led.setColor(0, 0, 255);
  else if (lastledcolor == "yellow")
    led.setColor(255, 255, 0);
  else if (lastledcolor == "cyan")
    led.setColor(0, 255, 255);
  else if (lastledcolor == "magenta")
    led.setColor(139, 0, 139);
  else if (lastledcolor == "orange")
    led.setColor(255, 69, 0);
  else if (lastledcolor == "pink")
    led.setColor(255, 20, 147);
}

void Rainbow()
{
  ledcolor = "red";
  led.setColor(255, 0, 0);
  pause(1000);
  ledcolor = "green";
  led.setColor(0, 255, 0);
  pause(1000);
  ledcolor = "blue";
  led.setColor(0, 0, 255);
  pause(1000);
  ledcolor = "yellow";
  led.setColor(255, 255, 0);
  pause(1000);
  ledcolor = "cyan";
  led.setColor(0, 255, 255);
  pause(1000);
  ledcolor = "magenta";
  led.setColor(139, 0, 139);
  pause(1000);
  ledcolor = "orange";
  led.setColor(255, 69, 0);
  pause(1000);
  ledcolor = "pink";
  led.setColor(255, 20, 147);
  pause(1000);
}

void pause(unsigned long period)
{
  currentTime = millis();
  if (currentTime - startTime >= period)
  {} startTime = currentTime;
}

Hello, I’ve programmed my google assistant on my phone to send MQTT commands “change” & “freeze”.
Currently the LED Strip lights up white in the setup, but Rainbow() & stopRainbow() are not working. How do I make colors change over Wifi?

aarg:
Can you please define “not working” in more detail?

The led does not change color is what I meant by not working. It just stays white

Can you please define “not working” in more detail?

Your pause function does absolutely nothing. I reformatted it so you can see that.

void pause(unsigned long period)
{
  currentTime = millis();
  if (currentTime - startTime >= period)
  {
  } 
  startTime = currentTime;
}

This code:

void Rainbow()
{
  ledcolor = "red";
  led.setColor(255, 0, 0);
  pause(1000);
  ledcolor = "green";
  led.setColor(0, 255, 0);
  pause(1000);
  ledcolor = "blue";
  led.setColor(0, 0, 255);
  pause(1000);
  ledcolor = "yellow";
  led.setColor(255, 255, 0);
  pause(1000);
  ledcolor = "cyan";
  led.setColor(0, 255, 255);
  pause(1000);
  ledcolor = "magenta";
  led.setColor(139, 0, 139);
  pause(1000);
  ledcolor = "orange";
  led.setColor(255, 69, 0);
  pause(1000);
  ledcolor = "pink";
  led.setColor(255, 20, 147);
  pause(1000);
}

Is equivalent to this code considering pause does nothing and you keep overwriting ledcolor:

void Rainbow()
{
  led.setColor(255, 0, 0);
  led.setColor(0, 255, 0);
  led.setColor(0, 0, 255);
  led.setColor(255, 255, 0);
  led.setColor(0, 255, 255);
  led.setColor(139, 0, 139);
  led.setColor(255, 69, 0);
  ledcolor = "pink";
  led.setColor(255, 20, 147);
}

ToddL1962:
Your pause function does absolutely nothing. I reformatted it so you can see that.

void pause(unsigned long period)

{
 currentTime = millis();
 if (currentTime - startTime >= period)
 {
 }
 startTime = currentTime;
}




Is equivalent to this code considering pause does nothing and you keep overwriting ledcolor:

I made the pause to replace delay. I added the unsigned long period so it will do nothing for the specified period of time. As for ledcolor I'm using a strip driver module. So I'm following the example RGBtest.ino from this link GitHub - MrKrabat/LED-Strip-Driver-Module: Arduino library for the full color RGB LED strip driver module shield

Professor_Joe:
I made the pause to replace delay. I added the unsigned long period so it will do nothing for the specified period of time.

OK. That is not what it does, however.

Please do not answer posts by going back and editing your previous posts. That messes up the continuity of the thread.

Just quote, or not quote, and answer.

Professor_Joe:
I made the pause to replace delay. I added the unsigned long period so it will do nothing for the specified period of time. As for ledcolor I'm using a strip driver module. So I'm following the example RGBtest.ino from this link GitHub - MrKrabat/LED-Strip-Driver-Module: Arduino library for the full color RGB LED strip driver module shield

He uses delays and does not have an ledcolor String variable that he overwrites.

I heard delay() slows down MQTT response time which is why I created pause().

Professor_Joe:
I heard delay() slows down MQTT response time which is why I created pause().

That's because the callback is called from the client.loop() method. Any delays in loop() will delay your callbacks. Whatever your reason for creating the pause() function it does nothing. Even if it did work it would not solve that issue.

I would suggest restructuring your code to use the command flag and set a counter to sequence you through the rainbow and pauses every time you go through loop().

ToddL1962:
That's because the callback is called from the client.loop() method. Any delays in loop() will delay your callbacks. Whatever your reason for creating the pause() function it does nothing. Even if it did work it would not solve that issue.

I would suggest restructuring your code to use the command flag and set a counter to sequence you through the rainbow and pauses every time you go through loop().

whats a command flag?

Professor_Joe:
whats a command flag?

I was referring to the command flag you already created.

Here is a version of your code which does what I described:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include "certs.h"
#include <LEDStripDriver.h>


// DIN=GPIO16, CIN=GPIO14
LEDStripDriver led = LEDStripDriver(16, 14);
WiFiClient espClient;
PubSubClient client(espClient);

char messageBuffer[50];
unsigned long currentTime;
unsigned long startTime;
const unsigned long pausePeriod = 1000;

bool command=false;
bool pause=true;

const int numLedColors = 8;
int ledSequenceCount = 0;

void setup_wifi()
{
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    pause(500);
  }
  Serial.println();
  Serial.print("WiFi connected to ");
  Serial.println(ssid);
  Serial.print("IP address : ");
  Serial.println(WiFi.localIP());
  pause(2000);
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  led.setColor(0, 0, 0);
}

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
  
  if (command)
  {
    if (pause)
    {
      currentTime = millis();
      if (currentTime - startTime >= pausePeriod) pause = false;
    }
    else
    {
      switch (ledSequenceCount)
      {
        case 0:
          led.setColor(255, 0, 0);
          break;

        case 1:
          led.setColor(0, 255, 0);
          break;

        case 2:
          led.setColor(0, 0, 255);
          break;

        case 3:
          led.setColor(255, 255, 0);
          break;

        case 4:
          led.setColor(0, 255, 255);
          break;

        case 5:
          led.setColor(139, 0, 139);
          break;

        case 6:
          led.setColor(255, 69, 0);
          break;

        case 7:
          led.setColor(255, 20, 147);
          break;
      }
      startTime = millis();
      pause = true;
      ledSequenceCount++;
      ledSequenceCount %= numLedColors;
    }
  }
}

void reconnect()
{
  while (!client.connected())
  {
    if (client.connect("Reception"))
    {
      Serial.println("connected");
      client.subscribe("RGB/Output");
    }
    else 
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again");
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  //Serial.println();
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  Serial.print("length : ");
  Serial.println(length);
  memcpy(messageBuffer, payload, length);
  messageBuffer[length] = '\0';
  Serial.print("the payload is : ");
  Serial.println(messageBuffer);
  if (strcmp(messageBuffer, "change") == 0)
  {
    Serial.println(strcmp(messageBuffer, "change"));
    command= true;
  }
  else if (strcmp(messageBuffer, "freeze") == 0)
  {
    Serial.println(strcmp(messageBuffer, "freeze"));
    command= false;
  }
}

I can’t compile or test it but you can try it. When the command flag is set every iteration of loop either sets a new LED color or executes a pause between LED colors. That way the callback can be executed without getting delayed. When the “freeze” command is received the sequence freezes, when the “change” command is received the sequence picks up where it left off.

Here is another way to do it using an array for the LED colors:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include "certs.h"
#include <LEDStripDriver.h>


// DIN=GPIO16, CIN=GPIO14
LEDStripDriver led = LEDStripDriver(16, 14);
WiFiClient espClient;
PubSubClient client(espClient);

char messageBuffer[50];
unsigned long currentTime;
unsigned long startTime;
const unsigned long pausePeriod = 1000;

bool command=false;
bool pause=true;

const int numLedColors = 8;
int ledSequenceCount = 0;
byte ledTable [numLedColors][3] = 
{{255, 0, 0},
 {0, 255, 0},
 {0, 0, 255},
 {255, 255, 0},
 {0, 255, 255},
 {139, 0, 139},
 {255, 69, 0},
 {255, 20, 147}};

void setup_wifi()
{
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    pause(500);
  }
  Serial.println();
  Serial.print("WiFi connected to ");
  Serial.println(ssid);
  Serial.print("IP address : ");
  Serial.println(WiFi.localIP());
  pause(2000);
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  led.setColor(0, 0, 0);
}

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
  
  if (command)
  {
    if (pause)
    {
      currentTime = millis();
      if (currentTime - startTime >= pausePeriod) pause = false;
    }
    else
    {
      led.setColor(ledTable[ledSequenceCount][0], ledTable[ledSequenceCount][1], ledTable[ledSequenceCount][2]);
      startTime = millis();
      pause = true;
      ledSequenceCount++;
      ledSequenceCount %= numLedColors;
    }
  }
}

void reconnect()
{
  while (!client.connected())
  {
    if (client.connect("Reception"))
    {
      Serial.println("connected");
      client.subscribe("RGB/Output");
    }
    else 
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again");
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  //Serial.println();
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  Serial.print("length : ");
  Serial.println(length);
  memcpy(messageBuffer, payload, length);
  messageBuffer[length] = '\0';
  Serial.print("the payload is : ");
  Serial.println(messageBuffer);
  if (strcmp(messageBuffer, "change") == 0)
  {
    Serial.println(strcmp(messageBuffer, "change"));
    command= true;
  }
  else if (strcmp(messageBuffer, "freeze") == 0)
  {
    Serial.println(strcmp(messageBuffer, "freeze"));
    command= false;
  }
}

So I'm following the example RGBtest.ino from this linkYeah i do have one of those units as well, and i suppose if you are just sending a single pixel the library works. You can daisy chain those and address each unit individually.

ToddL1962:
Here is another way to do it using an array for the LED colors:

#include <ESP8266WiFi.h>

#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include “certs.h”
#include <LEDStripDriver.h>

// DIN=GPIO16, CIN=GPIO14
LEDStripDriver led = LEDStripDriver(16, 14);
WiFiClient espClient;
PubSubClient client(espClient);

char messageBuffer[50];
unsigned long currentTime;
unsigned long startTime;
const unsigned long pausePeriod = 1000;

bool command=false;
bool pause=true;

const int numLedColors = 8;
int ledSequenceCount = 0;
byte ledTable [numLedColors][3] =
{{255, 0, 0},
{0, 255, 0},
{0, 0, 255},
{255, 255, 0},
{0, 255, 255},
{139, 0, 139},
{255, 69, 0},
{255, 20, 147}};

void setup_wifi()
{
  Serial.print(“connecting to “);
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(”.”);
    pause(500);
  }
  Serial.println();
  Serial.print("WiFi connected to ");
  Serial.println(ssid);
  Serial.print("IP address : ");
  Serial.println(WiFi.localIP());
  pause(2000);
}

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  led.setColor(0, 0, 0);
}

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
 
  if (command)
  {
    if (pause)
    {
      currentTime = millis();
      if (currentTime - startTime >= pausePeriod) pause = false;
    }
    else
    {
      led.setColor(ledTable[ledSequenceCount][0], ledTable[ledSequenceCount][1], ledTable[ledSequenceCount][2]);
      startTime = millis();
      pause = true;
      ledSequenceCount++;
      ledSequenceCount %= numLedColors;
    }
  }
}

void reconnect()
{
  while (!client.connected())
  {
    if (client.connect(“Reception”))
    {
      Serial.println(“connected”);
      client.subscribe(“RGB/Output”);
    }
    else
    {
      Serial.print(“failed, rc=”);
      Serial.print(client.state());
      Serial.println(" try again");
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length)
{
  //Serial.println();
  Serial.print(“Message arrived [”);
  Serial.print(topic);
  Serial.print("] ");
  Serial.print("length : ");
  Serial.println(length);
  memcpy(messageBuffer, payload, length);
  messageBuffer[length] = ‘\0’;
  Serial.print("the payload is : ");
  Serial.println(messageBuffer);
  if (strcmp(messageBuffer, “change”) == 0)
  {
    Serial.println(strcmp(messageBuffer, “change”));
    command= true;
  }
  else if (strcmp(messageBuffer, “freeze”) == 0)
  {
    Serial.println(strcmp(messageBuffer, “freeze”));
    command= false;
  }
}

I’ve tested this code works thanks a lot