ESP32使用MicroPython:快速參考手冊

ESP32使用MicroPython:快速參考手冊

pyWiFi-ESP32 pinout

ESP32開發板 (圖片來源: 01Studio).

以下內容是ESP32開發板的快速入門內容。如果這是你第一次使用ESP32開發板,那麼建議你先閱讀以下兩個章節熟悉一下:

安裝MicroPython

請參考教程的相應部分: ESP32 MicroPython上手指南. 它還包括故障排除小節。

通用控制

MicroPython 的串口交互調試(REPL)在 UART0 (GPIO1=TX, GPIO3=RX),波特率爲:115200。 Tab按鍵補全功能對於找到每個對象的使用方法非常有用。 粘貼模式 (ctrl-E) 對需要複製比較多 的python代碼到REPL是非常有用。

The machine module:

import machine

machine.freq()          # 獲取CPU當前工作頻率
machine.freq(240000000) # 設置CPU的工作頻率爲 240 MHz

The esp module:

import esp

esp.osdebug(None)       # 關閉原廠 O/S 調試信息
esp.osdebug(0)          # 將原廠 O/S 調試信息重定向到 UART(0) 輸出

# 與flash交互的低級方法
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 esp32 module:

import esp32

esp32.hall_sensor()     # 讀取內部霍爾傳感器
esp32.raw_temperature() # 讀取內部溫度傳感器,在MCU上, 單位:華氏度F
esp32.ULP()             # 使用超低功耗協處理器(ULP)

請注意ESP32內部溫度讀取數值會比實際要高,因爲芯片工作時候回發熱。 從睡眠狀態喚醒後立即讀取溫度傳感器可以最大限度地減少這種影響。

Networking

The network module:

import network

wlan = network.WLAN(network.STA_IF) # 創建 station 接口
wlan.active(True)       # 激活接口
wlan.scan()             # 掃描允許訪問的SSID
wlan.isconnected()      # 檢查創建的station是否連已經接到AP
wlan.connect('essid', 'password') # 連接到指定ESSID網絡
wlan.config('mac')      # 獲取接口的MAC地址
wlan.ifconfig()         # 獲取接口的 IP/netmask(子網掩碼)/gw(網關)/DNS 地址

ap = network.WLAN(network.AP_IF) # 創捷一個AP熱點接口
ap.config(essid='ESP-AP') # 激活接口
ap.config(max_clients=10) # 設置熱點允許連接數量
ap.active(True)         # 設置AP的ESSID名稱

連接到本地WIFI網絡的函數參考:

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())

一旦網絡建立成功,你就可以通過 socket 模塊創建和使用 TCP/UDP sockets 通訊, 以及通過 urequests 模塊非常方便地發送 HTTP 請求。

After a call to wlan.connect(), the device will by default retry to connect forever, even when the authentication failed or no AP is in range. wlan.status() will return network.STAT_CONNECTING in this state until a connection succeeds or the interface gets disabled. This can be changed by calling wlan.config(reconnects=n), where n are the number of desired reconnect attempts (0 means it won’t retry, -1 will restore the default behaviour of trying to reconnect forever).

延時和時間

Use the time module:

import time

time.sleep(1)           # 睡眠1秒
time.sleep_ms(500)      # 睡眠500毫秒
time.sleep_us(10)       # 睡眠10微妙
start = time.ticks_ms() # 獲取毫秒計時器開始值
delta = time.ticks_diff(time.ticks_ms(), start) # 計算從開始到當前時間的差值

定時器

ESP32擁有4個定時器。使用 machine.Timer 類通過設置timer ID號爲 0-3

from machine import Timer

tim0 = Timer(0)
tim0.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(0))

tim1 = Timer(1)
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))

該週期的單位爲毫秒(ms)

Virtual timers are not currently supported on this port.

引腳和GPIO口

使用 machine.Pin 模塊:

from machine import Pin

p0 = Pin(0, Pin.OUT)    # 創建對象p0,對應GPIO0口輸出
p0.on()                 # 設置引腳爲 "on" (1)高電平
p0.off()                # 設置引腳爲 "off" (0)低電平
p0.value(1)             # 設置引腳爲 "on" (1)高電平

