How to send data to arduino by using firebase then to web server to arduino?

Greetings!

I need help guys :slight_smile:

I wanna know how to send data to arduino
I'm using the following on the project

*firebase
*web server

I want to use the app to send data to firebase
then to web server to arduino
idea in mind :
am I going to use POST on the arduino code and php to firebase code?
aim:

--
using the mobile app
to make it more easier to change the SSID and password of the arduino device easily

here's the code for the arduino

#include <SoftwareSerial.h>
#include <DHT.h>;
SoftwareSerial Serial1(10, 11);
#define Trash "Trash3"
#define DHTTYPE DHT11
#define DHTPIN 2
#define TRIGGER_PIN 4
#define ECHO_PIN 3

DHT dht(DHTPIN, DHTTYPE, 11);

float humidity, temp_f;
int distance;
long duration;


String buff(64);
String getStr(128);

void setup() {

  Serial.begin(9600);

  Serial1.begin(9600);
  //Serial1.resetESP();
  delay(2000);
  Serial1.setTimeout(5000);

  dht.begin();
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  if (!connectWiFi()) {
    Serial.println("Can not connect to the WiFi.");
    while (true)
      ; // do nothing
  }
  Serial.println("OK, Connected to WiFi.");

  sendCommand("AT+CIPSTA?");
  //sendCommand("AT+CIPDNS_CUR?");
  sendCommand("AT+CIPSTAMAC?");
  
}

void loop() {

  temp_f = dht.readTemperature();
  humidity = dht.readHumidity();
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);

  duration = pulseIn(ECHO_PIN, HIGH);
  distance = duration * 0.034 / 2;

  // connect to server
  if (sendCommand("AT+CIPSTART=\"TCP\",\"gg.com\",80")) {
    Serial.println("connected to Cloud");

    // build HTTP request
    getStr = "GET /upload.php?trash=";
    getStr += Trash;
    getStr += "&distance=";
    getStr += distance;
    getStr += "&temp_f=";
    getStr += temp_f;
    getStr += "&humidity=";
    getStr += humidity;
    getStr += " HTTP/1.1\r\n";
    getStr += "Host: gg.com\r\n\r\n";

    // open send buffer
    buff = "AT+CIPSEND=";
    buff += getStr.length();
    if (sendCommand(buff.c_str()) && Serial1.find(">")) { // AT firmware is ready to accept data

      // send HTTP request
      Serial.println(getStr);
      Serial1.print(getStr);

      // print HTTP response
      if (Serial1.find("+IPD,")) { // response received
        int l = Serial1.parseInt();
        while (l > 0) {
          if (Serial1.available()) {
            Serial.write(Serial1.read());
            l--;
          }
        }
        Serial.println("--------------");
      } else {
        Serial.println("no response");
      }
    } else {
      Serial.println("send error");
    }
    sendCommand("AT+CIPCLOSE");
  } else {
    Serial.println("Error connecting");
  }
}

bool connectWiFi() {

  if (!sendCommand("ATE0")) // echo off
    return false;
  if (!sendCommand("AT+CIPMUX=0")) // set single connection mode
    return false;
  if (!sendCommand("AT+CWMODE=1")) // set STA mode
    return false;
  return sendCommand("AT+CWJAP=\"CAPSTONE\",\"capstonemis\"");
}

bool sendCommand(const char* cmd) {
  Serial.println(cmd);
  Serial1.println(cmd);
  while (true) {
    buff = Serial1.readStringUntil('\n');
    buff.trim();
    if (buff.length() > 0) {
      Serial.println(buff);
      if (buff == "OK" || buff == "SEND OK" || buff == "ALREADY CONNECTED")
        return true;
      if (buff == "ERROR" || buff == "FAIL" || buff == "SEND FAIL")
        return false;
    }
  }
}

here's the code on the web server to connect to firebase

<?php

require 'firebaseLib.php';
$Trash = $_GET["trash"];

$Distance = $_GET["distance"];
$Temperature = $_GET["temp_f"];
$Humidity= $_GET["humidity"];

// --- This is your Firebase URL
$baseURI = 'https://thesis1-69.firebaseio.com';
// --- Use your token from Firebase here
$token = 'gg';
// --- Here is your parameter from the http GET



