Loop function doesnt work arduino ide

Im making a voice controlled home automation using bluetooth module and arduino uno and i2c lcd that shows loads on or off and one of loads that i put is neopixel RGB 12 led light and it works for simple command such as "RGB red","RGB blue", but when i want to make a sequence loop such as RGB rainbow it doesnt loop and just stay constant in the rainbow colour but not looping, here my code

#include<SoftwareSerial.h>
#include <Arduino.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>


#define DATA_PIN 13        //Define led data pin in
#define LED_TYPE NEOPIXEL  //define type of led
#define NUM_LEDS 12        //num of leds in strip
#define BRIGHTNESS  50     //RGB Brightness
#define UPDATES_PER_SECOND 100

struct CRGB leds[NUM_LEDS];  // Initialize LED array

// Define 4 channel relay pins
const int Light1 = 9; // Relay pin 1 (IN1)

const int Light2 = 8;   // Relay pin 2 (IN2)

const int Fan = 10; //Relay pin 3 (IN3)

const int Alarm = 11; 

CRGBPalette16 currentPalette;
TBlendType    currentBlending;
 
extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

/* Create object named bt of the class SoftwareSerial */

SoftwareSerial bt(2, 3); /* (Rx,Tx) */

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);

hd44780_I2Cexp lcd;

void setup() {

  bt.begin(9600); /* Define baud rate for software serial communication */

  Serial.begin(9600); /* Define baud rate for serial communication */

  FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear(true);

  // Set Relay pins as OUTPUT
  pinMode(Light1, OUTPUT);

  pinMode(Light2, OUTPUT);

  pinMode(Fan, OUTPUT);

  pinMode(Alarm, OUTPUT);

  digitalWrite(Light1, HIGH);

  digitalWrite(Light2, HIGH);

  digitalWrite(Fan, HIGH);

  digitalWrite(Alarm, LOW);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.backlight(); 
}

void loop() {

  String data="";

  char ch;

  while (bt.available()) /* If data is available on serial port */

    { ch = bt.read(); /* Print character received on to the serial monitor */

      data=data+ch;

    }

   Serial.print(data);

  // Control the devices using voice command

    if (data.startsWith("RGB rainbow"))  // // set the RGB leds to  white
  {
    rainbow();
    delay(50);


  } else if ((data == "turn on light one")||(data == "*turn on light one")||(data == "turn on living room light"))               // turn on light number 1

    {

      digitalWrite(Light1, LOW);

      lcd.setCursor(0, 0);
      lcd.print("Light 1");
      lcd.setCursor(0, 1);
      lcd.print(":On");
      delay(2000);
      lcd.clear();
    }

    else if ((data == "turn off light one")||(data == "*turn off light one")||(data == "turn off living room light"))          // turn off light number 1
    {

      digitalWrite(Light1, HIGH);

      lcd.setCursor(0, 0);
      lcd.print("Light 1");
      lcd.setCursor(0, 1); 
      lcd.print(":Off");

      delay(2000);
      lcd.clear();
    }  

    // Control the devices using voice command

    else if ((data == "turn on light two")||(data == "turn on light to")||(data == "*turn on light two")||(data == "turn on bathroom light" ))// turn on light number 2

    {

      digitalWrite(Light2, LOW);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Light 2");
      lcd.setCursor(0, 1);
      lcd.print(":On");

      delay(2000);
      
    }

    else if ((data == "turn off light two")||(data == "turn off light to")||(data == "*turn off light two")||(data == "turn off bathroom light")) // turn off light number 2

    {

      digitalWrite(Light2, HIGH);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Light 2");
      lcd.setCursor(0, 1);
      lcd.print(":Off");

      delay(2000);

    }
    else if ((data == "turn on fan")||(data == "*turn on fan")||(data == "turn on fan"))// turn on fan

    {

      digitalWrite(Fan, LOW);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Fan");
      lcd.setCursor(0, 1);
      lcd.print(":On");

      delay(2000);

    }

    else if ((data == "turn off fan")||(data == "*turn off fan")||(data == "turn of fan")) // turn off fan

    {

      digitalWrite(Fan, HIGH);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Fan");
      lcd.setCursor(0, 1);
      lcd.print(":Off");

      delay(2000);

    }

    else if ((data == "turn on alarm")||(data == "*turn on alarm")) // turn on alarm

    {

      digitalWrite(Alarm, HIGH);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Alarm");
      lcd.setCursor(0, 1);
      lcd.print(":On");

      delay(2000);

    }

    else if ((data == "turn off alarm")||(data == "*turn off alarm")) // turn off alarm

    {

      digitalWrite(Alarm, LOW);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Alarm");
      lcd.setCursor(0, 1);      
      lcd.print(":Off");

      delay(2000);

    }
    else if (data.startsWith("RGB red"))  // set the RGB leds to red
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Red;  //set the RGB leds to red
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":red");

    delay(2000);

  } else if (data.startsWith("RGB Green"))  //set the RGB leds to green
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Green;  //set the RGB leds to green
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":green");

    delay(2000);

  } else if (data.startsWith("RGB blue"))  // set the RGB leds to blue
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Blue;  //set the RGB leds to blue
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":blue");

    delay(2000);

  } else if (data.startsWith("RGB yellow"))  // set the RGB leds to yellow
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Yellow;  //set the RGB leds to yellow
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":yellow");

    delay(2000);

  } else if (data.startsWith("RGB purple"))  // set the RGB leds to purple
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Purple;  //set the RGB leds to purple
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":purple");

    delay(2000);

  } else if (data.startsWith("RGB white"))  // // set the RGB leds to  white
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::White;  //set the RGB leds to white
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":white");

    delay(2000);

  } else if (data.startsWith("RGB party"))  // // set the RGB leds to  white
  {
    partyPattern();

  } else if (data.startsWith("RGB fading"))  // // set the RGB leds to  white
  {
    randomFading();

  } else if (data.startsWith("turn off RGB"))  // turn off all RGB LEDS
  {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;  //turn off all RGB LEDS
    }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":off");

    delay(2000);

  } 
    else if ((data == "turn on all")||(data == "turn all device on")||(data== "turn on all device")||(data== "turn all on")) // turn on all device

    {
      
      digitalWrite(Light1, LOW);
      digitalWrite(Light2, LOW);
      digitalWrite(Fan, LOW);
      digitalWrite(Alarm, HIGH);

    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Red;  //set the RGB leds to white
    }

      FastLED.show();

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("All");
      lcd.setCursor(0, 1);
      lcd.print(":On");

      delay(2000);

   }
    else if ((data== "turn off all")||(data == "turn all device off")||(data== "turn off all device")||(data== "turn all off")) // turn on all device
    {      
      
      digitalWrite(Light1, HIGH);
      digitalWrite(Light2, HIGH);
      digitalWrite(Fan, HIGH);
      digitalWrite(Alarm, LOW);

    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;  //turn off all RGB LEDS
    }

      FastLED.show();

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("All");
      lcd.setCursor(0, 1);
      lcd.print(":Off");      

      delay(2000);

    }

}

