Exiting a running function

Hi, I am working on a project using ESP32 and RGB LED lights.


#define BLYNK_TEMPLATE_ID ""
#define BLYNK_DEVICE_NAME ""
#define BLYNK_AUTH_TOKEN ""

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Blynk.h>
#include <analogWrite.h>
#include <EEPROM.h>
#include <TimeLib.h>

#define red 26
#define green 14
#define blue 33

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "";
char pass[] = "";

BlynkTimer timer;
int timerId;

int red_value;
int green_value;
int blue_value;

const int redAddr = 0;
const int greenAddr = 1;
const int blueAddr = 2;

int delai;

int pv1;
int pv2;

int on_off;

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  EEPROM.begin(512);

  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);

  red_value = EEPROM.read(redAddr1);
  green_value = EEPROM.read(greenAddr1);
  blue_value = EEPROM.read(blueAddr1);

  analogWrite(red, red_value);  
  analogWrite(green, green_value);
  analogWrite(blue, blue_value);
  delai = delai;
}

BLYNK_WRITE(V0) // rgb
{

  red_value = param[0].asInt();
  green_value = param[1].asInt();
  blue_value = param[2].asInt();
  if (on_off == 1)
  {
    analogWrite(red, red_value);
    analogWrite(green, green_value);
    analogWrite(blue, blue_value);

    EEPROM.write(redAddr1, red_value);
    EEPROM.write(greenAddr1, green_value);
    EEPROM.write(blueAddr1, blue_value);
    EEPROM.commit();
  }
}

BLYNK_WRITE(V3) // on/off
{
  on_off = param.asInt();
  if(on_off == 0){
    analogWrite(red, 0);
    analogWrite(green, 0);
    analogWrite(blue, 0);
    
    EEPROM.write(redAddr1, 0);
    EEPROM.write(greenAddr1, 0);
    EEPROM.write(blueAddr1, 0);
    EEPROM.commit();
  }else{
    analogWrite(red, red_value);
    analogWrite(green, green_value);
    analogWrite(blue, blue_value);

    EEPROM.write(redAddr1, red_value);
    EEPROM.write(greenAddr1, green_value);
    EEPROM.write(blueAddr1, blue_value);
    EEPROM.commit();
  }
}

BLYNK_WRITE(V6) // animation speed
{
  delai = param.asInt();

 EEPROM.write(delaiAddr, delai);
 EEPROM.commit();
}

BLYNK_WRITE(V5) // color change
{
  pv1 = param.asInt();
  if (on_off == 1)
  {
    if (pv1 == 1)
    {
      startLoop();
    }
    else if (pv1 == 0)
    {
      stopLoop();
    }
  }
}

void colorChange()
{
  digitalWrite(red, HIGH);
  digitalWrite(green, LOW);
  digitalWrite(blue, LOW);
  for (int i = 0; i < 255; i += 1)
  {
    red_value -= 1;
    green_value += 1;
    analogWrite(red, red_value);
    analogWrite(green, green_value);
    delay(delai);
  }

  red_value = 0;
  green_value = 255;
  blue_value = 0;

  for (int i = 0; i < 255; i += 1)
  {
    green_value -= 1;
    blue_value += 1;
    analogWrite(green, green_value);
    analogWrite(blue, blue_value);
    delay(delai);
    yield();
  }

  red_value = 0;
  green_value = 0;
  blue_value = 255;

  for (int i = 0; i < 255; i += 1)
  {
    blue_value -= 1;
    red_value += 1;
    analogWrite(blue, blue_value);
    analogWrite(red, red_value);
    delay(delai);
  }
}

void startLoop()
{
  timer.setInterval(pv1, colorChange);
}

void stopLoop()
{
  timer.deleteTimer(timerId);
  analogWrite(red, red_value);
  analogWrite(green, green_value);
  analogWrite(blue, blue_value);
}

void loop()
{
  Blynk.run();
  timer.run();
}


In my program code, I want the stopLoop() function to be executed immediately when called without waiting for the colorChange() function to finish executing its code.

Currently, when the colorChange() function is running and the stopLoop() function is called, it will wait for the colorChange() function to finish executing before executing the stopLoop() function.

What is the solution? Thank you.

You’re going to need to add a Blynk.run() into these for loops.

You may also need to ad a test to see if pv1 == 1, but I don’t think that will be necessary.

You’re doing some other dodgy stuff though, such as the blocking delays, and not capturing the timer ID of your timer when it’s created, and therefore assuming that it will always be zero.

Pete.

Thank you for your reply. It turns out that adding “Blynk.run()” inside the for loop has solved my problem, and the program now runs as intended.

But I still don’t understand what you mean by that, I am still new to learning programming

When you use a delay(x) command it stops ALL CODE EXECUTION for x milliseconds.
This means that the device is totally unresponsive and not communicating with the Blynk server. You would be better using non-blocking delays where possible.

Also, this…

Defines a variable to hold the timer ID, and it’s initialised with a value of zero (because you didn’t specify any value, which is fine).

When you create your timer…

You aren’t discovering which ID has been allocated to that timer, and storing it in your `timerid’ variable. You capture the ID allocated to the timer like this…

timerid = timer.setInterval(pv1, colorChange);

But, there is a bug with the underlying SimpleTimer code (which BlynkTimer is based on) that causes issues when multiple timers are used. You can get around this by creating a dummy sacrificial timer to take-up the first timer slot.

You can read more about non-blocking timers, timer IDs and sacrificial timers here…

Pete.