$devicestatus= array('Distance' => $Distance,'Temperature' => $Temperature,'Humidity' => $Humidity);

$firebasePath = '/thesis1-69/';




$full= array($Trash => $devicestatus);

/// --- Making calls
$fb = new Firebase($baseURI, $token);
$fb -> update($firebasePath, $full);


?>

Thank you

anyone that knows how to use the POST on arduino?

I still have no progress on receiving data from firebase to arduino
any help?

Thank you :slight_smile:

It appears you are already sending data using HTTP GET in your variables trash, distance, temp_f and humidity. Is there a reason you feel the need to change from GET to POST?

If so, you do HTTP POST requests the same way you do GET requests.

Thank you sir for answer

can I keep them both ? GET and POST?

You can use both request types in the same program. You must choose either GET or POST for a single HTTP request.

If you have different variables you probably want to create a different endpoint on your server to process the different request.

Thank you sir

ah I thought it will work the same or simultaneously with one another

What do you mean simultaneously? You can send two requests within microseconds of each other. You would most likely get the responses back similarly close.

You cannot send a GETPOST request, but you can send a GET then send a POST.

If you want to know the server's response you must then read the HTTP response on the Arduino. If you want to send information back, you put it in the body of the HTTP response.

good morning sir

thank you sir

can you provide me an example of receiving the information back to arduino

I just want to change the SSID & password of arduino (esp-01) by using an app
that app uses the firebase to send data to web server back to arduino
so the wifi will be change

then no need to manually code it by using arduino IDE

I will preface my response with, if you want to initialize your Arduino's SSID and password with a mobile phone app, you might want to directly connect your phone to your Arduino with Blutooth. This being said, it is entirely possible to manage SSID's and passwords on a server, but there is the caveat that you must be connected to update your Arduino device to get the data.

I am not entirely sure what Firebase is, but the basic client server paradigm is as follows:

A server in our case an HTTP server is running all the time. It waits for a request from a client. When it receives a request from a client it responds with an HTTP response.

The clients in our case the Arduino and what I am gathering you have a mobile phone app that connects to your server (through Firebase?). The clients will generate HTTP requests when it needs data from the server or when the client wants to update information on the server.

Your server must be connected to the network to be able to receive HTTP requests and generate HTTP responses. Likewise, your clients must be connected to the network to be able to make HTTP requests and receive HTTP responses.

If you want your server to store the SSID and password to your Arduino's network so that the Arduino can update its SSID and password, you will need to be connected to another network to access the server or be connected to the network already.

It is definitely impossible to have your server initialize your Arduino to connect to the network the first time, but you can use the server to change the Arduino's SSID and password. This can be useful if you want to load several SSID's and passwords into an array on the Arduino because you move your device around.

I have done this before and stored a list of recently used networks in non-volatile memory and if the device sees a network it knows, it can connect. Then you can manage the known networks from the server and just update your device when you are connected to a known network.

Below is the Espressif example of an HTTP client reading the server's HTTP response. I have commented in CAPITAL LETTERS the relevant part of reading in the response.

