Virtual pins and a switch case

Hi, im curious about the virtual pins and how the work with a switch case state inside a function. In the blynk write v8, i call the servo function but the function is a switch case, it only moves through the cases after every push of the button widget. Ive tried adding state++ after the function but it needs me to declare all these other variables. Is there anyway to move through the switch case to the end while only pushing the widget once?

I think you’d need to post your sketch, and a complete description of what currently happens versus what you’d like to happen, for us to be able to understand the issue.

Pete.

#define ESP32_RTOS  // Uncomment this line if you want to use the code with freertos only on the ESP32
                 // Has to be done before including "OTA.h"
#include "OTA.h"
#include "credentials.h"
#include "NoiascaLedControl.h"
#include <pwmWrite.h>
#include <FastLED.h>

////blynk/////
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

char ssid[] = "ssid";
char pass[] = "password";

//////////////////////////////////////////////////pin 35 used for input rx and 32 for tx at a later date//////////////



const int servoPin1 = 18; //pie holo
const int servoPin2 = 19; //front holo 
const int servoPin3 = 21;  // rear holo

Pwm pwm = Pwm();          //pwm for esp32

#define NUM_LEDS_PER_STRIP 7
CRGB leds1[NUM_LEDS_PER_STRIP];   //pie neo
CRGB leds2[NUM_LEDS_PER_STRIP];   //front neo
CRGB leds3[NUM_LEDS_PER_STRIP];   // rear neo

///////////////holo timers//////////////
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;
unsigned long interval1 = 3000;
unsigned long interval2 = 1000;
unsigned long interval3 = 1000;
unsigned long holodelay = 15000; //(random (1000 , 5000));
unsigned long PreviousMillis = 0;
///////////////psi/////////////////////////////////////
// Constants for LED strips
#define DATA_PIN_22   22   //front psi
#define DATA_PIN_23   23 //rear   psi
#define NUM_LEDSpsi      21
#define LED_TYPE      WS2812B
#define COLOR_ORDER   GRB
#define DATA_RATE     800000

// LED strip objects
CRGB leds4[NUM_LEDSpsi];
CRGB leds5[NUM_LEDSpsi];
///psi timing//////
unsigned long previousMillisf = 0;
unsigned long previousMillisr = 0;
unsigned long interval4 = 0;
unsigned long interval5 = 0;
bool isRed = true;
bool isGreen = true;


/*
matrix logic pins
*/
const uint8_t LEDCS_PIN = 26;           // 26 LED CS or LOAD software spi
const uint8_t LEDCLK_PIN = 25;         // 25 LED Clock software spi
const uint8_t LEDDATA_PIN = 27;        // 27 LED DATA IN software spi
const uint8_t LED_MODULES = 5;     

LedControl lc = LedControl  (LEDDATA_PIN, LEDCLK_PIN, LEDCS_PIN, LED_MODULES);  // Software Bitbang - use this if you can't use Hardware SPI

/* we always wait a bit between updates of the display */
const unsigned long delaytime=100;

const int numCols = 8; // number of columns in LED matrix
const int numRows = 8; // number of rows in LED matrix
bool matrix[numCols][numRows]; // keep track of which LEDs are on or off


//////blynk vpins///
BLYNK_CONNECTED()
{
Blynk.syncVirtual(V7);  // will cause BLYNK_WRITE(V1) to be executed
}

BLYNK_WRITE(V7) // Executes when the value of virtual pin 1 changes
{
if(param.asInt() == 1)
{
 // execute this code if the switch widget is now ON
  theaterChaseRainbow();
}
}
//////////////////////////