p2 = Pin(2, Pin.IN)     # 創建對象p2,對應GPIO2口輸入
print(p2.value())       # 獲取引腳輸入值, 0(低電平) 或者 1(高電平)

p4 = Pin(4, Pin.IN, Pin.PULL_UP) # 打開內部上拉電阻
p5 = Pin(5, Pin.OUT, value=1) # 初始化時候設置引腳的值爲 1(高電平)

可以使用引腳排列如下 (包括首尾): 0-19, 21-23, 25-27, 32-39.分別對應ESP32芯片的實際 引腳編號。 請注意,用戶使用自己其它的開發板有特定的引腳命名方式(例如:DO, D1, …)。 由於MicroPython致力於支持 不同的開發板和模塊,因此我們採用最原始簡單具且有共同特徵的引 腳命名方式。如果你使用自己的開發板,請參考其原理圖。

注意:

  • 引腳1和3分別是串口交互(REPL)的TX和RX。

  • 引腳6, 7, 8, 11, 16, 和 17 are 連接到模塊的Flash,不建議做其它用途。

  • 引腳 34-39 只允許輸入, 沒有內部上拉電阻。

  • 部分引腳的pull值可以設置爲 Pin.PULL_HOLD 以降低深度睡眠時候的功耗。

There’s a higher-level abstraction machine.Signal which can be used to invert a pin. Useful for illuminating active-low LEDs using on() or value(1).

UART (serial bus)

See machine.UART.

from machine import UART

uart1 = UART(1, baudrate=9600, tx=33, rx=32)
uart1.write('hello')  # write 5 bytes
uart1.read(5)         # read up to 5 bytes

The ESP32 has three hardware UARTs: UART0, UART1 and UART2. They each have default GPIO assigned to them, however depending on your ESP32 variant and board, these pins may conflict with embedded flash, onboard PSRAM or peripherals.

Any GPIO can be used for hardware UARTs using the GPIO matrix, so to avoid conflicts simply provide tx and rx pins when constructing. The default pins listed below.

 

UART0

UART1

UART2

tx

1

10

17

rx

3

9

16

PWM (脈寬調製)

PWM 能在所有可輸出引腳上實現。基頻的範圍可以從 1Hz 到 40MHz 但需要權衡: 隨着基頻的 增加 佔空分辨率 下降. 詳情請參閱: LED Control.

Use the machine.PWM class:

from machine import Pin, PWM

pwm0 = PWM(Pin(0))         # create PWM object from a pin
freq = pwm0.freq()         # get current frequency (default 5kHz)
pwm0.freq(1000)            # set PWM frequency from 1Hz to 40MHz

duty = pwm0.duty()         # get current duty cycle, range 0-1023 (default 512, 50%)
pwm0.duty(256)             # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%)

