mobizt / Firebase-ESP32

[DEPRECATED]🔥 Firebase RTDB Arduino Library for ESP32. The complete, fast, secured and reliable Firebase Arduino client library that supports CRUD (create, read, update, delete) and Stream operations.
MIT License
415 stars 118 forks source link

Consecutive Firebase.getInt returns wrong value #15

Closed nikrath closed 5 years ago

nikrath commented 5 years ago

I have a program that accepts performs the following operations:

  1. Acts as UDP Server
  2. Operates in AP_STA WiFi mode
  3. Shows IP Address of devices connected to ESP32's AP
  4. Uploads certain data to firebase on regular interval of 10s
#include "FirebaseESP32.h"

#define FASTLED_ESP8266_RAW_PIN_ORDER
#include<Arduino.h>
#include<WiFi.h>
#include<WiFiAP.h>
#include<esp_wifi.h>
#include<WiFiClientSecure.h>
#include<AsyncUDP.h>
#include<SPI.h>//load the spi library
#include<EEPROM.h>
#include<ArduinoJson.h>
#include<TimeLib.h>
#include<time.h>
#include<FastLED.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include "D:/esp-idf/components/freertos/include/freertos/FreeRTOS.h"
#include "D:/esp-idf/components/freertos/include/freertos/task.h"
#include "D:/esp-idf/components/freertos/include/freertos/event_groups.h"
#include "D:/esp-idf/components/esp32/include/esp_system.h"
#include "D:/esp-idf/components/esp32/include/esp_wifi.h"
#include "D:/esp-idf/components/esp32/include/esp_event_loop.h"
#include "D:/esp-idf/components/log/include/esp_log.h"
#include "D:/esp-idf/components/nvs_flash/include/nvs_flash.h"

#ifdef CONFIG_AP_HIDE_SSID
  #define CONFIG_AP_SSID_HIDDEN 1
#else
  #define CONFIG_AP_SSID_HIDDEN 0
#endif  
#ifdef CONFIG_WIFI_AUTH_OPEN
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_OPEN
#endif
#ifdef CONFIG_WIFI_AUTH_WEP
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_WEP
#endif
#ifdef CONFIG_WIFI_AUTH_WPA_PSK
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_WPA_PSK
#endif
#ifdef CONFIG_WIFI_AUTH_WPA2_PSK
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_WPA2_PSK
#endif
#ifdef CONFIG_WIFI_AUTH_WPA_WPA2_PSK
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_WPA_WPA2_PSK
#endif
#ifdef CONFIG_WIFI_AUTH_WPA2_ENTERPRISE
  #define CONFIG_AP_AUTHMODE WIFI_AUTH_WPA2_ENTERPRISE
#endif

#define MAX_WIFI_INFO_LENGTH 100
#define NUM_LEDS 1
#define led 25

//FIREBASE CREDENTIALS
#define FIREBASE_HOST "example.firebaseio.com"
#define FIREBASE_AUTH "exampleKey"
FirebaseData firebaseData;

void AccessPointInit();
void Sync();
void FirebaseSetInt(String path , int dat);
void FirebaseSetString(String path , String dat);
int FirebaseGetInt(String path);
String FirebaseGetString(String path);

uint8_t pin_led = 16;
char ssid[MAX_WIFI_INFO_LENGTH] = "home";
char pass[MAX_WIFI_INFO_LENGTH] = "12345678";

uint8_t pins[4] = {5 , 18 , 19 , 21};
int stta[4] = {0 , 0 , 0 , 0};

int runtime[4] = {0 , 0 , 0 , 0};

char myssid[] = "ESP32";
IPAddress ip(192, 168, 22, 22);
IPAddress fixedIp(192 , 168 , 0 , 200);
IPAddress gateway(192, 168, 22, 1);
IPAddress subnet(255, 255, 255, 0);

unsigned int localPort = 5000; //assign a port to talk over
String Data; //string for our Data
int packetSize; //variable storing the size of the packet

int numOfOutput;