void rainbow() {
  static uint8_t hue = 0;
  fill_rainbow(leds, NUM_LEDS, hue, 7);
  hue++;

  FastLED.show();

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RGB");
  lcd.setCursor(0, 1);
  lcd.print(":party");


}

void randomFading() {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].fadeToBlackBy(20);
    leds[i] += CHSV(random8(), 255, 255);
  }
    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":fading");

    delay(50);

  
}

void partyPattern() {
  static uint8_t hue = 0;

  // Shift the hue for each LED
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(hue + i * 10, 255, 255);
  }

  // Show the LEDs
  FastLED.show();

  // Increment the hue for the next iteration
  hue += 2;  // Adjust the increment value to control the speed of color change

  // Clear the LCD, set the cursor, and print the pattern information
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RGB");
  lcd.setCursor(0, 1);
  lcd.print(":party");

  // Delay to control the speed of the pattern
  delay(200);
}


Welcome to the forum

This is your rainbow() function

void rainbow()
{
    static uint8_t hue = 0;
    fill_rainbow(leds, NUM_LEDS, hue, 7);
    hue++;

    FastLED.show();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("RGB");
    lcd.setCursor(0, 1);
    lcd.print(":party");
}

What do you expect it to do other than fill the LEDs with a rainbow of colours ?

could you share fill_rainbow()

It is a FastLED library function

void fill_rainbow( struct CRGB * targetArray, int numToFill,
                  uint8_t initialhue,
                  uint8_t deltahue )
{
    CHSV hsv;
    hsv.hue = initialhue;
    hsv.val = 255;
    hsv.sat = 240;
    for( int i = 0; i < numToFill; ++i) {
        targetArray[i] = hsv;
        hsv.hue += deltahue;
    }
}

yes it is, and i expect it to loop in a rainbow sequence but its doesnt loop and just stuck in rainbow colour but not looping into the sequence

Is it your rainbow() function or the fill_rainbow() function that you expect to loop ?

Bear in mind that you reset the data variable at the start of loop() so rainbow() will only be called once

can you tell me what to change, because im not that good in coding

What exactly do you want a looping rainbow function to do ? What should change on each iteration of the loop, for instance ?

i dont care what it do or the sequence, i want it to function in looping, im sorry if it sound rude

If you can't describe what it should do then it will be impossible for anyone to meet your expectations

What made you think that the function should loop in the first place ?

im sorry if its burdening you and thank you for replying to me, i think i will stop here because im not that good in this

Your rainbow depends on your bluetooth. Do you have a bluetooth module connected?

You, more than anyone, should care.

Above an excerpt of the beginning of loop(). If you send RGB rainbow, it is stored in data, the if condition will evaluate to true and a colour is set.

Next time through loop(), data is cleared and the above if no longer evaluates to true if you did not send RGB rainbow (does it?) and nothing else will happen.

Just a warning:
You have a high chance of data corruption with the given serial approach. Timing for NeoPixels is critical and interrupts are disabled during the update of the strip (show()). In my opinion the best way is to send one character, echo it back to the sender and only when the sender has received the echo it will send the next character.

That's the problem indeed.

Solution: those if (data.startswith(... parts store the current state of the strip in a static or global variable.

Then in the next part of loop() you have a switch/case block where you do the LED updates based on your current setting.

OP mentions there are only 12 LEDs, 32 bits x 12 LEDs @ 800 kHz = 0.5 ms for the update.
At 9600 bps it takes about 1 ms per bit, so that should be slow enough to be reliable even if there's data being sent while the LEDs try to update.

A millis() based delay updating the LEDs (so the update function is run only every say 25 ms) would be a good idea as well.

Of course it would be preferable to connect the bluetooth to the hardware serial on pins 0 an 1, rather than using SoftwareSerial. OP can do this after they're done debugging.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.