CircuitPython 7.2.0 was
released. With espressif ESP32-S3 and ESP32-C3 supported (considered alpha and will
have bugs and missing functionality).
To flash firmware on esp32s3, esptool v3.2 is needed. This post
show the steps to flash CircuitPython 7.2.0 on
ESP32-S3-DevKitC-1 N8R8
(with 8MB Flash and 8MB PSRAM) run on Linux Mint (over VirtualBox/Windows
10).
Visit
CircuitPython download page, search "S3" and download .BIN for "ESP32-S3-DevKitC-1-N8R8 by
Espressif".
Connect USB to the port marked "UART".
To
check the ESP chip ID and Flash using commands: $ esptool.py --chip auto
--port /dev/ttyUSB0 chip_id $ esptool.py --chip auto --port /dev/ttyUSB0
flash_id
To program using
CircuitPython, re-connect USB to the port marked "USB".
cpyESP32S3_info.py
"""
CircuitPython 7.2.0 exercise run on ESP32-S3,
get system info.
"""
import board
import sys
import os
"""
ref:
The entire table of ANSI color codes working in C:
https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a
"""
class color:
RED = '\033[1;31;48m'
BLUE = '\033[1;34;48m'
BLACK = '\033[1;30;48m'
END = '\033[1;37;0m'
print(board.board_id)
print(sys.implementation[0] + ' ' +
str(sys.implementation[1][0]) +'.'+
str(sys.implementation[1][1]) +'.'+
str(sys.implementation[1][2]))
print("==========================================")
info = color.RED + \
sys.implementation[0] + ' ' + \
os.uname()[3] + color.END + '\n' + \
'run on ' + color.BLUE + os.uname()[4] + color.END
print(info)
print("==========================================")
print()
cpyESP32S3_NEOPIXEL.py, control onboard RGB LED.
import time
import os
import microcontroller
import neopixel
import board
def cycleNeopixel(wait):
for r in range(255):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for r in range(255, 0, -1):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for g in range(255):
pixel[0] = (0, g, 0)
time.sleep(wait)
for g in range(255, 0, -1):
pixel[0] = (0, g, 0)
time.sleep(wait)
for b in range(255):
pixel[0] = (0, 0, b)
time.sleep(wait)
for b in range(255, 0, -1):
pixel[0] = (0, 0, b)
time.sleep(wait)
print("==============================")
print("Hello ESP32-C3/CircuitPython NeoPixel exercise")
#print(os.uname())
for u in os.uname():
print(u)
print()
print("neopixel version: " + neopixel.__version__)
print()
# Create the NeoPixel object
pixel = neopixel.NeoPixel(board.NEOPIXEL,
1,
pixel_order=neopixel.GRB)
pixel[0] = (0, 0, 0)
time.sleep(2.0)
cycleNeopixel(0.01)
pixel[0] = (0, 0, 0)
time.sleep(2.0)
print("- bye -\n")
Related: ~ To flash ESP32-S3, esptool v3.2 or above is needed. With esptool upgraded, we can now flash ESP32-S3 on Rspberry Pi.
CircuitPython 7.2.0 was released. With espressif ESP32-S3 and ESP32-C3 supported (considered alpha and will
have bugs and missing functionality).
This post show how to install CircuitPython 7.2.0 on
ESP32-C3-DevKitM-1 (ESP32-C3-MINI-1), using Raspberry Pi 4B running Raspberry Pi OS 32-bit (buster). Then test with
exercise to read system info, control onboard RGB (NEOPIXEL), and 0.96" 80x160
IPS.
I can't find exact board named "ESP32-C3-DevKitM-1", so
I try "ESP32-C3-DevKitC-1-N4 by Espressif". DOWNLOAD .BIN NOW under
CircuitPython 7.2.0, it's
adafruit-circuitpython-espressif_esp32c3_devkitm_1_n4-en_US-7.2.0.bin.
Identify USB port:
Before connect the board to USB. Run the command to clear
dmesg buffer - $ sudo dmesg -c
Connect the
ESP32-C3-DevKitM-1 board to USB. Run dmesg again, the connected port will
be shown - $ dmesg
With esptool installed, you can check the ESP chip ID and Flash
using commands: $
esptool.py --chip auto --port /dev/ttyUSB0 chip_id $
esptool.py --chip auto --port /dev/ttyUSB0 flash_id
"""
CircuitPython 7.2.0 exercise run on ESP32-C3,
get system info.
"""
import board
import sys
import os
"""
ref:
The entire table of ANSI color codes working in C:
https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a
"""
class color:
RED = '\033[1;31;48m'
BLUE = '\033[1;34;48m'
BLACK = '\033[1;30;48m'
END = '\033[1;37;0m'
print(board.board_id)
print(sys.implementation[0] + ' ' +
str(sys.implementation[1][0]) +'.'+
str(sys.implementation[1][1]) +'.'+
str(sys.implementation[1][2]))
print("==========================================")
info = color.RED + \
sys.implementation[0] + ' ' + \
os.uname()[3] + color.END + '\n' + \
'run on ' + color.BLUE + os.uname()[4] + color.END
print(info)
print("==========================================")
print()
cpyESP32C3_NEOPIXEL.py, control onboard RGB (Neopixel).
import time
import os
import microcontroller
import neopixel
import board
def cycleNeopixel(wait):
for r in range(255):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for r in range(255, 0, -1):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for g in range(255):
pixel[0] = (0, g, 0)
time.sleep(wait)
for g in range(255, 0, -1):
pixel[0] = (0, g, 0)
time.sleep(wait)
for b in range(255):
pixel[0] = (0, 0, b)
time.sleep(wait)
for b in range(255, 0, -1):
pixel[0] = (0, 0, b)
time.sleep(wait)
print("==============================")
print("Hello ESP32-C3/CircuitPython NeoPixel exercise")
#print(os.uname())
for u in os.uname():
print(u)
print()
print("neopixel version: " + neopixel.__version__)
print()
# Create the NeoPixel object
pixel = neopixel.NeoPixel(board.NEOPIXEL,
1,
pixel_order=neopixel.RGB)
pixel[0] = (0, 0, 0)
time.sleep(2.0)
cycleNeopixel(0.01)
pixel[0] = (0, 0, 0)
time.sleep(2.0)
print("- bye -\n")
cpyESP32C3_st7735_80x160.py, test with 0.96" 80x160 IPS.
"""
CircuitPython 7.2.0 exercise run on ESP32-C3
with unknown brand 0.96 inch 80x160 SPI ST7735 IPS
ref:
adafruit/Adafruit_CircuitPython_ST7735R
https://github.com/adafruit/Adafruit_CircuitPython_ST7735R
"""
from sys import implementation as sysImplementation
import time
import board
import busio
import displayio
import terminalio
from adafruit_st7735r import ST7735R as TFT_ST7735
from adafruit_st7735r import __name__ as ST7735_NAME
from adafruit_st7735r import __version__ as ST7735_VERSION
from adafruit_display_text import label
# Release any resources currently in use for the displays
displayio.release_displays()
#Connection between ESP32-C3 and SPI ST7735 display
#marking on display
tft_sck = board.IO2 #SCL
tft_mosi = board.IO3 #SDA
tft_reset = board.IO0 #RES
tft_dc = board.IO1 #DC
tft_cs = board.IO10 #CS
#Backlight (BLK) connect to ESP32-C3 3V3
#TFT VCC - ESP32-C31 3V3
#TFT GND - ESP32-C3 GND
tft_spi = busio.SPI(clock=tft_sck, MOSI=tft_mosi)
display_bus = displayio.FourWire(
tft_spi, command=tft_dc, chip_select=tft_cs, reset=tft_reset
)
# I find out colrstart/rowstart by try/error and retry
display = TFT_ST7735(display_bus, width=160, height=80,
colstart=26, rowstart=1,
rotation=90,
invert=True
)
print(type(display))
print("display.width: ", display.width)
print("display.height: ", display.height)
# Make the display context
splash = displayio.Group()
display.show(splash)
color_bitmap = displayio.Bitmap(display.width, display.height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x000000
time.sleep(1)
bg_sprite = displayio.TileGrid(color_bitmap,
pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
for c in [["RED", 0xFF0000],
["GREEN", 0x00FF00],
["BLUE", 0x0000FF]]:
print(c[0], " : ", hex(c[1]))
color_palette[0] = c[1]
time.sleep(2)
splash.remove(bg_sprite)
#---
# Make the display context
#splash = displayio.Group()
#display.show(splash)
color_bitmap = displayio.Bitmap(display.width, display.height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00
bg_sprite = displayio.TileGrid(color_bitmap,
pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(display.width-2, display.height-2, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
pixel_shader=inner_palette, x=1, y=1)
splash.append(inner_sprite)
# Draw a label
text_group1 = displayio.Group(scale=1, x=5, y=10)
text1 = "ESP32-C3"
text_area1 = label.Label(terminalio.FONT, text=text1, color=0xFF0000)
text_group1.append(text_area1) # Subgroup for text scaling
# Draw a label
strSys = sysImplementation[0] + ' ' + \
str(sysImplementation[1][0]) +'.'+ \
str(sysImplementation[1][1]) +'.'+ \
str(sysImplementation[1][2])
text_group2 = displayio.Group(scale=1, x=5, y=25)
text2 = strSys
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2) # Subgroup for text scaling
# Draw a label
text_group3 = displayio.Group(scale=1, x=5, y=40)
text3 = ST7735_NAME
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x0000000)
text_group3.append(text_area3) # Subgroup for text scaling
# Draw a label
text_group4 = displayio.Group(scale=1, x=5, y=55)
text4 = ST7735_VERSION
text_area4 = label.Label(terminalio.FONT, text=text4, color=0x000000)
text_group4.append(text_area4) # Subgroup for text scaling
text_group5 = displayio.Group(scale=1, x=5, y=70)
text5 = str(display.width) + " x " + str(display.height)
text_area5 = label.Label(terminalio.FONT, text=text5, color=0x000000)
text_group5.append(text_area5) # Subgroup for text scaling
splash.append(text_group1)
splash.append(text_group2)
splash.append(text_group3)
splash.append(text_group4)
splash.append(text_group5)
time.sleep(3.0)
rot = 90
while True:
time.sleep(5.0)
rot = rot + 90
if (rot>=360):
rot = 0
display.rotation = rot
Just received ESP-C3-12F. With "C3FN4" marked on the module shield,
that means it have Build-in 4MByte FLASH. ESP-C3-12F is a Wi-Fi module
developed by Ai-Thinker. This module core processor ESP32-C3 is a Wi-Fi+ BLE
combination of system-level chips (SoC).
In order to use the ESP-C3-12F, I solder it on a special multi-function PCB
for ESP-12F (or called "diymore ESP8266 ESP-12E ESP-12F ESP32 Double Side
Prototype PCB Board").
I also add buttons of RESET and BOOT connect EN and IO9 (same position of IO0
on ESP-12F), to force it entering BOOTLOADER mode for using with esptool.
It's strongly recommended using separate 3V3 Power Supply for
ESP-C3-12F. A USB to Serial Breakout (FT232RL) in 3V3 operation mode is used
to connect to ESP-C3-12F.
In my practice, the connection is:
USB-to-Serial (FT232RL)ESP-C3-12F
(in 3V3 mode)
RXTX0
TXRX0
GNDGND
RESET BUTTONEN/GND
BOOT BUTTONIO9/GND
Separate Power Supply
+3V3VCC
GNDGND
log of esptool output:
pi@raspberrypi:~ $ esptool.py --chip auto --port /dev/ttyUSB0 chip_id
esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting........_____....._
Detecting chip type... ESP32-C3
Chip is unknown ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 84:f7:03:a5:10:94
Uploading stub...
Running stub...
Stub running...
Warning: ESP32-C3 has no Chip ID. Reading MAC instead.
MAC: 84:f7:03:a5:10:94
Hard resetting via RTS pin...
pi@raspberrypi:~ $ esptool.py --chip auto --port /dev/ttyUSB0 flash_id
esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting...
Detecting chip type... ESP32-C3
Chip is unknown ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 84:f7:03:a5:10:94
Stub is already running. No upload is necessary.
Manufacturer: 20
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...
pi@raspberrypi:~ $
According to ESP-AT v2.2.0.0_esp32c3 User Guide, AT Command should be sent to UART1 (GPIO6/GPIO7). But in my test as shown in the video. Both esptool and AT Command are sent to UART0 (GPIO20/21).
Or, is it AI-Thinker firmware have different port usage?
It is aimed to flash MicroPython firmware on ESP32-C3-DevKitM-1
with unknown ESP32-C3 (revision 3) and 4MB flash. I can't find any official
installation instruction, it's found out by my guessing and trying. Not
sure is it correct approach, it seem work for me anyway.
Download MicroPython for ESP32-C3:
Visit https://micropython.org/download/all/, search "esp32c3" firmware for ESP32-C3, download the .bin file.
It's esp32c3usb-20211018-unstable-v1.17-84-gba940250a.bin I tried.
Identify port and chip/flash:
To identify the ESP32 device connected USB port, chip and flash, refer to
the last post.
It's unknown ESP32-C3 (revision 3) and 4MB flash
on ESP32-C3-DevKitM-1, connected to /dev/ttyUSB0.
"""
MicroPython/ESP32C3 exercise run on ESP32-C3-DevKitM-1,
to display info.
"""
import uos
import usys
import machine
import esp
print("from uos.uname():")
for u in uos.uname():
print(u)
print()
print("from usys:")
print("usys.platform: ", usys.platform)
print("usys.implementation: ", usys.implementation)
print()
print("====================================")
print(usys.implementation[0], uos.uname()[3],
"\nrun on", uos.uname()[4])
print("====================================")
print("Flash size:", esp.flash_size())
print("CPU frequency:", machine.freq(), "(Hz)")
mpyESP32C3_RGB.py
"""
MicroPython/ESP32C3 exercise run on ESP32-C3-DevKitM-1,
to control the onboard GB LED (WS2812), driven by GPIO8.
"""
import uos
import usys
import machine
import neopixel
import time
print("====================================")
print(usys.implementation[0], uos.uname()[3],
"\nrun on", uos.uname()[4])
print("====================================")
np = neopixel.NeoPixel(machine.Pin(8), 1)
np[0] = (0, 0, 0)
np.write()
time.sleep(1)
np[0] = (100, 100, 100)
np.write()
time.sleep(1)
np[0] = (0, 0, 0)
np.write()
time.sleep(1)
for i in range(256):
np[0] = (i, 0, 0)
np.write()
time.sleep_ms(10)
for i in range(256):
np[0] = (0, i, 0)
np.write()
time.sleep_ms(10)
for i in range(256):
np[0] = (0, 0, i)
np.write()
time.sleep_ms(10)
for i in range(256):
np[0] = (255-i, 255-i, 255-i)
np.write()
time.sleep_ms(10)
esptool.py is a Python-based, open source, platform independent, utility to communicate with the ROM bootloader in Espressif ESP8266 & ESP32 chips, and also ESP32-S2.
To install on Raspberry Pi (running 32 bit Raspberry Pi OS), open Terminal and enter the command:
$ sudo pip install esptool
or install Development mode, allows you to run the latest development version from this repository.