Colour Fading with RGB LED Strip

Hi, I am having trouble getting the RGB to change colour. Currently it can only show white colour and nothing else. I created a function called RainbowEffect() to change colour but doesn't seem to work.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

#define Loop_Delay 30

// Connect to the WiFi
const char* ssid = "SSID";
const char* password = "PSWD";
const char* mqtt_server = "broker.mqttdashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Relays On");
      OnRelays();
   }
   if(receivedChar=='1'){
    Serial.print("Relays Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception")) {    // "explicit name for each client"
      Serial.println("Reception is connected to MQTT server");
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  RainbowEffect();
}


void RainbowEffect(){
    int brightness;
   int fadeAmount = 5;
    analogWrite(RED_PIN, brightness); //writing brightness value to red
  analogWrite(GREEN_PIN, brightness); //writing brightness value to green
 analogWrite(BLUE_PIN, brightness); //writing brightness value to blue
 
  brightness += fadeAmount; //increasing brightness value by 5 in each loop
 
  if (brightness < 0 || brightness > 255 )
  {
    fadeAmount = -fadeAmount; //reversing the direction of fading when brightness reachs 0 or 255
  }
    delay (Loop_Delay);
  }

I created a function called RainbowEffect() to change colour

  analogWrite(RED_PIN, brightness); //writing brightness value to red
  analogWrite(GREEN_PIN, brightness); //writing brightness value to green
  analogWrite(BLUE_PIN, brightness); //writing brightness value to blue

You are writing the same value to each of the 3 LEDs so no wonder the result is white.

So do I take away one?

Professor_Joe:
So do I take away one?

That will just give you a different non changing colour that fades

You could consider 3 nested for loops, one for each colour, but I am not clear what type of effect you are aiming for

So, if I wanted the strip to constantly change colours, would the function look something like this? (Whereby SetColour() is basically analogwrite)

void RainbowEffect()
{
   int R;
   int G;
   int B;
 for (R = 0 ; R < 256 ; R++)
{
   for (G = 0 ; G < 256 ; G++)
   {
      for (B = 0 ; B < 256 ; B++)
      {
        setColor(R,G,B);
      }
   }
};
}

That would certainly make an RGB LED cycle through 256 * 256 * 256 different colours.

Why don't you try it ?

Well, tried it and the communication with MQTT just stopped working.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

#define Loop_Delay 30

// Connect to the WiFi
const char* ssid = "SSID";
const char* password = "PSWD";
const char* mqtt_server = "broker.mqttdashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Relays On");
      OnRelays();
   }
   if(receivedChar=='1'){
    Serial.print("Relays Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception")) {    // "explicit name for each client"
      Serial.println("Reception is connected to MQTT server");
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  RainbowEffect();
}

void setColor(int R, int B, int G)
{
  R = 255 - R;
    G = 255 - G;
    B = 255 - B;
  analogWrite(RED_PIN, R);
  analogWrite(GREEN_PIN, G);
  analogWrite(BLUE_PIN, B); 
}

void RainbowEffect()
{
  int R;
  int B;
  int G;
 for (R = 0 ; R < 256 ; R++)
{
   for (G = 0 ; G < 256 ; G++)
   {
      for (B = 0 ; B < 256 ; B++)
      {
        setColor(R,G,B);
      }
   }
}
}

How long does the nest of for loops take to run ?

I don't know. Seems like adding those for loops are causing problems for MQTT communication

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

#define FADESPEED 5

// Connect to the WiFi
const char* ssid = "ASUS";
const char* password = "97983740";
const char* mqtt_server = "broker.mqttdashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Relays On");
      OnRelays();
   }
   if(receivedChar=='1'){
    Serial.print("Relays Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception")) {    // "explicit name for each client"
      Serial.println("Reception is connected to MQTT server");
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  RainbowEffect();
}