void setup() {
Serial.begin(115200);
Serial.println("Booting");
//////blynk////

Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

setupOTA("R2 HEAD  still test", mySSID, myPASSWORD);////CHANGE FOR BOARD

// Your setup code
/* The MAX72XX needs to initialize hardware */
lc.begin();
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
lc.shutdown(1,false);
lc.shutdown(2,false);
lc.shutdown(3,false);
lc.shutdown(4,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
lc.setIntensity(1,8);
 lc.setIntensity(2,8);
  lc.setIntensity(3,8);
   lc.setIntensity(4,8);
/* and clear the display */
lc.clearDisplay(0);
lc.clearDisplay(1);
lc.clearDisplay(2);
lc.clearDisplay(3);
lc.clearDisplay(4);

FastLED.addLeds<NEOPIXEL, 4>(leds1, NUM_LEDS_PER_STRIP);        // pie neo pin
FastLED.addLeds<NEOPIXEL, 17>(leds2, NUM_LEDS_PER_STRIP);      // front neo pin
FastLED.addLeds<NEOPIXEL, 16>(leds3, NUM_LEDS_PER_STRIP);      // rear neo pin
////////// holo servo initilisation/////////
pwm.attach(servoPin1, 0, 1000, 2000);
pwm.attach(servoPin2, 1, 1000, 2000);
pwm.attach(servoPin3, 2, 1000, 2000); 

pwm.writeServo(servoPin1, 90); // Stop
pwm.writeServo(servoPin2, 90); // Stop
pwm.writeServo(servoPin3, 90); // Stop
////////////psi////////////////////////////////////
FastLED.addLeds<LED_TYPE, DATA_PIN_22, COLOR_ORDER>(leds4, NUM_LEDSpsi).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, DATA_PIN_23, COLOR_ORDER>(leds5, NUM_LEDSpsi).setCorrection(TypicalLEDStrip);
theaterChaseRainbow();
setRandomInterval();


//////////////////// matrix lines on startup////////////////
for (int row=0; row<8; row++)
{
 for (int col=0; col<8; col++)
 {
   lc.setLed(0,col,row,true); // turns on LED at col, row
   lc.setLed(1,col,row,true); // turns on LED at col, row
    lc.setLed(2,col,row,true); // turns on LED at col, row
     lc.setLed(3,col,row,true); // turns on LED at col, row
      lc.setLed(4,col,row,true); // turns on LED at col, row
   delay(50);
 }
}

for (int row=0; row<8; row++)
{
 for (int col=0; col<8; col++)
 {
   lc.setLed(0,col,row,false); // turns off LED at col, row
    lc.setLed(1,col,row,false); // turns off LED at col, row
     lc.setLed(2,col,row,false); // turns off LED at col, row
      lc.setLed(3,col,row,false); // turns off LED at col, row
       lc.setLed(4,col,row,false); // turns off LED at col, row
   delay(50);
   //lc.clearDisplay(0);// clear screen
   //lc.clearDisplay(1);// clear screen
 }
}  

}


void rando() {
// Turn on or off random LEDs
int count = 0;
while (count < 20) {
 int x = random(numCols);
 int y = random(numRows);

 if (matrix[x][y] == false) {
   lc.setLed(0, x, y, true);
    lc.setLed(1, x, y, true);
    lc.setLed(2, x, y, true);
    lc.setLed(3, x, y, true);
    lc.setLed(4, x, y, true);
   matrix[x][y] = true;
   count++;
 }
 else {
   lc.setLed(0, x, y, false);
    lc.setLed(1, x, y, false);
     lc.setLed(2, x, y, false);
      lc.setLed(3, x, y, false);
       lc.setLed(4, x, y, false);
   matrix[x][y] = false;
 }
}

delay(40); // wait a short time before updating the LEDs
}





void loop() {
#ifdef defined(ESP32_RTOS) && defined(ESP32)
#else // If you do not use FreeRTOS, you have to regulary call the handle method.
ArduinoOTA.handle();
#endif
Blynk.run();


front();
rear();

// Your code here
unsigned long currentMillis = millis();
rando();



if (currentMillis - PreviousMillis >= holodelay) {
servo1();
PreviousMillis = currentMillis;
holodelay = 10000; //(random (8000 , 15000));
PreviousMillis = 0;


// ArduinoOTA.handle();
if (currentMillis - PreviousMillis >= holodelay) {
servo2();
PreviousMillis = currentMillis;
holodelay = 10000; //(random (8000 , 15000));
PreviousMillis = 0;



//ArduinoOTA.handle();
if (currentMillis - PreviousMillis >= holodelay) {
servo3();
PreviousMillis = currentMillis;
holodelay = 10000; //(random (8000 , 15000));
PreviousMillis = 0;

} 
}
} 
}

void servo1(){
static byte state1 = 0;
unsigned long currentMillis = millis();

switch(state1) {
 case 0:
 holo1on();
 
   previousMillis1 = currentMillis;
   state1++;
   break;
 case 1:
   if (currentMillis - previousMillis1 >= interval1) {
     pwm.writeServo(servoPin1, (random (140 ,180)));
             previousMillis1 = currentMillis;
     state1++;
   }
   break;
 case 2:
   if (currentMillis - previousMillis1 >= interval2) {
     pwm.writeServo(servoPin1, 90); // Stop
     previousMillis1 = currentMillis;
     state1++;
   }
   break;
 case 3:
   if (currentMillis - previousMillis1 >= interval3) {
     pwm.writeServo(servoPin1,(random (0 , 50)));
     previousMillis1 = currentMillis;
     state1++;
   }
   break;
 case 4:
   if (currentMillis - previousMillis1 >= interval2) {
     pwm.writeServo(servoPin1, 90); // Stop
     previousMillis1 = currentMillis;
     state1++;
   }
   break;
 case 5:
   if (currentMillis - previousMillis1 >= interval3) {
     //FastLED.clear(true);
     holo1off();
     
     previousMillis1 = currentMillis;
     state1 = 0;
  
   }
   break;
}
}

void servo2(){
static byte state2 = 0;
unsigned long currentMillis = millis();

switch(state2) {
 case 0:
  // fill_solid (leds2, 7, CRGB(179, 230, 255));
   //FastLED.show();
   holo2on();
   
   previousMillis2 = currentMillis;
   state2++;
   break;
 case 1:
   if (currentMillis - previousMillis2 >= interval1) {
      pwm.writeServo(servoPin2, (random (140 ,180)));
    
     previousMillis2 = currentMillis;
     state2++;
   }
   break;
 case 2:
   if (currentMillis - previousMillis2 >= interval2) {
     pwm.writeServo(servoPin2, 90); // Stop
     
     previousMillis2 = currentMillis;
     state2++;
   }
   break;
 case 3:
   if (currentMillis - previousMillis2 >= interval3) {
      pwm.writeServo(servoPin2,(random (0 , 50)));
    
     previousMillis2 = currentMillis;
     state2++;
   }
   break;
 case 4:
   if (currentMillis - previousMillis2 >= interval2) {
     pwm.writeServo(servoPin2, 90); // Stop
     
     previousMillis2 = currentMillis;
     state2++;
   }
   break;
 case 5:
   if (currentMillis - previousMillis2 >= interval3) {
     //FastLED.clear(true);
     holo2off();
     
     previousMillis2 = currentMillis;
     state2 = 0;
   
   }
   break;
}
}



void servo3(){
static byte state3 = 0;
unsigned long currentMillis = millis();

switch(state3) {
 case 0:
 holo3on();
  // fill_solid (leds3, 7, CRGB(179, 230, 255));
  //FastLED.show();
   previousMillis3 = currentMillis;
   state3++;
   break;
 case 1:
   if (currentMillis - previousMillis3 >= interval1) {
      pwm.writeServo(servoPin3, (random (140 ,180)));
     
     previousMillis3 = currentMillis;
     state3++;
   }
   break;
 case 2:
   if (currentMillis - previousMillis3 >= interval2) {
     pwm.writeServo(servoPin3, 90); // Stop
    
     previousMillis1 = currentMillis;
     state3++;
   }
   break;
 case 3:
   if (currentMillis - previousMillis1 >= interval3) {
      pwm.writeServo(servoPin3,(random (0 , 50)));
    
     previousMillis1 = currentMillis;
     state3++;
   }
   break;
 case 4:
   if (currentMillis - previousMillis3 >= interval2) {
     pwm.writeServo(servoPin3, 90); // Stop
     
     previousMillis3 = currentMillis;
     state3++;
   }
   break;
 case 5:
   if (currentMillis - previousMillis3 >= interval3) {
    // FastLED.clear(true);
     holo3off();
     
     previousMillis3 = currentMillis;
     state3 = 0;
    
   }
   break;
}
}

void holo1on(){
fill_solid (leds1, 7, CRGB(179, 230, 255));
   FastLED.show();

}

void holo1off(){
//FastLED.clear(true);
fill_solid (leds1, 7, CRGB::Black);

   FastLED.show();
}

void holo2off(){
//FastLED.clear(true);

 fill_solid (leds2, 7, CRGB::Black);
  
   FastLED.show();
}

void holo3off(){
//FastLED.clear(true);

  fill_solid (leds3, 7, CRGB::Black);
   FastLED.show();
}

void holo2on(){
 fill_solid (leds2, 7, CRGB(179, 230, 255));
   FastLED.show();
}

void holo3on(){
 fill_solid (leds3, 7, CRGB(179, 230, 255));
   FastLED.show();
}

// Set all LEDs of a strip to a specified color
void setLEDsColor(CRGB* leds, int numLeds, const CRGB& color) {
for (int i = 0; i < numLeds; i++) {
 leds[i] = color;
}
}

// Set a random interval between 1 and 5 seconds
void setRandomInterval() {
interval4 = random(5000, 15000);
interval5 = random(5000, 15000);
}


void theaterChaseRainbow() {
int firstPixelHue = 0;     // First pixel starts at red (hue 0)
for (int a = 0; a < 30; a++) {  // Repeat 30 times...
 for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2...
//   setLEDsColor(leds5, NUM_LEDSpsi, 0, 0, 0); // Set all LEDs to off
//      setLEDsColor(leds4, NUM_LEDSpsi, 0, 0, 0); // Set all LEDs to off
   
   // 'c' counts up from 'b' to end of strip in increments of 3...
   for (int c = b; c < NUM_LEDSpsi; c += 3) {
     // hue of LED 'c' is offset by an amount to make one full
     // revolution of the color wheel (range 65536) along the length
     // of the strip (NUM_LEDSpsi steps):
     int hue = firstPixelHue + c * 65536L / NUM_LEDSpsi;
     leds4[c] = CHSV(hue, 255, 255); // hue -> RGB
     leds5[c] = CHSV(hue, 255, 255); // hue -> RGB
   }
   
   FastLED.show(); // Update both LED strips
   
   delay(50); // Pause for a moment
   firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
 }
}
}

