Sending Data to Cloud with ESP32 and ThingSpeak

The Internet of Things ( or IoT) is a network of interconnected computing devices such as digital machines, automobiles with built-in sensors, or humans with unique identifiers and the ability to communicate data over a network without human intervention.

Hello readers, I hope you all are doing great. In this tutorial, we will learn how to send sensor readings from ESP32 to the ThingSpeak cloud. Here we will use the ESP32’s internal sensor like hall-effect sensor and temperature sensor to observe the data and then will share that data cloud.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is ThingSpeak?

Fig. 1: ESP32 ThingSpeak

It is an open data platform for IoT (Internet of Things). ThingSpeak is a web service operated by MathWorks where we can send sensor readings/data to the cloud. We can also visualize and act on the data (calculate the data) posted by the devices to ThingSpeak. The data can be stored in either private or public channels.

ThingSpeak is frequently used for internet of things prototyping and proof of concept systems that require analytics.

Features of ThingSpeak

  • ThingSpeak service enables users to share analyzed data through public channels: Users can view multiple options on their channels via the settings panel. The tab displays sharing options, allowing the user to make their channel private, public or shared with specific users. Professionals can import and export data through their channels as well.
  • ThingSpeak allows professionals to prepare and analyze data for their businesses: Weather forecasters use the MATLAB Analysis app to prepare, analyze, and filter data, such as estimating average humidity or calculating dew point. Users can use the visualization and analysis applications to perform operations on live or historical data by using template codes. To enable modular coding, industry professionals can add new functions to the software. Companies can use ThingSpeak Analysis to read stored data or write new data to their private channels. They can scrape numbers from various web pages thanks to the URL filter.
  • ThingSpeak updates various ThingSpeak channels using MQTT and REST APIs: Professionals in the industry also use the platform to analyze and chart numerical data sent from smart devices and stored on various channels. Business owners can update their feeds, clear, or delete their channels entirely by using REST API calls like POST, GET, DELETE, or PUT. MQTT Publish methods allow users to update their feeds, whereas MQTT Subscribe methods allow them to receive messages.

Preparing Arduino IDE for ESP32 and ThingSpeak

  • We are using Arduino IDE to compile and upload code into the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on the ESP32 programming series.

Downloading and installing the required Library file:

  • Follow the link attached below to download theThingSpeak Arduino library:

https://github.com/mathworks/thingspeak-arduino

  • Open the Arduino IDE.
  • Go to Sketch >> Include Library >> Add .ZIP Library and select the downloaded zip file.

Fig. 2: Adding ThingSpeak Library

To check whether the library is successfully added or not:

  • Go to Sketch >> Include Library >> Manage Libraries

Fig. 3

  • Type thingspeak in the search bar.

Fig. 4: Arduino IDE Library Manager

  • The ThingSpeak library by MathWorks has been successfully downloaded.

This library comes with multiple example codes. You can use any of the example codes as per your requirements ad also modify the example code.

Fig. 5: Example Codes

Getting Started with ThingSpeak

  • To create an account or log in to ThingSpeak (operated by MathWorks) server follow the link: https://thingspeak.com/
  • Click on Get Started for free.

Fig. 6: Getting Started For Free

  • Enter your details to create a MathWorks account as shown below:

Fig. 7: Create New Account

  • If you have already created a MathWorks account, then click on Sign in.

Fig. 8: MathWorks Sign in

  • Create a channel by clicking on the New Channel

Fig. 9: New Channel

  • Enter the respective details in the channel.
  • As we already mentioned, we will use ESP32’s inbuilt sensors, Hall and temperature sensor to take the readings and then publish them to the ThingSpeak server.
  • So we are using two files, field1 and field2 for temperature and hall readings respectively.
  • You can use/enable more than two fields as per your requirements.

Fig. 10: Enter the Details in Channel

  • Click o the save button to save the channel details.

Fig. 11: Save the channel

  • After successfully saving the channel, a new window will open containing the channel details and Channel Stats.

Fig. 12: Channel Stats

  • In the same window, go to API Keys which contains the Write API keys and Read API keys.
  • Copy the Write API key and paste this in ESP32 Arduino code to send the sensor values to ThingSpeak.
  • You can also customize the chart in Private View. Click on the icon present at the top-right menu of Field Chart (in red box) to edit the chart.
  • Edit the details as per your requirements and click on the save button to save the details.

Fig. 13: Field Chart Edit

Arduino Code

We have already published a tutorial on the ESP32 hall sensor and internal temperature sensor.

// ------style guard ----

#ifdef __cplusplus

extern "C"

{

#endif

uint8_t temprature_sens_read();

#ifdef __cplusplus

}

#endif

uint8_t temprature_sens_read();

// ------header files----

#include <WiFi.h>

#include "ThingSpeak.h"

// -----netwrok credentials

const char* ssid = "SSID"; // your network SSID (name)

const char* password = "PASSWORD"; // your network password

WiFiClient client;

// -----ThingSpeak channel details

unsigned long myChannelNumber = 1;

const char * myWriteAPIKey = "API Key";

// ----- Timer variables

unsigned long lastTime = 0;

unsigned long timerDelay = 1000;

void setup()

{

Serial.begin(115200); // Initialize serial

WiFi.mode(WIFI_STA);

if(WiFi.status() != WL_CONNECTED)

{

Serial.print("Attempting to connect");

while(WiFi.status() != WL_CONNECTED )

{

WiFi.begin(ssid, password);

delay(1000);

}

Serial.println("\nConnected. ");

}

ThingSpeak.begin(client); // Initialize ThingSpeak

}

void loop()

{

if ((millis() - lastTime) > timerDelay )

{

int hall_value = 0;

float temperature = 0;

hall_value = hallRead();

// Get a new temperature reading

temperature = ((temprature_sens_read()-32)/1.8 );

Serial.print("Temperature (ºC): " );

Serial.print(temperature);

Serial.println("ºC" );

Serial.print("Hall value:" );

Serial.println(hall_value);

ThingSpeak.setField(1, temperature );

ThingSpeak.setField(2, hall_value );

 

// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different

// pieces of information in a channel. Here, we write to field 1.

int x = ThingSpeak.writeFields(myChannelNumber,

myWriteAPIKey );

if(x == 200)

{

Serial.println("Channel update successful." );

}

else

{

Serial.println("Problem updating channel. HTTP error code " + String(x) );

}

lastTime = millis();

}

}

Code Description

  • Style guard is used at the beginning to declare some function to be of “C” linkage, instead of “C++” Basically, to allow C++ code to interface with C code.

Fig. 14: Style Guard

  • Add the required header files.
  • We have already discussed above how to download and add the ThingSpeak library file to Arduino IDE.

Fig. 15: Libraries

  • Enter the network credentials (SSID and Password).

Fig. 16

  • A Wi-Fi client is created to connect with ThingSpeak.

Fig. 17

  • Define timer variables.

Fig. 18

  • Add the channel number and API (Write) Key. If you have created only one channel then the channel number will be ‘1’.

Fig. 19

Setup()

    • Initialize the Serial monitor with a 115200 baud rate for debugging purposes.

Fig. 20

  • Set ESP32 Wi-Fi module in station mode using mode() function.
  • Enable ESP32’s Wi-Fi module using begin() function which is using SSID and password as arguments.
  • Wait until the ESP32 is not connected with the wifi network.

Fig. 21

  • Initialize the ThingSpeak server using begin() function that is passing client (globally created) as an argument.

Fig. 22

Loop()

    • Inside the loop() function, define an integer type variable to store the hall sensor readings.

Fig. 23

  • Define another float type variable to store temperature readings.

Fig. 24

  • Call the hallRead() function to store the hall sensor readings into hall_value

Fig. 25

  • Temperature_sens_read() function is used to read the temperature of ESP32 core.
  • Temperature observed by the internal temperature sensor is in Fahrenheit
  • o convert observed temperature i.e., in Fahrenheit into Celsius :

(F-32) *(5/9) = degree Celsius

Fig. 26

  • Print the temperature in degree Celsius and Hall sensor observations on serial moitor.

Fig. 27

  • Set the number of fields you have created to the thingSpeak server. We are adding only two fields. You can add up to maximum of 8 fields for different readings.

Fig. 28

  • writeFields() function is used to write data to the ThingSpeak server. This function is using the channel number and API key as an argument.

Fig. 29

  • Return the code 200 if the sensor readings are successfully published to ThingSpeak server and print the respective results on the serial monitor.

Fig. 30

Testing

  • Connect the ESP32 module with your laptop using USB cable.
  • Select the right development board in Tools >> Boards >> DOIT ESP32 DevKit V1.
  • Compile and upload the code into ESP32 using Arduino IDE.
  • Make sure that you have entered the right Wi-Fi credentials, API key and channel number before uploading the code.
  • Open the ThingSpeak website where you have created a channel and check the sensor readings.
  • A screenshot of the field chart we have created is show below. Where you can see the temperature and hall sensor values on the chart.

Fig. 31: ThingSpeak Channel Stats

 
  • To see the sensor values on Arduino IDE open the serial monitor with a 115200 baud rate.

Fig. 32: Results on the Serial Monitor

 

This concludes the tutorial. I hope you found this of some help and also to see you soon with new tutorial on ESP32.

ESP-NOW Protocol with ESP32 and ESP8266

Hello readers, I hope you all are doing great. In this tutorial, we will learn about the ESP-NOW protocol and how to communicate data between two ESP modules through ESP-NOW protocol and that is too without Wi-Fi connectivity.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is ESP-NOW Protocol?

Fig. 1: ESP-NOW Protocol

ESP–NOW is a connectionless communication protocol that is used for sharing small data packets between two ESP boards. This protocol is developed by Espressif.

Features of ESP-NOW Protocol:

  • It is a low-power wireless protocol, which makes two or more ESP devices communicate directly with each other without using Wi-Fi.
  • ESP-NOW protocol does not require a handshake for establishing a connection but, they require pairing and once the devices are paired they can exchange data.
  • ESP-NOW offers a persistent connection between ESP nodes. This means, once two ESP nodes are connected with each other (wirelessly) and suddenly one of the ESP devices loses power or restarted, the device will again (automatically) establish a connection with the other node to which it was connected before the power reset.
  • ESP- NOW protocol offers encrypted communication and hence, it is a secure method of wireless communication.
  • To check the success and failure of message delivery a callback function is used to send the information regarding the communication status. Before initializing the ESP-NOW, we need to enable the Wi-Fi for wireless connectivity but it is now required to connect the ESP devices with the internet.

ESP-NOW Protocol Limitations:

  • This protocol is only supported by ESP devices.
  • Only 10 (maximum) encrypted peers are supported in station mode and a maximum of 6 devices in access point mode.
  • The maximum payload size supported by ESP-NOW protocol is 250 bytes only.

Although, ESP-NOW protocol can communicate only small data packets ( maximum 250 bytes), but it is a high-speed protocol for wireless communication.

ESP devices can communicate over ESP-NOW protocol in different network topologies which makes it a very versatile protocol. The communication can be a point to point or point to multipoint (broadcast).

Different Scenarios in Which ESP Devices Can Communicate

Peer to peer or one to one communication

Fig. 2: Point to Point Communication

In peer-to-peer communication, only two ESP (either ESP32 or ESP8266) devices can connect with each other for data exchange. Each ESP device can act as a master device, a slave device or both master and slave at the same time.

Broadcast or one to many (master and slave)

Fig. 3: ESP32 Broadcasting with ESP-NOW protocol

In broadcast one ESP device (known as a broadcaster) act as a master device and broadcast the data to ESP devices acting as slave devices. Data is shared with all the slave devices simultaneously.

This communication method is used when users want to control multiple slave devices at a time.

Many to one. (Gateway)

Fig. 4: Many to One Communication

In many to one communication scenarios, there will be a central node or gateway which collects all the data from its nearby connected ESP devices.

This scenario can be applied when you need to collect sensor data from various sensor nodes to a single collector or central device, which is connected to all the nearby sensors.

Application of ESP-NOW Protocol

  • ESP-NOW protocol is used when users need to communicate data between two or more ESP devices without using a Wi-Fi router (whether it is ESP32 or ESP8266).
  • This protocol can be used for industrial or residential automation applications. Where we need to transmit small data or instructions like to turn ON and OFF equipment without using Wi-Fi. For example smart lights, sensors, remote control devices etc.

MAC Address to Identify The Receiver

MAC address or Media Access Control address is a six-byte hexadecimal address, that is used to track or connect with devices in a network. It provides the user with a secure way to identify senders and receivers in a network and avoid unwanted network access.

Fig. 5: MAC Address

Each ESP device has a unique MAC address.

So, before sharing the data between two or more ESP devices the MAC address of the receiver device should be known to the sender device.

Implementing ESP-NOW protocol with ESP32 in Arduino IDE

Both, the ESP32 and ESP8266 modules support the ESP-NOW protocol.

In this tutorial, we will connect the ESP32 and ESP8266 using the ESP-NOW protocol.

  • We are using Arduino IDE as a compiler and upload into the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on the ESP32 programming series.

Fig. 6: ESP-NOW Example Code in Arduino IDE

Library file Required to implement ESP-NOW Protocol:

  • Download the library from the given link: https://github.com/yoursunny/WifiEspNow
  • In this example, we are using two ESP devices where one is ESP32 and another is ESP8266.
  • We will make ESP32 to act as a Master device and ESp8266 as slave device.

Sender (ESP32) Source Code

#include <esp_now.h>

#include <WiFi.h>

// REPLACE WITH YOUR RECEIVER MAC Address

uint8_t broadcastAddress[] = {0xEE, 0xFA, 0xBC, 0xC5, 0xA4, 0xBF};

