MicroPython on ESP32: Tools – esptool.py

 Python  Comments Off on MicroPython on ESP32: Tools – esptool.py
Sep 262017
 

These are my notes on using some MicroPython specific tools in relation to a ESP32-DevKitC board.

These notes are for v2.1 of the esptool; an ESP8266 and ESP32 serial bootloader utility.

esptool has a number of functions, but I will only speak to those features required to identify the chip, get flash information and load the MicroPython firmware. See the docs for more information.

Installing esptool

(myproject) $ pip install esptool

Confirm install

(myproject) $ esptool.py version

Display chip information (chip_id)

(myproject) $ esptool.py -p /dev/ttyUSB0 chip_id
esptool.py v2.1
Connecting......
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
Chip ID: 0x7240ac40964
Hard resetting...

Display Flash memory information (flash_id)

(myproject) $ esptool.py -p /dev/ttyUSB0 flash_id
esptool.py v2.1
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting...

Display MAC address of wifi adapter (read_mac)

(myproject) $ esptool.py -p /dev/ttyUSB0 read_mac
esptool.py v2.1
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
MAC: 24:0a:c4:09:64:c8
Hard resetting...

Loading MicroPython Firmware
You will need MicroPython firmware http://micropython.org/download#esp32
I download to a directory named images in my project folder. Since the ESP32 code is under development, I check out the GitHub commit page for the chip for any interesting new bits.

When loading to a board that does not already have MicroPython loaded, you should erase the entire flash before flashing the MicroPython firmware.

(myproject) $ esptool.py -p /dev/ttyUSB0 erase_flash
esptool.py v2.1
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 5.0s
Hard resetting...

Now load the firmware with the write_flash command
The general form is:


esptool.py write_flash -p <port> -z <address> <filename>
  -p                    specify the port
  <port>                the port to use  i.e. /dev/ttyUSB0
  -z   			Compress data in transfer (default unless --no-stub is
                        specified)
  <address> <filename>  Address followed by binary filename, separated by
                        space
(myproject) $ esptool.py -p /dev/ttyUSB0 write_flash -z 0x1000 images/esp32-20170916-v1.9.2-272-g0d183d7f.bin
esptool.py v2.1
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 902704 bytes to 566927...
Wrote 902704 bytes (566927 compressed) at 0x00001000 in 50.0 seconds (effective 144.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...

Verify the firmware loaded correctly

(myproject) $ miniterm.py --raw /dev/ttyUSB0 115200
--- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

>>>

Now do a hard reset using the reset button on the board

>>> ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371 
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0010,len:4
load:0x3fff0014,len:4268
load:0x40078000,len:0
load:0x40078000,len:10648
entry 0x4007a56c
I (982) cpu_start: Pro cpu up.
I (983) cpu_start: Single core mode
I (984) heap_init: Initializing. RAM available for dynamic allocation:
I (994) heap_init: At 3FFAE2A0 len 00001D60 (7 KiB): DRAM
I (1013) heap_init: At 3FFD4158 len 0000BEA8 (47 KiB): DRAM
I (1032) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (1052) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1072) heap_init: At 4008F3A8 len 00010C58 (67 KiB): IRAM
I (1091) cpu_start: Pro cpu start user code
I (1152) cpu_start: Starting scheduler on PRO CPU.
OSError: [Errno 2] ENOENT
MicroPython v1.9.2-272-g0d183d7f on 2017-09-16; ESP32 module with ESP32
Type "help()" for more information.
>>> 

You should verify that the firmware specified in the banner after the reset matches that firmware that you just loaded. In this case, v1.9.2-272-g0d183d7f

May the Zen of Python be with you.

 Posted by at 10:08 pm

MicroPython on ESP32: Tools – virtual environments vs system installs

 Python  Comments Off on MicroPython on ESP32: Tools – virtual environments vs system installs
Sep 232017
 

These are my notes on using some MicroPython specific tools in relation to a ESP32-DevKitC board.

There are many tutorials and youtube videos that constantly encourage users to install tools and packages into their system-level libraries. (If you need to use sudo when you pip install foo, you are installing it as a system level library.) Please, Please, Please take the time to learn the basics of virtual environment. If you are a developer/hacker/maker – save yourself lots of frustration by using virtual environments.

A virtual environment is an isolated Python environment it contains all the necessary executables to use the packages that a Python project would need. It allows you use the desired version of a specific library and isolates that library from other virtual environments and the system and user level libraries. It allows you to easily define what packages are required to reproduce your work.

A short primer based on Python3.

To Create and setup a Python3 virtualenv

# nav to where you want to create your project then ...
$ python3 -m venv your-project-name
$ cd your-project-name
$ source bin/activate
(your-project-name) $ pip install --upgrade pip

Now just use pip and skip the sudo and kludging up your system level install.