void front(){
unsigned long currentMillisf = millis();

// Control the first set of LEDs on pin 22
if (currentMillisf - previousMillisf >= interval4) {
 if (isRed) {
   setLEDsColor(leds4, NUM_LEDSpsi, CRGB::Red);
   isRed = false;
 } else {
   setLEDsColor(leds4, NUM_LEDSpsi, CRGB::Blue);
   isRed = true;
 }

 FastLED.show(); // Update the first LED strip

 setRandomInterval(); // Set a new random interval

 previousMillisf = currentMillisf; // Update the previous millis
}
}

void rear(){

unsigned long currentMillisr = millis();

// Control the second set of LEDs on pin 23
if (currentMillisr - previousMillisr >= interval5) {
 if (isGreen) {
   setLEDsColor(leds5, NUM_LEDSpsi, CRGB::Green);
   isGreen = false;
 } else {
   setLEDsColor(leds5, NUM_LEDSpsi, CRGB::Yellow);
   isGreen = true;
 }

 FastLED.show(); // Update the second LED strip

 setRandomInterval(); // Set a new random interval

 previousMillisr = currentMillisr; // Update the previous millis
}
}

This is basically the sketch. When i use the blynk write and call the servo functions i have to press the widget button 5 times to go through all the states. What i was expecting was to press it once and have the whole function execute( holo on, servo move, servo stop, servo move, servo stop and holo off.)

Have you posted the correct sketch?
There is no BLYNK_WRITE(V8) in this sketch.

Pete.