typedef struct struct_message {

char a[32];

int b;

float c;

bool d;

} struct_message;

// Create a struct_message called myData

struct_message myData;

// callback when data is sent

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {

Serial.print("\r\nLast Packet Send Status:\t");

Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");

}

void setup() {

// Init Serial Monitor

Serial.begin(115200);

// Set device as a Wi-Fi Station

WiFi.mode(WIFI_STA);

// Init ESP-NOW

if (esp_now_init() != ESP_OK) {

Serial.println("Error initializing ESP-NOW");

return;

}

// get the status of Trasnmitted packet

esp_now_register_send_cb(OnDataSent);

// Register peer

esp_now_peer_info_t peerInfo;

memcpy(peerInfo.peer_addr, broadcastAddress, 6);

peerInfo.channel = 0;

peerInfo.encrypt = false;

// Add peer

if (esp_now_add_peer(&peerInfo) != ESP_OK){

Serial.println("Failed to add peer");

return;

}

}

void loop()

{ strcpy(myData.a, "THIS IS A CHAR");   // Send message via ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));   if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); } delay(2000); }

Code Description

  • The first step is including the required libraries or header files.

Fig. 7: Library Files

  • Replace the string with the MAC address of the receiver ESP device.

Fig. 8: MAC Address

  • The next step is creating a structure that contains the type of data you want to share with the receiver node or device. We are using four different data variables which include char, int, float, and bool. You can the data type according to your requirements.

Fig. 9: Variables

  • Create a variable of struct_message type to store the variable values. We created myData

Fig.10

  • onDataSent() function is a callback function which will be executed when a message is sent. This function will print a string on serial monitor to show that the message is successfully sent.

Fig. 11

Setup()

    • Inside the setup function, the first task is the usual one i.e., initializing the serial monitor for debugging purpose.
    • Set the ESP device in STA mode or in Wi-Fi station mode before initializing ESP-NOW.

Fig. 12: Serial monitor and Wi-Fi Initialization

  • Next step is, initializing ESP-NOW.

Fig. 13

  • A callback function is registered which will be called when a message is send (after initializing the ESP-NOW successfully).

Fig. 14

  • The next thing is pairing with another ESP-NOW device to communicate data.

Fig. 15: Pairing with the ESP8266 Receiver

  • esp_now_add_peer () function is used to pair with the receiver.
  • This function is passing a parameter called This parameter contains the MAC address of the receiver (ESP8266) to which the sender want to connect and communicate data.
  • If somehow the sender is not able to pair with the receiver ESP device, the result will be printed on the serial monitor.

Fig. 16

Loop()

  • In the loop() function, the message will be sent.
  • We have globally declared a structure variable myData.
  • In the loop function values or message that we want to share with the receiver ESP device (ESP8266) is assigned to the variables.

Fig. 17: Data to Be Shared

  • If the ESP32 (or sender) is successfully connected/paired with the receiver (ESP8266) send the message and once the message is sent, print the result on the Serial monitor.

Fig. 18

  • Esp_now_send() function is used to send data to receiver (i.e., ESP8266) over ESP-NOW protocol.
  • This function is passing two parameters. First is the broadcastAddress i.e. the MAC address of the receiver and another is the data stored in the variables.

Fig. 19: Send The Message

  • If there is some error in message sending then print the respective details on the serial monitor.
  • The next message will be sent with a delay of 2 sec (or 2000ms).

Fig. 20

ESP8266 (Receiver) Code

#include <WifiEspNow.h>

#if defined(ARDUINO_ARCH_ESP8266)

#include <ESP8266WiFi.h>

#elif defined(ARDUINO_ARCH_ESP32)

#include <WiFi.h>

#endif

// The recipient MAC address. It must be modified for each device.

static uint8_t PEER[]{0x02, 0x00, 0x00, 0x45, 0x53, 0x50};

void printReceivedMessage(const uint8_t mac[WIFIESPNOW_ALEN],

const uint8_t* buf, size_t count, void* arg)

{

Serial.printf("Message from %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3],

mac[4], mac[5]);

for (int i = 0; i < static_cast<int>(count); ++i) {

Serial.print(static_cast<char>(buf[i]));

}

Serial.println();

}

 

void setup()

{

Serial.begin(115200);

Serial.println();

WiFi.persistent(false);

WiFi.mode(WIFI_AP);

WiFi.disconnect();

WiFi.softAP("ESPNOW", nullptr, 3);

WiFi.softAPdisconnect(false);

Serial.print("MAC address of this node is ");

Serial.println(WiFi.softAPmacAddress());

uint8_t mac[6];

WiFi.softAPmacAddress(mac);

Serial.println();

Serial.println("You can paste the following into the program for the other device:");

Serial.printf("static uint8_t PEER[]{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X};\n", mac[0],

mac[1], mac[2], mac[3], mac[4], mac[5]);

Serial.println();

bool ok = WifiEspNow.begin();

if (!ok) {

Serial.println("WifiEspNow.begin() failed");

ESP.restart();

}

WifiEspNow.onReceive(printReceivedMessage, nullptr);

ok = WifiEspNow.addPeer(PEER);

if (!ok) {

Serial.println("WifiEspNow.addPeer() failed");

ESP.restart();

}

}

loop()

{

char msg[60];

int len = snprintf(msg, sizeof(msg), "hello ESP-NOW from %s at %lu",

WiFi.softAPmacAddress().c_str(), millis());

WifiEspNow.send(PEER, reinterpret_cast<const uint8_t*>(msg), len);

delay(1000);

}

Code Description

  • This code can be used for both ESP8266 as well as ESP32 receivers.
  • The first task is adding the required libraries.
  • h is for enabling wireless connectivity in ESP8266 and WiFi.h is for ESP32 module (if you are using this device).
  • h is to enable the ESP-NOW protocol and its respective function is the ESP device.

Fig. 21: Header files in Receiver Code

  • printReceivedMessay() function is used to fetch the message details transmitted by ESP32 (sender node), and the MAC address of the transmitter.
  • If you are receiving data from multiple sender nodes then a unique MAC address will be fetched from multiple sender nodes along with the message received.

Fig. 22

Setup()

  • Initialize the serial monitor with a 115200 baud rate for debugging purposes.
  • Wi-Fi should be enabled to implement the ESP-NOW protocol and wireless connectivity. It could be either AP or STA mode and does not require to be connected.

Fig. 23: Serial Monitor Wi-Fi Initialization

  • Print the MAC address of the sender on the serial monitor.

Fig. 24

  • Initialize the ESP-NOW using begin() function.
  • If somehow the ESP device is unable to initialize the ESP then print the respective details on the serial monitor.

Fig. 25

  • Once ESP-NOW and Wi-Fi are successfully initialized, the ESP receiver (ESP8266) is ready to receive the data packets from sender.

Fig. 26

  • Testing (Receiving a message in ESP8266 from ESP32 )
  • Select the ESP8266 development board you are using in Arduino IDE.
  • For that, go to Tools >> Boards and select the right development board.
  • We are using the ESP8266 Generic module as shown below:

Fig. 27: Selecting The ESP 8266 Development Board

  • Upload the Receiver code in the ESP8266 module.
  • Open the serial monitor with a baud rate of 115200.
  • Press the reset (Rst) button from the ESP8266 development board.
  • MAC address of the receiver will be printed on the serial monitor as shown below:

Fig. 28: MAC Address of Receiver

  • Copy the MAC address of the receiver and paste into the sender (ESP32) code.
  • Again change the development board from ESP8266 to ESP32.

Fig. 29: Selecting ESP32 Board in Arduino IDE

  • Upload the code into sender (ESP32).
  • Open the serial monitor with a 115200 baud rate.
  • Press the enable (EN) button from the ESP32 development board.
  • Results are shown below:

Fig. 30: Message Sent

  • If you want to read the data received at ESP8266, remove the ESP32 and power it with a different power source.
  • Connected the ESP8266 with a laptop.
  • Again select the ESP8266 development board on Arduino IDE’s Tools >> Boards
  • Open the serial monitor with a 115200 baud rate.
  • Press the reset (RST) button from the ESP8266 developments board.
  • Results are shown below:

Fig. 31: Message Received

This concludes the tutorial. I hope, you found this helpful and I hope to see you soon for the new ESP32 tutorial.

ESP32 Internal Temperature Sensor

Hello friends, I hope you all are doing great. Welcome to the 3rd lecture of Section 5(ESP32 Sensors) in the ESP32 Programming Series. We have already discussed the two built-in ESP32 sensors i.e. Hall Effect Sensor and Capacitive Touch Sensor. Today, we are going to discuss the 3rd and final built-in ESP32 sensor i.e. Internal Temperature Sensor.

ESP32 Internal Temperature Sensor is used to calculate the temperature of the ESP32 core. So, we can't use it to measure the ambient temperature (the temperature of the atmosphere), for that, we need to use embedded temperature sensors i.e. DS18B20, DHT11, BMP280 etc. We will first discuss the basics of this Internal Temperature Sensor and then will design a code to monitor the change in temperature by changing the frequency of the ESP32 CPU.

Note:

  • Internal Temperature Sensor is not present in all ESP32 variants.
  • So, if ESP32 lacks the sensor, it sends an invalid temperature reading of 53.33oC(equivalent to 128 in decimal).

Important specs of the ESP32 Temperature Sensor are given in the below table:

ESP32 Temperature Sensor Features
Parameter Value
Converter Types ADC (Analog-to-Digital Converter), DAC (Digital-to-Analog Converter)
Accurate Temperature Sensing Range -40 °C to 125 °C
Suitability Good
Most Accurate Range -10 °C to 80 °C
Temperature Fluctuation Measurement High resolution
Potential Performance & Accuracy Issues Voltage fluctuations, Noise, Environmental factors, Nearby heat sources
Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

ESP32 Internal Temperature Sensor

ESP32’s on-chip temperature sensor cannot be used for monitoring external temperature. It can only be used to monitor the temperature of the core. This temperature sensor is available on some selective ESP32 boards and obsolete on most ESP32 variants. It has a high-temperature sensing range of -40 to 125 °C.

ESP32 boards are normally used in real-time IoT Projects i.e. home automation, back security etc. Such projects need to run 24/7 to get live updates and may heat up the motherboard. Thus, to get a stable performance in continuous operations, these internal temperature sensors are introduced to monitor the ESP32 Core.

ESP32 Boards with Built-in Temperature Sensor

Most of the modern ESP32 variants are equipped with the Internal Temperature Sensor. I have created a list of the ESP32 boards by taking the ESP-IDF documentation that caters to the built-in temperature sensor. Here's the list:

  • ESP32-C2
  • ESP32-C3
  • ESP32-C6
  • ESP32-H2
  • ESP32-S2
  • ESP32-S3

As you can see, most of the newer versions have a temperature sensor, but some older versions may also have one.

How does this temperature sensor work?

ESP32 temperature sensor consists of 2 converters:

  1. 8-bit Sigma-Delta analog-to-digital converter(ADC)
  2. digital-to-analog converter(DAC)

8-bit Sigma-Delta analog-to-digital converter (ADC)

Sigma-delta ADCs are widely favored for their exceptional accuracy and remarkable resolution, enabling them to deliver precise measurements. This ADC takes the analog signal from the temperature sensor, converts it to a digital signal and feeds it to the microcontroller for processing.

Digital-to-analog converter (DAC)

The DAC is responsible for the accuracy of the temperature measurements. It is embedded within the ESP32 and converts the digital values(converted by the Sigma-Delta ADC) again into analog values to offset any temperature-induced variation. As a result, it ensures accurate readings from the sensor.

Measuring Errors in Temperature Sensor

The accuracy of this temperature sensor changes according to the range group of the temperature values. Among different groups, the range of -10 ~ 80 is the most accurate. The reading errors along with their measuring ranges are shown in the below table:

Measuring Errors in ESP32 Temperature Sensor
No. Offset Predefined Range (°C) Error (°C) Operating Range (°C)
1 -2
50 ~ 125 < 3 Not recommended(Error)
2
-1
20 ~ 100 < 2 Ideal range for best accuracy
3
0 -10 ~ 80 < 1 Acceptable range with moderate accuracy
4
1
-30 ~ 50 < 2 Usable range with increased error at extremes
5
2
-40 ~ 20 < 3 Not recommended (error)

Different factors, including voltage fluctuations, noise, environmental factors, and nearby heat sources, can affect the performance and accuracy of this sensor.

Formula to convert observed temperature i.e. Fahrenheit to Celsius:

(F-32) *(5/9) = degree Celsius

ESP32 Temperature Sensor Applications

Here are the main applications of the ESP32 built-in temperature sensor:

Improve Chip Performance

A designer can easily monitor the internal chip’s temperature through the temperature sensor, identify bottleneck conditions, and conduct performance evaluations under extreme circumstances. So, the sensor helps in optimizing the chip's temperature and, thus, the performance.

Avoid Overheating

Electronic components/modules are sensitive, and if they are designed to work for prolonged operation, temperature management is one of the most crucial points to be considered. The built-in temperature sensor is a useful way to measure the operating temperature of the components connected to its peripherals and the whole system. These values are then utilized to set the threshold value so the system can trigger the safety mechanism when a certain heat level is passed. This can be done using the ESP32 code and surely prevent overheating to maintain the performance.

Energy Monitoring

The built-in temperature sensor helps to maintain the energy monitoring that, in turn, allows the energy monitoring of the project. The careful observation of the built-in temperature sensor output helps the user understand the relationship between temperature change and energy consumption. Using this approach, designers can target an optimized energy consumption.

Programming ESP32 to measure Core temperature in Arduino IDE

  • We are using the Arduino IDE as a compiler, we have already installed ESP32 in it, if you haven't, please read out How to Install ESP32 in Arduino IDE.
#ifdef __cplusplus
extern "C" {
    #endif
    uint8_t temprature_sens_read();
    #ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();

void setup()
{
    Serial.begin(115200);
}

void loop()
{
    Serial.print("Temperature: ");
    Serial.print(temprature_sens_read() );
    Serial.print(" F");
    Serial.print("______");

    // Convert raw temperature in F to Celsius degrees
    Serial.print((temprature_sens_read() - 32) / 1.8);
    Serial.println(" C");
    delay(1000);
}

Code Description

  • Style guard is used at the beginning to declare some function to be of “C” linkage, instead of “C++” Basically, to allow C++ code to interface with C code.
#ifdef __cplusplus
extern "C" {
    #endif
    uint8_t temprature_sens_read();
    #ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();

Setup() Function

  • Initialize the Serial monitor with a 115200 baud rate for debugging purposes.
void setup()
{
    Serial.begin(115200);
}

Loop() Function

  • Temperature_sens_read() function is used to read the temperature of the core.
  • Print the observer temperature on the serial monitor.
void loop()
{
    Serial.print("Temperature: ");
    Serial.print(temprature_sens_read() );
    Serial.print("______");
}
  • Convert the temperature from Fahrenheit to degrees Celsius and print on the serial monitor.
  • The result will be printed with a delay of 1 sec.
// Convert raw temperature in F to Celsius degrees
    Serial.print((temprature_sens_read() - 32) / 1.8);
    Serial.println(" C");
    delay(1000);

Testing/Results

  • Upload the code into the ESP32 board.
  • Open the serial monitor with a 115200 baud rate.
  • Press the EN button from the ESP32 development board.
  • See the result on the serial monitor as shown below:

This concludes the tutorial. I hope you found this of some help and also to see you soon with the new tutorial on ESP32.

Receiving Emails with ESP32 using IMAP Server

Hello readers, I hope you all are doing great. In our previous tutorial, we learned SMTP server and how to implement an SMTP server for sending emails with ESP32. In the previous tutorial, we also demonstrated some examples like sharing raw text, HTML text, images and text files.

So, at the transmitter end, we are using the SMTP server.

But, what about the receiver end?

At the receiver end, we use another protocol called IMAP (or Internet Message Access Protocol) and POP3 (Post office Protocol V3) for receiving the emails.

Fig. IMAP and SMTP

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is IMAP Protocol and How does it Work?

IMAP is an application layer (TCP/IP) protocol that is used at the receiver end to receive emails from SMTP server or mail server. IMAP follows the client/server model.

Fig. IMAP Protocol

Features of IMAP protocol:

  • IMAP can operate in three modes:
    1. Online mode
    2. Offline mode
    3. Disconnected mode
  • IMAP uses two ports:
    1. 143 Port – Communication over this port is not secure because this is a non-encrypted IMAP port.
    2. 993 Port – Communication over this port is secure and it is used when the client (IMAP) wants to connect securely through IMAP.
  • Users can access emails from a remote server without deleting the emails from the email server.
  • Setting message flag – The message flag is set to help the user in keeping the track of which message has already been seen.
  • Receivers can create a folder to organize mails in the hierarchy.
  • Users can also download a portion of a message from the mime-multi part in case of large multimedia files.
  • Organizing mail on the server.
  • Check email header – user can check the email header before downloading the mail.

What is POP3?

POP3 stands for Post Office Protocol version 3.

POP3 is another protocol to receive emails. This protocol is used to access the TCP/IP mailbox. The protocol is quite popular due to its offline mail access model.

The offline access model enables the user to access the mails from the mail server on the local machine, and then delete them from the mail server.

Why IMAP is Preferred over the POP3?

  • Being an offline access model, POP3 is not suitable for the ideal world. The biggest drawback of the POP3 model is that emails are permanently deleted from the server, and is it not possible to access the mails in different computers.
  • In POP3 user is not allowed to manage the mails on the server whilst in IMAP protocol the user can delete, create or rename the mails on the server.
  • Another drawback of the protocol is data security and safety.
  • So, a new protocol is developed to overcome the drawback of the POP3 protocol. The protocol was named Internet Message Access Protocol or IMAP. Which is an online protocol and mails received via IMAP protocol can be accessed on different computers.

Though in some applications POP3 protocol is still used, but in most of the email receivers, it is preferred to use IMAP protocol over POP3 protocol.

Setting parameters for different IMAP service provider

IMAP (incoming) setting parameter for Gmail

  • IMAP Server address – imap.gmail.com
  • IMAP username – xyz@gmail.com
  • IMAP password – password
  • IMAP port – 993

IMAP (incoming) setting parameters for Yahoo

  • IMAP Server address – mail.yahoo.com
  • IMAP username – xyz@yahoo.com
  • IMAP password – password
  • IMAP port – 993
  • SSL required – Yes

Similarly, other email service providers like Outlook and Hotmail, have different setting parameters.

  • Components required to send and receive emails using ESP32 over SMTP server are:
  • Recipient’s email address.
  • Sender’s email address.
  • Content to be shared over SMTP server.
  • ESP mail client library.
  • ESP32 module.

ESP mail client Library

To send emails with ESP32 we need to install this ESP Mail Client library. This library, make ESP32 able to send emails over SMTP server.

Step to install ESP Mail Client Library:

  • To download the ESP Mail Client Library click on the link: https://github.com/mobizt/ESP-Mail-Client
  • Open the Arduino IDE.
  • Go to Sketch >> Include Library >> Add .ZIP Library.
  • Select the downloaded ZIP file.
  • Click on

Your Arduino IDE is ready to send email using ESP32.

Create a new Gmail account

It is recommended to create a new email account for sending emails using ESP32 or ESP8266 modules.

If you are using your main (personal) email account (for sending emails) with ESP and by mistake, something goes wrong in the ESP code or programming part, your email service provider can ban or disable your main (personal) email account.

In this tutorial, we are using a Gmail account.

Follow the link to create a new Gmail account: https://accounts.google.com

Access to Less Secure apps

To get access to this new Gmail account, you need to enable Allow less secure apps and this will make you able to send emails. The link is attached below:

https://myaccount.google.com/lesssecureapps?pli=1

Fig.

Arduino IDE Code, for configuring IMAP Protocol in ESP32

  • As we mentioned earlier, we are using Arduino IDE as a compiler and upload into ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on the ESP32 programming series.
  • We have already discussed installing the ESP Mail Client Library to make ESP32 able to send emails over the SMTP server.
  • This library includes multiple examples on SMTP like sending text messages, images, HTML code, text files etc. We have attached an image below for your reference.
  • You can use those examples to send emails.

Fig IMAP and SMTP Example Code

Note: You can not use the exact code. Hence, you need to make some changes like replacing SSID and password with your network credentials, email address of sender and receiver, setting IMAP and SMTP parameters for respective email service providers etc, needs to be done before uploading the code. We will also describe these things during code description.

ESP32 IMAP Code

In this code, we will implement both IMAP and SMTP protocols to receive and transmit emails.

Although, we are using SMTP in this tutorial, but we have already discussed and demonstrated the implementation on SMTP protocol in our previous tutorial. So, in this tutorial we will not explain the SMTP part.

Follow our previous tutorial for detailed study of SMTP implementation in ESP32.

#include <Arduino.h>

#include <WiFi.h>

#include <ESP_Mail_Client.h>

//To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h.

#define WIFI_SSID "public"

#define WIFI_PASSWORD "ESP32@123"

//-----------setting IMAP parameters------

/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */

#define IMAP_HOST "imap.gmail.com"

#define IMAP_PORT 993

#define AUTHOR_EMAIL "techeesp697@gmail.com"

#define AUTHOR_PASSWORD "Tech@ESP123"

#define RECIPIENT_EMAIL "maneesha607ece@gmail.com"

//------------setting SMTP credentials----------

#define SMTP_HOST "smtp.gmail.com"

#define SMTP_PORT 465

//------IMAP Rx emails and their status

/* Callback function to get the Email reading status */

void imapCallback(IMAP_Status status);

void printAllMailboxesInfo(IMAPSession &imap);

void printSelectedMailboxInfo(SelectedFolderInfo sFolder);

void printMessages(std::vector<IMAP_MSG_Item> &msgItems, bool headerOnly);

/* Print all attachments info from the message */

void printAttacements(std::vector<IMAP_Attach_Item> &atts);

/* The IMAP Session object used for Email reading */

IMAPSession imap;

//-------SMTP sending mails and their status----

/* The SMTP Session object used for Email sending */

SMTPSession smtp;

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status);

 

void setup()

{

Serial.begin(115200);

#if defined(ARDUINO_ARCH_SAMD)

while (!Serial)

;

Serial.println();

Serial.println("**** Custom built WiFiNINA firmware need to be installed.****\nTo install firmware, read the instruction here, https://github.com/mobizt/ESP-Mail-Client#install-custom-built-wifinina-firmware");

#endif

Serial.println();

Serial.print("Connecting to AP");

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED)

{

Serial.print(".");

delay(200);

}

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

Serial.println();

/** Enable the debug via Serial port

* none debug or 0

* basic debug or 1

*

* Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h

*/

imap.debug(1);

/* Set the callback function to get the reading results */

imap.callback(imapCallback);

ESP_Mail_Session session;

session.server.host_name = IMAP_HOST;

session.server.port = IMAP_PORT;

session.login.email = AUTHOR_EMAIL;

session.login.password = AUTHOR_PASSWORD;

/* Setup the configuration for searching or fetching operation and its result */

IMAP_Config config;

/* Set seen flag */

//config.fetch.set_seen = true;

/* Search criteria */

config.search.criteria.clear();

/* Also search the unseen message */

config.search.unseen_msg = true;

/* Set the storage to save the downloaded files and attachments */

config.storage.saved_path = "/email_data";

config.storage.type = esp_mail_file_storage_type_flash;

 

config.download.header = true;

config.download.text = true;

config.download.html = true;

config.download.attachment = true;

config.download.inlineImg = true;

config.enable.html = true;

config.enable.text = true;

/* Set to enable the sort the result by message UID in the ascending order */

config.enable.recent_sort = true;

/* Set to report the download progress via the default serial port */

config.enable.download_status = true;

config.limit.search = 5;

config.limit.msg_size = 512;

config.limit.attachment_size = 1024 * 1024 * 5;

/* Connect to server with the session and config */

if (!imap.connect(&session, &config))

return;

/* {Optional} */

printAllMailboxesInfo(imap);

/* Open or select the mailbox folder to read or search the message */

if (!imap.selectFolder("INBOX"))

return;

/* {Optional} */

printSelectedMailboxInfo(imap.selectedFolder());

String uid = String(imap.getUID(imap.selectedFolder().msgCount()));

config.fetch.uid = uid;

/* Read or search the Email and close the session */

//When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status,

//as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag

//to message, see the Set_Flags.ino example.

MailClient.readMail(&imap);

/* Clear all stored data in IMAPSession object */

imap.empty();

}

void loop()

{

}

/* Callback function to get the Email reading status */

void imapCallback(IMAP_Status status)

{

/* Print the current status */

Serial.println(status.info());

/* Show the result when reading finished */

if (status.success())

{

/* Print the result */

/* Get the message list from the message list data */

IMAP_MSG_List msgList = imap.data();

printMessages(msgList.msgItems, imap.headerOnly());

/* Clear all stored data in IMAPSession object */

imap.empty();

SMTP_MSG();

}

}

void printAllMailboxesInfo(IMAPSession &imap)

{

/* Declare the folder collection class to get the list of mailbox folders */

FoldersCollection folders;

/* Get the mailbox folders */

if (imap.getFolders(folders))

{

for (size_t i = 0; i < folders.size(); i++)

{

/* Iterate each folder info using the folder info item data */

FolderInfo folderInfo = folders.info(i);

ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : "");

}

}

}