To Deactivate a virtual environment

(your-project-name) $ deactivate
$

to activate an existing virtual environment

$ source bin/activate
(your-project-name) $

Mandatory link to the documentation.

Now you can list the packages you have installed for THIS project with pip:

(your-project-name) $ pip freeze
pkg-resources==0.0.0

(your-project-name) $ pip list
pip (9.0.1)
pkg-resources (0.0.0)
setuptools (20.7.0)

May the Zen of Python be with you.

 Posted by at 6:52 pm

Hello World on a naked ESP32-DevKitC Board using MicroPython

 Python  Comments Off on Hello World on a naked ESP32-DevKitC Board using MicroPython
Sep 172017
 

Every now and again, I get the bug to build something. Lately, I’ve been following MicroPython and the microcontrollers that it supports. The new hotness is the Expressif ESP32 chip. These are available from a number of different sources, many supplying a breakout board. Prices are all over the place from 20+ to 8+ depending on where you shop and how patient you are.

I went with the dev board from Expressif. I got a pair of them for about 15 each from Amazon. I like the trade off of delivery time, supplier and cost. You can see and order it here: 2 PACK Espressif ESP32 ESP32-DEVKITC inc ESP-WROOM-32 soldered dils CE FCC Rev 1 Silicon

$ esptool.py  -p /dev/ttyUSB0 flash_id
esptool.py v2.1
Connecting.....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub...
Running stub...
Stub running...
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting...

With just a bit of searching, you’ll find that you need the latest Micropython for ESP32 and the esptool.py

pip install esptool

. Then after you connect your Board to your computer, you can load up the MicroPython firmware.

esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 images/esp32-20170916-v1.9.2-272-g0d183d7f.bin

Now in the world of microcontrollers, blinking an LED is the “Hello World” program. However, the boards I purchased only had an LED that lit if the board was receiving power. No other LEDs on the board connected to a GPIO pin like some other breakout boards. It does have 2 switches, one of which, Switch 1(SW1) is connected to the GPIO0 pin.
ESP32 In the image, SW1 is the button on the top right, labeled boot.

So I write some code to figure out the initial state of GPIO and then toggle the button a couple times.

"""sw1_1.py - look at initial state of GPIO0 and then record it toggling"""
from machine import Pin


def main():
    # setup
    sw1p0 = Pin(0, Pin.IN)  # switch sw1 connected to logical Pin0
    state_changes = 0       # loop control
    prior_value = sw1p0.value() # sw1p0 previous state, initially unknown
    print("sw1p0 initial value is %s" % prior_value) # report initial state

    # main loop
    while state_changes < 4:    # press, release, press, release
        new_value = sw1p0.value()   # cache value, as inputs can change
        if new_value != prior_value:    # has state changed?
            print('sw1p0 was %s is now %s' % (prior_value, new_value))
            prior_value = new_value # update prior_value for next loop
            state_changes += 1


if __name__ == '__main__':
    main()

I did sort some of this out using the serial REPL, but for this post, I wrote up a script to demonstrate my findings.

Using the adafruit ampy tool, we’ll run the code.

pip install adafruit-ampy

Note: you will need to press sw1 twice before you see anything after the ampy cmd.

$ ampy -p /dev/ttyUSB0 run sw1_1.py 
sw1p0 initial value is 1
sw1p0 was 1 is now 0
sw1p0 was 0 is now 1
sw1p0 was 1 is now 0
sw1p0 was 0 is now 1

As you can see from the results, the initial state of GPIO0 was high(or 1). When sw1 is pressed/closed it goes low(0) and goes back high(1) when it is released/open. If you look at the board schematic, in the Switch Button section, you’ll see that when sw1 is closed, it shorts out GPIO0 to ground. This would indicate that you were pulling it low from a high state. So our observations match the schematic.

If you look at the schematic, you will see a capacitor from R3 to Ground that is used to debounce the switch. You should assume that all mechanical switches bounce and that bouncing needs to be dealt with in either the circuit or code. Life is much easier if you debounce the circuit with hardware.

Conclusions:

  1. Success! While we don’t have an onboard LED to blink, we can do something with the board without extraneous components, a Hello World app.
  2. The app is very naive since it uses polling to monitor state changes and spins in a tight loop most of the time. Often the reason for using a microprocessor has a power element to it. Sitting and spinning would be counter to a goal of low power usage.
  3. We covered a lot of ground in this article, skipping or very lightly going over how to load MicroPython and the other tools I used. There are lots of very good resources for them on the interwebs.
  4. If you liked this article, and you want to get an ESP32 board, you can use the Amazon affiliate link above as an expression of your support.

In an upcoming article, I’ll rework the example to be more energy conscious by using an interrupt to signal the state change.

May the Zen of Python be with you!

 Posted by at 10:53 am