Yes it is correct i just posted at the last point i saved it. But it’s essentially the same as the v7. I used v8 to call a function, the function being servo1, it only moves through the states with each press of the widget. Is there something else I should add? Is it a switch case thing?

The function you are calling is theaterChaseRainbow not servo1

If this really is the correct code then you won’t get good results with Blynk.
Blynk does not like a cluttered void loop or delays within the code.

You should read this…

I’d also spend more time on describing exactly what your issue is, and what the desired functionality is, as I suggested here…

because so far everything you’ve posted has been contradictory.

Pete.

//#define BLYNK_TEMPLATE_ID "TMPL6_MnUjhpi"
//#define BLYNK_TEMPLATE_NAME "dome head"
//#define BLYNK_AUTH_TOKEN "315bHCPDhZbcGfnFl63oxXo2Qp4PQv8M"
#define BLYNK_TEMPLATE_ID "TMPL6U11xeHKO"
#define BLYNK_TEMPLATE_NAME "dome lift"
#define BLYNK_AUTH_TOKEN "zKkzd7fj1n9Ev2jXcytRmVCry11IMeXX"




#define ESP32_RTOS  // Uncomment this line if you want to use the code with freertos only on the ESP32
                    // Has to be done before including "OTA.h"
#include "OTA.h"
#include "credentials.h"
#include "NoiascaLedControl.h"
//#include <pwmWrite.h>
#include <FastLED.h>
#include <ESP32Servo.h>



////blynk/////
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

char ssid[] = "TelstraA857CE";
char pass[] = "fuateu9u4t";

//////////////////////////////////////////////////pin 35 used for input rx and 32 for tx at a later date//////////////


const int servoPin[3] = {18, 19, 21}; ///martin change
//const int servoPin1 = 18; //pie holo
//const int servoPin2 = 19; //front holo 
//const int servoPin3 = 21;  // rear holo

#define NUM_HOLOS 3
 //Pwm pwm = Pwm();          //pwm for esp32
Servo servos[NUM_HOLOS];

#define NUM_HOLOS 3
#define NUM_LEDS_PER_STRIP 7
CRGB leds[3][NUM_LEDS_PER_STRIP];   //martin change

//CRGB leds[NUM_HOLOS * NUM_LEDS_PER_STRIP];  // total LEDS for all the holos as one strip   revision2
//CRGB* holoLeds[NUM_HOLOS];  // points to the start of each holo   revisoinn 2


//CRGB leds1[NUM_LEDS_PER_STRIP];   //pie neo
//CRGB leds2[NUM_LEDS_PER_STRIP];   //front neo
//CRGB leds3[NUM_LEDS_PER_STRIP];   // rear neo

///////////////holo timers//////////////
unsigned long PreviousMillis[3];

unsigned long interval1 = 1000;
unsigned long interval2 = 2000;
unsigned long interval3 = 3000;
//unsigned long holodelay[3] = {(random(4000 , 5000))}; //{500, 600, 700}; //(random (1000 , 5000)); revision 2
unsigned long holodelay = random (1000 , 5000);

/*unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;
unsigned long interval1 = 3000;
unsigned long interval2 = 1000;
unsigned long interval3 = 1000;
unsigned long holodelay = 15000; //(random (1000 , 5000));
unsigned long PreviousMillis = 0;
*/
///////////////psi/////////////////////////////////////
// Constants for LED strips
#define DATA_PIN_22   22   //front psi
#define DATA_PIN_23   23 //rear   psi
#define NUM_LEDSpsi      21
#define LED_TYPE      WS2812B
#define COLOR_ORDER   GRB
#define DATA_RATE     800000

// LED strip objects
CRGB leds4[NUM_LEDSpsi];
CRGB leds5[NUM_LEDSpsi];
///psi timing//////
unsigned long previousMillisf = 0;
unsigned long previousMillisr = 0;
unsigned long interval4 = 0;
unsigned long interval5 = 0;
bool isRed = true;
bool isGreen = true;


/*
matrix logic pins
 */
const uint8_t LEDCS_PIN = 26;           // 26 LED CS or LOAD software spi
const uint8_t LEDCLK_PIN = 25;         // 25 LED Clock software spi
const uint8_t LEDDATA_PIN = 27;        // 27 LED DATA IN software spi
const uint8_t LED_MODULES = 5;     

LedControl lc = LedControl  (LEDDATA_PIN, LEDCLK_PIN, LEDCS_PIN, LED_MODULES);  // Software Bitbang - use this if you can't use Hardware SPI

/* we always wait a bit between updates of the display */
const unsigned long delaytime=100;

const int numCols = 8; // number of columns in LED matrix
const int numRows = 8; // number of rows in LED matrix
bool matrix[numCols][numRows]; // keep track of which LEDs are on or off


//////blynk vpins///
BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V7);  // will cause BLYNK_WRITE(V1) to be executed
   Blynk.syncVirtual(V8);  // will cause BLYNK_WRITE(V1) to be executed
}

BLYNK_WRITE(V7) // Executes when the value of virtual pin 1 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
     theaterChaseRainbow();
  }
  }
//////////////////////////

BLYNK_WRITE(V8) // Executes when the value of virtual pin 1 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
     servo(1);
   
  }
  }