duty_u16 = pwm0.duty_u16() # get current duty cycle, range 0-65535
pwm0.duty_u16(2**16*3//4)  # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)

duty_ns = pwm0.duty_ns()   # get current pulse width in ns
pwm0.duty_ns(250_000)      # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%)

pwm0.deinit()              # turn off PWM on the pin

pwm2 = PWM(Pin(2), freq=20000, duty=512)  # create and configure in one go
print(pwm2)                               # view PWM settings

ESP chips have different hardware peripherals:

Hardware specification

ESP32

ESP32-S2

ESP32-C3

Number of groups (speed modes)

2

1

1

Number of timers per group

4

4

4

Number of channels per group

8

8

6

Different PWM frequencies (groups * timers)

8

4

4

Total PWM channels (Pins, duties) (groups * channels)

16

8

6

A maximum number of PWM channels (Pins) are available on the ESP32 - 16 channels, but only 8 different PWM frequencies are available, the remaining 8 channels must have the same frequency. On the other hand, 16 independent PWM duty cycles are possible at the same frequency.

See more examples in the Pulse Width Modulation tutorial.

ADC (模數轉換)

ADC功能在ESP32引腳32-39上可用。請注意,使用默認配置時,ADC引腳上的輸入電壓必須 介於0.0v和1.0v之間(任何高於1.0v的值都將讀爲4095)。如果需要增加測量範圍,需要配置 衰減器。

Use the machine.ADC class:

from machine import ADC

adc = ADC(Pin(32))          # 在ADC引腳上創建ADC對象
adc.read()                  # 讀取測量值, 0-4095 表示電壓從 0.0v - 1.0v

adc.atten(ADC.ATTN_11DB)    # 設置 11dB 衰減輸入 (測量電壓大致從 0.0v - 3.6v)
adc.width(ADC.WIDTH_9BIT)   # 設置 9位 精度輸出 (返回值 0-511)
adc.read()                  # 獲取重新配置後的測量值

ESP32 特定的 ADC 類使用方法說明:

ADC.atten(attenuation)

該方法允許設置ADC輸入的衰減量,以獲取更大的電壓測量範圍,但是以精度爲代價的。 (配置後相同的位數表示更寬的範圍)。衰減選項如下:

  • ADC.ATTN_0DB: 0dB 衰減, 最大輸入電壓爲 1.00v - 這是默認配置

  • ADC.ATTN_2_5DB: 2.5dB 衰減, 最大輸入電壓約爲 1.34v

  • ADC.ATTN_6DB: 6dB 衰減, 最大輸入電壓約爲 2.00v

  • ADC.ATTN_11DB: 11dB 衰減, 最大輸入電壓約爲3v

Warning

儘管通過配置11dB衰減可以讓測量電壓到達3.6v,但由於ESP32芯片的最大允許輸入電壓是3.6V, 因此輸入接近3.6V的電壓可能會導致IC燒壞!

ADC.width(width)

該方法允許設置ADC輸入的位數精度。 選項如下:

  • ADC.WIDTH_9BIT: 9 bit data

  • ADC.WIDTH_10BIT: 10 bit data

  • ADC.WIDTH_11BIT: 11 bit data

  • ADC.WIDTH_12BIT: 12 bit data - 這是默認配置

軟件SPI總線

EPS32內部有兩個SPI驅動。其中1個是通過軟件實現 (bit-banging),並允許配置到所有引腳, 通過 machine.SoftSPI 類模塊配置:

from machine import Pin, SoftSPI

# 在給定的引腳上創建SoftSPI總線
# (極性)polarity是指 SCK 空閒時候的狀態
# (相位)phase=0 表示SCK在第1個邊沿開始取樣,phase=1 表示在第2個邊沿開始。
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))


spi.init(baudrate=200000) # 設置頻率

spi.read(10)            # 在MISO引腳讀取10字節數據
spi.read(10, 0xff)      # 在MISO引腳讀取10字節數據同時在MOSI輸出0xff

buf = bytearray(50)     # 建立緩衝區
spi.readinto(buf)       # 讀取數據並存放在緩衝區 (這裏讀取50個字節)
spi.readinto(buf, 0xff) # 讀取數據並存放在緩衝區,同時在MOSI輸出0xff

spi.write(b'12345')     # 在MOSI引腳上寫5字節數據

buf = bytearray(4)      # 建立緩衝區
spi.write_readinto(b'1234', buf) # 在MOSI引腳上寫數據並將MISO讀取數據存放到緩衝區
spi.write_readinto(buf, buf) # 在MOSI引腳上寫緩衝區的數據並將MISO讀取數據存放到緩衝區

Warning

目前在創建軟件SPI對象時,sck, mosimiso 所有 的引腳 必須 定義。

硬件SPI總線

有兩個硬件SPI通道允許更高速率傳輸(到達80MHz)。 也可以配置成任意引腳,但相關引腳要 符合輸入輸出的方向性,這可以參閱(see 引腳和GPIO口)內容。通過自定義引腳而非 默認引腳,會降低傳輸速度,上限爲40MHz。以下是硬件SPI總線默認引腳:

 

HSPI (id=1)

VSPI (id=2)

sck

14

18

mosi

13

23

miso

12

19

Hardware SPI is accessed via the machine.SPI class and has the same methods as software SPI above:

