Browse Source
With contributions from Oliver Robson (@HowManyOliversAreThere), Sean Lanigan (@seanlano) and @rprr.pull/3464/head
Matt Trentini
6 years ago
committed by
Damien George
8 changed files with 710 additions and 7 deletions
@ -0,0 +1,63 @@ |
|||
.. _esp32_general: |
|||
|
|||
General information about the ESP32 port |
|||
======================================== |
|||
|
|||
The ESP32 is a popular WiFi and Bluetooth enabled System-on-Chip (SoC) by |
|||
Espressif Systems. |
|||
|
|||
Multitude of boards |
|||
------------------- |
|||
|
|||
There is a multitude of modules and boards from different sources which carry |
|||
the ESP32 chip. MicroPython tries to provide a generic port which would run on |
|||
as many boards/modules as possible, but there may be limitations. Espressif |
|||
development boards are taken as reference for the port (for example, testing is |
|||
performed on them). For any board you are using please make sure you have a |
|||
datasheet, schematics and other reference materials so you can look up any |
|||
board-specific functions. |
|||
|
|||
To make a generic ESP32 port and support as many boards as possible the |
|||
following design and implementation decision were made: |
|||
|
|||
* GPIO pin numbering is based on ESP32 chip numbering. Please have the manual/pin |
|||
diagram of your board at hand to find correspondence between your board pins and |
|||
actual ESP32 pins. |
|||
* All pins are supported by MicroPython but not all are usable on any given board. |
|||
For example pins that are connected to external SPI flash should not be used, |
|||
and a board may only expose a certain selection of pins. |
|||
|
|||
|
|||
Technical specifications and SoC datasheets |
|||
------------------------------------------- |
|||
|
|||
The datasheets and other reference material for ESP32 chip are available |
|||
from the vendor site: https://www.espressif.com/en/support/download/documents?keys=esp32 . |
|||
They are the primary reference for the chip technical specifications, capabilities, |
|||
operating modes, internal functioning, etc. |
|||
|
|||
For your convenience, some of technical specifications are provided below: |
|||
|
|||
* Architecture: Xtensa Dual-Core 32-bit LX6 |
|||
* CPU frequency: up to 240MHz |
|||
* Total RAM available: 528KB (part of it reserved for system) |
|||
* BootROM: 448KB |
|||
* Internal FlashROM: none |
|||
* External FlashROM: code and data, via SPI Flash; usual size 4MB |
|||
* GPIO: 34 (GPIOs are multiplexed with other functions, including |
|||
external FlashROM, UART, etc.) |
|||
* UART: 3 RX/TX UART (no hardware handshaking), one TX-only UART |
|||
* SPI: 4 SPI interfaces (one used for FlashROM) |
|||
* I2C: 2 I2C (bitbang implementation available on any pins) |
|||
* I2S: 2 |
|||
* ADC: 12-bit SAR ADC up to 18 channels |
|||
* DAC: 2 8-bit DACs |
|||
* Programming: using BootROM bootloader from UART - due to external FlashROM |
|||
and always-available BootROM bootloader, the ESP32 is not brickable |
|||
|
|||
For more information see the ESP32 datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf |
|||
|
|||
MicroPython is implemented on top of the ESP-IDF, Espressif's development |
|||
framework for the ESP32. This is a FreeRTOS based system. See the |
|||
`ESP-IDF Programming Guide <https://docs.espressif.com/projects/esp-idf/en/latest/index.html>`_ |
|||
for details. |
After Width: | Height: | Size: 84 KiB |
@ -0,0 +1,478 @@ |
|||
.. _esp32_quickref: |
|||
|
|||
Quick reference for the ESP32 |
|||
============================= |
|||
|
|||
.. image:: img/esp32.jpg |
|||
:alt: ESP32 board |
|||
:width: 640px |
|||
|
|||
The Espressif ESP32 Development Board (image attribution: Adafruit). |
|||
|
|||
Below is a quick reference for ESP32-based boards. If it is your first time |
|||
working with this board it may be useful to get an overview of the microcontroller: |
|||
|
|||
.. toctree:: |
|||
:maxdepth: 1 |
|||
|
|||
general.rst |
|||
tutorial/intro.rst |
|||
|
|||
Installing MicroPython |
|||
---------------------- |
|||
|
|||
See the corresponding section of tutorial: :ref:`esp32_intro`. It also includes |
|||
a troubleshooting subsection. |
|||
|
|||
General board control |
|||
--------------------- |
|||
|
|||
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200. |
|||
Tab-completion is useful to find out what methods an object has. |
|||
Paste mode (ctrl-E) is useful to paste a large slab of Python code into |
|||
the REPL. |
|||
|
|||
The :mod:`machine` module:: |
|||
|
|||
import machine |
|||
|
|||
machine.freq() # get the current frequency of the CPU |
|||
machine.freq(240000000) # set the CPU frequency to 240 MHz |
|||
|
|||
The :mod:`esp` module:: |
|||
|
|||
import esp |
|||
|
|||
esp.osdebug(None) # turn off vendor O/S debugging messages |
|||
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0) |
|||
|
|||
# low level methods to interact with flash storage |
|||
esp.flash_size() |
|||
esp.flash_user_start() |
|||
esp.flash_erase(sector_no) |
|||
esp.flash_write(byte_offset, buffer) |
|||
esp.flash_read(byte_offset, buffer) |
|||
|
|||
The :mod:`esp32` module:: |
|||
|
|||
import esp32 |
|||
|
|||
esp32.hall_sensor() # read the internal hall sensor |
|||
esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit |
|||
esp32.ULP() # access to the Ultra-Low-Power Co-processor |
|||
|
|||
Note that the temperature sensor in the ESP32 will typically read higher than |
|||
ambient due to the IC getting warm while it runs. This effect can be minimised |
|||
by reading the temperature sensor immediately after waking up from sleep. |
|||
|
|||
Networking |
|||
---------- |
|||
|
|||
The :mod:`network` module:: |
|||
|
|||
import network |
|||
|
|||
wlan = network.WLAN(network.STA_IF) # create station interface |
|||
wlan.active(True) # activate the interface |
|||
wlan.scan() # scan for access points |
|||
wlan.isconnected() # check if the station is connected to an AP |
|||
wlan.connect('essid', 'password') # connect to an AP |
|||
wlan.config('mac') # get the interface's MAC adddress |
|||
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses |
|||
|
|||
ap = network.WLAN(network.AP_IF) # create access-point interface |
|||
ap.config(essid='ESP-AP') # set the ESSID of the access point |
|||
ap.active(True) # activate the interface |
|||
|
|||
A useful function for connecting to your local WiFi network is:: |
|||
|
|||
def do_connect(): |
|||
import network |
|||
wlan = network.WLAN(network.STA_IF) |
|||
wlan.active(True) |
|||
if not wlan.isconnected(): |
|||
print('connecting to network...') |
|||
wlan.connect('essid', 'password') |
|||
while not wlan.isconnected(): |
|||
pass |
|||
print('network config:', wlan.ifconfig()) |
|||
|
|||
Once the network is established the :mod:`socket <usocket>` module can be used |
|||
to create and use TCP/UDP sockets as usual, and the ``urequests`` module for |
|||
convenient HTTP requests. |
|||
|
|||
Delay and timing |
|||
---------------- |
|||
|
|||
Use the :mod:`time <utime>` module:: |
|||
|
|||
import time |
|||
|
|||
time.sleep(1) # sleep for 1 second |
|||
time.sleep_ms(500) # sleep for 500 milliseconds |
|||
time.sleep_us(10) # sleep for 10 microseconds |
|||
start = time.ticks_ms() # get millisecond counter |
|||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference |
|||
|
|||
Timers |
|||
------ |
|||
|
|||
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class |
|||
with timer ID of -1:: |
|||
|
|||
from machine import Timer |
|||
|
|||
tim = Timer(-1) |
|||
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1)) |
|||
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2)) |
|||
|
|||
The period is in milliseconds. |
|||
|
|||
Pins and GPIO |
|||
------------- |
|||
|
|||
Use the :ref:`machine.Pin <machine.Pin>` class:: |
|||
|
|||
from machine import Pin |
|||
|
|||
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0 |
|||
p0.on() # set pin to "on" (high) level |
|||
p0.off() # set pin to "off" (low) level |
|||
p0.value(1) # set pin to on/high |
|||
|
|||
p2 = Pin(2, Pin.IN) # create input pin on GPIO2 |
|||
print(p2.value()) # get value, 0 or 1 |
|||
|
|||
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor |
|||
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation |
|||
|
|||
Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39. |
|||
These correspond to the actual GPIO pin numbers of ESP32 chip. Note that many |
|||
end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). |
|||
For mapping between board logical pins and physical chip pins consult your board |
|||
documentation. |
|||
|
|||
Notes: |
|||
|
|||
* Pins 1 and 3 are REPL UART TX and RX respectively |
|||
|
|||
* Pins 6, 7, 8, 11, 16, and 17 are used for connecting the embedded flash, |
|||
and are not recommended for other uses |
|||
|
|||
* Pins 34-39 are input only, and also do not have internal pull-up resistors |
|||
|
|||
PWM (pulse width modulation) |
|||
---------------------------- |
|||
|
|||
PWM can be enabled on all output-enabled pins. The base frequency can |
|||
range from 1Hz to 40MHz but there is a tradeoff; as the base frequency |
|||
*increases* the duty resolution *decreases*. See |
|||
`LED Control <https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html>`_ |
|||
for more details. |
|||
|
|||
Use the ``machine.PWM`` class:: |
|||
|
|||
from machine import Pin, PWM |
|||
|
|||
pwm0 = PWM(Pin(0)) # create PWM object from a pin |
|||
pwm0.freq() # get current frequency |
|||
pwm0.freq(1000) # set frequency |
|||
pwm0.duty() # get current duty cycle |
|||
pwm0.duty(200) # set duty cycle |
|||
pwm0.deinit() # turn off PWM on the pin |
|||
|
|||
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go |
|||
|
|||
ADC (analog to digital conversion) |
|||
---------------------------------- |
|||
|
|||
On the ESP32 ADC functionality is available on Pins 32-39. Note that, when |
|||
using the default configuration, input voltages on the ADC pin must be between |
|||
0.0v and 1.0v (anything above 1.0v will just read as 4095). Attenuation must |
|||
be applied in order to increase this usable voltage range. |
|||
|
|||
Use the :ref:`machine.ADC <machine.ADC>` class:: |
|||
|
|||
from machine import ADC |
|||
|
|||
adc = ADC(Pin(32)) # create ADC object on ADC pin |
|||
adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v |
|||
|
|||
adc.atten(ADC.ATTN_11DB) # set 11dB input attentuation (voltage range roughly 0.0v - 3.6v) |
|||
adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511) |
|||
adc.read() # read value using the newly configured attenuation and width |
|||
|
|||
ESP32 specific ADC class method reference: |
|||
|
|||
.. method:: ADC.atten(attenuation) |
|||
|
|||
This method allows for the setting of the amount of attenuation on the |
|||
input of the ADC. This allows for a wider possible input voltage range, |
|||
at the cost of accuracy (the same number of bits now represents a wider |
|||
range). The possible attenuation options are: |
|||
|
|||
- ``ADC.ATTN_0DB``: 0dB attenuation, gives a maximum input voltage |
|||
of 1.00v - this is the default configuration |
|||
- ``ADC.ATTN_2_5DB``: 2.5dB attenuation, gives a maximum input voltage |
|||
of approximately 1.34v |
|||
- ``ADC.ATTN_6DB``: 6dB attenuation, gives a maximum input voltage |
|||
of approximately 2.00v |
|||
- ``ADC.ATTN_11DB``: 11dB attenuation, gives a maximum input voltage |
|||
of approximately 3.6v |
|||
|
|||
.. Warning:: |
|||
Despite 11dB attenuation allowing for up to a 3.6v range, note that the |
|||
absolute maximum voltage rating for the input pins is 3.6v, and so going |
|||
near this boundary may be damaging to the IC! |
|||
|
|||
.. method:: ADC.width(width) |
|||
|
|||
This method allows for the setting of the number of bits to be utilised |
|||
and returned during ADC reads. Possible width options are: |
|||
|
|||
- ``ADC.WIDTH_9BIT``: 9 bit data |
|||
- ``ADC.WIDTH_10BIT``: 10 bit data |
|||
- ``ADC.WIDTH_11BIT``: 11 bit data |
|||
- ``ADC.WIDTH_12BIT``: 12 bit data - this is the default configuration |
|||
|
|||
Software SPI bus |
|||
---------------- |
|||
|
|||
There are two SPI drivers. One is implemented in software (bit-banging) |
|||
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>` |
|||
class:: |
|||
|
|||
from machine import Pin, SPI |
|||
|
|||
# construct an SPI bus on the given pins |
|||
# polarity is the idle state of SCK |
|||
# phase=0 means sample on the first edge of SCK, phase=1 means the second |
|||
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) |
|||
|
|||
spi.init(baudrate=200000) # set the baudrate |
|||
|
|||
spi.read(10) # read 10 bytes on MISO |
|||
spi.read(10, 0xff) # read 10 bytes while outputing 0xff on MOSI |
|||
|
|||
buf = bytearray(50) # create a buffer |
|||
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) |
|||
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI |
|||
|
|||
spi.write(b'12345') # write 5 bytes on MOSI |
|||
|
|||
buf = bytearray(4) # create a buffer |
|||
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer |
|||
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf |
|||
|
|||
.. Warning:: |
|||
Currently *all* of ``sck``, ``mosi`` and ``miso`` *must* be specified when |
|||
initialising Software SPI. |
|||
|
|||
Hardware SPI bus |
|||
---------------- |
|||
|
|||
There are two hardware SPI channels that allow faster (up to 80Mhz) |
|||
transmission rates, but are only supported on a subset of pins. |
|||
|
|||
===== =========== ============ |
|||
\ HSPI (id=1) VSPI (id=2) |
|||
===== =========== ============ |
|||
sck 14 18 |
|||
mosi 13 23 |
|||
miso 12 19 |
|||
===== =========== ============ |
|||
|
|||
Hardware SPI has the same methods as Software SPI above:: |
|||
|
|||
from machine import Pin, SPI |
|||
|
|||
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) |
|||
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19)) |
|||
|
|||
|
|||
I2C bus |
|||
------- |
|||
|
|||
The I2C driver is implemented in software and works on all pins, |
|||
and is accessed via the :ref:`machine.I2C <machine.I2C>` class:: |
|||
|
|||
from machine import Pin, I2C |
|||
|
|||
# construct an I2C bus |
|||
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) |
|||
|
|||
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a |
|||
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a |
|||
|
|||
buf = bytearray(10) # create a buffer with 10 bytes |
|||
i2c.writeto(0x3a, buf) # write the given buffer to the slave |
|||
|
|||
Real time clock (RTC) |
|||
--------------------- |
|||
|
|||
See :ref:`machine.RTC <machine.RTC>` :: |
|||
|
|||
from machine import RTC |
|||
|
|||
rtc = RTC() |
|||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time |
|||
rtc.datetime() # get date and time |
|||
|
|||
Deep-sleep mode |
|||
--------------- |
|||
|
|||
The following code can be used to sleep, wake and check the reset cause:: |
|||
|
|||
import machine |
|||
|
|||
# check if the device woke from a deep sleep |
|||
if machine.reset_cause() == machine.DEEPSLEEP_RESET: |
|||
print('woke from a deep sleep') |
|||
|
|||
# put the device to sleep for 10 seconds |
|||
machine.deepsleep(10000) |
|||
|
|||
Notes: |
|||
|
|||
* Calling ``deepsleep()`` without an argument will put the device to sleep |
|||
indefinitely |
|||
* A software reset does not change the reset cause |
|||
|
|||
OneWire driver |
|||
-------------- |
|||
|
|||
The OneWire driver is implemented in software and works on all pins:: |
|||
|
|||
from machine import Pin |
|||
import onewire |
|||
|
|||
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 |
|||
ow.scan() # return a list of devices on the bus |
|||
ow.reset() # reset the bus |
|||
ow.readbyte() # read a byte |
|||
ow.writebyte(0x12) # write a byte on the bus |
|||
ow.write('123') # write bytes on the bus |
|||
ow.select_rom(b'12345678') # select a specific device by its ROM code |
|||
|
|||
There is a specific driver for DS18S20 and DS18B20 devices:: |
|||
|
|||
import time, ds18x20 |
|||
ds = ds18x20.DS18X20(ow) |
|||
roms = ds.scan() |
|||
ds.convert_temp() |
|||
time.sleep_ms(750) |
|||
for rom in roms: |
|||
print(ds.read_temp(rom)) |
|||
|
|||
Be sure to put a 4.7k pull-up resistor on the data line. Note that |
|||
the ``convert_temp()`` method must be called each time you want to |
|||
sample the temperature. |
|||
|
|||
NeoPixel driver |
|||
--------------- |
|||
|
|||
Use the ``neopixel`` module:: |
|||
|
|||
from machine import Pin |
|||
from neopixel import NeoPixel |
|||
|
|||
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels |
|||
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels |
|||
np[0] = (255, 255, 255) # set the first pixel to white |
|||
np.write() # write data to all pixels |
|||
r, g, b = np[0] # get first pixel colour |
|||
|
|||
For low-level driving of a NeoPixel:: |
|||
|
|||
import esp |
|||
esp.neopixel_write(pin, grb_buf, is800khz) |
|||
|
|||
.. Warning:: |
|||
By default ``NeoPixel`` is configured to control the more popular *800kHz* |
|||
units. It is possible to use alternative timing to control other (typically |
|||
400kHz) devices by passing ``timing=0`` when constructing the |
|||
``NeoPixel`` object. |
|||
|
|||
|
|||
Capacitive Touch |
|||
---------------- |
|||
|
|||
Use the ``TouchPad`` class in the ``machine`` module:: |
|||
|
|||
from machine import TouchPad, Pin |
|||
|
|||
t = TouchPad(Pin(14)) |
|||
t.read() # Returns a smaller number when touched |
|||
|
|||
``TouchPad.read`` returns a value relative to the capacitive variation. Small numbers (typically in |
|||
the *tens*) are common when a pin is touched, larger numbers (above *one thousand*) when |
|||
no touch is present. However the values are *relative* and can vary depending on the board |
|||
and surrounding composition so some calibration may be required. |
|||
|
|||
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13 |
|||
14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ``ValueError``. |
|||
|
|||
Note that TouchPads can be used to wake an ESP32 from sleep:: |
|||
|
|||
import machine |
|||
from machine import TouchPad, Pin |
|||
import esp32 |
|||
|
|||
t = TouchPad(Pin(14)) |
|||
t.config(500) # configure the threshold at which the pin is considered touched |
|||
esp32.wake_on_touch(True) |
|||
machine.sleep() # put the MCU to sleep until a touchpad is touched |
|||
|
|||
For more details on touchpads refer to `Espressif Touch Sensor |
|||
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/touch_pad.html>`_. |
|||
|
|||
|
|||
DHT driver |
|||
---------- |
|||
|
|||
The DHT driver is implemented in software and works on all pins:: |
|||
|
|||
import dht |
|||
import machine |
|||
|
|||
d = dht.DHT11(machine.Pin(4)) |
|||
d.measure() |
|||
d.temperature() # eg. 23 (°C) |
|||
d.humidity() # eg. 41 (% RH) |
|||
|
|||
d = dht.DHT22(machine.Pin(4)) |
|||
d.measure() |
|||
d.temperature() # eg. 23.6 (°C) |
|||
d.humidity() # eg. 41.3 (% RH) |
|||
|
|||
WebREPL (web browser interactive prompt) |
|||
---------------------------------------- |
|||
|
|||
WebREPL (REPL over WebSockets, accessible via a web browser) is an |
|||
experimental feature available in ESP32 port. Download web client |
|||
from https://github.com/micropython/webrepl (hosted version available |
|||
at http://micropython.org/webrepl), and configure it by executing:: |
|||
|
|||
import webrepl_setup |
|||
|
|||
and following on-screen instructions. After reboot, it will be available |
|||
for connection. If you disabled automatic start-up on boot, you may |
|||
run configured daemon on demand using:: |
|||
|
|||
import webrepl |
|||
webrepl.start() |
|||
|
|||
# or, start with a specific password |
|||
webrepl.start(password='mypass') |
|||
|
|||
The WebREPL daemon listens on all active interfaces, which can be STA or |
|||
AP. This allows you to connect to the ESP32 via a router (the STA |
|||
interface) or directly when connected to its access point. |
|||
|
|||
In addition to terminal/command prompt access, WebREPL also has provision |
|||
for file transfer (both upload and download). The web client has buttons for |
|||
the corresponding functions, or you can use the command-line client |
|||
``webrepl_cli.py`` from the repository above. |
|||
|
|||
See the MicroPython forum for other community-supported alternatives |
|||
to transfer files to an ESP32 board. |
@ -0,0 +1,139 @@ |
|||
.. _esp32_intro: |
|||
|
|||
Getting started with MicroPython on the ESP32 |
|||
============================================= |
|||
|
|||
Using MicroPython is a great way to get the most of your ESP32 board. And |
|||
vice versa, the ESP32 chip is a great platform for using MicroPython. This |
|||
tutorial will guide you through setting up MicroPython, getting a prompt, using |
|||
WebREPL, connecting to the network and communicating with the Internet, using |
|||
the hardware peripherals, and controlling some external components. |
|||
|
|||
Let's get started! |
|||
|
|||
Requirements |
|||
------------ |
|||
|
|||
The first thing you need is a board with an ESP32 chip. The MicroPython |
|||
software supports the ESP32 chip itself and any board should work. The main |
|||
characteristic of a board is how the GPIO pins are connected to the outside |
|||
world, and whether it includes a built-in USB-serial convertor to make the |
|||
UART available to your PC. |
|||
|
|||
Names of pins will be given in this tutorial using the chip names (eg GPIO2) |
|||
and it should be straightforward to find which pin this corresponds to on your |
|||
particular board. |
|||
|
|||
Powering the board |
|||
------------------ |
|||
|
|||
If your board has a USB connector on it then most likely it is powered through |
|||
this when connected to your PC. Otherwise you will need to power it directly. |
|||
Please refer to the documentation for your board for further details. |
|||
|
|||
Getting the firmware |
|||
-------------------- |
|||
|
|||
The first thing you need to do is download the most recent MicroPython firmware |
|||
.bin file to load onto your ESP32 device. You can download it from the |
|||
`MicroPython downloads page <https://micropython.org/download#esp32>`_. |
|||
From here, you have 3 main choices: |
|||
|
|||
* Stable firmware builds |
|||
* Daily firmware builds |
|||
* Daily firmware builds with SPIRAM support |
|||
|
|||
If you are just starting with MicroPython, the best bet is to go for the Stable |
|||
firmware builds. If you are an advanced, experienced MicroPython ESP32 user |
|||
who would like to follow development closely and help with testing new |
|||
features, there are daily builds. If your board has SPIRAM support you can |
|||
use either the standard firmware or the firmware with SPIRAM support, and in |
|||
the latter case you will have access to more RAM for Python objects. |
|||
|
|||
Deploying the firmware |
|||
---------------------- |
|||
|
|||
Once you have the MicroPython firmware you need to load it onto your ESP32 device. |
|||
There are two main steps to do this: first you need to put your device in |
|||
bootloader mode, and second you need to copy across the firmware. The exact |
|||
procedure for these steps is highly dependent on the particular board and you will |
|||
need to refer to its documentation for details. |
|||
|
|||
Fortunately, most boards have a USB connector, a USB-serial convertor, and the DTR |
|||
and RTS pins wired in a special way then deploying the firmware should be easy as |
|||
all steps can be done automatically. Boards that have such features |
|||
include the Adafruit Feather HUZZAH32, M5Stack, Wemos LOLIN32, and TinyPICO |
|||
boards, along with the Espressif DevKitC, PICO-KIT, WROVER-KIT dev-kits. |
|||
|
|||
For best results it is recommended to first erase the entire flash of your |
|||
device before putting on new MicroPython firmware. |
|||
|
|||
Currently we only support esptool.py to copy across the firmware. You can find |
|||
this tool here: `<https://github.com/espressif/esptool/>`__, or install it |
|||
using pip:: |
|||
|
|||
pip install esptool |
|||
|
|||
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer). |
|||
An older version (at least 1.2.1 is needed) works fine but will require Python |
|||
2.7. |
|||
|
|||
Using esptool.py you can erase the flash with the command:: |
|||
|
|||
esptool.py --port /dev/ttyUSB0 erase_flash |
|||
|
|||
And then deploy the new firmware using:: |
|||
|
|||
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20180511-v1.9.4.bin |
|||
|
|||
Notes: |
|||
|
|||
* You might need to change the "port" setting to something else relevant for your |
|||
PC |
|||
* You may need to reduce the baudrate if you get errors when flashing |
|||
(eg down to 115200 by adding ``--baud 115200`` into the command) |
|||
* For some boards with a particular FlashROM configuration you may need to |
|||
change the flash mode (eg by adding ``-fm dio`` into the command) |
|||
* The filename of the firmware should match the file that you have |
|||
|
|||
If the above commands run without error then MicroPython should be installed on |
|||
your board! |
|||
|
|||
Serial prompt |
|||
------------- |
|||
|
|||
Once you have the firmware on the device you can access the REPL (Python prompt) |
|||
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial |
|||
convertor, depending on your board. The baudrate is 115200. |
|||
|
|||
From here you can now follow the ESP8266 tutorial, because these two Espressif chips |
|||
are very similar when it comes to using MicroPython on them. The ESP8266 tutorial |
|||
is found at :ref:`esp8266_tutorial` (but skip the Introduction section). |
|||
|
|||
Troubleshooting installation problems |
|||
------------------------------------- |
|||
|
|||
If you experience problems during flashing or with running firmware immediately |
|||
after it, here are troubleshooting recommendations: |
|||
|
|||
* Be aware of and try to exclude hardware problems. There are 2 common |
|||
problems: bad power source quality, and worn-out/defective FlashROM. |
|||
Speaking of power source, not just raw amperage is important, but also low |
|||
ripple and noise/EMI in general. The most reliable and convenient power |
|||
source is a USB port. |
|||
|
|||
* The flashing instructions above use flashing speed of 460800 baud, which is |
|||
good compromise between speed and stability. However, depending on your |
|||
module/board, USB-UART convertor, cables, host OS, etc., the above baud |
|||
rate may be too high and lead to errors. Try a more common 115200 baud |
|||
rate instead in such cases. |
|||
|
|||
* To catch incorrect flash content (e.g. from a defective sector on a chip), |
|||
add ``--verify`` switch to the commands above. |
|||
|
|||
* If you still experience problems with flashing the firmware please |
|||
refer to esptool.py project page, https://github.com/espressif/esptool |
|||
for additional documentation and a bug tracker where you can report problems. |
|||
|
|||
* If you are able to flash the firmware but the ``--verify`` option returns |
|||
errors even after multiple retries the you may have a defective FlashROM chip. |
Loading…
Reference in new issue