void RainbowEffect()
{
 int r, g, b;
 
  // fade from blue to violet
  for (r = 0; r < 256; r++) { 
    analogWrite(RED_PIN, r);
    delay(FADESPEED);
  } 
  // fade from violet to red
  for (b = 255; b > 0; b--) { 
    analogWrite(BLUE_PIN, b);
    delay(FADESPEED);
  } 
  // fade from red to yellow
  for (g = 0; g < 256; g++) { 
    analogWrite(GREEN_PIN, g);
    delay(FADESPEED);
  } 
  // fade from yellow to green
  for (r = 255; r > 0; r--) { 
    analogWrite(RED_PIN, r);
    delay(FADESPEED);
  } 
  // fade from green to teal
  for (b = 0; b < 256; b++) { 
    analogWrite(BLUE_PIN, b);
    delay(FADESPEED);
  } 
  // fade from teal to blue
  for (g = 255; g > 0; g--) { 
    analogWrite(GREEN_PIN, g);
    delay(FADESPEED);
  } 
}

Changed RainbowEffect() this time it took 8 seconds before payloads were displayed on the monitor. Is there a way to speed this up?

You could reduce the value of FADESPEED

Using 3 nested for loops will certainly stop the program for a while. The alternative is to use millis() for timing so that loop() can keep running freely but that is more complicated than using for loops

Try this example and adapt it for your needs. Instead of printing teh values call your function to set the RGB levels of the LED

unsigned long currentTime;
unsigned long startTime;
unsigned long period = 1;
int countR;
int countG;
int countB;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  currentTime = millis();
  if (currentTime - startTime >= period)
  {
    countR++;
    if (countR > 255)
    {
      countR = 0;
      countG++;
      if (countG > 255)
      {
        countG = 0;
        countB++;
        if (countB > 255)
        {
          countB = 0;
        }
      }
    }
    Serial.print(countR);
    Serial.print("\t");
    Serial.print(countG);
    Serial.print("\t");
    Serial.println(countB);
    startTime = currentTime;
  }
}

MQTT to Serial communication a lot faster now, thanks a lot.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// Connect to the WiFi
const char* ssid = "ASUS";
const char* password = "97983740";
const char* mqtt_server = "broker.mqttdashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

unsigned long currentTime;
unsigned long startTime;
unsigned long period = 1;
int countR;
int countG;
int countB;

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Relays On");
      OnRelays();
   }
   if(receivedChar=='1'){
    Serial.print("Relays Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception")) {    // "explicit name for each client"
      Serial.println("Reception is connected to MQTT server");
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  RainbowEffect();
}

void RainbowEffect()
{
 currentTime = millis();
  if (currentTime - startTime >= period)
  {
    countR++;
    if (countR > 255)
    {
      countR = 0;
      countG++;
      if (countG > 255)
      {
        countG = 0;
        countB++;
        if (countB > 255)
        {
          countB = 0;
        }
      }
    }
    startTime = currentTime;
  }
}
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// Connect to the WiFi
const char* ssid = "";
const char* password = "";
const char* mqtt_server = "broker.mqttdashboard.com";
const char* mqtt_user = "";
const char* mqtt_pswd = "";
WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

