[SOLVED] Help with serial communication bewtween Arduino UNO Rev3 and ESP8266-01

Hi guys,
at the moment I must communicate sensor's data between Arduino and the ESP and push them on firebase via serial communication with a baud rate of 9600.
I want to know if there is a way to optimize my code since from my empirical experience there is a delay of about 8 seconds from when the value changes to when it's actually stored in the db.
Here I leave the Arduino UNO code:

//Libreries
#include <Adafruit_BMP085.h>
#include "DHT.h"

// Constants
#define DELAY 1000 // Delay between two measurements in ms
#define VIN 5 // V power voltage
#define R 10000 // Ohm resistance value
#define DHT11_PIN 6 // Pin connected to DHT11
#define DHTTYPE DHT11 // Type of sensor
const int sensorPin = A0; // Pin connected to photoresistor

//Variables
int16_t sensorVal; // Analog value from the sensor
int16_t lux; //Lux value
String values;

//Objects
Adafruit_BMP085 bmp;
DHT dht(DHT11_PIN, DHTTYPE);
  
void setup() {
  Serial.begin(9600);
  bmp.begin();
  dht.begin();

  delay(5000);
}
  
void loop() 
{
    lux=sensorRawToPhys(analogRead(sensorPin));
    
    values= ((String)bmp.readTemperature()+','+(String)dht.readHumidity()+','+(String)bmp.readPressure()+','+(String)bmp.readAltitude(101500)+','+(String)lux);
    delay(500);
    // removed any buffered previous serial data.
    Serial.flush();
    delay(500);
    // sent sensors data to serial (sent sensors data to ESP8266)
    Serial.print(values);
    delay(1000);
}

int sensorRawToPhys(int raw)
{
  // Conversion rule
  float Vout = float(raw) * (VIN / float(1023));// Conversion analog to voltage
  float RLDR = (R * (VIN - Vout))/Vout; // Conversion voltage to resistance
  int phys=500/(RLDR/1000); // Conversion resitance to lumen
  return phys;
}

and here I leave the ESP01 ones:

#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>

//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

/* 1. Define the WiFi credentials */
#define WIFI_SSID ""
#define WIFI_PASSWORD ""

/* 2. Define the API Key */
#define API_KEY ""

/* 3. Define the RTDB URL */
#define DATABASE_URL "" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app

/* 3. Define the project ID */
#define FIREBASE_PROJECT_ID ""

/* 4. Define the user Email and password that alreadey registerd or added in your project */
#define USER_EMAIL ""
#define USER_PASSWORD ""

//Define Firebase Data object
FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

unsigned long sendDataPrevMillis = 0;

int count = 0;
String values;