//////////////////////////

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  Serial.println("Holo Control");
//////blynk////

 Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

  setupOTA("R2 HEAD  still test", mySSID, myPASSWORD);////CHANGE FOR BOARD

  // Your setup code
   /* The MAX72XX needs to initialize hardware */
  lc.begin();
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
   lc.shutdown(1,false);
   lc.shutdown(2,false);
   lc.shutdown(3,false);
   lc.shutdown(4,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
   lc.setIntensity(1,8);
    lc.setIntensity(2,8);
     lc.setIntensity(3,8);
      lc.setIntensity(4,8);
  /* and clear the display */
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
  lc.clearDisplay(3);
  lc.clearDisplay(4);

unsigned long currentMillis = millis();  // Initialise millis here for main loop timer
   
  int holo;
  for  (holo = 0; holo < NUM_HOLOS; holo++)
  {
  //  holoLeds[holo] = &leds[holo * NUM_LEDS_PER_STRIP];  // set each array element to the start number to the first LED for each holo

    ESP32PWM::allocateTimer(holo);  // PWM timwer for each servo
     servos[holo].setPeriodHertz(50);    // standard 50 hz servo
    servos[holo].attach(servoPin[holo], 500, 2400); // attaches the servopin to the servo object
    servos[holo].write(90);  // move servo home
  }


  //FastLED.addLeds<NEOPIXEL, 15>(leds, NUM_HOLOS * NUM_LEDS_PER_STRIP);        // All LEDs for all holos as one strip  revision 2
//  FastLED.addLeds<NEOPIXEL, 2>(holoLeds[1], NUM_LEDS_PER_STRIP);      // front neo pin                                 rev2
//  FastLED.addLeds<NEOPIXEL, 15>(holoLeds[2], NUM_LEDS_PER_STRIP);      // rear neo pin                                 rev2
 
 



FastLED.addLeds<NEOPIXEL, 4>(leds[0], NUM_LEDS_PER_STRIP);        // pie neo pin                                         /rev1
  FastLED.addLeds<NEOPIXEL, 17>(leds[1], NUM_LEDS_PER_STRIP);      // front neo pin                                        rev1
  FastLED.addLeds<NEOPIXEL, 16>(leds[2], NUM_LEDS_PER_STRIP);      // rear neo pin                                       rev1


  
 //FastLED.addLeds<NEOPIXEL, 4>(leds1, NUM_LEDS_PER_STRIP);        // pie neo pin
 // FastLED.addLeds<NEOPIXEL, 17>(leds2, NUM_LEDS_PER_STRIP);      // front neo pin
 // FastLED.addLeds<NEOPIXEL, 16>(leds3, NUM_LEDS_PER_STRIP);      // rear neo pin
////////// holo servo initilisation/////////
/* pwm.attach(servoPin[0], 0, 1000, 2000);   /////martin change
  pwm.attach(servoPin[1], 1, 1000, 2000);
  pwm.attach(servoPin[2], 2, 1000, 2000); 
 
   pwm.writeServo(servoPin[0], 90); // Stop
   pwm.writeServo(servoPin[1], 90); // Stop
   pwm.writeServo(servoPin[2], 90); // Stop


 unsigned long currentMillis = millis();
 int holo;
 for  (holo = 0; holo < 3; holo++)
  PreviousMillis[holo] = currentMillis;

*/



 /*pwm.attach(servoPin1, 0, 1000, 2000);
  pwm.attach(servoPin2, 1, 1000, 2000);
  pwm.attach(servoPin3, 2, 1000, 2000); 
 
   pwm.writeServo(servoPin1, 90); // Stop
   pwm.writeServo(servoPin2, 90); // Stop
   pwm.writeServo(servoPin3, 90); // Stop
   */
 ////////////psi////////////////////////////////////
  FastLED.addLeds<LED_TYPE, DATA_PIN_22, COLOR_ORDER>(leds4, NUM_LEDSpsi).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE, DATA_PIN_23, COLOR_ORDER>(leds5, NUM_LEDSpsi).setCorrection(TypicalLEDStrip);
theaterChaseRainbow();
  setRandomInterval();


  //////////////////// matrix lines on startup////////////////
   for (int row=0; row<8; row++)
  {
    for (int col=0; col<8; col++)
    {
      lc.setLed(0,col,row,true); // turns on LED at col, row
      lc.setLed(1,col,row,true); // turns on LED at col, row
       lc.setLed(2,col,row,true); // turns on LED at col, row
        lc.setLed(3,col,row,true); // turns on LED at col, row
         lc.setLed(4,col,row,true); // turns on LED at col, row
      delay(50);
    }
  }

  for (int row=0; row<8; row++)
  {
    for (int col=0; col<8; col++)
    {
      lc.setLed(0,col,row,false); // turns off LED at col, row
       lc.setLed(1,col,row,false); // turns off LED at col, row
        lc.setLed(2,col,row,false); // turns off LED at col, row
         lc.setLed(3,col,row,false); // turns off LED at col, row
          lc.setLed(4,col,row,false); // turns off LED at col, row
      delay(50);
      //lc.clearDisplay(0);// clear screen
      //lc.clearDisplay(1);// clear screen
    }
  }  
 
}


void rando() {
  // Turn on or off random LEDs
  int count = 0;
  while (count < 20) {
    int x = random(numCols);
    int y = random(numRows);

    if (matrix[x][y] == false) {
      lc.setLed(0, x, y, true);
       lc.setLed(1, x, y, true);
       lc.setLed(2, x, y, true);
       lc.setLed(3, x, y, true);
       lc.setLed(4, x, y, true);
      matrix[x][y] = true;
      count++;
    }
    else {
      lc.setLed(0, x, y, false);
       lc.setLed(1, x, y, false);
        lc.setLed(2, x, y, false);
         lc.setLed(3, x, y, false);
          lc.setLed(4, x, y, false);
      matrix[x][y] = false;
    }
  }
  
  delay(40); // wait a short time before updating the LEDs
}