/**
   StreamHTTPClient.ino
    Created on: 24.05.2015
*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

ESP8266WiFiMulti WiFiMulti;

void setup() {

  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "PASSWORD");

}

void loop() {
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    WiFiClient client;
    HTTPClient http; //must be declared after WiFiClient for correct destruction order, because used by http.begin(client,...)

    Serial.print("[HTTP] begin...\n");

    // configure server and url
    http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
    //http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");

    Serial.print("[HTTP] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {

        // get lenght of document (is -1 when Server sends no Content-Length header)
        int len = http.getSize();

        // create buffer for read
        uint8_t buff[128] = { 0 };

#if 0
        // with API
        Serial.println(http.getString());
#else




//THIS IS HOW YOU CAN READ AN HTTP RESPONSE*********************************************
        // or "by hand"

        // get tcp stream
        WiFiClient * stream = &client;

        // read all data from server
        while (http.connected() && (len > 0 || len == -1)) {
          // read up to 128 byte
          int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff)));
          Serial.printf("readBytes: %d\n", c);
          if (!c) {
            Serial.println("read timeout");
          }

          // write it to Serial
          Serial.write(buff, c);

          if (len > 0) {
            len -= c;
          }
        }
//end -- THIS IS HOW YOU CAN READ AN HTTP RESPONSE*********************************************




#endif

        Serial.println();
        Serial.print("[HTTP] connection closed or file end.\n");
      }
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  }

  delay(60000);
}

good morning

thank you so much sir
more power!

I will try this now

but how (format) the php code will send the data (SSID and password) ?

I can't use your code for the arduinos because I'm using AT commands
not directly coding the esp8266-01

but still thanks to the idea

biancadelos:
but how (format) the php code will send the data (SSID and password) ?

Your PHP code, if run on an HTTP server like Apache, does not need to be formatted in an special way. If you are making a GET request from your HTTP server such as:

GET /network/accesspoints/SSID.php HTTP/1.1
Host: www.example.com
User-Agent: Arduino ESP8266 Client Datalogger

Your PHP code from file SSID.php can format the SSID and passwords however you like because you must read the values in the HTTP response on the Arduino. You can make it as easy as:

network1, pass1
net2, pass2
ap3, passWd3
router4, 5558675309

The HTTP server running PHP will create the formatted HTTP response for you and the HTTP body will hold whatever you've ECHO'd / printed in PHP.

biancadelos:
I can't use your code for the arduinos because I'm using AT commands
not directly coding the esp8266-01

I am unfamiliar with AT commands, but I am sure there must be read and write commands or it would be useless because you could not read data from your Arduino or pass any data along to your Arduino from your WiFi connection. While I know it is possible to do these things using AT commands, I have read may places that it might be better to setup the Arduino IDE to use the Arduino WiFi libraries.

I am not sure you gain anything by using the AT commands. Maybe other's know why one would use AT commands over the Arduino or Espressif Arduino libraries. @Juraj might know. If there is something to know about the ESP8266 Juraj seems to know everything about it.

thank you so much sir

I am still working on it
to connect the PHP by receiving data from firebase then send it to arduino

God bless sir :slight_smile:

good evening everyone

I still got no solution for this result I wanted to obtain

I hope I can get it somewhat

Hi everyone can anyone help me about the output I wanted to get?

I am using PHP and not the easy stuff like arduino firebase library

I hope can anyone help me with this

thank you so much

Are your $Trash, $Distance, $Temperature and $Humidity variables coming through in PHP? If you are receiving those variables from your HTTP GET request already, all you have to do is add SSID and password to the GET request and they will be in your PHP $_GET array.

good afternoon sir

those data/variables are from arduino then send to PHP and will be sent to firebase and also in the app

I already added a variable on firebase (SSID and password) those are needed to be received by the PHP and then send to arduino to be able to change the wifi of ESP8266-01

On your HTTP server (PHP) create a new endpoint for getting the new SSID and password. Use a URI such as http://www.example.com/aDirectory/updateSSID.php

This is as simple as uploading the file updateSSID.php to aDirectory/ in your HTTP server root.

The file updateSSID.php could look something like this, but use whatever characters would help you parse the data best:

<?
$SSID = "Access_Point_1";
$password = "1234567890";

echo $SSID;
echo "\n";
echo $password;
?>

Then you would make an HTTP GET request to your new endpoint, http://www.example.com/aDirectory/updateSSID.php the same way you do it for $Trash, $Distance ect.

Then when you read the response from the HTTP server here:

Section from your Arduino code below

...
      // print HTTP response
      if (Serial1.find("+IPD,")) { // response received
        int l = Serial1.parseInt();
        while (l > 0) {
          if (Serial1.available()) {
            Serial.write(Serial1.read());  //***********INSTEAD OF READING THE RESPONSE AND IMEDIATELY WRITING IT TO SERIAL YOU WOULD PARSE THE DATA AND PUT IT INTO VARIABLES
            l--;
          }
        }
        Serial.println("--------------");
      } else {
        Serial.println("no response");
      }
...

I have marked where you read in the HTTP response in your code above. Instead of immediately writing it to Serial, you want to read it, parse it and save it to new variables that you can then use to set your SSID and password.

hello sir

thank you so much

but still I can't change the SSID and password of the wifi

I am confused on how I will do it like HTTP GET request

is it like this

$ssid = $_GET[""];

$password = $_GET[""];

$devicestatus= array('Distance' => $Distance,'Temperature' => $Temperature,'Humidity' => $Humidity, 'ssid'=>$ssid,'password' => $password);