CRGB leds[NUM_LEDS];

AsyncUDP udp;

void WiFiEvent(WiFiEvent_t event)
{
    Serial.printf("[WiFi-event] event: %d\n", event);

    switch (event)
    {
    case SYSTEM_EVENT_STA_GOT_IP:
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        Serial.println("WiFi lost connection");
        break;
    }
}

String client_status();
void PostData();
void UDPSetup();

void setup() {
  Serial.begin(115200);
  while(!Serial){;}//wait for Serial to begin
  Serial.println();
  //Prepare status led-->
  FastLED.addLeds<WS2812, led , GRB>(leds , NUM_LEDS);
  leds[0] = CRGB(255,0,0);
  FastLED.show();

  AccessPointInit();

  WiFi.begin(ssid, pass);
  WiFi.onEvent(WiFiEvent);
  UDPSetup();
  delay(2000); //wait 2 seconds
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);
  Sync();
}

void UDPSetup(){
  if(udp.listen(5000)) { //port 5000
    Serial.print("UDP Listening on IP: ");
    Serial.println(WiFi.localIP());
    udp.onPacket([](AsyncUDPPacket packet) {
      uint8_t *packets = new uint8_t[packet.length() + 1];
      int it=0;
      for(it=0 ; it < packet.length() ; it++){
        packets[it] = packet.data()[it];
      }
      packets[it] = 0;
      String Data = (char*)packets;
      delete[] packets;
      Serial.print("Data : ");
      Serial.println(Data);
      packet.printf("got it");
    });
  }
}

int lastDate = -1;
void Sync(){
  String outside_string = FirebaseGetString("/out");
  if(outside_string == ""){
    //means if we are not able to connect with Firebase, restart the module
    ESP.restart();
  }
  if(outside_string == "1" || outside_string == "0"){
    lastDate = FirebaseGetInt("/date");
  }
  int prevDate = FirebaseGetInt("/date");
  if(String(prevDate) != ""){
    if(prevDate != day()){
      FirebaseSetInt("/date" , day());
      CheckFlag();
    }
  }
  String stta_string = FirebaseGetString("/stta");
  String shouldWeUpdate = FirebaseGetString("/update");
}

void CheckFlag(){
  Serial.println("Checking for Flag");
  int flag = FirebaseGetString("/flag").toInt();
  Serial.print("Flag is : ");
  Serial.println(flag);
}

void AddUpTime(){
  for(int i = 0 ; i < numOfOutput ; i++){
    runtime[i] = runtime[i] + 10; //add 10 seconds
  }
}
long previousTime = 0;
long interval = 10000;
void loop() {
  if(millis()-previousTime > interval){ //every 10 seconds
    previousTime = millis();
    AddUpTime();
    Sync(); //using as a general purpose sync function
    PostData();
    Serial.println(client_status());
  }
}

void PostData(){
  String outside_string = FirebaseGetString("/outside");
  if(outside_string == ""){
    //means if we are not able to connect with Firebase, restart the module
    ESP.restart();
  }
  String temp = "1;1;1;1";
  FirebaseSetString("/status", temp);
  FirebaseSetString("/last_update", String(hour())+":"+String(minute())+":"+String(second()));
  temp = "0;0;0;0";
  FirebaseSetString("/current", temp);
} 

