MicroPython(ESP32)快速入门

ESP32 board

YD-ESP32开发板.

下面是基于YD-ESP32的开发板使用MicroPyhon的快速参考。如果这是你第一次使用这个板,请详尽阅读快速使用手册:

植入MicroPython

参考下载指导: 开始在ESP32板子上使用 MicroPython. 包括故障排除手册.

通用控制

MicroPython REPL位于UART0 (GPIO1=TX, GPIO3=RX)使用115200波特率。 找出有那些可用的功能模块使用Tab按键命令。 在粘贴模式(ctrl-E),python代码粘贴到REPL也是非常有用的。

The machine module:

import machine

machine.freq()          # 获得模块运行的频率
machine.freq(240000000) # 设置模块运行的频率

The esp module:

import esp

esp.osdebug(None)       # 关闭 vendor O/S 调试管理器
esp.osdebug(0)          # 重新设置 vendor 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的内部温度,以华氏度表示
esp32.ULP()             # 使用低功耗 Ultra-Low-Power 协同处理器

注意,从ESP32中读取的温度传感器通常会高于环境温度,这是由于IC发热造成的。从休眠中醒来后立即读取温度传感器可以将这种影响降到最低。

网络

The network module:

import network

wlan = network.WLAN(network.STA_IF) # 创建链接
wlan.active(True)       # 激活链接
wlan.scan()             # 扫描可用接入点
wlan.isconnected()      # 检查该链接是否链接到AP
wlan.connect('essid', 'password') # 接入到AP注意需要名称和密码
wlan.config('mac')      # 获取链接的MAC地址
wlan.ifconfig()         # 获取链接的 IP/netmask/gw/DNS 地址

ap = network.WLAN(network.AP_IF) # 创建 AP接入点
ap.config(essid='ESP-AP') # 设置接入点的ESSID的名称
ap.active(True)         # 激活接入点

一个有用的实例,实现连接到您的本地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请求.

延迟和时间应用

Use the time module:

import time

time.sleep(1)           # 延迟1s
time.sleep_ms(500)      # 延迟500ms
time.sleep_us(10)       # 延迟10us
start = time.ticks_ms() # 获取毫秒计数器
delta = time.ticks_diff(time.ticks_ms(), start) # 计算时间差

定时器

支持虚拟(RTOS-based)定时器. 使用 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))

周期的单位是毫秒.

引脚和GPIO

使用 machine.Pin class:

from machine import Pin

p0 = Pin(0, Pin.OUT)    # 使用GPIO0创建为输出
p0.on()                 # p0输出设置为高
p0.off()                # p0输出设置为低
p0.value(1)             # 设置引脚高

p2 = Pin(2, Pin.IN)     # 使用GPIO2创建为输入
print(p2.value())       # 查看获得的值是0或1

p4 = Pin(4, Pin.IN, Pin.PULL_UP) # 使能内部上拉电阻做输入
p5 = Pin(5, Pin.OUT, value=1) # 设置引脚为高输出

开发板可用的引脚范围包括:0-19、21-23、25-27、32-39。 这些对应于ESP32芯片的实际GPIO pin数。注意,许多引脚都有自己专用功能(例如D0, D1,…)。 有关板子逻辑引脚和物理芯片引脚之间的映射,请参相关文档。

注意:

  • 引脚1和3是REPL串口引脚的TX和RX
  • 引脚6、7、8、11、16和17用在了内置flash连接上,就不用于其他功能了
  • 引脚34-39只能用在输入也不能用内部上拉

PWM (脉宽调试技术)

PWM可以在任何有输出功能的引脚上使用。PWM的基频可以设置范围在1Hz到40MHz,注意最好选择不要太极端,注意实现的条件是否满足。基础频率 越高 占空比 减少. 参考 LED Control 获取更多细节.

使用 machine.PWM class:

from machine import Pin, PWM

pwm0 = PWM(Pin(0))      # 使用一个脚创建一个PWM对象
pwm0.freq()             # 获取一下频率
pwm0.freq(1000)         # 设置一下频率
pwm0.duty()             # 获取一下占空比
pwm0.duty(200)          # 设置一下占空比
pwm0.deinit()           # 关闭该引脚上的pwm

pwm2 = PWM(Pin(2), freq=20000, duty=512) # 一句话设置一路PWM

ADC (模拟量转数字量)

在ESP32 ADC功能可用的引脚是32-39。注意,当使用默认配置时,ADC引脚上的输入电压在0~1V,超过1V虽然不至于烧但是度数就4095了 衰减输入还是有必要的,以适配这个弱弱的ADC.

使用 machine.ADC class:

from machine import ADC

adc = ADC(Pin(32))          # 在一个引脚上创建一个ADC对象
adc.read()                  # 读取数值 0-4095 对应着 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:

ADC.atten(attenuation)