void printSelectedMailboxInfo(SelectedFolderInfo sFolder)

{

/* Show the mailbox info */

ESP_MAIL_PRINTF("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount());

ESP_MAIL_PRINTF("Predicted next UID: %d\n", sFolder.nextUID());

for (size_t i = 0; i < sFolder.flagCount(); i++)

ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : "");

}

void printAttacements(std::vector<IMAP_Attach_Item> &atts)

{

ESP_MAIL_PRINTF("Attachment: %d file(s)\n****************************\n", atts.size());

for (size_t j = 0; j < atts.size(); j++)

{

IMAP_Attach_Item att = atts[j];

/** att.type can be

* esp_mail_att_type_none or 0

* esp_mail_att_type_attachment or 1

* esp_mail_att_type_inline or 2

*/

ESP_MAIL_PRINTF("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate);

}

Serial.println();

}

void printMessages(std::vector<IMAP_MSG_Item> &msgItems, bool headerOnly)

{

for (size_t i = 0; i < msgItems.size(); i++)

{

/* Iterate to get each message data through the message item data */

IMAP_MSG_Item msg = msgItems[i];

 

Serial.println("****************************");

ESP_MAIL_PRINTF("Number: %d\n", msg.msgNo);

ESP_MAIL_PRINTF("UID: %d\n", msg.UID);

ESP_MAIL_PRINTF("Messsage-ID: %s\n", msg.ID);

ESP_MAIL_PRINTF("Flags: %s\n", msg.flags);

//The attachment may not detect in search because the multipart/mixed

//was not found in Content-Type header field.

ESP_MAIL_PRINTF("Attachment: %s\n", msg.hasAttachment ? "yes" : "no");

if (strlen(msg.acceptLang))

ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);

if (strlen(msg.contentLang))

ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);

if (strlen(msg.from))

ESP_MAIL_PRINTF("From: %s\n", msg.from);

if (strlen(msg.sender))

ESP_MAIL_PRINTF("Sender: %s\n", msg.sender);

if (strlen(msg.to))

ESP_MAIL_PRINTF("To: %s\n", msg.to);

if (strlen(msg.cc))

ESP_MAIL_PRINTF("CC: %s\n", msg.cc);

if (strlen(msg.date))

{

ESP_MAIL_PRINTF("Date: %s\n", msg.date);

ESP_MAIL_PRINTF("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date));

}

if (strlen(msg.subject))

ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);

if (strlen(msg.reply_to))

ESP_MAIL_PRINTF("Reply-To: %s\n", msg.reply_to);

if (strlen(msg.return_path))

ESP_MAIL_PRINTF("Return-Path: %s\n", msg.return_path);

if (strlen(msg.in_reply_to))

ESP_MAIL_PRINTF("In-Reply-To: %s\n", msg.in_reply_to);

if (strlen(msg.references))

ESP_MAIL_PRINTF("References: %s\n", msg.references);

if (strlen(msg.comments))

ESP_MAIL_PRINTF("Comments: %s\n", msg.comments);

if (strlen(msg.keywords))

ESP_MAIL_PRINTF("Keywords: %s\n", msg.keywords);

/* If the result contains the message info (Fetch mode) */

if (!headerOnly)

{

if (strlen(msg.text.content))

ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);

if (strlen(msg.text.charSet))

ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);