void AccessPointInit() {
  // initialize NVS
  ESP_ERROR_CHECK(nvs_flash_init());
  // initialize the tcp stack
  tcpip_adapter_init();
  // stop DHCP server
  ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));
  // assign a static IP to the network interface
  tcpip_adapter_ip_info_t info;
    memset(&info, 0, sizeof(info));
  IP4_ADDR(&info.ip, 192, 168, 22, 1);
    IP4_ADDR(&info.gw, 192, 168, 22, 1);
    IP4_ADDR(&info.netmask, 255, 255, 255, 0);
  ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info));
  // start the DHCP server   
    ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP));
  Serial.println("Beginning Access Points");
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAPConfig(ip , gateway , subnet);
  WiFi.softAP(myssid , pass);
  Serial.println("Server started");
}
String client_status() 
{ 
  wifi_sta_list_t wifi_sta_list;
  tcpip_adapter_sta_list_t adapter_sta_list;

  memset(&wifi_sta_list, 0, sizeof(wifi_sta_list));
  memset(&adapter_sta_list, 0, sizeof(adapter_sta_list));

  ESP_ERROR_CHECK(esp_wifi_ap_get_sta_list(&wifi_sta_list));  
  ESP_ERROR_CHECK(tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list));
  String temp = "";
  for(int i = 0; i < adapter_sta_list.num; i++) {

    tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
    temp += String(ip4addr_ntoa(&(station.ip))) + ";";
  }
  return temp;
}

void FirebaseSetInt(String path , int dat){
  if (!Firebase.setInt(firebaseData, path, dat))
  {
    Serial.println("Failed to upload data");
  }
}
void FirebaseSetString(String path , String dat){
  if (!Firebase.setString(firebaseData, path, dat))
  {
    Serial.println("Failed to upload data");
  }
}

int FirebaseGetInt(String path){
  if (Firebase.getInt(firebaseData, path))
  {
    if(firebaseData.dataType() == "int"){
      return firebaseData.intData();
    }
  }
  return 0;
}

String FirebaseGetString(String path){
  if (Firebase.getString(firebaseData, path))
  {
    if(firebaseData.dataType() == "string"){
      return firebaseData.stringData();
    }
  }
  return "";
}

These functions are called one after the other in regular intervals of 10 seconds. The flag variable (in CheckFlag function) should return the flag value stored on the Firebase Database in path "/flag". BUT Sometimes, the flag (in CheckFlag function) actually returns the value of the date variable stored on firebase database (which should be fetched by prevDate variable in Sync function). But instead prevDate returns 0 (i.e, it fails to fetch a value).

I even tried to make FirebaseData firebaseData a local variable to these functions instead of a global one. I thought some kind of an overwrite issue might be causing this. But turning it into local variables led the ESP32 to crash for some reason.

Does someone know a fix for this? Thanks

mobizt commented 5 years ago

Your above code is error and can't compile due to return integer inside String returned function getFirstInt() and getSecondInt()

And you're not provide the WiFi connection in setup too.

The normal usage of Firebase Data object does not cause problems.

Use Firebase Data object as local variable is not recommend which may lead to unreleased memory used by WiFi core.

You can help me to address the root causes by do the following.

nikrath commented 5 years ago

@mobizt Thanks for the response. I have updated the code in the original question, and added some additional information. I will state those here again:

I have a program that accepts performs the following operations:

Acts as UDP Server Operates in AP_STA WiFi mode Shows IP Address of devices connected to ESP32's AP Uploads certain data to firebase on regular interval of 10s

The flag variable (in CheckFlag function) should return the flag value stored on the Firebase Database in path "/flag". BUT Sometimes, the flag (in CheckFlag function) actually returns the value of the date variable stored on firebase database (which should be fetched by prevDate variable in Sync function). But instead prevDate returns 0 (i.e, it fails to fetch a value).

I'll give an example of the above statement. Yesterday, the value stored in my Firebase database at /date was 21, and at /flag was 0. The code looped and every 10 seconds, it showed the following output: prevDate = 21 flag = 0 It ran fine for around 8-9 hours. After that, it suddenly shows the following output: prevDate = 0 flag = 21

I guess prevDate was 0 because it couldn't fetch properly from online (in which case the function FirebaseGetInt returns 0). But what I don't get is why flag variable in code showed the value at /date instead of the value at /flag?

P.S Sorry I couldn't give the credentials of the Firebase Database, it belongs to the company I am currently interning at. But if required, please inform me so and I will create a new dummy database for your testing purpose.

Thanks

mobizt commented 5 years ago

My library is rather give the exact what type of data store and read from database.

Please check your free heap and stack size that may lead to heap corruption problem because your application used large of memory for all time.