这个函数允许设置ADC输入的衰减量。这允许更大的输入电压范围,但代价是精度(现在相同的比特数代表更大的范围)。可能的衰减选项是:

  • ADC.ATTN_0DB: 0dB 衰减,最大输入电压为1v,这是默认配置
  • ADC.ATTN_2_5DB: 2.5dB 衰减, 最大输入电压约为1.34v
  • ADC.ATTN_6DB: 6dB 衰减, 最大输入电压约为2.00v
  • ADC.ATTN_11DB: 11dB 衰减, 最大输入电压约3.6v
ADC.width(width)

这个函数允许设置ADC利用的位数,在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

开发板有两个SPI驱动器。一个是使用软件方式实现的,并在所有的可用引脚上工作,并通过 machine.SPI

class:

from machine import Pin, SPI

# 在给定的引脚上构建SPI总线
# SCK的空闲状态的极性
# phase=0 意味着在SCK第一个上升沿捕获, phase=1 意味着在SCK在第二个上升沿捕获
spi = SPI(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)      # 在MOSI上输出0xff时读取10个字节

buf = bytearray(50)     # 创建一个缓冲区
spi.readinto(buf)       # 读入给定的缓冲区 (本例设置为50 bytes)
spi.readinto(buf, 0xff) # 读入给定的缓冲区并在MOSI上输出0xff

spi.write(b'12345')     # 写5个字节 MOSI

buf = bytearray(4)      # 创建一个缓冲区
spi.write_readinto(b'1234', buf) #写入MOSI并从MISO读入缓冲区
spi.write_readinto(buf, buf) # 将buf写入MOSI并将MISO读入buf

硬件SPI总线

有两路硬件SPI总线,速率更快(可达80Mhz的传输速率),但是是指定的引脚,而不是任意引脚了。

HSPI (id=1) VSPI (id=2)
sck 14 18
mosi 13 23
miso 12 19

硬件SPI像软件SPI一样有相同的函数:

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 总线

The 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)   # 从地址为0x3a的从机设备上读取4个字节
i2c.writeto(0x3a, '12') # 写 '12' 到地址为0x3a的从机设备

buf = bytearray(10)     # 创造一个10字节的储存区
i2c.writeto(0x3a, buf)  # 写给定的缓冲区到地址为0x3a的从机设备

实时时钟 (RTC)

See machine.RTC

from machine import RTC

rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # 设置时间和日期
rtc.datetime() # 获取时间和日期

深度睡眠模式

以下代码可用于睡眠、唤醒和检查重置原因:

import machine

# 检查设备是否从深度睡眠中醒来
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print('woke from a deep sleep')

# 让设备休眠10秒
machine.deepsleep(10000)

注意:

  • 调用 deepsleep() 不带参数将会进入无休止的休眠
  • 软件复位将不会改变重置原因

一线通讯

一线通讯是使用软件方式实现的可以用在任何可用引脚:

from machine import Pin
import onewire

ow = onewire.OneWire(Pin(12)) # 创建一个一线通讯在GPIO12
ow.scan()               # 返回一个一线设备在线列表
ow.reset()              # 重启总线
ow.readbyte()           # 读一个字节
ow.writebyte(0x12)      # 在总线上写一个字节
ow.write('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() 在每次想获取温度就调用这个函数.

像素驱动

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

低电平驱动一个像素:

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.

电容式触控

使用 触摸板 class 在 machine module:

from machine import TouchPad, Pin

t = TouchPad(Pin(14))
t.read()              # Returns a smaller number when touched

TouchPad.read 返回相对于电容性变量的值。当触摸时,是个较小数字(通常在 10 内),当没有触针时,是较大数字(大于 * 1000 *)是常见的。然而,这些值是“相对的”,可以根据电路板和周围不同而变化,因此可能的需要进行一些校准。

有10个电容触摸控脚,可以使用在ESP32: 0, 2, 4, 12, 13 14 15 27 32 33。如果调用其他的引脚将会导致 ValueError

提示这些电容触摸引脚可以唤醒EPS32从休眠状态:

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的更多细节,请参考 Espressif Touch Sensor.

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浏览器REPL)

WebREPL (通过web浏览器访问WebSockets上的REPL) 在ESP32端口中非常使用的功能. 下载网页客服端 https://github.com/micropython/webrepl (官方 http://micropython.org/webrepl), 执行并配置:

import webrepl_setup

并遵循屏幕上的指示。重启之后,就可以连接了。如果在启动时禁用了自动启动功能,则可以使用以下命令按需运行已配置的dome进程:

import webrepl
webrepl.start()

# 或者,开始需要一个特殊的密码
webrepl.start(password='mypass')

WebREPL程序进程监听所有活动接口(可以是STA或AP),这允许您通过路由器(STA接口)连接到ESP32,或者直接连接到它的接入点。

除了终端/命令提示符访问,WebREPL还提供了文件传输(上传和下载)。web客户机有对应函数的按钮,或者您可以使用命令行客户机 webrepl_cli.py 来自上面的存储库。

请参阅MicroPython论坛,了解其他社区支持的将文件传输到ESP32板的替代方案.