My code crashes the esp32 (forces reboot)

HI, on my ESP32 i am trying to do the following:

BLYNK_WRITE(V1) {
  int pinValue = param.asInt();
  digitalWrite(leftLightEnable, pinValue == 0 ? LOW : HIGH);
  digitalWrite(rightLightEnable, pinValue == 0 ? LOW : HIGH);
  Blynk.virtualWrite(V3, pinValue == 0 ? 0 : 1);
  Blynk.virtualWrite(V5, pinValue == 0 ? 0 : 1);
}

which does not work, as the virtualWrite() call inside this crashes the esp32 (forces reboot).
Can anyone explain why?

Then i tried the following as a workaround after deleting the virtualWrite calls:

BLYNK_READ(V1) {
  Serial.printf("App requests V1 state\n");
  Blynk.virtualWrite(V3, digitalRead(leftLightEnable) == LOW ? 0 : 1);
  Blynk.virtualWrite(V5, digitalRead(rightLightEnable) == LOW ? 0 : 1);
}

But the BLYNK_READ function never gets called. Shouldn’t this function be called every time a virtual pin’s state changes in the app (or at least the specified pin) ?

I am running a local Blynk server (Docker container on a Synology NAS).
Everything else works so far (turning the lights on/off via app and setting their brightness).

The rest of the code should not be relevant in this case, but i can attach it if anyone needs it for better understanding/etc.

Thanks in advance for any help!

Perhaps due to the fancy comparator shortcuts within the Blynk proprietary command structure… something that doesn’t compute with the Blynk library?

BLYNK_READ() is only used with display type widgets set to a reading frequency, not PUSH. This way the Widget acts like a timer, calling the function (when App/project is open/active) as needed.

Thanks for your reply!

tried replacing the ternary operators with the following:

BLYNK_WRITE(V1) {
  int pinValue = param.asInt(); 

  if (pinValue == 0) {
    digitalWrite(leftLightEnable, LOW);
    Blynk.virtualWrite(V3, 0);
  } else {
    digitalWrite(leftLightEnable, HIGH);
    Blynk.virtualWrite(V3, 1);
  }
  if (pinValue == 0) {
    digitalWrite(rightLightEnable, LOW);
    Blynk.virtualWrite(V5, 0);
  } else {
    digitalWrite(rightLightEnable, HIGH);
    Blynk.virtualWrite(V5, 1);
  }
}

same result (crash) :frowning:
Any other ideas?

Troubleshooting 101 I guess…

Confirm if it the Blynk function works itself (EG. containing only Serial Prints for diagnostics… only with virtual writes… only with digital writes, etc.).

Look at whatever the digital writes are doing… do you have proper pinMode() settings? Improper pins used? Something drawing too much current when GPIO activated? Etc, etc…

PS If so, then perhaps your comparator shortcuts WILL work with Blynk function? Test with known good scenarios.

PPS I fixed your title to something more relevant

Confirm if it the Blynk function works itself (EG. containing only Serial Prints for diagnostics… only with virtual writes

The following works without any problems, Serial prints are shown correctly and the physical lights respond by lighting up:

BLYNK_WRITE(V1) {
  int pinValue = param.asInt();

  Serial.printf("Pin V1 changed to: %d\n", pinValue);
  digitalWrite(leftLightEnable, pinValue == 0 ? LOW : HIGH);
  digitalWrite(rightLightEnable, pinValue == 0 ? LOW : HIGH);
}

So cases “Serial print woking?” and “digitalWrites working?” are :white_check_mark:

only with digital writes, etc.).

Crashes the system:

BLYNK_WRITE(V1) {
  int pinValue = param.asInt();
  Blynk.virtualWrite(V3, pinValue == 0 ? 0 : 1);
  Blynk.virtualWrite(V5, pinValue == 0 ? 0 : 1);
}

do you have proper pinMode() settings

Yes, pins are set up properly. checked twice and thrice, hardware behaves as it should:

ledcSetup(leftLightPwmChannel, lightsPwmFrequency, lightsPwmResolution);
ledcSetup(rightLightPwmChannel, lightsPwmFrequency, lightsPwmResolution);
ledcAttachPin(leftLightPwmPin, leftLightPwmChannel);
ledcAttachPin(rightLightPwmPin, rightLightPwmChannel);
pinMode(leftLightEnablePin, OUTPUT);
pinMode(rightLightEnablePin, OUTPUT);

Something drawing too much current when GPIO activated? Etc, etc…

No, i made sure the esp32 is not serving as a current source, only voltage (H-Bridge Motor controller board, external psu etc.)

PS If so, then perhaps your comparator shortcuts WILL work with Blynk function

Yes, these operators always worked so far in any esp32 project ans also in the digitalWrite functions. the compiler interpretes these as simple if/elses.

Can you confirm the virtualWrite functions are in general working inside BLYNK_WRITE ?

Totally confirmed (just look around this forum full of code :slight_smile: )… it is one of the backbone functionality’s of Blynk.

Again… perhaps the method of your comparator shortcuts??

BTW, it is entirely possible that your shortcut method allows for double processes on each Widget press… once for press, once for release.