void loop() {
#ifdef defined(ESP32_RTOS) && defined(ESP32)
#else // If you do not use FreeRTOS, you have to regulary call the handle method.
  ArduinoOTA.handle();
#endif
 Blynk.run();

rando();
 front();
  rear();
/////////////////////rev2 code//////////////////////

 static long holo = NUM_HOLOS;  // which holo we are manipulating, needs to be static so we remember, set as invalid initially
  unsigned long currentMillis;
  static unsigned long PreviousMillis = 0;  // previous timer, statc so we can keep track of where we are up to

 

  currentMillis = millis();

  if (holo >= NUM_HOLOS)  // check if we have set a holo to move, if it is NUM_HOLOS or more it is invalid, so we can see if we pick a new one
  {
    if (currentMillis - PreviousMillis >= holodelay)  // holo is invalid so see if the delay between holos has expired so we can pick a new one
      holo = random(0, NUM_HOLOS);  // time to pick a new holo
  }
  else  // holo is valid so do something with it
  {
    if (servo(holo) == true)  // do something with the servo and then see if we have finished
    {
      holo = NUM_HOLOS;  // we are done so invalidate the holo
      PreviousMillis = currentMillis;  // set old time to now so we can wait between holos
    }
  }
  // blynk code here, can set call servo with a value
  // would need timer similar to above 
}



/*
 
  // Your code here
 //unsigned long currentMillis = millis();
 rando();

int holo;
 unsigned long currentMillis;

 currentMillis = millis();
 for  (holo = 0; holo < 3; holo++)
 { 
  if (currentMillis - PreviousMillis[holo] >= holodelay[holo])
  {
   servo(holo);
   PreviousMillis[holo] = currentMillis;
  }
 }
 */