if (strlen(msg.text.transfer_encoding))

ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);

if (strlen(msg.html.content))

ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);

if (strlen(msg.html.charSet))

ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);

if (strlen(msg.html.transfer_encoding))

ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);

if (msg.rfc822.size() > 0)

{

ESP_MAIL_PRINTF("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size());

printMessages(msg.rfc822, headerOnly);

}

}

Serial.println();

}

}

void SMTP_MSG()

{

smtp.debug(1);

smtp.callback(smtpCallback);

ESP_Mail_Session session;

session.server.host_name = SMTP_HOST;

session.server.port = SMTP_PORT;

session.login.email = AUTHOR_EMAIL;

session.login.password = AUTHOR_PASSWORD;

session.login.user_domain = "";

/* Declare the message class */

SMTP_Message message;

message.sender.name = "The_Engineering_Projects";

message.sender.email = AUTHOR_EMAIL;

message.subject = "Auto_Response";

message.addRecipient("Maneesha", RECIPIENT_EMAIL);

//Send raw text message

String textMsg = "Thanks for contacting us. One of our client will contact you soon. www.theengineeringprojects";

message.text.content = textMsg.c_str();

message.text.charSet = "us-ascii";

message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;

message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

/* Connect to server with the session config */

if (!smtp.connect(&session))

return;

/* Start sending Email and close the session */

if (!MailClient.sendMail(&smtp, &message))

Serial.println("Error sending Email, " + smtp.errorReason());

}

//-----------SMTP Status function-----

// Callback function to get the Email sending status

void smtpCallback(SMTP_Status status)

{

/* Print the current status */

Serial.println(status.info());

/* Print the sending result */

if (status.success())

{

Serial.println("----------------");

ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());

ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());

Serial.println("----------------\n");

struct tm dt;

for (size_t i = 0; i < smtp.sendingResult.size(); i++)

{

/* Get the result item */

SMTP_Result result = smtp.sendingResult.getItem(i);

time_t ts = (time_t)result.timestamp;

localtime_r(&ts, &dt);

ESP_MAIL_PRINTF("Message No: %d\n", i + 1);

ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");

ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);

ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);

ESP_MAIL_PRINTF("Subject: %s\n", result.subject);

}

Serial.println("----------------\n");

}

}

Code Description

  • The first task is adding the required header files or libraries.
  • h is used to enable the Wi-Fi module and hence wireless network connectivity.
  • Another library is h to enable email services for receiving and transmitting mails over IMAP and SMTP protocols respectively.
  • Enter the network credentials in place of SSID and PASSWORD.
  • Enter the IMAP server address and port number of the respective email service provider.
  • In this code, we are using the Gmail service.
  • Enter the SMTP server address and port number of respective email service provider.

Fig. SMTP server address and port number

  • Enter your (source) email address and password details to receive and transmit emails.
  • Insert another (destination) email address.
  • imapCallback() function is used to fetch the email reading status.
  • Print the list of mailbox folders.
  • Print the information of the selected mail folder.
  • Print all the messages from the message list.
  • Print the attachment contained in the mail.
  • Call the IMAP session object which is used to read emails.
  • SMTPSession object is used for sending emails.
  • This smtpCallback() function is used to get the email sending status.
  • This function also includes printing the results like success and failure of email sent.

Setup() Code

  • Initialize the serial monitor at a 115200 baud rate for debugging purposes.
  • WiFi.begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.
  • The While loop will continuously run until the ESP32 is connected to the Wi-Fi network.

Fig

  • If the device is connected to a local Wi-Fi network then print the details on the serial monitor.
  • WiFi.localIP() function is used to fetch the IP address.
  • Print the IP address on the serial monitor using println() function.

Fig.

  • Imap.debug(1) function is used for debugging through the serial monitor.
  • Where parameter ‘1’ represents basic debug.

Fig.

  • imap.callback() function is set to get the reading results.

Fig.

  • Declare the session configuring data.

 

  • Some properties of session configuration and imap_configuration accept the pointer to constant char. You can also change them to a string.
  • Set the session configuration which includes the server address of the IMAP service provider, port, and your email address and password.
  • For searching and fetching operation results set the configuration.
  • Configure the searching criteria for available information.
  • Configuration for searching unseen messages.

Fig.

  • Set the storage path to save the downloaded files.

Fig.

  • Configure the flash for storing email files.

Fig.

  • Set the message (download) header which includes text, HTML message, attachments (to store the attachments you need to enable Serial Peripheral Interface Flash File System or SPIFFS).
  • Follow our previous tutorial i.e., on sending emails with ESP32 over SMTP

  • Enable the results for HTML and text messages which are to be stored in IMAPSession object.
  • The IMAPSession object’s size is limited by config.limit.msg_size.
  • Enable.recent_sort is configured to enable the feature of sorting the messages by UID in ascending order.
  • download_status is configured to indicate the download progress on the serial monitor.
  • limit.search is configured to limit the emails in the search result.
  • The size of the message stored is limited to 512 bytes.
  • The size of attachments and images that can be downloaded is limited to 1024*1024*5bytes.
  • Connect to IMAP server with the set session and configurations.

 

  • Open the selected mail folder to read the received information.
  • Fetch UID from the maximum message number in mailbox and write the UID into a string type variable
  • Read the message once it is fetched.
  • Delete/clear all the data stored in the IMAPSession

imapCallback()

  • As we mentioned earlier, imapCallback() function is used to fetch the email reading status.
  • The current status is printed on the serial monitor from info() function.
  • If the email is fetched successfully, print the result and message list.
  • After that clear all the data stored in IMAPSession object.
  • SMTP_MSG() function is called when an email is fetched.
  • SMTP_MSG() function initialize the SMTP server to send an email to the destination client. This function contains all the instructions related to sending email which includes debugging, session object, message header, type of data contained in the email (raw text or HTML text), SMTP server settings, connecting to the server.
  • ESP32 will automatically send an email in reply of the mail received from the client device using this SMTP_MSG function.

Fig.

Note:- We have already discussed the SMTP server in our previous tutorial that is Sending Emails with ESP32 using SMTP server. So, follow our previous tutorial for a detailed study on SMTP protocol and send an email using ESP32.

Testing

  • After making the required changes in the given code like Wi-Fi credentials, email service provider’s details, email address of sender and receiver etc. upload the code into the ESP32 module.
  • Make sure you have turned on the access for less secure apps as discussed earlier.
  • Open the serial monitor with a 115200 baud rate.
  • Send an email to the address login in ESP32 from another email.
  • Make sure ESP32 is connected to the internet.
  • When an email is received by ESP32, the respective results are shown below :

Fig. Email received by ESP32 over IMAP

  • Once the email is fetched completely, SMTP will be initialized and an auto-response email will be sent to the destination email address.

Fig. Email successfully sent from ESP32 over SMTP

 

Fig. Response from ESP32

This concludes the tutorial. I hope you found this helpful and also hope to see you soon with a new tutorial on ESP32.

Sending Email with ESP32 using SMTP Protocol

Hello readers, I hope you all are doing great. In this tutorial, we will learn how to send an email using ESP32 module. We will also learn to send text files, images or some sensor readings using the SMTP server using the ESP32 module.

In IoT (Internet of things), there are various applications where we need to send emails carrying information like sending some sensor readings, altering emails, images, text files and much more.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is SMTP?

SMTP or simple mail transfer protocol is an internet standard for sending and receiving electronic mail (or email) where an SMTP server receives emails from the email client.

SMTP is also used for setting communication between servers.

Various email providers like Gmail, Hotmail, Yahoo, etc. have unique SMTP addresses and port numbers.

How does SMTP work?

SMTP protocol which is also known as a push protocol is used to send emails and IMAP that is Internet Message Access Protocol (or post office protocol or POP) is used to receive emails at the receiver end.

SMTP protocol operates at the application layer of TCP/IP protocol.

When a client wants to send emails, a TCP connection will be open for the SMTP server and emails will be sent across the connection.

SMTP commands:

  • HELO – This command is sent only once per session and is used to identify the qualified domain names and the client to the server.
  • MAIL – used to initiate a message
  • RCPT – Identifies the address
  • DATA – share the data line by line

SMTP parameters for different email providers

SMTP parameters for Gmail

Gmail is the email service provided by Google and Gmail SMTP server is free to access and anyone can access this service, who has a Gmail account.

  • SMTP server: smtp.gmail.com
  • SMTP Port: 465
  • SMTP sender’s address: Gmail address
  • SMTP sender's password: Gmail Password

SMTP parameters for Yahoo

  • SMTP server: smtp.mail.yahoo.com
  • SMTP Port: 465 (with SSL)
  • Another Port number: 587 (with TLS)
  • SMTP sender’s address: email address
  • SMTP sender’s password: password

SMTP parameters for Hotmail

  • SMTP server: smtp-mail.outlook.com
  • SMTP port: 587
  • SMTP sender’s address: Hotmail email address
  • SMTP sender’s password: Hotmail password
  • SMTP TLS/SSL required : YES

SMTP parameters for Outlook

  • SMTP server: smtp-mail.office.com
  • SMTP server port for incoming mail: 993
  • SMTP server port for outgoing mail: 587
  • SMTP sender’s address: Outlook email address
  • SMTP sender’s password: Outlook password
  • SMTP TLS/SSL required : YES

Sending emails over SMTP using ESP32 in Arduino IDE

  • In this tutorial, we will demonstrate sending raw text messages and HTML messages, images, text files, etc. to the client over the SMTP server.

Components required to send and receive emails using ESP32 over SMTP server are:

  • Recipient’s email address.
  • Sender’s email address.
  • Content to be shared over SMTP server.
  • ESP mail client library.
  • ESP32 module.

ESP mail client Library

To send emails with ESP32 we need to install this ESP Mail Client library. This library, make ESP32 able to send emails over an SMTP server.

Step to install ESP Mail Client Library:

  • To download the ESP Mail Client Library click on the link given below: https://github.com/mobizt/ESP-Mail-Client
  • Open the Arduino IDE.
  • Go to Sketch >> Include Library >> Add .ZIP Library.
  • Select the downloaded ZIP file. Click on

Your Arduino IDE is ready to send email using ESP32.

Create a new Gmail account (Sender)

It is recommended to create a new email account for sending emails using ESP32 or ESP8266 modules.

If you are using your main (personal) email account (for sending emails) with ESP and by mistake, something goes wrong in the ESP code or programming part, your email service provider can ban or disable your main (personal) email account.

In this tutorial, we are using a Gmail account.

Follow the link to create a new Gmail account: https://accounts.google.com

 

Access to Less Secure apps

To get access to this new Gmail account, you need to enable Allow less secure apps and this will make you able to send emails. The link is: https://myaccount.google.com/lesssecureapps?pli=1

Arduino IDE Code, for sharing raw text and HTML text with ESP32 and SMTP server:
  • As we mentioned earlier, we are using Arduino IDE as a compiler and upload into the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial Introduction to ESP32 Programming Series.
  • We have already discussed installing the ESP Mail Client Library to make ESP32 able to send emails over the SMTP server.
  • This library includes multiple examples on SMTP like sending text messages, images, HTML code, text files etc. We have attached an image below for your reference.
  • You can use those examples to send emails.

Fig SMTP example code

  • Note: You can not use the exact code. Hence, you need to make some changes like replacing SSID and password with your network credentials, email address of sender and receiver, SMTP setting parameters for respective email service providers etc, which need to be done before uploading the code. We will also describe these things during code description.

#include <WiFi.h>

#include <ESP_Mail_Client.h>

#define WIFI_SSID "SSID"

#define WIFI_PASSWORD "PASSWORD"

#define SMTP_HOST "smtp.gmail.com"

#define SMTP_PORT 465

/* The sign in credentials */

#define AUTHOR_EMAIL "email address"

#define AUTHOR_PASSWORD "email password"

/* Recipient's email*/

#define RECIPIENT_EMAIL "email address_Rx"

/* The SMTP Session object used for Email sending */

SMTPSession smtp;

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status);

void setup(){ Serial.begin(115200);

Serial.println();

Serial.print("Connecting to AP");

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED){

Serial.print(".");

delay(200);

}

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

Serial.println();

/** Enable the debug via Serial port

none debug or 0 basic debug or 1

*/

smtp.debug(1);

/* Set the callback function to get the sending results */

smtp.callback(smtpCallback);

/* Declare the session config data */

ESP_Mail_Session session;

/* Set the session config */

session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD;

session.login.user_domain = "";

/* Declare the message class */

SMTP_Message message; message.sender.name = "ESP32"; message.sender.email = AUTHOR_EMAIL; message.subject = "ESP32 Test Email";

message.addRecipient("Sara", RECIPIENT_EMAIL);

/*Send HTML message*/

String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello CLient!</h1><p>- Sent from ESP board</p></div>"; message.html.content = htmlMsg.c_str(); message.html.content = htmlMsg.c_str(); message.text.charSet = "us-ascii";

message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

//Send raw text message

/* String textMsg = "Hello Client! - you have a message from ESP32 board"; message.text.content = textMsg.c_str(); message.text.charSet = "us-ascii";

message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;

message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

/* Set the custom message header */

//message.addHeader("Message-ID: <abcde.fghij@gmail.com>");

/* Connect to server with the session config */ if (!smtp.connect(&session))

return;

/* Start sending Email and close the session */ if (!MailClient.sendMail(&smtp, &message))

Serial.println("Error sending Email, " + smtp.errorReason());

}

void loop(){

}

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status){

/* Print the current status */

Serial.println(status.info());

/* Print the sending result */ if (status.success()){

Serial.println("----------------");

ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());

ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());

Serial.println("----------------\n"); struct tm dt;

for (size_t i = 0; i < smtp.sendingResult.size(); i++){

/* Get the result item */

SMTP_Result result = smtp.sendingResult.getItem(i);

time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt);

ESP_MAIL_PRINTF("Message No: %d\n", i + 1);

ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900,

dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients); ESP_MAIL_PRINTF("Subject: %s\n", result.subject);

}

Serial.println("----------------\n");

}

}

Code Description

  • The first task is adding the required header files or libraries.
  • Wifi.h is used to enable the Wi-Fi module and hence wireless network connectivity.
  • Another library is ESP_Mail_Client.h to enable email service over SMTP (simple mail transfer protocol).
  • Enter the network credentials in place of SSID and PASSWORD.
  • Insert SMTP parameter of the respective email service provider.
  • The parameters used below are for Gmail.
  • Enter the sender’s email address and password details.
  • Insert recipient’s email address.
  • SMTPSession object is used for sending emails.
  • This smtpCallback() function is used to get the email sending status.
  • This function also includes printing the results like success and failure of email sent.

Setup()

  • Initialize the serial monitor at a 115200 baud rate for debugging purposes.
  • WiFi.begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.
  • The While loop will continuously run until the ESP32 is connected to the Wi-Fi network.

  • If the device is connected to a local Wi-Fi network then print the details on the serial monitor.
  • WiFi.localIP() function is used to fetch the IP address.
  • Print the IP address on the serial monitor using Serial.println() function.

  • Serial.debug() is used to enable the debug via Serial port where ‘0’ and ‘1’ are used as arguments where;
    • - none debug
    • - basic debug
  • Inside ESP_Mail_FS.h header file, ESP_MAIL_DEFAULT_DEBUG_PORT can be used to change the Debug port.
  • Set the smtp.callback() function to get sending results.

  • Next step is setting the message header.
  • Message header will be set inside the setup() function which includes, sender’s name, subject, sender’s email address, receiver’s email address and name.

Sending raw text message

Write the message content (raw text) in the textMsg variable which you want to share over email.

Sending HTML text

To send HTML text write the respective content in the htmlMsg variable.

  • Connect to server with session configuration using smtp.connect() function.
  • Next thing to do is, send an email to the client for that MailClient.sendMail() function is used and if mail transmission is failed then that will be printed on the serial monitor along with the reason.
  • Loop() function will remain empty.

Testing

  • Upload the Arduino IDE code in the ESP32 module.
  • Make sure the Wi-Fi network is ON to which your ESP32’s Wi-Fi module is supposed to connect.
  • Open Serial monitor with 115200 baud rate.
  • Also, make sure that you have turned ON the permission for less secure apps.

Otherwise, you won’t be able to send emails and an error will be printed on the serial monitor.

  • Press the EN button from the ESP32 development board.

  • Check receiver email inbox.

Arduino IDE code, for sending images and text files using ESP32 and SMTP server:

In this example code, we will demonstrate how to share text files and images through emails using ESP32 over the SMTP server.

But, before sharing attachments (text files or images) you need to save those files on the ESP32 filesystem (SPIFFS).

Uploading files to ESP32 Filesystem (SPIFFS)

SPIFFS stands for Serial Peripheral Interface Flash File System, which is built into the ESP32 module. This is a lightweight filesystem designed for microcontrollers with flash chips connected via SPI bus, such as the ESP32 flash memory. In this flash memory, we can write, delete, read, and close files.

  • Text files and images will be saved on ESP32 filesystem (SPIFFS) using ESP32 filesystem uploader plugin for Arduino IDE.

Installing Arduino ESP32 Filesystem Uploader:

Fig.

  • Restart the Arduino IDE.

Check if the plugin is successfully uploaded or not:

  • Open Arduino IDE. Select ESP32 development board.
  • Go to
  • Check whether this ESP32 Sketch Data Upload option is available or not. If it is available that means plugin is uploaded successfully and it is ready to upload files.

Fig.

Finally, uploading files using SPIFFS or filesystem upload:

  • In Arduino IDE, create a new Arduino sketch.
  • Save the project.
  • Go to Sketch >> Show Sketch Folder. As shown in the image below:

Fig.

  • Create a new folder named as

Fig.

  • Inside that data folder add the respective text files or images you want to share over email as shown in the image below:

Fig.

  • If you are using the example code from ESP mail-client library then the images should be named as png and text files as text_file.text.
  • After saving files inside data folder, open the Arduino IDE then go to Tools >> ESP32 Sketch Data Upload to upload the SPIFFS Image.

Fig.

A message “SPIFFS Image Uploaded” will be displayed at the bottom of Arduino IDE, once the SPIFFS image is uploaded successfully.

Fig.

Arduino IDE Code

Code is already available in ESP Mail Client Library. As shown below:

Fig.

  • You can not use the exact code.
  • Some changes like Wi-Fi credentials, email address of sender and receiver, SMTP setting parameters for respective email service providers etc, need to be done before uploading the code.

// To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1

// The file systems for flash and sd memory can be changed in ESP_Mail_FS.h.

#include <Arduino.h>

#include <WiFi.h>

#include <ESP_Mail_Client.h>

#define WIFI_SSID "SSID"

#define WIFI_PASSWORD "PASSWORD"

// server address for Gmail account

#define SMTP_HOST "smtp.gmail.com"

/** The smtp port e.g.

25 or esp_mail_smtp_port_25 465 or esp_mail_smtp_port_465 587 or esp_mail_smtp_port_587

*/

#define SMTP_PORT 465

/* The log in credentials */

#define AUTHOR_EMAIL "Sender's email address"

#define AUTHOR_PASSWORD "password"

/* Recipient's email*/

#define RECIPIENT_EMAIL "receiver's email address"

/* The SMTP Session object used for Email sending */

SMTPSession smtp;

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status);

void setup(){

Serial.begin(115200);

Serial.println();

Serial.print("Connecting to AP");

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED){

Serial.print(".");

delay(200);

}

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

Serial.println();

if (!SPIFFS.begin(true)) {

Serial.println("An error has occurred while mounting SPIFFS");

}

else{

Serial.println("SPIFFS mounted successfully");

}

/** Enable the debug via Serial port

  • none debug or 0
  • basic debug or 1

*/

smtp.debug(1);

/* Set the callback function to get the sending results */

smtp.callback(smtpCallback);

/* Declare the session config data */

ESP_Mail_Session session;

/* Set the session config */ session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD;

session.login.user_domain = "mydomain.net";

/* Declare the message class */

SMTP_Message message;

/* Enable the chunked data transfer with pipelining for large message if server supported

*/

message.enable.chunking = true;

/* Set the message headers */ message.sender.name = "ESP Mail";

message.sender.email = AUTHOR_EMAIL;

message.subject = "Test sending Email with attachments and inline images from SD card and Flash";

message.addRecipient("Sara", RECIPIENT_EMAIL);

/** Two alternative content versions are sending in this example e.g. plain text and html */

String htmlMsg = "This message contains attachments: image and text file."; message.html.content = htmlMsg.c_str(); message.html.charSet = "utf-8";

message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;

message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

/* The attachment data item */

SMTP_Attachment att;

/** Set the attachment info e.g.

  • file name, MIME type, file path, file storage type,
  • transfer encoding and content encoding

*/

att.descr.filename = "image.png"; att.descr.mime = "image/png"; //binary data

att.file.path = "/image.png";

att.file.storage_type = esp_mail_file_storage_type_flash;

att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

/* Add attachment to the message */

message.addAttachment(att);

message.resetAttachItem(att);

att.descr.filename = "text_file.txt"; att.descr.mime = "text/plain"; att.file.path = "/text_file.txt";

att.file.storage_type = esp_mail_file_storage_type_flash;

att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

/* Add attachment to the message */

message.addAttachment(att);

/* Connect to server with the session config */ if (!smtp.connect(&session))

return;

/* Start sending the Email and close the session */ if (!MailClient.sendMail(&smtp, &message, true))

Serial.println("Error sending Email, " + smtp.errorReason());

}

void loop()

{

}

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status){

/* Print the current status */

Serial.println(status.info());

/* Print the sending result */ if (status.success()){

Serial.println("----------------");

ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());

ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());

Serial.println("----------------\n"); struct tm dt;

for (size_t i = 0; i < smtp.sendingResult.size(); i++){

/* Get the result item */

SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp;

localtime_r(&ts, &dt);

ESP_MAIL_PRINTF("Message No: %d\n", i + 1);

ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900,

dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);

ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);

ESP_MAIL_PRINTF("Subject: %s\n", result.subject);

}

Serial.println("----------------\n");

}

}

Code Description:

Most part of the code is similar to the previous one (that is sending raw text and HTML text), including libraries, network credentials, enabling Wi-Fi and the serial monitor, setting the email parameters of the respective email service provided. So we not explaining the complete code but, we will explain the programming part which is different than the previous one.

Setup()

  • We are initializing the SPIFFS, inside the setup() function to sore files which are to be shared over the SMTP server.
  • begin() function is used to for initializing SPIFFS.

Fig.

  • If the server supports, enable chunked data transfer with pipelining for large messages.

Fig.

  • Next, you need to create data attachments.

Fig.

  • The next thing is sending the image, for that you need to add the attachment details: filename, path, mime type, type of storage, encoding technique.
 

Fig.

  • After adding the details of the image, add the attachment to the message.

Fig.

  • To send a text file you also need to add similar details: name of the file, path, storage type, mime type and encoding technique.

Fig.

  • Add this attachment too to the message.

Testing

  • Upload the code into the ESP32 board.
  • Make sure you have selected the correct ESP32 development board and COM port.
  • Also, make sure that you have turned on the access for less secure apps for the sender’s email account as discussed earlier. Otherwise, the ESP32 will face an authentication error.
  • Turn ON the Wi-Fi with which your device is supposed to connect with.
  • Once the device is connected with the access point, it will automatically send the attachment to the receiver's email account.

Fig.

Fig.

Fig. Email Received

This concludes the tutorial; I hope you found this helpful and also hope to see you again with a new tutorial on ESP32.

ESP32 Capacitive Touch Sensor in Arduino IDE

Hello readers, I hope you are all doing great. Welcome to the 2nd lecture of Section 5(ESP32 Sensors) in the ESP32 Programming Series. In the previous tutorial, we discussed the built-in ESP32 Hall Effect Sensor. In this tutorial, we will discuss another inbuilt sensor of the ESP32 i.e. Capacitive Touch Sensor.

ESP32 Board has 10 built-in capacitive touch pins, which generate an electrical signal when someone touches these pins. These ESP32 touch pins are normally used to wake up the board from deep sleep mode. These touch pins are also used to replace the normal mechanical buttons with touch pads, improving the presentation of the IoT projects.

Here's the video demonstration of the ESP32 Capacitive Touch Sensor:

Before going forward, let's first understand how this touch sensor works:

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is a Capacitive Touch Sensor?

Capacitance is determined by the geometry of the conductors and the dielectric materials used. Changing any of these factors will result in changing the capacitance.

C = Ad

As we know, the human body also carries a small electric charge. So, when a body approaches the metallic plates(of a capacitor), the mutual capacitance between the two metal plates decreases. This change in capacitance is used to detect the touch in these capacitive sensors.

Capacitive touch sensor in ESP32

  • ESP32 offers 10 Capacitive-sensitive GPIO pins, operating at a normally HIGH state.
  • So, at open state, these pins provide +5V at the output but when someone touches any of these pins, the respective pin voltage drops to 0.
  • These ESP32 Capacitive Touch Sensor Pins are labeled in the below figure:(for detailed pinout, please read ESP32 Pinout)

So, if someone touches any of these pins, ESP32 can easily detect it. The pin mapping of touch-sensitive pins in DOIT ESP32 DevKit V1 with GPIO pins is shown below:

ESP32 Capacitive Touch Pins
No. Parameter Name Parameter Value
1
Touch0 GPIO4
2
Touch1 GPIO0(not available in DOIT ESP32 Dev-kit V1 30-pin module but available in the 36-pin module)
3
Touch2 GPIO2
4
Touch3 GPIO15
5
Touch4 GPIO13
6
Touch5 GPIO12
7
Touch6 GPIO14
8
Touch7 GPIO27
9
Touch8 GPIO33
10
Touch9 GPIO32

Programming ESP32 Capacitive Sensor

We are using the Arduino IDE development environment for programming ESP32. If you are new to Arduino IDE, read out How to Install ESP32 in Arduino IDE. Let's use the builtin Touch Sensor example in Arduino IDE:

  • Open the Arduino IDE, go to File > Examples > ESP32 > Touch. An image from Arduino IDE is attached below for your reference:

In Arduino IDE there are two example codes available for the ESP32 touch sensor. We will discuss and implement both example codes in this tutorial. So, let's first open the TouchRead Code:

ESP32 TouchRead Example

Here's the code for the TouchRead Example:

// ESP32 Touch Test
void setup()
{
    Serial.begin(115200);
    delay(1000); // give me time to bring up serial monitor
    Serial.println("ESP32 Touch Test");
}

void loop()
{
    Serial.println(touchRead(T0)); // get value using T0
    delay(1000);
}

Code Description

  • This is a basic code to test/understand the touch sensor feature of ESP32.
  • In this code, we are using a touch-sensitive pin to read the variation in capacitance and print the respective readings on the serial monitor.

Setup() Function

Inside the setup() function, the serial monitor is initialized at a baud rate of 115200 to display the sensor readings. Finally, we printed the message(ESP32 Touch Test) on the Serial Monitor:

void setup()
{
    Serial.begin(115200);
    delay(1000); // give me time to bring up serial monitor
    Serial.println("ESP32 Touch Test");
}

Loop() Function

  • Inside the loop function, the touchRead(T0) function takes the T0 capacitive sensor pin as an argument and reads the output of T0(GPIO Pin4).
  • The observed output is continuously printed on the serial monitor with a delay of 1 sec.
void loop()
{
    Serial.println(touchRead(T0)); // get value using T0
    delay(1000);
}

Testing/Result

  • Upload the above code into the ESP32 development board and connect a jumper wire to the T0 capacitive sensor pin(GPIO4).
  • To open the serial monitor in Arduino IDE, go to Tools > Serial monitor or use the Ctrl+Shift+M shortcut key.
  • Select the 115200 baud rate on the serial monitor.
  • Now hold the metal end of the jumper wire connected to the GPIO4.
  • To check the results, open the serial plotter, go to Toole > Serial Plotter or use Ctrl+Shift+L shortcut keys.
  • As you can see in the above figure, the sensor's value drops to 0 when we touch the metallic part of the capacitive sensor pin.
  • When we are not touching the sensor pin, the normal sensor output is around 107.
  • Here's the Serial Monitor showing the touch results:

ESP32 Touch Interrupt Example

These capacitive touch sensor pins are mainly used to generate an external interrupt for waking up ESP32 from low power modes(deep sleep mode). Moreover, can also be used to control external peripherals like LED blinking or tuning on a DC motor, when a capacitive touch-interrupt is observed. So, let's have a look at How to Generate external interrupt by touching the ESP32 capacitive touch pins:

ESP32 Touch Interrupt Code

Here's the ESP32 Touch Interrupt Code:

const int CAPACITIVE_TOUCH_INPUT_PIN = T0; // GPIO pin 4
const int LED_OUTPUT_PIN = LED_BUILTIN;
const int TOUCH_THRESHOLD = 40; // turn on light if touchRead value < this threshold
volatile boolean _touchDetected = false;

void setup()
{
    Serial.begin(115200);
    pinMode(LED_OUTPUT_PIN, OUTPUT);
    pinMode(LED_OUTPUT_PIN, LOW);
    touchAttachInterrupt(CAPACITIVE_TOUCH_INPUT_PIN, touchDetected, TOUCH_THRESHOLD);
}

void touchDetected()
{
    _touchDetected = true;
}

void loop()
{
    if(_touchDetected)
    {
        Serial.println("Touch detected.");
        _touchDetected = false;

        Serial.println("blink the LED");
        digitalWrite(LED_OUTPUT_PIN, HIGH);
        delay(1000);
        digitalWrite(LED_OUTPUT_PIN, LOW);
        delay(1000);
    }
}

Let's understand the code by parts:

Variables Initialization

  • The first step is to select the GPIO or touch sensor input pin to trigger an interrupt. We are using T0 or GPIO4 as an interrupt pin.
  • Select the LED output pin which will react or blink on the occurrence of an interrupt.
  • In the code, we are using the threshold value of 40. When a body, containing an electric charge touches a touch-sensitive pin, the threshold value decreases below 40.
  • The default state of the touchDetect variable is set to false.
const int CAPACITIVE_TOUCH_INPUT_PIN = T0; // GPIO pin 4
const int LED_OUTPUT_PIN = LED_BUILTIN;
const int TOUCH_THRESHOLD = 40; // turn on light if touchRead value < this threshold
volatile boolean _touchDetected = false;

Setup() Function

  • In the Setup Function, we initialized the serial monitor with a baud rate of 115200 so that you can display the results on the serial monitor for debugging purposes.
  • Set the LED pin as output and set the default state to LOW.
  • Attach the interrupt with the capacitive touch pin T0 using touchAttachInterrupt(), it takes the T0 pin, touchDetected and threshold value as arguments.
void setup()
{
    Serial.begin(115200);
    pinMode(LED_OUTPUT_PIN, OUTPUT);
    pinMode(LED_OUTPUT_PIN, LOW);
    touchAttachInterrupt(CAPACITIVE_TOUCH_INPUT_PIN, touchDetected, TOUCH_THRESHOLD);
}
  • touchDetected() function will be called when an interrupt is triggered i.e. someone touches the T0 Pin.
  • This Function will change the state of the "_touchDetected" variable to true.
void touchDetected()
{
    _touchDetected = true;
}

Loop() Function

  • Inside the loop() function, we are using the ‘if’ statement which is continuously checking the state of variable "_touchDetected".
  • Once the variable state is changed to true, an interrupt is triggered and the output LED (inbuilt LED) will start blinking with a delay of 1 second.
  • The result will be printed on the serial monitor.
void loop()
{
    if(_touchDetected)
    {
        Serial.println("Touch detected.");
        _touchDetected = false;

        Serial.println("blink the LED");
        digitalWrite(LED_OUTPUT_PIN, HIGH);
        delay(1000);
        digitalWrite(LED_OUTPUT_PIN, LOW);
        delay(1000);
    }
}

Testing of ESP32 Touch Sensitive Pin

  • Open the serial monitor with a 115200 baud rate.
  • Connect a male-to-female jumper wire with T0 or GPIO 4 of ESP32.
  • Hold the metallic end of the jumper wire.
  • LED will blink with a delay of 1 sec.
  • See the results displayed on the serial monitor.

This concludes the tutorial; I hope you found this helpful and also hope to see you again with a new tutorial on ESP32.

ESP32 Hall Effect Sensor in Arduino IDE

Hello readers, I hope you all are doing great. Welcome to Section 5 of the ESP32 Programming Series. In this section, we are going to interface different Embedded Sensors with the ESP32 Microcontroller Board. ESP32 development board is featured with some inbuilt sensors(i.e. hall effect sensor, capacitive touch sensor) so, in the initial tutorials of this section, we will explore these built-in ESP32 sensors and in the later lectures, we will interface third-party sensors with the ESP32.

In today's lecture, we will discuss the working/operation of the ESP32 built-in Hall Effect Sensor. Hall Effect sensor is used to detect the variation in the magnetic field of its surroundings. So, let's first understand What's Hall Effect:

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is the Hall Effect?

The Hall Effect phenomenon was first discovered by Edwin Hall in 1879. When current passes through a conductor, the electrons move in a straight line and thus the voltage difference across the conductor's surface remains zero, as shown in the below figure:

However, when a magnet is placed near the current-carrying conductor in a way that the direction of the magnetic field is perpendicular to the flow of current, the electrons get diverted and don't follow a straight line, which results in generating a small potential difference across the conductor's surface, as shown in the below figure:

This small potential difference generated because of magnetic field presence is called Hall Voltage. This magnetic field influence over the current-carrying conductor is termed the Hall Effect.

Hall Effect Sensor

A Hall Effect Sensor is a non-contact type embedded sensor, used to detect the presence & intensity of a magnetic field in its surroundings. Different third-party Hall Effect Sensors available in the market are shown in the below figure:

  • A normal Hall Effect Sensor Pinout consists of 3 Pins i.e.
  1. Vcc: Normally +5V, few +3.3V are also available.
  2. GND: We need to provide Ground here.
  3. OUT: The Output Pin to give the sensor's response.
  • When a perpendicular magnetic field is placed near a Hall-effect sensor, it changes the status of its Output Pin.
  • The analog Hall Effect Sensors can also detect the strength of the magnetic field i.e. greater the magnetic field greater will be the sensor's output or voltage deviation.

Applications of Hall Effect sensor

  • In an Automotive system, Hall Sensors are used to detect speed, distance, position etc.
  • Used in Proximity sensing.
  • Used in Current sensing.
  • Used in Anti-lock braking system.
  • Used in Internal combustion engines to assist with ignition timing.
  • To switch an electric circuit ON and OFF.

Hall Effect Sensor in ESP32

In ESP32, the Hall effect sensor is located inside the ESP-WROOM-32 metallic cover. As the Hall Effect sensor is a non-contact type, it doesn't have to be in contact with the magnet. We just need to place the magnet above this metallic sheet and the ESP32 Hall Effect sensor will detect it.

Programming ESP32 Hall Effect Sensor using Arduino IDE

To understand the working of the Hall sensor with ESP32, let's test the builtin ESP32 example:

  • You can find the code through File> Examples> ESP32 > Hall Sensor, as shown in the below figure:

Arduino IDE code

Here's the code for this ESP32 Hall Sensor example:

int val = 0;

void setup()
{
   Serial.begin (9600);
}

void loop() 
{
   val = hallRead();
   Serial.print ("sensor value = ");
   Serial.println (val);//to graph

   delay(100);
}

Code Description

The code is quite simple, where the hallRead() function is called to read the hall sensor value, store it into a variable and then print it on the Serial monitor. Finally added a small delay to get the next value. Let me explain the code line by line for the beginners:

Variables Declaration

  • The first step will be the declaration of an integer-type variable to store the hall sensor value. The initial value assigned to the variable is zero.
int val = 0;

Setup() Function

  • Inside the setup function, the only task is to initialize the serial port at a 9600 baud rate for serial communication.
void setup()
{
   Serial.begin (9600);
}

Loop() Function

  • Inside the loop function, we called a function ‘hallRead()’ to read the sensor value and store those readings into the variable ‘val’.
  • Printed the sensor readings on the serial monitor or serial plotter using serial.println() function.
  • A delay of 0.3 sec is added at the end.
void loop() 
{
   val = hallRead();
   Serial.print ("sensor value = ");
   Serial.println (val);//to graph

   delay(100);
}

ESP32 Hall Effect Sensor - Testing

  • After successfully uploading the code into ESP32, open the serial plotter or serial monitor to monitor the results.
  • Place a magnet near the ESP32 board.
  • The sensor reading will increase/decrease depending on the magnet pole(i.e. North or South Pole) facing the Hall sensor.
  • Now click on Tools > Serial Plotter to visually analyze the sensor's output.
  • The Serial Plotter of our project is shown in the below figure:
  • As you can see in the above figure, the sensor is giving negative output when facing the North Pole of the magnet.
  • In the case of a South Pole, the sensor's output is positive.
  • In the absence of a magnetic field, the sensor's output is almost 0.
  • The distance between the magnet and the Hall sensor decides the amount of potential difference generated.
  • The greater the distance between the two, the smaller the hall voltage or potential difference will be.
  • We have attached an image from the Arduino IDE serial monitor for your reference.

This concludes the tutorial. I hope you found this helpful, test it out and if feel any difficulty, let me know in the comments. In the next tutorial, we will have a look at another built-in sensor of ESP32 i.e. Capacitive Touch Sensor. Thanks for reading.

ESP32 Over The Air (OTA) Web Updater

Hello readers, I hope you are all doing great. In this tutorial, we are going to discuss the OTA web updater on the ESP32.

We already covered the fundamentals of OTA programming in ESP32, in our previous tutorial where we used the Arduino IDE to upload OTA code into the ESP32 module using the network port.

In the OTA web updater, you need to create a web server page for OTA programming.

[caption id="attachment_166886" align="aligncenter" width="1920"] ESP32 OTA web updater[/caption]

Fig.1 ESP32 OTA web updater

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

Over the Air Web Updater

  • "Over-the-air" refers to the ability to wirelessly download an application, configuration, or firmware to internet-enabled devices, also known as IoT. (OTA). It functions similarly to our computers, laptops, tablets, and phones.
  • Instead of using a serial port and a wired medium to upload a code, the OTA web updater allows the user to update the code or firmware wirelessly via a web server.
  • When sensor nodes are frequently placed in remote or difficult-to-reach locations, OTA programming can be used.

Steps to implement an OTA web updater using ESP32

  • Using the serial communication port, upload the code containing the instructions to enable the OTA web updater (so that in the future you can update the code using a browser instead of a wired medium).
  • The code uploaded via the serial port will launch a web server, allowing you to upload new code over the air.
  • The new code, which has been uploaded using a web server, should contain instructions to keep the OTA web updater enabled on the ESP32 board so that you can use the OTA programming feature in future applications as well.
  • Create a .bin using Arduino IDE compiler and upload the file on the server.

Fig. 2

Code for OTA web updater implementation in ESP32

In this tutorial, we will discuss only the OTA web updater method using Arduino IDE and ESP32 dev-Kit V1 module.

If you want to know more about the basics of ESP32 and how to get started with Arduino IDE, then read Introduction to ESP32 Programming Series.

  • You can find the code through File> Examples> ArduinoOTA> BasicOTA.
  • An image has been attached below for reference:

