Firebase.setString() only works once

Hi. I’m using the ESP8266Wi-Fi module. In my project, the ESP will read data through UART and send corresponding data to Firebase. The data receive through UART will be in the form of SWx/y where x will be 0/1/2 and y will be 0/1. The code will check for character x and y in the data and send the corresponding data to Firebase. After being powered on, the ESP was able to send data to Firebase correctly when it receives data through UART, but data is not sent after first time. It seems like if(UARTDone) always return false.

Here is my code:

#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

#define FIREBASE_HOST "xxx"
#define FIREBASE_AUTH "xxx"
#define WIFI_SSID "xxx"
#define WIFI_PASSWORD "xxx"

int dataCnt = 0;

int num;
char UARTData[10];
char UARTTemp;
bool UARTValid;
bool UARTDone = false;


void setup() {
  Serial.begin(9600);
  delay(1000);
                      
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

  delay(1000);
}

void loop() {

  if(Serial.available()>0)    //Checks is there any data in buffer 
  {
      dataCnt++;
      UARTTemp = Serial.read();
      if (dataCnt == 1 && UARTTemp == 'S'){     // If first character received is S
          UARTValid = true;
      }
      else if (dataCnt == 1 && UARTTemp != 'S'){
          UARTValid == false;
          dataCnt = 0;
      }

      if (UARTValid){
          UARTData[num] = UARTTemp;
          num++;

          if (num == 5){
              num = 0;
              dataCnt = 0;
              UARTDone = true;
          }
      }

      if (UARTDone){
          UARTDone = false;
          switch(UARTData[2]){
            case '0':
              if (UARTData[4] == '0'){
                Firebase.setString("SW0/status", "0");
                Serial.print("SW0/0");
              }
              else if (UARTData[4] == '1'){
                Firebase.setString("SW0/status", "1");
                Serial.print("SW0/1");
              }
              break;
              
            case '1':
              if (UARTData[4] == '0'){
                Firebase.setString("SW1/status", "0");
                Serial.print("SW1/0");
              }
              else if (UARTData[4] == '1'){
                Firebase.setString("SW1/status", "1");
                Serial.print("SW1/1");
              }
              break;
              
            case '2':
              if (UARTData[4] == '0'){
                Firebase.setString("SW2/status", "0");
                Serial.print("SW2/0");
              }
              else if (UARTData[4] == '1'){
                Firebase.setString("SW2/status", "1");
                Serial.print("SW2/1");
              }
              break;
          }
      }
  }
  
  delay(1000);
}

The Firebase library describes setString as:

/**

  • Writes the String value to the node located at path equivalent to the
  • REST API’s PUT.
    __ * You should check success() after calling.__
  • \param path The path inside of your db to the node you wish to update.
  • \param value String value that you wish to write.
    */
    virtual void setString(const String& path, const String& value);

And the demo example uses setString like this:

  // set string value
  Firebase.setString("message", "hello world");
  // handle error
  if (Firebase.failed()) {
      Serial.print("setting /message failed:");
      Serial.println(Firebase.error());  
      return;
  }

Maybe you should try to check for errors after calling setString. You can do this after the switch block.

I've tried what you suggested. I use Firebase.success() right after the setString statement, so 1 or 0 should be printed if the code in UARTDone is executed. However, the 1 or 0 is not printed. I think the statement in if (UARTDone) is not executed after the first time. The problem might be the logic of the code.

UPDATE

if(Serial.available()>0)    //Checks is there any data in buffer 
  {
      if(Serial.read() == 'A'){
        Serial.println('A');
        Firebase.setString("SW0/status", "0");
        Serial.print(Firebase.success());
      }
      if(Serial.read() == 'B'){
        Serial.println('B');
        Firebase.setString("SW0/status", "1");
        Serial.print(Firebase.success());
      }
  }

I've changed the code in if(serial.available()>0) to the code above. The statement is not executed after it's being executed for the first time. It seems like the serial.available is causing the problem.

Take a look at @Robin2's Serial Input Tutorial and implement one of his techniques for handling the input.

The problem is that each time you do a Serial.read you take whatever is in the Serial buffer and remove it. So after the first read, there may be no more character in the buffer and the next 'if' will never be true, even if you read a 'B' just before.

So try something like this:

if(Serial.available()>0)    //Checks is there any data in buffer
 {
     char letter = Serial.read();
     if(letter  == 'A'){
       Serial.println('A');
       Firebase.setString("SW0/status", "0");
       Serial.print(Firebase.success());
     }
     if(letter  == 'B'){
       Serial.println('B');
       Firebase.setString("SW0/status", "1");
       Serial.print(Firebase.success());
     }
 }