BlynkWrite not updating the button state when got looping inside

• Hardware model + communication type : ESP32 + Wifi
• Smartphone OS : Android
• Blynk server region : Asia/Local
• Blynk Library version : 0.6.1

What i want to acheive is :

  • When switch is click, the scanCard function will be called continuously.
  • AND it will stop only if i click the switch back, turn off.
    The problem here is when i click turnOFF, the looping is still going and the else statement is not executed. Neither removing if (scanON == 0) { break; } will make any different.
BLYNK_WRITE(V6) {
  scanON = param.asInt();

  if (scanON == 1) {
    while (scanON == 1) {

      Serial.println("Scanning Start");
      scanCard();
      delay(1000);
      if (scanON == 0) { break; }
    }
  } else {
    Serial.println("Closing");
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();

    Serial.println("Scanning END");
  }
}

btw this is code for RFID.

extra note. the scanON variable once inside the scanCard() will remain value 1. Will never change to 0 even the switch already click to change state to 0

You’re using the BLYNK_WRITE(vPin) callback function incorrectly.

You should simply be using it to set a global variable value, then using that value in code that is called via a BlynkTimer, or in the case of an RFID reader it will probably need to be in the void loop.

You should avoid the use of while and delay commands when using Blynk.

If you want further help then posting snippets of code isn’t the best way to obtain assistance.

Pete.

should avoid while and delay because it block all process within blynk and server? or I can said it lock my system process at a point?

while for using blynk_write incorrectly. did u mean that I should used it straightfoward?

BLYNK_WRITE(V6)   {
  //scanON = param.asInt();

  if (param.asInt() == 1)
{ 
//do something 
}
}

They should be avoided for both reasons.
The Blynk library only knows about widget button presses when it executes Blynk.run(), and can only do server ping and handshake operations, and service Blynk.virtualWrite() commands when Blynk.run() is executed.

BLYNK_WRITE() is a one-shot function - it executes once, when execution of Blynk.run() signals that new data has arrived on a datastream which has a BLYNK_WRITE() callback in the sketch.

If you explain more about the functionality that you’re trying to achieve then we might be able to suggest a more suitable approach.

Pete.

It straightfoward

  • when switch(V6) clicked, the RFID will be in “scanning any present card mode” and if present then it will proceed to “reading the card mode”
  • this process is continuous until i click back the switch(V6) to turn off
    [please avoid void loop if possible because the RFID scanning mode is not always needed 24/7]
void scanCard() {

  Serial.println("Ready to read");
  String content = "";


  if (!mfrc522.PICC_IsNewCardPresent()) {
    Serial.println("Card present, Reading...");
    Serial.print("UID tag :");
    return;
  }
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }


  delay(500);  // Add a delay to avoid rapid looping

  Serial.print("scanON condition :");
  Serial.println(scanON);
}


BLYNK_WRITE(V6) {
  //scanON = param.asInt();

  if (param.asInt() == 1) {
    if (millis() - lastSecond = > 500) {
      Serial.println("Scanning Start");
      scanCard();
    } else {
      Serial.println("Closing");
      mfrc522.PICC_HaltA();
      mfrc522.PCD_StopCrypto1();

      Serial.println("Scanning END");
    }
  }```

As I explained…

so what I can see of your current approach, based on these code snippet, won’t work.

My approach would be…

bool RFID_enabled; // Global flag, is RFID enabled?

BLYNK_WRITE(V6) 
{
  //scanON = param.asInt();

  RFID_enabled = param.asInt();
}

void loop
{
  Blynk.run();
  if(RFID_enabled)
    {
      // call your RFID scanning code here
    }
}

This isn’t ideal from a Blynk point of view, as it clutters-up your void loop, but provided you avoid any delay() or while commands and keep your RFID scanning code as tight as possible then you should be okay.

Pete.

owh sorry about the snippet. As i see on ur suggestion, it good to try and maybe that the best i can do. Thank you Pete, again a big help from u

btw, if anyone got better solution please do share ur opinion as current solution might lead to system crash etc

A better system would be to use RFID hardware and libraries that can generate interrupts when an RFID keyfob is detected, so that this interrupt can be processed, and the door opened if criteria such as the state of a Blynk switch are met.

However, that type of system isn’t possible with most dumb RFID readers, including the ones I use.

Pete.

1 Like

So the other suggested method is by purchase high-end RFID? That all for this topic. Thanks Pete spending ur time. Appreciate it
btw I dont see any edit button to mark this as solved