Introduction: ESP32 As WiFi and Web Server

About: DIY projects
  • ESP32, most used WiFi development board in handmade IoT projects,this is predecessor of ESP8266. Although its not so new, the ESP32 popularity has began to grow because of its Bluetooth capabilities, but not only. The ESP32 comes now with almost 32 I/O pins and a powerful 32bits dual core CPU ready to process more complex jobs.

Open-hardware platforms enable rapid prototyping and fasterdevelopment of new IoT applications. The objective of this post is to give a brief introduction to another open-hardware IoT playground — the ESP32 board. The ESP32 is, in fact, a small development board based on the ESP32 IoT-enabled microcontroller, the successor of the far-famed ESP8266 microcontroller from Espressif. ESP32 is a very powerful Wi-Fi-/Bluetooth-enabled SoC with a massive GPIO count, and the development board exposes this power in a very accessible IoT module design, suitable for both beginners and encouraged users.

The ESP32 comes not only with Wi-Fi but also with Bluetooth and Bluetooth Low Energy (BLE). This post is a quick introduction to BLE with the ESP32. First, we’ll explore what’s BLE and what it can be used for, and then we’ll take a look at some examples with the ESP32 using Arduino IDE. For a simple introduction we’ll create an ESP32 BLE server, and an ESP32 BLE scanner to find that server.

What is Bluetooth Low Energy?
Bluetooth Low Energy, BLE for short, is a power-conserving variant of Bluetooth. BLE’s primary application is short distance transmission of small amounts of data (low bandwidth). Unlike Bluetooth that is always on, BLE remains in sleep mode constantly except for when a connection is initiated.

Hardwares
The “ESP32 development board” that you usually get from eBay is a small and convenient generic breakout board with ESP-WROOM-32 module installed, exposed I/O pin headers, and a few additional supportive components. The 30-pin board (often referred to as ESP32-DOIT development board v1) includes a CP2102-based USB-to-Serial programming interface that also provides the power supply for the board. The board also has a 3.3-V onboard voltage regulator, two push buttons (enable, boot), and visual indicators (power, user).

Listed below are the key components used in the ESP32-DOIT (v1) board:

  • Power Part: NCP1117-3.3 (3.3-V LDO positive voltage regulator)
  • USB Part: CP2102 (USB-UART Bridge)
  • Core Part: ESP-Wroom-32 Module (Wi-Fi/Bluetooth Classic/BLE module based on ESP32-D0WDQ6 chip with two Xtensa 32-bit LX6 microprocessors)

Setup:-programming environments:--

  • Install from -- https://www.arduino.cc/ (win)
  • Start Git GUI and Select Clone Existing RepositorySelect source (https://github.com/espressif/arduino-esp32.git) and destination (target directory).(Linux)
  • Click Clone to start cloning the repository
  • Go to the destination folder, open Tools (…/Arduino/hardware/espressif/esp32/tools), and double-click get.exe
  • Wait for the process to complete

Step 1: WebServer Introduction

  • A web server is a computer that runs websites.
  • It's a computer program that distributes web pages as they are requisitioned.
  • The basic objective of the web server is to store, process and deliver web pages to the users.
  • This intercommunication is done using Hypertext Transfer Protocol (HTTP).
  • These web pages are mostly static content that includes HTML documents, images, style sheets, test etc.
  • Apart from HTTP, a web server also supports SMTP (Simple Mail transfer Protocol) and FTP (File Transfer Protocol) protocol for emailing and for file transfer and storage.

Technically, "Web server" can refer to hardware or software, or both of them working together.

On the hardware side, a web server is a computer that stores web server software and a website's component files (e.g. HTML documents, images, CSS stylesheets, and JavaScript files). It is connected to the Internet and supports physical data interchange with other devices connected to the web.

On the software side, a web server includes several parts that control how web users access hosted files, at minimum an HTTP server. An HTTP server is a piece of software that understands URLs (web addresses) and HTTP (the protocol your browser uses to view webpages). It can be accessed through the domain names (like mozilla.org) of websites it stores, and delivers their content to the end-user's device.

At the most basic level, whenever a browser needs a file which is hosted on a web server, the browser requests the file via HTTP. When the request reaches the correct web server (hardware), the HTTP server (software) accepts request, finds the requested document (if it doesn't then a 404 response is returned), and sends it back to the browser, also through HTTP.

Step 2: Esp32 Web OTA Update (Over the Air Update)

  • The first sketch should be uploaded via serial port.
  • This sketch should contain the code to create the OTA Web Updater, so that you are able to upload code later using your browser.
  • The OTA Web Updater sketch creates a web server you can access to upload a new sketch via web browser.
  • Then, you need to implement OTA routines in every sketch you upload, so that you’re able to do the next updates/uploads over-the-air.
  • If you upload a code without a OTA routine you’ll no longer be able to access the web server and upload a new sketch over-the-air.
  1. The first sketch should be uploaded via serial port. This sketch should contain the code to create the OTA Web Updater, so that you are able to upload code later using your browser.
  2. The OTA Web Updater sketch creates a web server you can access to upload a new sketch via web browser.
  3. Then, you need to implement OTA routines in every sketch you upload, so that you’re able to do the next updates/uploads over-the-air.
  4. If you upload a code without a OTA routine you’ll no longer be able to access the web server and upload a new sketch over-the-air.
<p>/*<br> 
*/</p><p>#include 
#include 
#include 
#include 
#include </p><p>const char* host = "esp32";
const char* ssid     = "OTfer2.4";
const char* password = "Gixxxx";

WebServer server(80);

/// Set your Static IP address
//IPAddress local_IP(192, 168, 1, 144);
//
//// Set your Gateway IP address
//IPAddress gateway(192, 168, 1, 1);
//IPAddress subnet(255, 255, 255, 0);
//IPAddress primaryDNS(8, 8, 8, 8);   //optional
//IPAddress secondaryDNS(8, 8, 4, 4); //optional</p>
/*
 * Login page
 
const char* loginIndex = //html code for below design
                "<strong>ESP32 Login Page</strong>"
                "<br>"
            "Username:<br>Password:<br><p> 
const char* serverIndex = /*html codes given as doc file*/


void setup(void) {
  Serial.begin(115200);</p><p>//// Configures static IP address
//  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
//    Serial.println("STA Failed to configure");
//  }</p><p>  // Connect to WiFi network
  WiFi.begin(ssid, password);
  Serial.println("");</p><p>  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());</p><p>  /*use mdns for host name resolution*/
  if (!MDNS.begin(host)) {       //http://esp32.local
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
  /*return index page which is stored in serverIndex */
  server.on("/", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", loginIndex);
  });
  server.on("/serverIndex", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", serverIndex);
  });
  /*handling uploading firmware file */
  server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      /* flashing firmware to ESP*/
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true to set the size to the current progress
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
  });
  server.begin();
}</p><p>void loop(void) {
  server.handleClient();
  delay(1);
}