from machine import Pin, SPI

hspi = SPI(1, 10000000)
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))

SoftI2C總線

I2C總線分軟件和硬件對象,硬件可以定義0和1,通過配置可以在任意引腳上實現改功能, 詳情請看 machine.SoftI2C 類模塊:

from machine import Pin, SoftI2C

# 構建1個I2C對象
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)

# 構建一個硬件 I2C 總線
i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)

i2c.scan()              # 掃描從設備

i2c.readfrom(0x3a, 4)   # 從地址爲0x3a的從機設備讀取4字節數據
i2c.writeto(0x3a, '12') # 向地址爲0x3a的從機設備寫入數據"12"

buf = bytearray(10)     # 創建1個10字節緩衝區
i2c.writeto(0x3a, buf)  # 寫入緩衝區數據到從機

Hardware I2C bus

There are two hardware I2C peripherals with identifiers 0 and 1. Any available output-capable pins can be used for SCL and SDA but the defaults are given below.

 

I2C(0)

I2C(1)

scl

18

25

sda

19

26

The driver is accessed via the machine.I2C class and has the same methods as software I2C above:

from machine import Pin, I2C

i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)

I2S bus

See machine.I2S.

from machine import I2S, Pin

i2s = I2S(0, sck=Pin(13), ws=Pin(14), sd=Pin(34), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object
i2s.write(buf)             # write buffer of audio samples to I2S device

i2s = I2S(1, sck=Pin(33), ws=Pin(25), sd=Pin(32), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object
i2s.readinto(buf)          # fill buffer with audio samples from I2S device

The I2S class is currently available as a Technical Preview. During the preview period, feedback from users is encouraged. Based on this feedback, the I2S class API and implementation may be changed.

ESP32 has two I2S buses with id=0 and id=1

實時時鐘(RTC)

See machine.RTC

from machine import RTC

rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # 設置時間(年,月,日,星期,時,分,秒,微秒)
                                             # 其中星期使用0-6表示星期一至星期日。
rtc.datetime() # 獲取當前日期和時間

WDT (Watchdog timer)

See machine.WDT.

from machine import WDT

# enable the WDT with a timeout of 5s (1s is the minimum)
wdt = WDT(timeout=5000)
wdt.feed()

深度睡眠模式

下面代碼可以用來睡眠、喚醒和檢測復位喚醒:

import machine

# 檢測設備是否從深度睡眠中喚醒
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print('woke from a deep sleep')

# 使設備進入深度睡眠,時間10秒。
machine.deepsleep(10000)

注意事項:

  • 調用深度睡眠函數 deepsleep() 如果不提供參數(時間)的話可能會讓設備無限期休眠。

  • 軟件復位不能觸發復位事件(reset cause)。

  • 可能會出現一些泄漏電流流經內部上下拉電阻,爲了進一步降低功耗,可以關閉GPIO的上下拉電阻:

    p1 = Pin(4, Pin.IN, Pin.PULL_HOLD)

    退出深度睡眠後,有必要恢復GPIO原來的狀態 (例如:原來是輸出引腳)

    p1 = Pin(4, Pin.OUT, None)

SD card

See machine.SDCard.

import machine, os

# Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
sd = machine.SDCard(slot=2)
os.mount(sd, "/sd")  # mount

os.listdir('/sd')    # list directory contents

os.umount('/sd')     # eject

RMT

The RMT is ESP32-specific and allows generation of accurate digital pulses with 12.5ns resolution. See esp32.RMT for details. Usage is:

import esp32
from machine import Pin

r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r   # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), 0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns

單總線驅動(Onewire)

單總線驅動允許通過軟件在各個引腳上實現:

from machine import Pin
import onewire

ow = onewire.OneWire(Pin(12)) # 在引腳 GPIO12 創建單總線對象ow
ow.scan()               # 掃描設備,返回設備編號列表
ow.reset()              # 復位總線
ow.readbyte()           # 讀取1字節
ow.writebyte(0x12)      # 寫入1個字節(0x12)
ow.write('123')         # 寫入多個字節('123')
ow.select_rom(b'12345678') # 根據ROM編號選擇總線上的指定設備

下面是一個DS18B20設備的驅動函數:

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))

