Technical Specifications
| Specification | Value |
|---|---|
| Number of cores | 2 |
| Architecture | 32 bit |
| CPU Frequency | 240MHz |
| Wi-Fi | YES |
| Bluetooth | YES |
| RAM | 512 KB |
| FLASH | 16 MB |
| GPIO Pins | 36 |
| Communication Protocols | SPI, IIC, I2S, UART, CAN |
| ADC channels | 18 channels |
| ADC Resolution | 12-bit |
| DAC channels | 2 |
| DAC Resolution | 8-bit |
Official Repository: https://github.com/espressif/arduino-esp32
Know
- Tools β Serial Monitor is the tool to log and supply the commands to the board.
- SPIFFS - Serial Peripheral Interface Flash File System is the flash memory for permanent storage. 4MB flash memory is available.
Getting Started
- Set up Arduino IDE and add the ESP32 board using https://dl.espressif.com/dl/package_esp32_index.json. This is to be done from File β Preferences.
- Select DOIT ESP32 DEVKIT V1 from the board selection. My model is xcluma ESP32 ESP-32 ESP-32S ESP 32 Development Board CP2102 Wifi Bluetooth Ultra-Low Power Consumption Dual Core.
- Follow https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/debian_ubuntu.md to set up the dependencies. The commands might vary slightly depending on the Linux distribution.
- Logout β Login the system. This is IMPORTANT.
Debugging
Cannot open /dev/ttyUSB0: Permission denied while Upload
# check if the device is recognized (if /dev/ttyUSB[0:9] is present)
ls /dev/tty*
# modify the permissions for execution on the external device
sudo usermod -a -G tty <username>Serial Monitor does not produce any output (Java error)
# check what all java versions are available
archlinux-java status
# then set the default to be java 11 or 12
sudo archlinux-java set java-12-openjdkPACKET_HEADER / PACKET_CONTENT not found
This might be a permanent problem due to manufacturing defects in certain boards. To solve this problem, we need to keep BOOT pin pressed while flashing. If the sketch is still not loaded after successful flashing, then try pressing EN pin for sometime.
Flashing bigger sketches on ESP32 - changing flash size
Use Arduino IDE for the purpose
- Change the Board: Use ESP32 Dev Module instead of DOIT ESP32 DEVKIT V1
- Change the Partition Schema
I changed it to 3MB / NO OTA / 1MB SPIFFS
This allows to flash bigger sketches. You might be willing to change the partition scheme according to your requirements.
Interesting
- Upon being used as WiFi access point, upon the password string being kept empty, it's an open network.
- The ESP32 board can be used interestingly as a repeater - https://github.com/martin-ger/esp_wifi_repeater
Programming on ESP32 using Arduino IDE
Connecting to WiFi β Making a GET request (webpage / file)
Lengthier code
/**
* BasicHTTPClient.ino
*
* Created on: 24.05.2015
*
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#define USE_SERIAL Serial
WiFiMulti wifiMulti;
/*
const char* ca = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
"-----END CERTIFICATE-----\n";
*/
void setup() {
USE_SERIAL.begin(115200);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
wifiMulti.addAP("Redmi", "1234567899");
}
void loop() {
// wait for WiFi connection
if((wifiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS
// http.begin("http://example.com/index.html"); //HTTP
http.begin("http://esp32.surge.sh/sample.bin"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(5000);
}#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "Redmi";
const char* password = "1234567899";
void setup() {
Serial.begin(115200);
delay(4000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("http://wtfismyip.com/json"); //Specify the URL
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
String payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
delay(10000);
}Downloading a file and storing it into SPIFFS
#include <SPIFFS.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include "SPIFFS.h"
const char* ssid = "Moinak's_Wifi";
const char* password = "Moinak123";
void setup() {
Serial.begin(115200);
delay(4000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
String fileName = "/final.bin";
Serial.println(fileName);
File f = SPIFFS.open(fileName, FILE_WRITE);
if (f) {
http.begin("http://wtfismyip.com/json");
int httpCode = http.GET();
if (httpCode > 0) {
String dataContent = http.getString();
Serial.println(dataContent);
f.print(dataContent);
} else {
Serial.println("HTTP GET request failed!");
}
Serial.println("File Write Succeeded!");
} else {
Serial.println("File mounting failed!");
}
f.close();
http.end(); //Free the resources
}
delay(10000);
}
void loop() {
}Reading the persistent file from SPIFFS
#include "SPIFFS.h"
void setup() {
Serial.begin(115200);
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
File file2 = SPIFFS.open("/hello.txt");
if(!file2){
Serial.println("Failed to open file for reading");
return;
}
Serial.println("File Content:");
while(file2.available()){
Serial.write(file2.read());
}
file2.close();
}
void loop() {}Programming on ESP32 using uPyCraft IDE
Flashing Micropython firmware on ESP32
- Download the latest firmware (standard firmware) .bin file from here.
- Install esptool.py from source or
pip3 install esptool. Make sure that esptool.py is in PATH - Erase the flash memory using esptool.py using command
esptool.py βchip esp32 erase_flash - Flash the downloaded firmware using command
esptool.py --chip esp32 --port/dev/ttyUSB0write_flash -z 0x1000esp32-20190904-v1.11-274-g06661890d.bin
Set up Micropython Development Environment
- Download uPyCraft IDE from GitHub according to OS.
- On Linux you need to
chmod +x uPyCraft_linux_V1.0and then./uPyCraft_linux_V1.0to execute the IDE. - Select the correct port from Tools β Serial
- Learn and explore uPyCraft IDE
Debugging
pyserialmodule for MicropythonDiscussion: https://forum.micropython.org/viewtopic.php?t=2408 Implementation: https://github.com/dhylands/bioloid3/blob/master/stm_uart_port.py [Pyboard not ESP32]
Developing on ESP32 using Micropython
Connect to a WiFi network
def wlan_connect(ssid='MYSSID', password='MYPASS'):
import network
wlan = network.WLAN(network.STA_IF)
if not wlan.active() or not wlan.isconnected():
wlan.active(True)
print('connecting to:', ssid)
wlan.connect(ssid, password)
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
wlan_connect("ro.d", "fo45#cuu")ESP32 recieves through UART and immediately sends it again through UART
import urequests
from machine import UART
from machine import Pin
from time import sleep
def init_uart():
uart = UART(2)
uart.init(2400)
print(uart)
return uart
def uart_loopback(uart):
foo = uart.read()
uart.write(str(foo))
uart = init_uart()
while(True):
uart_loopback()
led.value(not led.value())
sleep(0.5)Downloading a file from a web server and storing it in the flash memory
REMEMBER: urequests is the micropython library for making http requests
import urequests
def wlan_connect(ssid='MYSSID', password='MYPASS'):
import network
wlan = network.WLAN(network.STA_IF)
if not wlan.active() or not wlan.isconnected():
wlan.active(True)
print('connecting to:', ssid)
wlan.connect(ssid, password)
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
def downloadMyFile():
wlan_connect("ro.d", "fo45#cuu")
path = '/final.bin'
# url = 'http://jsonplaceholder.typicode.com/todos/1'
url = 'http://esp32.surge.sh/final.bin'
response = urequests.get(url)
# print(response.content)
f = open(path, 'wb')
f.write(response.content)
f.close()
downloadMyFile()ESP32 flashes .bin file through UART
from machine import UART
def writeMemory(addr, data, lng):
print("writeMemory: Writing to memory through offset")
offs = 0
while lng > 256:
cmdWriteMemory(addr, data[offs:offs+256])
offs = offs + 256
addr = addr + 256
lng = lng - 256
cmdWriteMemory(addr, data[offs:offs+lng] + ([0xFF] * (256-lng)), lng)
def cmdGeneric(cmd):
print("cmdGeneric: Generic Flash command")
sp.write(chr(cmd))
sp.write(chr(cmd ^ 0xFF)) # Control byte
return _wait_for_ask(hex(cmd))
def cmdWriteMemory(addr, data, lengthOriginal):
print("cmdWriteMemory: Driver for writing to memory")
assert(lengthOriginal <= 1024) # changed this from 256
if cmdGeneric(0x31):
sp.write(_encode_addr(addr))
_wait_for_ask("0x31 address failed")
#map(lambda c: hex(ord(c)), data)
lng = (lengthOriginal-1) & 0xFF
sp.write(chr(lng)) # len really
crc = 0xFF
for c in data:
crc = crc ^ c
sp.write(chr(c))
sp.write(chr(crc))
_wait_for_ask("0x31 programming failed")
else:
print("Write memory (0x31) failed")
def _wait_for_ask(info = ""):
print("Waiting")
# wait for ask
try:
ask = ord(sp.read())
except:
if ask == 0x79:
# ACK
return 1
def init_uart():
uart = UART(2)
uart.init(115200)
print(uart)
return uart
def uart_loopback(uart):
foo = uart.read()
uart.write(str(foo))
def loadData():
f = open('final.bin', 'rb')
# rawData = f.read()
# data = map(lambda c: c, rawData)
data = [c for c in f.readline()]
f.close()
return data
sp = init_uart()
dataMap = loadData()
mapLength = len(dataMap)
writeMemory(0x08000000, dataMap, mapLength)