void setup()
{

  Serial.begin(9600);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  //Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    //Serial.print(".");
    delay(300);
  }
  /*.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);*/

  /* Assign the api key (required) */
  config.api_key = API_KEY;

  /* Assign the user sign in credentials */
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  /* Assign the RTDB URL (required) */
  config.database_url = DATABASE_URL;

  /* Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  //Or use legacy authenticate method
  //config.database_url = DATABASE_URL;
  //config.signer.tokens.legacy_token = "<database secret>";

  Firebase.begin(&config, &auth);

  Firebase.reconnectWiFi(true);
}

void loop()
{
  if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0))
  {
    bool Sr = false;

    while(Serial.available())
    {
      //get sensor data from serial put in sensor_data
      values = Serial.readString();
      Sr = true;
    }

    delay(1000);

    if (Sr == true)
    {
      //values=sensor_data;

      //get comma indexes from values variable
      int fristCommaIndex = values.indexOf(',');
      int secondCommaIndex = values.indexOf(',', fristCommaIndex + 1);
      int thirdCommaIndex = values.indexOf(',', secondCommaIndex + 1);
      int fourthCommaIndex = values.indexOf(',', thirdCommaIndex + 1);
      int fifthCommaIndex = values.indexOf(',', fourthCommaIndex + 1);

      float temp = values.substring(0, fristCommaIndex).toFloat();
      float hum = values.substring(fristCommaIndex + 1, secondCommaIndex).toFloat();
      int pres = values.substring(secondCommaIndex + 1, thirdCommaIndex).toInt();
      float alt = values.substring(thirdCommaIndex + 1, fourthCommaIndex).toFloat();
      int lum = values.substring(fourthCommaIndex + 1, values.length()).toInt();
      
      Firebase.RTDB.setFloatAsync(&fbdo, "/test/real/temp", temp);
      Firebase.RTDB.setFloatAsync(&fbdo, "/test/real/hum", hum);
      Firebase.RTDB.setIntAsync(&fbdo, "/test/real/pres", pres);
      Firebase.RTDB.setFloatAsync(&fbdo, "/test/real/alt", alt);
      Firebase.RTDB.setIntAsync(&fbdo, "/test/real/lum", lum);
      Firebase.RTDB.setTimestamp(&fbdo, "/test/real/timestamp");
      Firebase.RTDB.getDouble(&fbdo, "/test/real/timestamp");
      double timeStamp = fbdo.to<uint64_t>()+7200;
      Firebase.RTDB.setDoubleAsync(&fbdo, "/test/real/timestamp", timeStamp);

      //delay(10);
      
      if (count == 61)
      {
        FirebaseJson json;
        json.add("temp", temp);
        json.add("hum", hum);
        json.add("pres", pres);
        json.add("alt", alt);
        json.add("lum", lum);

        //Firebase.RTDB.getDouble(&fbdo, "/test/real/timestamp");
        
        //Firebase.RTDB.getInt(&fbdo, "/test/real/timestamp");
        json.add("timestamp", timeStamp);

        Firebase.RTDB.pushJSONAsync(&fbdo, "/test/data", &json);
        //Firebase.RTDB.updateNode(&fbdo, String("/test/data/" + fbdo.pushName()).c_str(), &json);

        count=0;
      }
      count++;
    }
  }

}

is there a way to sync on the setup the two boards? And then, is there a way to optimize the way I send and fetch these data from board to board?
Thank you all in advance! :slightly_smiling_face:

How did you make that measurement? Any chance the 15000ms interval in loop() corresponds to that delay?

Is this your code?

  • left index finger on the sensor
  • right index finger on the stopwatch
  • eyes on the db
    When the value changes, eyes on the stopwatch. In a way of saying that engineers like this is a value obtained spannometrically :joy:

You must use logic level shifters when connecting 5V I/O lines and 3.3V I/O lines. Don't forget to connect the grounds.

...a temperature sensor? They don't respond instantly to temperature changes.

Actually I didn't pay attention to this, my sketch is based on the example in the library and actually in all the tests I did I didn't consider that condition should be verified, which corresponds to 15 seconds. I should double check this, thx


These are the specifications. I noticed that some models already have the logic level shifter built in. How do I understand if it's my case? Actually without this shifter it has never caused any problem in reading data

the easiest solution is to use

  • a ESP8266 Wemos D1 mini
    or
  • a nodeMCU ESP8266
    or
    even better
  • a nodeMCU ESP32

and get rid of the Arduino Uno.

best regards Stefan

Level shifter built in where? The specs you posted clearly state that the I/O pins are 3.3V only.

For UART to UART communications, a simple resistive voltage divider will work for connecting 5V TX to 3.3V RX. See below.

3.3V TX can safely be connected directly to 5V RX, and but is not necessarily guaranteed to work.

I have already had a chance to read your thoughts on the matter Stefan, and I thank you for your continued interest in this. On a practical level, however, I need advice not so much on what equipment to use, but on how to optimise the communication.
So many dear things,

Federico

Optimization is a "feel good" exercise, unless it solves a problem. If you are measuring temperature with a typical thermal sensor, optimizing your communication to the n-th degree, will net you zero effective improvement.

Actually, so far, there is no proof that it isn't already optimal.

I tested it using a photoresistor as a parameter to check on.
I changed the way they communicate using an initial control character and when the upload it's successful I send from ESP01 to Arduino another character to confirm that the upload was successful.
By setting the communication this way, I optimised the data transmission to the db at about 2.5' seconds per record.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.