BTW, this is a rather convoluted way of doing whatever you are doing… Try this…

BLYNK_WRITE(V1) { 
int pinValue = param.asInt(); 
  if (pinValue) {  // If 1/HIGH
    // Digital Pin actions
    digitalWrite(leftLightEnable, HIGH);
    digitalWrite(rightLightEnable, HIGH);
    // Virtual pin actions
    Blynk.virtualWrite(V3, 1);
    Blynk.virtualWrite(V5, 1);
  } else {
    // Digital Pin actions
    digitalWrite(leftLightEnable, LOW);
    digitalWrite(rightLightEnable, LOW);
    // Virtual Pin actions
    Blynk.virtualWrite(V3, 0);
    Blynk.virtualWrite(V5, 0);
  }
}

Totally confirmed (just look around this forum full of code :slight_smile: )… it is one of the backbone functionality’s of Blynk.

As i tought, saw many examples with virtualWrites inside WRITE so i am wondering…

Again… perhaps the method of your comparator shortcuts??

No luck :frowning: :

BLYNK_WRITE(V1) {
      int pinValue = param.asInt();  

  if (pinValue == 0) {
    Blynk.virtualWrite(V3, 0);
  } else {
    Blynk.virtualWrite(V3, 1);
  }
  if (pinValue == 0) {
    Blynk.virtualWrite(V5, 0);
  } else {
    Blynk.virtualWrite(V5, 1);
  }
}

BTW, it is entirely possible that your shortcut method allows for double processes on each Widget press… once for press, once for release.

i configured the widgets as switches, instead of push buttons if this helps

BTW, this is a rather strange way of doing whatever you are doing…

i know, normally i would use eventor to update the state of another button as soon as one button state changes, but my current project does not work with eventor (sliders with range 0-1023) would need 1024 cases…

my project to give you a better picture:

As in ESP32 reboot, or ESP32 fine but nothing happens in App??

Also, what widget is on V3 and V5? EDIT I see your image now… Buttons/switches?? What is it you are expecting to happen?

ESP reboot = crash of the system and app state does not change

Also, what widget is on V3 and V5?

V3 is for left light, V5 for right. these work fine:

BLYNK_WRITE(V3) {  // State of left light
  int pinValue = param.asInt();
  Serial.printf("Pin V3 changed to: %d\n", pinValue);
  digitalWrite(leftLightEnable, pinValue == 0 ? LOW : HIGH);
}

BLYNK_WRITE(V5) {  // State of right light
  int pinValue = param.asInt();
  Serial.printf("Pin V5 changed to: %d\n", pinValue);
  digitalWrite(rightLightEnable, pinValue == 0 ? LOW : HIGH);
}

i just want the following functionality:

V3 and V5 are off => V1 goes off
same for on

V1 goes off => V3 off and V5 off
same for on again

Buttons/switches?? What is it you are expecting to happen?

Switches, receiving 0 for off and 1 for on.
Same configuration for V3 and V5.

Well… I am not going to rewrite your code in a way that I think might logicly work better… but that is not the primary issue (or is it??)… the ESP32 rebooting.

I would experiment with some simpler code to test all the basic Blynk functions you want, one at a time… and see if any of them cause another reboot.

Something to note, a Blynk.virtualWrite(vPin, value) will change the Widget state/value just fine (normally :slight_smile: )… but if you then want your code to act as if “you” had pressed that widget, and thus do something based on the new state, you need to follow up with a Blynk.syncVirtual(vPin) which triggers the server to call the associated BLYNK_WRITE(vpin) function and do something.

The logics are not the problem, no worries about that :smiley:

I will do as you recommend and start the project from scratch taking examples from the current one and debug on each change. was just hoping someone here ran into this issue and could give a quick solution for this, but seems to be a unique problem i have to investigate step by step.

Thank you for all your time and help! :slight_smile:

I meant that I suspect something in your code is causing the ESP32 crash… but that is mostly based on the code and logic I have seen so far as being a bit unusual (at least for me :slight_smile: )

Ah, found the issue!

Initially i created a thread dedicated to run Blynk.run() to keep my loop() clean :

void* BlynkLoop(void* param) {
  while (true) {
    Blynk.run();
  }
}

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

// Setup
...

// Thread Creations
if (pthread_create(&blynkThread, NULL, BlynkLoop, NULL) == 0) Serial.printf("Thread Blynk Runner successfully started\n");
}

This worked fine, until i tried calling virtualWrite() inside any BLYNK_WRITE()
So far pthreads worked perfectly in any project, guess blynk has some implementation hidden which crashes on posix stuff or there is a stack/heap overflow happening. Could be helpful to write a line on this in the docs for the future :slight_smile:

pthreads… umm, yep… never heard of them before… Blynk was made way back before ESP32 and multicore/thread options… we probably should have seen the whole code before running down rabbit trails :stuck_out_tongue:

As Blynk is going through commercialization changes (over last 1-2 years), the devs have made it clear that this version is not about to get any further real work done to it, or the docs…

But then you are only the 2nd user… ever… to even mention pthreads in this forum :laughing:

my bad :man_facepalming: :sweat_smile: