Secondary Menu

IOT Made Simple: Playing With the ESP32 on Arduino IDE

Introduction: IOT Made Simple: Playing With the ESP32 on Arduino IDE

Let's explore in this tutorial, the ESP32, the fantastic newer Development Kit board for IoT use. This board, developed by Espressif, should be the NodeMCU's successor, due to its low price and great features.

But is also important to point that NOT ALL libraries or functions that you are used to working with ESP8266 and/or Arduino are yet functional on this new board. Probably this will be soon, so check it regularly on ESP 32 Forum WebPage.

Here we will learn how to program the ESP32 on Arduino IDE, exploring its most common functions and libraries, point some of the important differences and new features introduced with this great chip.

In short, we will explore:

Digital Output: Blinking a LED

Digital Input: Reading a Touch Sensor

Analog Input: Reading a variable voltage from a potentiometer

Analog Output: Controlling a LED brightness

Analog Output: Controlling a Servo Position

Reading Temperature/Humidity Data with a Digital sensor

Connecting to the Internet and getting local time

Receiving data from a simple local web page, turning on/off a LED

Transmitting data to a simple local webPage

Step 1: The ESP32 Main Characterictics

The ESP32 is an under US$10 board with great advantages over similar IoT boards in the market.

This board has a dual processed microprocessor that helps a lot, because when one processor is handle communication, the other one is in charge of I/O control, for example. This feature will prevent some issues that happen with ESP8266, where the sole CPU needs stop controlling I/Os when handle with Comm. Besides, the ESP32 has integrated WIFI, BLUETOOTH, DAC, several ADC (not only one as the ESP8266), capacitive touch sensors, etc (give a look at above block diagram). And the good news is that Power Consumption is almost the same as ESP8266.

Bellow a chart that can show us its main characteristics, and differences when compared with ESP8266:

Step 3: ESP32 Arduino IDE Installation

We will use the Arduino IDE to program our ESP32, same way we do with the ESP8266 family.

Install Drivers:

It is important that you have installed on your computer, the updated CP210x USB to UART Driver. Enter in this link: usb-to-uart-bridge-vcp-drivers and install the proper driver for your OS.

Install Library:

The novelty here is that Expressif itself in its GitHub, will give us the proper directions for library installation: arduino-esp32. Follow the instructions for your OS. In my case (MacOS), the installation is very simple:

Open Terminal and execute the following command (copy->paste and hit enter):

After that, restart Arduino IDE and it's done! You must see several boards on "TOOLS" Menu. Select the appropriate for you. In general, the "generic" ESP32 DEV MODULE works fine.

When you open the Arduino IDE for the first time, you will note that the default upload speed is 921,600 bauds. This can provoque instability. Change it to 115,200 bauds!

Step 4: Hello World! Blinking a LED

As usual, the first thing to do when we start exploring a new HW is to blink a LED.

Go to Examples Menu in the IDE and open the Blink sketch.

The ESP32 DevKit, has a built-in LED that is connected to its GPIO 02. It is important to check if "LED_BUILTIN" is automatically recognized by IDE. If not, you must add to code the line:

int LED_BUILTIN = 2;

Each ESP32 board has an internal LED connected to a different GPIO

/*
ESP 32 Blink
Turns on an LED on for one second, then off for one second, repeatedly.
The ESP32 has an internal blue LED at D2 (GPIO 02)
*/
int LED_BUILTIN = 2;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

Below the internal LED blinking (note the blue light) together with an external one connected to GPIO 2:

There are several different boards with different pin maps in the market. The above diagram shows the board that I am using. You can find it here: /ESP32-Development-Board

Perfect! So, DigitalWrite() is working perfectly, same way with ESP8266 and Arduino. BTW, DigitalRead() also works the same way to read a digital input, like a push-button for example.

Step 5: The Touch Sensor

Let's jump to a new cool feature, the Touch Sensor!

The ESP32 has 10 internal capacitive touch sensors. You can use it as buttons for example.

Those sensors are connected with several GPIOs:

T0: GPIO 4

T1: GPIO 0

T2: GPIO 2

T3: GPIO 15

T4: GPIO 13

T5: GPIO 12

T6: GPIO 14

T7: GPIO 27

T8: GPIO 33

T9: GPIO 32

In order to read them you must use the function: touchRead(Touch Pin #);

For example, to read the Touch Sensor 0 (T0), you must do something like:

int value = touchRead(4);

Let's create a code, where if we touch the sensor T0 (GPIO4), the LED will be on.

Use the serial monitor to check the values read by the sensor and adjust the code properly.

Step 6: Analog Input

There are in total 18 x 12 bits ADC input channels, versus only 1 X 10bits ADC on NodeMCU.

GPIO ADC Channel

GPIO 0 ==> ADC2_CH1

GPIO 2 ==> ADC2_CH2

GPIO 4 ==> ADC2_CH0

GPIO 12 => ADC2_CH5

GPIO 13 => ADC2_CH4

GPIO 14 => ADC2_CH6

GPIO 15 => ADC2_CH3

GPIO 25 => ADC2_CH8

GPIO 26 => ADC2_CH9

GPIO 27 => ADC2_CH7

GPIO 32 => ADC1_CH4

GPIO 33 => ADC1_CH5

GPIO 34 => ADC1_CH6

GPIO 35 => ADC1_CH7

GPIO 36 => ADC1_CH0

GPIO 37 => ADC1_CH1

GPIO 38 => ADC1_CH2

GPIO 39 => ADC1_CH3

To read the analog input, you will the same as have done with Arduino and ESP8266:

int analog_value = analogRead(36);

It's very important to note that, the ESP32 ADCs have 12bits of resolution (versus 10bits on ESP8266 and Arduino), so the total range of ADCs reading go to 4,095 (instead 1,027 on Arduinos and ESP8266) when a maximum of 3.3V is applied to its inputs.

For input, let's use a 10K ohm potentiometer, connecting it from 3.3V and GND. Let's use its variable output to be the input for ESP32 ADC pins. The Above diagram shows the potentiometer connected to GPIO 36 that is the ADC1 Channel 0. Try also other inputs on your board.

Turn your potentiometer and observe on IDE Serial Monitor the measurements going from zero to 4,095.

Step 7: Dimming a LED: Analog Output Using PWM

If we want to "Dimmer a LED" on ESP8266 or an Arduino, we can simply use a command like analogWrite(), that will vary the PWM value of its output, simulating an analog value. Unfortunately, we still do not have such kind of command developed for the ESP32 on Arduino IDE. but the very good news is that all 36 of ESP32 GPIOs has a PWM capability, what is great! Only we must use more complex code to reach the same result.

The first thing to think about a PWM signal to be generated is its frequency. We will use a value of 5000 Hz, that works fine with the LED. We must also specify the LED PWM channel and the resolution of the PWM duty cycle, in bits. We can choose a channel from 0 to 15 and a resolution between 1 and 16 bits. We will use channel 0 and a resolution of 8 bits.

int freq = 5000;
int ledChannel = 0;
int resolution = 8;

Let's use GPIO2, where we have our external LED attached (and the internal one).

#define LED_PIN 2

Those parameters must be defined during setup() phase, using below functions:

To turn on the LED with a specific brightness, we must define the "duty cycle".

For example, to turn off the LED, the duty cycle must be zero and the function ledcWrite(ledChannel, dutyCycle) used to send the value thru a specific PWM channel:

int dutyCycle = 0;
ledcWrite(ledChannel, dutyCycle);

Different values of the dutyCycle variable will turn on the LED with different brightness. this variable, dutyCycle, will vary from 0 to 255, once the resolution used is 8 bits.

We can use the Potentiometer (connected to analog_value variable) to manually setup the dutyCycle variable, but once their range of values are different, let's use a map function to match input and output:

Step 8: Servo Control

Let's control a Servo Motor using the PWM capability of our ESP32. The code will be basically the same one that was used to control the LED brightness.

First, it's important to remember that the frequency to work with a Micro Servo is 50Hz, so we must change the frequency parameter to 50 (instead of 5,000 used with LED). We must also specify the LED PWM channel and the resolution of the PWM duty cycle, in bits. We will use again channel 0 and a resolution of 8 bits.

int freq = 50;
int channel = 0;
int resolution = 8;

The Servo will be connected to GPIO 5 (see above electrical diagram).

#define SERVO_PIN 5

Same as with LED, those parameters must be defined during setup() phase, using below functions:

To position the servo on a specific angle, we must define the "duty cycle" (please, see the above diagram).

For example, to position the servo around 90 degrees, the duty cycle must be around 21 and the function ledcWrite(ledChannel, dutyCycle) should be used to send the value thru the PWM channel:

int dutyCycle = 21;
ledcWrite(channel, dutyCycle);

Different values of the dutyCycle variable will position the servo with different angles. This variable, dutyCycle, should vary from 10 to 32 (this range was gotten manually).

Same as we did with the LED, the Potentiometer (connected to analog_value variable) can be used to manually setup the dutyCycle variable and so, changing the servo position. Once their ranges of values are different, let's use a map function to match input and output:

Step 10: Simple WiFi Server

Open the EXAMPLES menu on your Arduino IDE and get the ESP32 WiFi/SimpleWiFiServer.ino sketch:

About this program:

WiFi Web Server LED Blink

Created for arduino 25 Nov 2012 by Tom Igoe

Ported for sparkfun esp32 31.01.2017 by Jan Hendrik Berlin

A simple web server that lets you blink an LED via the web. This sketch will print the IP address of your ESP32 WiFi network to the Serial monitor. From there, you can open that address in a web browser to turn on and off the LED on pin 5.

This example is written for a network using WPA encryption. For WEP or WPA, change the Wifi.begin() call accordingly.

Circuit: LED attached to pin 5

So, let's use the program without significant modifications. Change the External LED Pin to GPIO5

Off course, if you prefer change the code for GPIO2 w/o changing the HW.

First, enter your network credentials:

const char* ssid = "yourssid";
const char* password = "yourpasswd";

And upload it on your ESP32.

The first thing that you will see at your serial Monitor will be the information that your ESP32 is connected and what is its Ip Address:

WiFi connected.
IP address:
10.0.1.40

Open your favorite browser, typing this IP address. You will get a WebPage like the one above. There you can Turn on or off the LED remotely.

Step 11: DHT 22 - Reading Temperature and Humidity

A very useful sensor to be used on IoT projects is the DHT 11 or 22. They are very cheap and easy to include in your projects.

First, you need to have the Adafrut Library installed on your IDE. Go to their GitHub and download the updated version of this library: DHT-sensor-library

Unzip the file, rename it to DHT and move the complete folder to your Arduino Library directory

When I used for the first time I got a message:

fatal error: Adafruit_Sensor.h: No such file or directory

After some digging, I found that it is also necessary to have the Adafruit Unified Sensor Library also installed. So, I did it from Arduino IDE Library Manager (see picture above). After that, everything worked fine, same as we use to do with Arduino and NodeMCU.

Let's do some tests with this sensor. Follow the above electrical diagram and install the DHT22 as shown (looking the sensor with the "grid" face you, count the 4 legs from left to right):

Pin VCC ==> 3.3V

Pin Data ==> GPIO 23

N/C

PIN GND ==> GND

Also, connect a 10K ohm resistor between VCC and Data.

That's it!

You can use the "DHT tester.ino" example sketch that it is included in the library, or do your own.

The novelty here is the "WiFiLocalWebPageCtrl()" function. But, this is exactly the original setup() function used on SimpleWebServer. What I included inside this function, is what should appear in the web page (see the above print screen for the web page).

Note that the temperature, humidity and analog values, will be updated everytime that you click on the links used to LED control or when you refresh the page.

Step 13: Conclusion

We could go on and on here, but we would never covered all ESP32 functions or potentiality. There is a lot left to explore with this great IoT device and on my next tutorial, you will learn how to add an OLED display on your ESP32:

Epilog Challenge 9

Trash to Treasure

Pro Tips Challenge

Tips

5 Questions

Hey there, can you tell me if this board is able to use the Joystick HID library like a leonardo? I am trying to make a wireless game controller and was wondering if this is a good board to use for that. Thank you!

However, I am having trouble connecting my ESP32 to Internet. For instance, I am not able to run the Local Time Stamp example, since my module never connects to the Wifi. The weird thing is that I have been able to connect it to a Wifi access point created by a mobile phone. Nevertheless, this wifi sharing zone has no access to Internet, it is just like a local network. In that case, I have been able to test the blink LED wifi server example, but if I try to connect to a "normal" Wifi, it never works.

Any help would be highly appreciated, since my final goal is to use Google charts display so I need this Internet connection to work properly.

10 Comments

interesting. Sadly the timestamp example in step 9 throws an error. Had chosen the ESP32 DevModule byut get this error:

In file included from /home/xxxxx/Arduino/ESP32_TimeStamp/ESP32_TimeStamp.ino:5:0:/home/xxxxx/Arduino/libraries/ESP8266_Weather_Station/src/NTPClient.h:5:25: fatal error: ESP8266WiFi.h: No such file or directory

Excellent tutorial, thanks. I was getting a "brown out" error. It was difficult to find a straight forward answer to this problem, so I thought I would post it here so others do waste the same amount of time I did. I was powering the board through a USB cable directly from PC as shown in your video, the 'blink' program worked just fine but when starting to use WiFi would throw the error. I checked my soldering twice. It turns out that the USB cable I was supplied was not capable of providing enough power to drive the WiFi component. Hope this helps someone else.