boolean servo(long holo)
{
  static byte state[NUM_HOLOS] = {0, 0, 0};  //  maintain a current state for each holo
  unsigned long currentMillis;
  static unsigned long previousMillis[NUM_HOLOS] = {0, 0, 0};  // maintain current timer for each holo
  boolean retval = false;  // flag to see if we have finished, set to false by default

  currentMillis = millis();
  switch(state[holo])  // state machine of where we are in the cycle for each holo
  {
    case 0:  // initiallise state
      holoOn(holo);  // holo on (obviously)
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
      previousMillis[holo] = currentMillis;
      state[holo]++;
      break;

    case 1:  // first movement
      if ((currentMillis - previousMillis[holo]) >= interval3)  // only move if time to do so
      {
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        servos[holo].write(random (100 ,150));  // move to rando position
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 2:  // first move back to home state
      if ((currentMillis - previousMillis[holo]) >= interval2)
      {
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        servos[holo].write(90); // Stop
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 3:  // next move state
      if ((currentMillis - previousMillis[holo]) >= interval1)
      {
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        servos[holo].write(random (50 , 90));
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 4:  // second go home state
      if ((currentMillis - previousMillis[holo]) >= interval2)
      {
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        servos[holo].write(90); // Stop
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 5:  // final state
      if ((currentMillis - previousMillis[holo]) >= interval3)
      {
//Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        //FastLED.clear(true);
        holoOff(holo);  // holo off (beleive it or not)
        previousMillis[holo] = currentMillis;
        holodelay = random (2000 , 5000);  // pick a random delay for how long to wait for next holo move
        state[holo] = 0;  // reset state back to start
        retval = true;  // set the flag to finished for the callers
       }
      break;
  }
  return(retval);  // return progress flag - true = done, false = still processing
}
 
void holoOn(long holo)
{
Serial.printf("Holo %d on\n", holo);
  //fill_solid(holoLeds[holo], NUM_LEDS_PER_STRIP, CRGB(179, 230, 255));  // set the holo LEDs to some colour  rev2
  fill_solid(leds[holo], 7, CRGB(179, 230, 255));         // rev1
  FastLED.show();
}
 
void holoOff(int holo)
{
Serial.printf("Holo %d off\n", holo);
 //fill_solid(holoLeds[holo], NUM_LEDS_PER_STRIP, CRGB::Black);  // set holo LEDs to black (off) rev2
 fill_solid(leds[holo], 7, CRGB::Black);                     // rev1
 FastLED.show();
}






////////////rev1 below///////////////////////
/*
void servo(int holo)
{
  static byte state[3] = {0, 0, 0};
  unsigned long currentMillis;
  unsigned long previousMillis[3] = {0, 0, 0};
 unsigned long interval1 = 1000;
unsigned long interval2 = 100;
unsigned long interval3 = 100;
  currentMillis = millis();
  switch(state[holo])
  {
    case 0:
      holoOn(holo);
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
      previousMillis[holo] = currentMillis;
      state[holo]++;
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
      break;

    case 1:
      if ((currentMillis - previousMillis[holo]) >= interval1)
      {
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        pwm.writeServo(servoPin[holo], (random (140 ,180)));
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 2:
      if ((currentMillis - previousMillis[holo]) >= interval2)
      {
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        pwm.writeServo(servoPin[holo], 90); // Stop
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 3:
      if ((currentMillis - previousMillis[holo]) >= interval3)
      {
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        pwm.writeServo(servoPin[holo],(random (0 , 50)));
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 4:
      if ((currentMillis - previousMillis[holo]) >= interval2)
      {
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        pwm.writeServo(servoPin[holo], 90); // Stop
        previousMillis[holo] = currentMillis;
        state[holo]++;
      }
      break;

    case 5:
      if ((currentMillis - previousMillis[holo]) >= interval1)
      {
Serial.printf("H: %d - S: %d, C: %d - P: %d\n", holo, state[holo], currentMillis, previousMillis[holo]);
        //FastLED.clear(true);
        holoOff(holo);
        previousMillis[holo] = currentMillis;
        holodelay[holo] = random (5000 , 10000);
        state[holo] = 0;
       }
      break;
  }
}
 
void holoOn(int holo){
fill_solid(leds[holo], 7, CRGB(179, 230, 255));
      FastLED.show();
 
}
 
void holoOff(int holo){
 //FastLED.clear(true);
   fill_solid(leds[holo], 7, CRGB::Black);
 
      FastLED.show();
}



 
 /* 
 if (currentMillis - PreviousMillis >= holodelay) {
  servo1();
  PreviousMillis = currentMillis;
  holodelay = 10000; //(random (8000 , 15000));
  PreviousMillis = 0;
  
 
// ArduinoOTA.handle();
 if (currentMillis - PreviousMillis >= holodelay) {
  servo2();
  PreviousMillis = currentMillis;
  holodelay = 10000; //(random (8000 , 15000));
  PreviousMillis = 0;
  
  
  
  //ArduinoOTA.handle();
  if (currentMillis - PreviousMillis >= holodelay) {
  servo3();
  PreviousMillis = currentMillis;
  holodelay = 10000; //(random (8000 , 15000));
  PreviousMillis = 0;
  
 } 
 }
 } 
}

void servo1(){
  static byte state1 = 0;
  unsigned long currentMillis = millis();

  switch(state1) {
    case 0:
    holo1on();
    
      previousMillis1 = currentMillis;
      state1++;
      break;
    case 1:
      if (currentMillis - previousMillis1 >= interval1) {
        pwm.writeServo(servoPin1, (random (140 ,180)));
                previousMillis1 = currentMillis;
        state1++;
      }
      break;
    case 2:
      if (currentMillis - previousMillis1 >= interval2) {
        pwm.writeServo(servoPin1, 90); // Stop
        previousMillis1 = currentMillis;
        state1++;
      }
      break;
    case 3:
      if (currentMillis - previousMillis1 >= interval3) {
        pwm.writeServo(servoPin1,(random (0 , 50)));
        previousMillis1 = currentMillis;
        state1++;
      }
      break;
    case 4:
      if (currentMillis - previousMillis1 >= interval2) {
        pwm.writeServo(servoPin1, 90); // Stop
        previousMillis1 = currentMillis;
        state1++;
      }
      break;
    case 5:
      if (currentMillis - previousMillis1 >= interval3) {
        //FastLED.clear(true);
        holo1off();
        
        previousMillis1 = currentMillis;
        state1 = 0;
     
      }
      break;
  }
}

void servo2(){
  static byte state2 = 0;
  unsigned long currentMillis = millis();

  switch(state2) {
    case 0:
     // fill_solid (leds2, 7, CRGB(179, 230, 255));
      //FastLED.show();
      holo2on();
      
      previousMillis2 = currentMillis;
      state2++;
      break;
    case 1:
      if (currentMillis - previousMillis2 >= interval1) {
         pwm.writeServo(servoPin2, (random (140 ,180)));
       
        previousMillis2 = currentMillis;
        state2++;
      }
      break;
    case 2:
      if (currentMillis - previousMillis2 >= interval2) {
        pwm.writeServo(servoPin2, 90); // Stop
        
        previousMillis2 = currentMillis;
        state2++;
      }
      break;
    case 3:
      if (currentMillis - previousMillis2 >= interval3) {
         pwm.writeServo(servoPin2,(random (0 , 50)));
       
        previousMillis2 = currentMillis;
        state2++;
      }
      break;
    case 4:
      if (currentMillis - previousMillis2 >= interval2) {
        pwm.writeServo(servoPin2, 90); // Stop
        
        previousMillis2 = currentMillis;
        state2++;
      }
      break;
    case 5:
      if (currentMillis - previousMillis2 >= interval3) {
        //FastLED.clear(true);
        holo2off();
        
        previousMillis2 = currentMillis;
        state2 = 0;
      
      }
      break;
  }
}



void servo3(){
  static byte state3 = 0;
  unsigned long currentMillis = millis();

  switch(state3) {
    case 0:
    holo3on();
     // fill_solid (leds3, 7, CRGB(179, 230, 255));
     //FastLED.show();
      previousMillis3 = currentMillis;
      state3++;
      break;
    case 1:
      if (currentMillis - previousMillis3 >= interval1) {
         pwm.writeServo(servoPin3, (random (140 ,180)));
        
        previousMillis3 = currentMillis;
        state3++;
      }
      break;
    case 2:
      if (currentMillis - previousMillis3 >= interval2) {
        pwm.writeServo(servoPin3, 90); // Stop
       
        previousMillis3 = currentMillis;
        state3++;
      }
      break;
    case 3:
      if (currentMillis - previousMillis3 >= interval3) {
         pwm.writeServo(servoPin3,(random (0 , 50)));
       
        previousMillis3 = currentMillis;
        state3++;
      }
      break;
    case 4:
      if (currentMillis - previousMillis3 >= interval2) {
        pwm.writeServo(servoPin3, 90); // Stop
        
        previousMillis3 = currentMillis;
        state3++;
      }
      break;
    case 5:
      if (currentMillis - previousMillis3 >= interval3) {
       // FastLED.clear(true);
        holo3off();
        
        previousMillis3 = currentMillis;
        state3 = 0;
       
      }
      break;
  }
}

void holo1on(){
fill_solid (leds1, 7, CRGB(179, 230, 255));
      FastLED.show();
  
}

void holo1off(){
 //FastLED.clear(true);
   fill_solid (leds1, 7, CRGB::Black);
   
      FastLED.show();
}

void holo2off(){
 //FastLED.clear(true);
  
    fill_solid (leds2, 7, CRGB::Black);
     
      FastLED.show();
}

void holo3off(){
 //FastLED.clear(true);
   
     fill_solid (leds3, 7, CRGB::Black);
      FastLED.show();
}

void holo2on(){
    fill_solid (leds2, 7, CRGB(179, 230, 255));
      FastLED.show();
}

void holo3on(){
    fill_solid (leds3, 7, CRGB(179, 230, 255));
      FastLED.show();
}
*/
// Set all LEDs of a strip to a specified color
void setLEDsColor(CRGB* leds, int numLeds, const CRGB& color) {
  for (int i = 0; i < numLeds; i++) {
    leds[i] = color;
  }
}

// Set a random interval between 1 and 5 seconds
void setRandomInterval() {
  interval4 = random(5000, 15000);
  interval5 = random(5000, 15000);
}


void theaterChaseRainbow() {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for (int a = 0; a < 30; a++) {  // Repeat 30 times...
    for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2...
   //   setLEDsColor(leds5, NUM_LEDSpsi, 0, 0, 0); // Set all LEDs to off
//      setLEDsColor(leds4, NUM_LEDSpsi, 0, 0, 0); // Set all LEDs to off
      
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for (int c = b; c < NUM_LEDSpsi; c += 3) {
        // hue of LED 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (NUM_LEDSpsi steps):
        int hue = firstPixelHue + c * 65536L / NUM_LEDSpsi;
        leds4[c] = CHSV(hue, 255, 255); // hue -> RGB
        leds5[c] = CHSV(hue, 255, 255); // hue -> RGB
      }
      
      FastLED.show(); // Update both LED strips
      
      delay(50); // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

void front(){
 unsigned long currentMillisf = millis();

  // Control the first set of LEDs on pin 22
  if (currentMillisf - previousMillisf >= interval4) {
    if (isRed) {
      setLEDsColor(leds4, NUM_LEDSpsi, CRGB::Red);
      isRed = false;
    } else {
      setLEDsColor(leds4, NUM_LEDSpsi, CRGB::Blue);
      isRed = true;
    }

    FastLED.show(); // Update the first LED strip

    setRandomInterval(); // Set a new random interval

    previousMillisf = currentMillisf; // Update the previous millis
  }
}

void rear(){
  
  unsigned long currentMillisr = millis();
  
   // Control the second set of LEDs on pin 23
  if (currentMillisr - previousMillisr >= interval5) {
    if (isGreen) {
      setLEDsColor(leds5, NUM_LEDSpsi, CRGB::Green);
      isGreen = false;
    } else {
      setLEDsColor(leds5, NUM_LEDSpsi, CRGB::Yellow);
      isGreen = true;
    }

    FastLED.show(); // Update the second LED strip

    setRandomInterval(); // Set a new random interval

    previousMillisr = currentMillisr; // Update the previous millis
  }
}

ok this is the exact code i have running, it has been modified to the previous and all the commented out stuff needs deleting, but essentially my problem still exists as it did before. when i press the widget button on the web dashboard or the mobile app all it does is light the leds, then if i push it again it moves the servo, etc etc. each “press” moves through the different cases until i get to the case 5 and the leds turn off. Am i missing something like state++ after the function call?

Which one? The widget connected to V7 or the one connected to V8?

What is it that you want/expect the LEDs and servo to do when you press whichever widget button it is that you’re referring to?

Pete.

Im referring to v8 widget, I expected it to move through the function as if it was called from loop. This is what happens when press the v7 widget calling theatrechaserainbow(). It does its thing and continues back on its loop. Its also the same thing in a separate sketch on a different template. In the sketch as a whole, the holos move at random intervals, i intend to make the random value longer and call the servos with the blynk app. So i ask again, will the virtual pins call a switch case and move through it by itself or is there something im missing in the blynk write

When you press a button attached to a virtual datastream the corresponding BLYNK_WRITE(vPin) function is triggered once.

Your theaterChaseRainbow function loops because of the nested for loops within that function, not because `BLYNK_WRITTE(V7) is triggered multiple times from one button press.

If you want your servo1 function to loop in a similar way then you need to re-write the function or triggers the function with a BlynkTimer and do a logical if test to check if the button widget attached to V8 is currently on or off. To do that you would need to set a global variable and add V8 into your BLYNK_CONNECTED function.

Pete.

Yay, ok. Thanks for the clarification.

I dont suppose you could explain in a bit more detail, or an exampe? I didnt write the entire sketch, just trying to modify it