My musings with ESP32

Posted on Sun, Aug 25, 2019 IoT

Technical Specifications

Official Repository: https://github.com/espressif/arduino-esp32

Know

Getting Started

  1. 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.
  2. 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.
  3. 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.
  4. 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-openjdk

PACKET_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

  1. Change the Board: Use ESP32 Dev Module instead of DOIT ESP32 DEVKIT V1
  2. 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

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

  1. Download the latest firmware (standard firmware) .bin file from here.
  2. Install esptool.py from source or pip3 install esptool. Make sure that esptool.py is in PATH
  3. Erase the flash memory using esptool.py using command esptool.py β€”chip esp32 erase_flash
  4. Flash the downloaded firmware using command esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20190904-v1.11-274-g06661890d.bin

Set up Micropython Development Environment

  1. Download uPyCraft IDE from GitHub according to OS.
  2. On Linux you need to chmod +x uPyCraft_linux_V1.0 and then ./uPyCraft_linux_V1.0 to execute the IDE.
  3. Select the correct port from Tools β†’ Serial
  4. Learn and explore uPyCraft IDE

Debugging

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)