Fig. 3

  • This code should be uploaded serially through a serial communication port only then you can access the OTA web updater feature.

Code

#include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> #include <ESPmDNS.h> #include <Update.h>   const char* host = "esp32"; const char* ssid = "SSID"; const char* password = "password";   WebServer server(80);   /* * Login page */   const char* loginIndex = "<form name='loginForm'>" "<table width='20%' bgcolor='A09F9F' align='center'>" "<tr>" "<td colspan=2>" "<center><font size=4><b>ESP32 Login Page</b></font></center>" "<br>" "</td>" "<br>" "<br>" "</tr>" "<td>Username:</td>" "<td><input type='text' size=25 name='userid'><br></td>" "</tr>" "<br>" "<br>" "<tr>" "<td>Password:</td>" "<td><input type='Password' size=25 name='pwd'><br></td>" "<br>" "<br>" "</tr>" "<tr>" "<td><input type='submit' onclick='check(this.form)' value='Login'></td>" "</tr>" "</table>" "</form>" "<script>" "function check(form)" "{" "if(form.userid.value=='admin' && form.pwd.value=='admin')" "{" "window.open('/serverIndex')" "}" "else" "{" " alert('Error Password or Username')/*displays error message*/" "}" "}" "</script>";   /* * Server Index Page */   const char* serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>" "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>" "<input type='file' name='update'>" "<input type='submit' value='Update'>" "</form>" "<div id='prg'>progress: 0%</div>" "<script>" "$('form').submit(function(e){" "e.preventDefault();" "var form = $('#upload_form')[0];" "var data = new FormData(form);" " $.ajax({" "url: '/update'," "type: 'POST'," "data: data," "contentType: false," "processData:false," "xhr: function() {" "var xhr = new window.XMLHttpRequest();" "xhr.upload.addEventListener('progress', function(evt) {" "if (evt.lengthComputable) {" "var per = evt.loaded / evt.total;" "$('#prg').html('progress: ' + Math.round(per*100) + '%');" "}" "}, false);" "return xhr;" "}," "success:function(d, s) {" "console.log('success!')" "}," "error: function (a, b, c) {" "}" "});" "});" "</script>";   /* * setup function */ void setup(void) { Serial.begin(115200);   // Connect to WiFi network WiFi.begin(ssid, password); Serial.println("");   // 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());   /*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"); 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(); }   void loop(void) { server.handleClient(); delay(1); }

Code Description

The first task is to add the header files, required to perform over the air (OTA) web updates using the ESP32 module.
  • WiFi.h : This header file allows the ESP32 board to connect to the internet. It can serve either as a server or a client.
  • ESPmDNS.h : This library is used to implement multicast DNS query support for the ESP32 chip. A multicast UDP service is used to provide local network service.
  • WiFiClient.h : It is used to create a client that can connect to a specific port and IP address.

Fig. 4

  • Enter the SSID and password.

Fig. 5

  • You can style the HTML page anytime as per your requirements or use the default style given in the example code.

Setup()

  • Initialize the serial monitor at a 115200 baud rate.
  • WiFi.begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.

Fig. 6

  • Wait until the ESP32 is connected to the Wi-Fi network.

Fig. 7

  • If the device is connected to a local Wi-Fi network then print the details on the serial monitor.
  • WiFi.localIP() function is used to fetch the IP address.
  • Print the IP address on the serial monitor using Serial.println() function.

Fig. 8

  • Use multicast Domain Name System (mDNS) for hostname resolution.
  • Hostname has been defined as a global variable at the beginning of code.
  • Start the mDNS responder for esp32 or host using MDNS.begin() function.

Fig. 9

  • Return the index page which is stored in serverIndex.
  • Send the status OK (200 represents ‘OK’) to inform the client.

Fig. 10

  • Handling the uploading of firmware files.

Fig. 11

  • Start uploading the new firmware into the ESP32 board.

Fig. 12

  • Server.begin() function will start the server to listen for incoming connections.

Fig. 13

Loop()

  • Server.handleCLient() function is used to handle the client devices.
  • It will monitor the client devices and provide the requested HTML page.

Fig. 14

  • After successfully uploading the code into ESP32 board using serial communication port, open the serial monitor with 115200 baud rate.
  • Press EN or enable button from the ESP32 board.
  • You can see the IP address printed on the serial monitor, once the ESP32’s Wi-Fi module is connected to wi-fi network.
  • We have attached a screenshot below for your reference:

Fig. 15 Serial monitor

Testing

  • Now the ESP32 module is ready for over the air (OTA) programming.
  • For testing the OTA web updater, remove the ESP32 module from your computer and power the ESP32 board using another power source.
  • Open the browser and enter the IP address from the Serial Monitor as shown in the above image.
  • A web page with an IP address of 168.43.223 is shown below:

Fig. 16

  • Enter the username and password on the login page. As per the example code:
Username: admin Password: admin
  • You can change the username and password details if you wish to.
  • Click on Login.
  • A new browser page with URL 192.168.43.223/serverIndex will be displayed on the screen, as shown below:

Fig. 17

  • You can style the browser page as per your requirements.

Test code

  • Write a new code in Arduino IDE.
  • The code should contain two sections:
  1. The instructions to keep OTA web updater feature enabled
  2. Instructions to blink the LED (you can replace the LED code with another code as per your requirements).
#include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> #include <ESPmDNS.h> #include <Update.h>   const char* host = "esp32"; const char* ssid = "SSID"; const char* password = "password";   //variabls to blink without delay: const int led = 2; unsigned long previousMillis = 0; // will store last time LED was updated const long interval = 1000; // interval at which to blink (milliseconds) int ledState = LOW; // ledState used to set the LED   WebServer server(80);   /* * Login page */   const char* loginIndex = "<form name='loginForm'>" "<table width='20%' bgcolor='A09F9F' align='center'>" "<tr>" "<td colspan=2>" "<center><font size=4><b>ESP32 Login Page</b></font></center>" "<br>" "</td>" "<br>" "<br>" "</tr>" "<td>Username:</td>" "<td><input type='text' size=25 name='userid'><br></td>" "</tr>" "<br>" "<br>" "<tr>" "<td>Password:</td>" "<td><input type='Password' size=25 name='pwd'><br></td>" "<br>" "<br>" "</tr>" "<tr>" "<td><input type='submit' onclick='check(this.form)' value='Login'></td>" "</tr>" "</table>" "</form>" "<script>" "function check(form)" "{" "if(form.userid.value=='admin' && form.pwd.value=='admin')" "{" "window.open('/serverIndex')" "}" "else" "{" " alert('Error Password or Username')/*displays error message*/" "}" "}" "</script>";   /* * Server Index Page */   const char* serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>" "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>" "<input type='file' name='update'>" "<input type='submit' value='Update'>" "</form>" "<div id='prg'>progress: 0%</div>" "<script>" "$('form').submit(function(e){" "e.preventDefault();" "var form = $('#upload_form')[0];" "var data = new FormData(form);" " $.ajax({" "url: '/update'," "type: 'POST'," "data: data," "contentType: false," "processData:false," "xhr: function() {" "var xhr = new window.XMLHttpRequest();" "xhr.upload.addEventListener('progress', function(evt) {" "if (evt.lengthComputable) {" "var per = evt.loaded / evt.total;" "$('#prg').html('progress: ' + Math.round(per*100) + '%');" "}" "}, false);" "return xhr;" "}," "success:function(d, s) {" "console.log('success!')" "}," "error: function (a, b, c) {" "}" "});" "});" "</script>";   /* * setup function */ void setup(void) { pinMode(led, OUTPUT);   Serial.begin(115200);   // Connect to WiFi network WiFi.begin(ssid, password); Serial.println("");   // 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());   /*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(); }   void loop(void) { server.handleClient(); delay(1);   //loop to blink without delay unsigned long currentMillis = millis();   if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis;   // if the LED is off turn it on and vice-versa: ledState = not(ledState);   // set the LED with the ledState of the variable: digitalWrite(led, ledState); } }

Test Code Description

  • We are using the same old code with an additional LED blinking part.
  • In this code, we are using inbuilt LED for testing.
  • Define the GPIO pin to which LED is connected.
  • GPIO 2 is connected to the inbuilt LED.
  • To add delay, we are using timers instead of delay() function.
  • The variable interval is defining the time delay.
  • Set LED’s state to low.

Fig. 18

Arduino Loop() Function

  • Blink the LED after every 1000ms or 1sec delay as defined in variable ‘interval’.

Fig. 19

How to generate a bin file

  • Compile the code in Arduino IDE.
  • Go to Sketch > Export compiled Binary or press Crl+Alt+S to generate .bin file.

Fig. 20

Fig. 21 bin file

  • Upload the .bin file on the browser with 192.168.43.223/serverIndex URL and click on update option.
  • At 100% progress the inbuilt LED from the ESP32 board will start blinking.

Fig 22

Fig. 23 LED blink

  • Similarly, you can upload a new code using over the air web updater.

This concludes the tutorial. I hope, you found this helpful and I hope to see you soon for the new ESP32 tutorial.

ESP32 OTA (Over The Air) Programming

Hello readers, hope you all are doing great. In this tutorial, we are going to discuss a mechanism that allows users to update the ESP32 with a new program wirelessly or over the air (without using a USB cable to upload a new program).

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

Over-The-Air (OTA) programming

Fig. 1 ESP32 OTA

  • OTA programming is the mean by which a product manufacturer or product service provider can update the features or functionality of the device wirelessly or over the air, after the device has been deployed in the field where connecting a cable or uploading the code serially is difficult.
  • One key advantage of OTA is that a single central node can send an update to multiple ESPs on the same network.
  • The device must have a provisioning client capable of receiving, processing, and setting parameters in order to receive, process, and set parameters in a mobile device over the air.

Applications of OTA programming

Mobile Phones:

  • In order to improve the compatibility with hardware and enhance the stability of software and applications, software updates are required.
  • OTA updates are intended to improve the underlying operating system, time zone rules, read-only apps installed on the system partition these updates have no effect on user-installed applications.

IoT (internet of things) application:

  • The ability to wirelessly download an application, configuration, or firmware to internet-enabled devices, also known as IoT, is referred to as over-the-air (OTA). It works in the same way that our computers, laptops, tablets, and phones do.
  • Application, where sensor nodes are frequently placed in remote or difficult-to-reach locations OTA programming can be used.

Fig. 2 OTA programming for IoT

 

How does OTA programming work?

There are two methods of OTA implementation.

  • Basic OTA: In the basic OTA method the program is updated into ESP32 over the air using Arduino IDE.
  • OTA web updater: In web updater OTA the program is updated over the air using a web browser.

Implementing OTA Update feature using ESP32

In this tutorial, we will discuss only the basic OTA method using Arduino IDE and ESP32 module.

If you want to know more about the basics of ESP32 and how to get started with Arduino IDE, then follow the tutorial Introduction to ESP32 Programming Series.

  • For Basic OTA programming with ESP32, it is required to install the python 2.7.x version in your system.
  • Follow the link to download python: https://www.python.org/downloads/
  • Install the python into your system.
  • Upload the basic OTA code into ESP32 using the serial port.
  • Upload the new ESP32 test code over the air using the network port into esp32 module.

To implement the Basic OTA method, an example is available is Arduino IDE.

  • You can find the code through File> Examples> ArduinoOTA> BasicOTA.
  • An image has been attached below for reference:

Fig. 3

Arduino IDE Code

  • It is required to first upload the basic OTA code serially (using serial com port).
  • Because in default mode the ESP32 is not ready for OTA updates (as there is no inbuilt OTA firmware available inside the ESP32 board).
  • Only after that you can access the OTA feature
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h>   const char* ssid = "SSID"; const char* password = "Password";   void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } ArduinoOTA.onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem";   // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); }

Code Description

  • The first step is to add all the necessary header files. Here we are using four header files.
  • WiFi.h: This header file allows the ESP32 board to connect to the internet. It can serve either as a server or a client.
  • ESPmDNS.h: This library is used to implement multicast DNS query support for the ESP32 chip. A multicast UDP service is used to provide local network service.
  • WiFiUdp.h: This is a library for Arduino wifi shield. It is used to send data to a UDP host over a wireless network.
  • ArduinoOTA.h: this library allows users to update the code in the ESP32 board using wifi instead of using the serial port.
  • Next, you need to add your wifi credentials. Enter the SSID and password.

Arduino Setup() Function

  • Inside the setup () function, the first task is to begin the serial monitor at a 115200 baud rate so that, you can print the results and other required details on the serial monitor for verification purposes.
  • Set ESP32 Wi-Fi module in station mode(esp32 will act as a client device) using WiFi.mode() function.
  • Enable ESP32’s Wi-Fi module using WiFi.begin() function which is using SSID and password as arguments.
  • Wait until the ESP32 is not connected with the wifi network.
  • ESP.restart() function will reset the ESP32. ESP.restart() function tells SDK to reboot.
  • If an error occurred in OTA programming, print the error on the serial monitor

  • ArduinoOTA.begin() function is used to initialize the OTA updater.
  • Wi-Fi.lockIP() is used to fetch the IP address.
  • Print the IP address on the serial monitor.

Arduino Loop() Function

  • Inside the loop() function, ArduinoOTA.handle() function is used for updating the ESP32 code over the air using the network port instead of the serial port.
  • Compile the code and upload serially using serial com port.
  • Open the serial monitor, set the baud rate to 115200.
  • You can see the IP address on the serial monitor once the ESP32 is connected to the Wi-Fi network.

Fig. 11 Serial monitor

Uploading new program into ESP32 module Over the Air

Code