unsigned long currentTime;
unsigned long startTime;
unsigned long period = 1;
int countR=255;
int countG=255;
int countB=255;

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Payload selected [");
  Serial.print(topic);
  Serial.print("]=> ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Rainbow On");
      OnRelays();
      RainbowEffect();
   }
   if(receivedChar=='1'){
    Serial.print("Rainbow Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception"),mqtt_user,mqtt_pswd) {    // "explicit name for each client"
      Serial.print("Reception is connected to ");
      Serial.println(mqtt_user);
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

void RainbowEffect()
{
 currentTime = millis();
  if (currentTime - startTime >= period)
  {
    countR++;
    analogWrite(RED_PIN,countR);
    if (countR > 255)
    {
      countR = 0;
      analogWrite(RED_PIN,countR);
      countG++;
      analogWrite(GREEN_PIN,countG);
      if (countG > 255)
      {
        countG = 0;
        analogWrite(GREEN_PIN,countG);
        countB++;
        analogWrite(BLUE_PIN,countB);
        if (countB > 255)
        {
          countB = 0;
          analogWrite(BLUE_PIN,countB);
        }
      }
    }
    startTime = currentTime;
  }
}

The lights are still white though. Apparently if the RainbowEffect() is in void loop() the Turn off command would turn the led yellow instead.

      countR = 0;
      analogWrite(RED_PIN, countR);

You are writing to the LED after you have set the level back to zero. Don't do that

Look at my example again. It prints the RGB values and note that I said

Instead of printing the values call your function to set the RGB levels of the LED

Write to all 3 LEDs when the timing period ends at the same place that I printed the values

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// Connect to the WiFi
const char* ssid = "";
const char* password = "";
const char* mqtt_server = "broker.mqttdashboard.com";
const char* mqtt_user = "";
const char* mqtt_pswd = "";
WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

unsigned long currentTime;
unsigned long startTime;
unsigned long period = 1;
int countR;
int countG;
int countB;

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Payload selected [");
  Serial.print(topic);
  Serial.print("]=> ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Rainbow On");
      OnRelays();
      RainbowEffect();
   }
   if(receivedChar=='1'){
    Serial.print("Rainbow Off");
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception"),mqtt_user,mqtt_pswd) {    // "explicit name for each client"
      Serial.print("Reception is connected to ");
      Serial.println(mqtt_user);
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

void RainbowEffect()
{
 currentTime = millis();
  if (currentTime - startTime >= period)
  {
    countR++;
    if (countR > 255)
    {
      countR = 0;
      countG++;
      if (countG > 255)
      {
        countG = 0;
        countB++;
        if (countB > 255)
        {
          countB = 0;
        }
      }
    }
    analogWrite(RED_PIN,countR);
    analogWrite(GREEN_PIN,countG);
    analogWrite(BLUE_PIN,countB);
    startTime = currentTime;
  }
}

Lights are still white. Did I do it correctly here?

In order for it to work you must call RainbowEffect() repeatedly when the effect is required to be running, not just once as now.

When you get a '0' set a boolean to true. Call RainbowEffect() every time through loop() if the boolean is true. Set the boolean to false to turn off the rainbow effect but you might like to tidy up the colour of the LEDs at that point

What do you mean by tidy up the leds?

If you stop calling the RainbowEffect() function the LEDs could currently be set at any one of about 16 million colours. You might want to set them to a fixed value, possibly all on or all off but it is up to you

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// Connect to the WiFi
const char* ssid = "";
const char* password = "";
const char* mqtt_server = "broker.mqttdashboard.com";
const char* mqtt_user = "";
const char* mqtt_pswd = "";
WiFiClient espClient;
PubSubClient client(espClient);

//Pins are connected to relays
const int RED_PIN = 12;    //D6: Red Pin
const int GREEN_PIN = 14;  //D5: Green Pin
const int BLUE_PIN = 13; //D7: Blue Pin

unsigned long currentTime;
unsigned long startTime;
unsigned long period = 1;
int countR;
int countG;
int countB;

bool power=false;

// The function below connects your NodeMCU to the wireless network
void setup_wifi(){

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Payload selected [");
  Serial.print(topic);
  Serial.print("]=> ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    if(receivedChar=='0'){
      Serial.print("Rainbow On");
      power=true;
      OnRelays();
   }
   if(receivedChar=='1'){
    Serial.print("Rainbow Off");
    power=false;
    OffRelays();
    }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Reception"),mqtt_user,mqtt_pswd) {    // "explicit name for each client"
      Serial.print("Reception is connected to ");
      Serial.println(mqtt_user);
      // ... and subscribe to topic
      client.subscribe("RGB/Output");//Topic subscribed to
    } else {
      Serial.print("Failed to connect to MQTT...");
      Serial.println();
      Serial.println("Attempting to connect again in 3 seconds.");
      // Wait  seconds before retrying
      delay(3000);
    }
  }
}

void OnRelays(){
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
}
void OffRelays(){
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}
void setup()
{
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if(power==true)
   RainbowEffect();
   else if(power==false){
      countR=0;
      countG=0;
      countB=0;
   }
}

void RainbowEffect()
{
 currentTime = millis();
  if (currentTime - startTime >= period)
  {
    countR++;
    if (countR > 255)
    {
      countR = 0;
      countG++;
      if (countG > 255)
      {
        countG = 0;
        countB++;
        if (countB > 255)
        {
          countB = 0;
        }
      }
    }
    analogWrite(RED_PIN,countR);
    analogWrite(GREEN_PIN,countG);
    analogWrite(BLUE_PIN,countB);
    startTime = currentTime;
  }
}

So would it look like this?