確保數據引腳連接了 4.7k 的上拉電阻。另外請注意每次採集溫度都需要用到 convert_temp() 模塊。

NeoPixel and APA106 driver

Use the neopixel and apa106 modules:

from machine import Pin
from neopixel import NeoPixel

pin = Pin(0, Pin.OUT)   # 設置引腳GPIO0來驅動 NeoPixels
np = NeoPixel(pin, 8)   # 在GPIO0上創建一個 NeoPixel對象,包含8個燈珠
np[0] = (255, 255, 255) # 設置第一個燈珠顯示數據爲白色
np.write()              # 寫入數據
r, g, b = np[0]         # 獲取第一個燈珠的顏色

The APA106 driver extends NeoPixel, but internally uses a different colour order:

from apa106 import APA106
ap = APA106(pin, 8)
r, g, b = ap[0]

APA102 (DotStar) uses a different driver as it has an additional clock pin.

低級別的 NeoPixel 驅動:

import esp
esp.neopixel_write(pin, grb_buf, is800khz)

Warning

默認情況下 NeoPixel 被配置成控制更常用的 800kHz 單元設備。用戶可以通過使用替代的定時器 來說控制其他頻率的設備 (通常是 400kHz)。 可以通過使用定時器 timing=0 當構建 NeoPixel 對象的時候。

The low-level driver uses an RMT channel by default. To configure this see RMT.bitstream_channel.

APA102 (DotStar) uses a different driver as it has an additional clock pin.

電容觸摸

Use the TouchPad class in the machine module:

from machine import TouchPad, Pin

t = TouchPad(Pin(14))
t.read()              # 當觸摸的時候返回一個很小的數字。

TouchPad.read 返回一個跟電容相關的變量數值。 當被觸摸時候,這個數值很小 (通常是 十位), 而當電容按鍵沒有被觸摸時候,返回一個很大的數字 (大於*1000*)。 然而,這些值是 相對的,它可能會 隨外部環境變化,因此你可能需要做一些校準。

ESP32有10個電容觸摸輸入IO口: 0, 2, 4, 12, 13,14, 15, 27, 32, 33。嘗試其它GPIO會返回``ValueError``。

TouchPads可以喚醒睡眠中的ESP32:

import machine
from machine import TouchPad, Pin
import esp32

t = TouchPad(Pin(14))
t.config(500)               # 配置觸摸引腳的閾值
esp32.wake_on_touch(True)
machine.lightsleep()        # MCU進入睡眠狀態,直到touchpad被觸摸

有關 touchpads 更多資料請參考以下鏈接: Espressif Touch Sensor.

DHT 驅動

DHT 溫溼度驅動允許通過軟件在各個引腳上實現:

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瀏覽器交互提示)

WebREPL (通過WebSockets的REPL, 可以通過瀏覽器使用) 是ESP8266端口實驗的功能。 可以從 https://github.com/micropython/webrepl 下載並打開html文件運行。 (在線託管版可以通過訪問 http://micropython.org/webrepl)直接使用, 通過執行 以下命令進行配置:

import webrepl_setup

按照屏幕的提示操作。重啓後,允許使用WebREPL。如果你禁用了開機自動啓動WebREPL, 可以通過以下命令使用:

import webrepl
webrepl.start()

# 也可在在開始時候設置一個密碼
webrepl.start(password='mypass')

這個 WebREPL 通過連接到ESP32的AP使用,如果你的路由器配網絡配置正確,這個功能 也可以通過STA方式使用,那意味着你可以同時上網和調試ESP32。(如果遇到不可行的 特殊情況, 請先使用ESP32 AP方式)。

除了終端/命令符的訪問方式, WebREPL同時允許傳輸文件 (包含上傳和下載)。Web客戶端有相應的 功能按鈕,也可以通過 webrepl_cli.py 模塊上存儲的命令行進行操作。

有關將文件傳輸到ESP32其他支持的替代方法,請參閱MicroPython論壇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章