#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h>   const char* ssid = "public"; const char* password = "ESP32@123";   //variabls for blinking an LED with Millis const int led = 2; // ESP32 Pin to which onboard LED is connected unsigned long previousMillis = 0; // will store last time LED was updated const long interval = 1000; // interval at which to blink (milliseconds) int ledState = LOW; // ledState used to set the LED   void setup() {   pinMode(led, OUTPUT);   Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem";   // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); });   ArduinoOTA.begin();   Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }   void loop() { ArduinoOTA.handle();   //loop to blink without delay unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: ledState = not(ledState); // set the LED with the ledState of the variable: digitalWrite(led, ledState); } }
  • In the test code, which we are going to upload using a wireless network port over the air, a LED blinking function is added just to test whether the OTA functionality is working fine or not.

Note: It is required to upload the OTA programming handler code every time you upload a new code into ESP32 over the air. So that, OTA programming remains enabled for future use.

Code Description

  • Add the required header files.

  • Enter Wi-FI credentials over which you are going to upload the code wirelessly.
  • Define the GPIO pin to which LED is connected.
  • GPIO 2 is connected to the inbuilt LED.
  • To add delay, we are using timers instead of delay() function.
  • The variable interval is defining the time delay.
  • Set LED’s state to low.

Arduino Setup() Function

  • Although in the example code serial monitor is initialized but it is not required anymore as we are using the network port for communication.
  • Initialize ESP32 Wi-Fi in station mode using WiFi.mode() function.
  • Wait until esp32 is connected to the Wi-Fi network.

  • ArduinoOTA.begin() function is used to initialize the OTA updater.
  • Wi-Fi.lockIP() is used to fetch the IP address.
  • Print the IP address on the serial monitor.

Arduino Loop() Function

  • Blink the LED after every 1000ms or 1sec delay as defined in variable ‘interval’.

  • Compile the above code.
  • Go to the Tools menu, then click on port and select the network port as shown in the image below.

This concludes the tutorial. I hope you found this helpful. In the next tutorial, we will discuss the OTA web updater in ESP32.

ESP32 Low Power Modes

Hello readers, hope you all are doing great. In this tutorial, we will discuss low power modes in ESP32, their purpose and their implementation to increase the battery life by reducing power consumption.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

Purpose of Low Power Modes

Fig.1

Along with multiple wireless and processing features, ESP32 also provides us with a power-saving feature by offering sleep modes. When you are powering the ESP32 module from the live supply using an adaptor or a USB cable, there is nothing to worry about power consumption. But when you are using a battery, as a power source to ESP32, you need to manage the power consumption for longer battery life.

Low Power Modes in ESP32

When ESP32 is in sleep mode, a small amount of power is required to maintain the state of ESP32 in RAM (random access memory) and retain necessary data. Meanwhile, the power supply won’t be consumed by any unnecessary peripheral or inbuilt modules like Wi-Fi and Bluetooth.

ESP32 offers 5 power modes. Each mode is configurable and offers different power-saving capabilities:

  1. Active Mode
  2. Modem Sleep Mode
  3. Light Sleep Mode
  4. Deep Sleep Mode
  5. Hibernation Mode

Fig. 2

Active Mode:

  • In active mode, all the modules and features of ESP32, like processing cores, Wi-Fi, Bluetooth, radio etc. remain active all the time.
  • Most of the power consumption occurs in this power mode which can vary between 160 -240mA and sometimes the maximum consumption could reach up to 790mA (when both Wi-Fi and Bluetooth are enabled or active at the same time).

Modem Sleep Mode:

  • In this mode, radio, Wi-Fi, Bluetooth will be disabled and everything else will remain active. Power consumption in this mode varies from 3 to 20mA.
  • Sleep modes can switch between modem and active modes as per the predefined intervals, by following the associated sleep pattern.

Light Sleep Mode:

  • During this mode, the central processing unit is paused by turning/powering off its clock.
  • ULP- coprocessor and RTC (real-time clock) remain active during light sleep mode and power consumption is 0.8mA.

Deep Sleep mode:

  • In this mode, the Ultra Low Power (ULP) coprocessor remains active while the ESP32 core and other digital peripherals remain inactive.
  • The ULP coprocessor wakes up the core processor when required.
  • The amount of power consumed in this mode is 10uA.

Fig 3

Hibernation Mode:

    • In this mode, the ULP coprocessor and internal oscillator both are disabled.
  • Only a real-time clock (RTC) remains active to wake up the processor and other required modules from hibernation mode and the power consumption in this mode is extremely low that is approximately 2.5uA.

For a better understanding of low power modes in ESP32, we are going to implement deep sleep mode in esp32 and will also discuss how to wake up the device from deep sleep mode.

Deep Sleep mode and Wakeup Using Capacitive Touch-sensitive pins

To implement deep sleep modes we are going to use another ESP32 feature that is Capacitive Touch Sensing pins. These pins can sense the presence of a body that holds an electric charge.

So we are going to use these touch-sensitive pins for waking up ESP32 from deep sleep mode using the Arduino IDE compiler.

In Arduino IDE examples are given for deep sleep mode with various wake-up methods.

  • Follow the image attached below to open the example code:

Fig. 4 Example code.

  • Arduino IDE Code

#define Threshold 40 /* Greater the value, more the sensitivity */ RTC_DATA_ATTR int bootCount = 0; touch_pad_t touchPin; /* Method to print the reason by which ESP32 has been awaken from sleep */ void print_wakeup_reason(){ esp_sleep_wakeup_cause_t wakeup_reason;   wakeup_reason = esp_sleep_get_wakeup_cause();   switch(wakeup_reason) { case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break; } }   /* Method to print the touchpad by which ESP32 has been awaken from sleep */ void print_wakeup_touchpad(){ touchPin = esp_sleep_get_touchpad_wakeup_status();   switch(touchPin) { case 0 : Serial.println("Touch detected on GPIO 4"); break; case 1 : Serial.println("Touch detected on GPIO 0"); break; case 2 : Serial.println("Touch detected on GPIO 2"); break; case 3 : Serial.println("Touch detected on GPIO 15"); break; case 4 : Serial.println("Touch detected on GPIO 13"); break; case 5 : Serial.println("Touch detected on GPIO 12"); break; case 6 : Serial.println("Touch detected on GPIO 14"); break; case 7 : Serial.println("Touch detected on GPIO 27"); break; case 8 : Serial.println("Touch detected on GPIO 33"); break; case 9 : Serial.println("Touch detected on GPIO 32"); break; default : Serial.println("Wakeup not by touchpad"); break; } }   void callback(){ //placeholder callback function }   void setup(){ Serial.begin(115200); delay(1000); //Take some time to open up the Serial Monitor   //Increment boot number and print it every reboot ++bootCount; Serial.println("Boot number: " + String(bootCount));   //Print the wakeup reason for ESP32 and touchpad too print_wakeup_reason(); print_wakeup_touchpad();   //Setup interrupt on Touch Pad 3 (GPIO15) touchAttachInterrupt(T3, callback, Threshold);   //Configure Touchpad as wakeup source esp_sleep_enable_touchpad_wakeup();   //Go to sleep now Serial.println("Going to sleep now"); esp_deep_sleep_start(); Serial.println("This will never be printed"); }   void loop(){ //This will never be reached }

Code Description

  • The first step is to set the threshold value for touch-sensitive pins.
  • When a body, containing an electric charge touches a touch-sensitive pin, the threshold value decreases below 40, that decrease in the threshold value will make ESP32 wake up from deep sleep mode. In the example code threshold value is 40.
  • The next task is to store the data into RTC memory (using RTC_DATA_ATTR ) because in deep sleep mode only RTC remains active and all other peripherals, processors, wireless modules will be disabled.
  • ESP32 offers 8kB SRAM on RTC to store the data.
  • But when you press EN/reset button the data stored in RTC memory will also be erased.
  • bootCount an integer type variable is used to count the number of times ESP32 has woken up during sleep mode. The value of bootCount variable is stored in RTC memory.
  • The print_wakeup_reason() function is used to print the reason for ESP32 wakeup from deep sleep whether it is due to an external interrupt, timer, or touch-sensitive pins.
  • The ESP32 has multiple capacitive touch-sensitive GPIO pins which can be used to wake up esp32 from deep sleep mode.
  • Print_wakeup_touchpad() function is used to print the GPIO pin which made ESP32 wake up from sleep mode.
  • When you hold a capacitive sensitive pin for a longer duration the threshold value (initialized globally) decreases from its predefines value i.e., 40 which will cause ESP32 to wake up, at that time the callback() function comes into action.
  • This function will be used as an argument inside the touchAttachInterrupt() function.

Setup()

  • Inside the setup() function the first task is to start the serial monitor with a baud rate of 115200.
  • Next, if there is any increment in boot count due to wake up calls, then print that count on the serial monitor.

Call the respective functions to print the wake-up reason:
  • Print_wakeup_reason() is used to print whether the ESP32 wake-up is caused by an external interrupt, timer or a capacitive sensitive pin.
  • If the wake up is due to a capacitive sensitive pin then the print_wakeup_touchpad() function will print the GPIO pin number which caused the wake-up.
  • The next task is to attach the interrupt using touchAttachInterrupt() function, to capacitive sensitive GPIO pin which you will use to wake up ESP32.
  • In this example we are using GPIO 15 capacitive sensitive pin as a wakeup interrupt pin.
  • esp_sleep_enable_touchpad_wakeup() is used to enable touch sensor feature.
  • esp_deep_sleep_start() function is used to make ESP32 enter to deep sleep mode.
  • Once ESP32 enters the sleep mode no other operation or data communication is possible until it receives a wakeup call.

Fig 12

Loop()

  • In this example code, there is nothing, written inside the loop function. But you can change the code as per your requirements.

Code Testing

  • To test the code, use a connecting wire (male to female) and connect one side to ESP32’s touch-sensitive pin (which you have mentioned in the code as an interrupt).
  • When you touch that pin an interrupt will be generated to wake ESP32 from sleep.
  • You can see the results on a serial monitor or can check the current consumption or can run other functions once it is awake like blinking LED.
  • In this code, we are using GPIO_15 touch-sensitive pin.

Fig. 13 waking up esp32 using capacitive sensitive GPIO pin

We have attached a screenshot from the serial monitor for reference.

Fig. 14

Deep Sleep mode and Wakeup Using Interrupt method

Arduino IDE Code

#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */ #define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */ RTC_DATA_ATTR int bootCount = 0; /* Method to print the reason by which ESP32 has been awaken from sleep */ void print_wakeup_reason(){ esp_sleep_wakeup_cause_t wakeup_reason; wakeup_reason = esp_sleep_get_wakeup_cause(); switch(wakeup_reason) { case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break; } }   void setup(){ Serial.begin(115200); delay(1000); //Take some time to open up the Serial Monitor   //Increment boot number and print it every reboot ++bootCount; Serial.println("Boot number: " + String(bootCount));   //Print the wakeup reason for ESP32 print_wakeup_reason();   /* First we configure the wake up source We set our ESP32 to wake up every 5 seconds */ esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");   /* Next we decide what all peripherals to shut down/keep on By default, ESP32 will automatically power down the peripherals not needed by the wakeup source, but if you want to be a poweruser this is for you. Read in detail at the API docs http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html Left the line commented as an example of how to configure peripherals. The line below turns off all RTC peripherals in deep sleep. */ //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); //Serial.println("Configured all RTC Peripherals to be powered down in sleep");   /* Now that we have setup a wake cause and if needed setup the peripherals state in deep sleep, we can now start going to deep sleep. In the case that no wake up sources were provided but deep sleep was started, it will sleep forever unless hardware reset occurs. */ Serial.println("Going to sleep now"); Serial.flush(); esp_deep_sleep_start(); Serial.println("This will never be printed"); }   void loop(){ //This is not going to be called }

Code Description

  • The first task is, to define the timer period for which ESP32 will be in deep sleep mode.
  • As we know that ESP32 operates at the MHz frequency range so the timer will be in microseconds. So, it is required to convert the time into seconds.
  • To add a timer of 5sec we need to multiply 5*1000000.
  • bootCount an integer type variable is used to count the number of times ESP32 has woken up during sleep mode. The value of bootCount variable is stored in RTC memory.

Fig 15

  • The print_wakeup_reason() function is used to print the reason for ESP32 wakeup from deep sleep whether it is due to an external interrupt, timer or touch-sensitive pins.

Fig. 16

Setup()

  • As discussed earlier, inside the setup function first we need to initialize the serial monitor at 115200 baud rate and then print the value of bootCount variable which is incrementing every time a wakeup interrupt occurs.

Fig. 17

  • The esp_sleep_enable_wakeup() function is used to enable the timer to generate a timer interrupt by passing time in microsecond as an argument.
  • In the beginning of code we have defined some global variable to add 5 sec timer (or 5000000us) and after every 5 sec ESP32 should wake up from deep sleep till 5 sec.

Fig. 18

  • esp_deep_sleep_start() function is used to make ESP32 enter the deep sleep mode.

Fig. 19

Testing

  • You can see the results of above code on serial monitor as shown is the image attached below.

Fig 20

This concludes the tutorial. I hope you found this useful, and I hope to see you soon for the new ESP32 tutorial.

Syed Zain Nasir

I am Syed Zain Nasir, the founder of <a href=https://www.TheEngineeringProjects.com/>The Engineering Projects</a> (TEP). I am a programmer since 2009 before that I just search things, make small projects and now I am sharing my knowledge through this platform.I also work as a freelancer and did many projects related to programming and electrical circuitry. <a href=https://plus.google.com/+SyedZainNasir/>My Google Profile+</a>

Share
Published by
Syed Zain Nasir