Step 3: Esp32 and Bme280(Temp. Sensor) With SdCard Storage

// Libraries for SD card

#include "WiFi.h" #include "FS.h" #include "SD.h" #include #include #include #include

// Define deep sleep options uint64_t uS_TO_S_FACTOR = 1000000; // Conversion factor for micro seconds to seconds // Sleep for 10 minutes = 600 seconds uint64_t TIME_TO_SLEEP = 600;

// Replace with your network credentials const char* ssid = "esp32"; const char* password = "asdfg1234";

// Define CS pin for the SD card module #define SD_CS 5 #define SD_MOSI 23 #define SD_MISO 19 #define SD_SCK 18

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C //Adafruit_BME280 bme(BME_CS); // hardware SPI //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

String dataMessage=""; float tempMessage;

void setup() { // Start serial communication for debugging purposes Serial.begin(115200);

// Connect to Wi-Fi network with SSID and password Serial.print("Connecting to "); Serial.println(ssid); WiFi.softAP(ssid, password);

IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); Serial.println(""); Serial.println("WiFi connected.");

// Initialize SD card Serial.println("Initializing SD card..."); SD.begin(SD_CS); //SD_CS,SD_MOSI,SD_MISO,SD_SCK || chipSel, mosi, miso, sck //if(!SD.begin(SD_CS)) { // Serial.println("Card Mount Failed"); // return; // } uint8_t cardType = SD.cardType(); if(cardType == CARD_NONE) { Serial.println("No SD card attached"); return; } Serial.println(F("BME280 test")); bool status;

// default settings // (you can also pass in a Wire library object like &Wire2) status = bme.begin(); if (!status) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); }

// If the data.txt file doesn't exist // Create a file on the SD card and write the data labels File file = SD.open("/data.txt"); if(!file) { Serial.println("File doens't exist"); Serial.println("Creating file..."); writeFile(SD, "/data.txt", "Reading ID, Date, Hour, Temperature \r\n"); } else { Serial.println("File already exists"); } file.close();

// Enable Timer wake_up esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

logSDCard(); // Start deep sleep Serial.println("DONE! Going to sleep now."); esp_deep_sleep_start(); }

void loop() { // The ESP32 will be in deep sleep // it never reaches the loop() }

// Write the sensor readings on the SD card void logSDCard() { dataMessage = "sd card test from rudra.."; Serial.print("Save data: "); Serial.println(dataMessage); appendFile(SD, "/data.txt", dataMessage.c_str()); appendFile(SD, "/data.txt", "BME: Temp. Value"); tempMessage=bme.readTemperature(); //appendFile(SD, "/data.txt",tempMessage); }

// Write to the SD card (DON'T MODIFY THIS FUNCTION) void writeFile(fs::FS &fs, const char * path, const char * message) { Serial.printf("Writing file: %s\n", path);

File file = fs.open(path, FILE_WRITE); if(!file) { Serial.println("Failed to open file for writing"); return; } if(file.print(message)) { Serial.println("File written"); } else { Serial.println("Write failed"); } file.close(); }

// Append data to the SD card (DON'T MODIFY THIS FUNCTION) void appendFile(fs::FS &fs, const char * path, const char * message) { Serial.printf("Appending to file: %s\n", path);

File file = fs.open(path, FILE_APPEND); if(!file) { Serial.println("Failed to open file for appending"); return; } if(file.print(message)) { Serial.println("Message appended"); } else { Serial.println("Append failed"); } file.close(); }