MicroPython ESP32开发:快速参考

ESP32是使用非常广泛的一款微处理器,集成了WiFi和蓝牙模块,根据性能和应用场景的不同有很多不同的版本,本文是ESP32开发板在MicroPython环境下运行的快速参考,对于首次使用这个开发板在MicroPython下进行开发的应该会有一定的帮助。

下面以Espressif ESP32开发板为例进行说明。

在这里插入图片描述

安装MicroPython

关于安装可以参考:在 ESP32 上开始使用 MicroPython,其中还包括故障排除小节。

一般电路板控制

MicroPython REPL 位于 UART0(GPIO1=TX,GPIO3=RX)上,波特率为 115200。Tab-completion 用于查找对象的方法。粘贴模式 (ctrl-E) 可以将一大段 Python 代码粘贴到 REPL 中。

machine模块:

import machine

machine.freq()          # 获取CPU频率
machine.freq(240000000) # 将CPU频率设置为240 MHz

esp模块:

import esp

esp.osdebug(None)       # 关闭厂商O/S调试信息
esp.osdebug(0)          # 把厂商O/S调试信息重定向到UART(0)

# 使用底层方法操作闪存
esp.flash_size()
esp.flash_user_start()
esp.flash_erase(sector_no)
esp.flash_write(byte_offset, buffer)
esp.flash_read(byte_offset, buffer)

esp32模块:


import esp32

esp32.raw_temperature() # 读取MCU核心温度,单位是摄氏度
esp32.ULP()             # 访问低功耗协处理器

**注意:**ESP32 中的温度传感器读数通常会高于环境温度,这是因为集成电路在运行时会变热。从睡眠状态唤醒后立即读取温度传感器的读数可将这种影响降至最低。

网络

WLAN

network模块:

import network

wlan = network.WLAN(network.STA_IF) # 创建站点接口
wlan.active(True)       # 激活接口
wlan.scan()             # 扫描热点
wlan.isconnected()      # 检查站点是否连接到热点
wlan.connect('ssid', 'key') # 连接到一个热点
wlan.config('mac')      # 获取接口的MAC地址
wlan.ifconfig()         # 获取接口的IP、子网掩码、网关和DNS地址

ap = network.WLAN(network.AP_IF) # 创建一个热点
ap.config(ssid='ESP-AP') # 设置热点的SSID
ap.config(max_clients=10) # 设置允许连接的客户端数量
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('ssid', 'key')
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())

网络建立后,套接字模块可用于创建和使用TCP/UDP套接字,请求模块可方便用于HTTP的请求。

调用wlan.connect()后,设备将默认永久重试连接,即使身份验证失败或范围内没有接入点。在此状态下,wlan.status()将返回network.STAT_CONNECTING,直到连接成功或接口被禁用。可以通过调用wlan.config(reconnects=n)可以改变这种状态,其中n是所需的重连尝试次数(0 表示不会重试,-1 表示恢复默认状态,即永远尝试重连)。

LAN

要使用有线接口,必须指定引脚和模式

import network

lan = network.LAN(mdc=PIN_MDC, ...)   # 设置引脚和模式
lan.active(True)                      # 启动网络接口
lan.ifconfig()                        # 获取网络的IP、子网掩码、网关和DNS地址

定义PHY类型和接口的构造函数的关键参数有:

mdc=machine.Pin(n) # 设置 mdc 和 mdio 引脚。
mdio=machine.Pin(n) #管脚对象
power=machine.Pin(n) # 设置 PHY 设备的电源开关引脚。
phy_type=<type> # 选择 PHY 设备类型。支持的设备有 PHY_LAN8710、PHY_LAN8720、PH_IP101、PHY_RTL8201、PHY_DP83848 和 PHY_KSZ8041
phy_addr=number # PHY 设备的地址编号。
ref_clk_mode=mode # 定义ESP32的ref_clk 是输入还是输出。合适的值是 Pin.IN 和 Pin.OUT。
ref_clk=machine.Pin(n) # 定义用于 ref_clk 的引脚。

这些是常用电路板局域网接口的工作配置:

# Olimex ESP32-GATEWAY: 电源由Pin(5)控制
# Olimex ESP32 PoE and ESP32-PoE ISO: 电源由Pin(12)控制

lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5),
                  phy_type=network.PHY_LAN8720, phy_addr=0,
                  ref_clk=machine.Pin(17), ref_clk_mode=machine.Pin.OUT)

# Wireless-Tag's WT32-ETH01

lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18),
                  phy_type=network.PHY_LAN8720, phy_addr=1, power=None)

# Wireless-Tag's WT32-ETH01 v1.4

lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18),
                  phy_type=network.PHY_LAN8720, phy_addr=1,
                  power=machine.Pin(16))

# Espressif ESP32-Ethernet-Kit_A_V1.2

lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
                  phy_type=network.PHY_IP101, phy_addr=1)

延迟和定时

使用time模块:

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 端口有四个硬件定时器。使用 machine.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))

周期以毫秒为单位。

该端口目前不支持虚拟计时器。

引脚和GPIO

使用machine.Pin类:

from machine import Pin

p0 = Pin(0, Pin.OUT)    # 在GPIO0上创建输出引脚
p0.on()                 # 设置引脚为高电平
p0.off()                # 设置引脚为低电平
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) # 在引脚创建时设置为高电平
p6 = Pin(6, Pin.OUT, drive=Pin.DRIVE_3) # 设置引脚为最大驱动能力

可用引脚范围如下(含): 0-19、21-23、25-27、32-39:0-19, 21-23, 25-27, 32-39。这些引脚与ESP32芯片的实际 GPIO 引脚编号一致。注意,许多最终用户电路板使用自己专用引脚编号(如 D0、D1…)。有关电路板逻辑引脚和芯片物理引脚之间的映射关系,请查阅电路板文档。

使用Pin()构造函数或Pin.init()方法的驱动关键字参数,可支持四种驱动强度,并具有不同的相应安全最大源/汇电流和近似内部驱动电阻:

  • Pin.DRIVE_0: 5mA / 130 欧姆
  • Pin.DRIVE_1: 10mA / 60 欧姆
  • Pin.DRIVE_2: 20mA / 30 欧姆 (默认强度,如果未配置)
  • Pin.DRIVE_3: 40mA / 15 欧姆

Pin()Pin.init()hold=关键字参数将启用ESP32的 "焊盘保持 "功能。设置为True时,引脚配置(方向、上拉电阻和输出值)将被保持,任何进一步的更改(包括更改输出电平)都不会应用。设置hold=False将立即应用任何未完成的引脚配置更改并释放引脚。在引脚已保持的情况下使用hold=True会应用任何配置更改,然后立即重新应用保持。

注意:

  • 引脚 1 和 3 分别为 REPL UART TX 和 RX
  • 引脚 6、7、8、11、16 和 17 用于连接嵌入式闪存,不建议用于其他用途
  • 引脚 34-39 仅用于输入,也没有内部上拉电阻器
  • 有关引脚在休眠状态下的行为,请参阅深度休眠模式

这里有一个更高层次的抽象machine.Signal,可用于反转引脚。使用on()value(1)可以点亮低电平有效的LED。

UART(串口总线)

使用machine.UART

from machine import UART

uart1 = UART(1, baudrate=9600, tx=33, rx=32)
uart1.write('hello')  # 写5个字节
uart1.read(5)         # 读取5个字节

ESP32 有三个硬件的UART:UART0、UART1和UART2,它们都有分配给它们的默认 GPIO,但根据您的 ESP32 变体和电路板,这些引脚可能会与嵌入式闪存、板载 PSRAM 或外设发生冲突。

任何GPIO都可用于使用GPIO矩阵的硬件UART,但可用作rx的纯输入引脚34-39除外。为避免冲突,只需在构建时提供tx和rx引脚即可。默认引脚如下。

UART0UART1UART2
tx11017
rx3916

PWM(脉宽调制pulse width modulation)

PWM 可在所有输出引脚上启用。基频范围为1Hz至40MHz,但需要权衡;随着基频的增加,占空比会降低。

使用machine.PWM类:

from machine import Pin, PWM

pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # 从指定引脚创建PWM对象
freq = pwm0.freq()         # 获取当前频率
pwm0.freq(1000)            # 设置PWM频率从1Hz到40MHz

duty = pwm0.duty()         # 获取当前占空比,范围0-1023 (缺省 512, 50%)
pwm0.duty(256)             # 设置占空比,从0到1023,占空比为 duty/1023, (当前为 25%)

duty_u16 = pwm0.duty_u16() # 获取当前的占空比,范围0-65535
pwm0.duty_u16(2**16*3//4)  # 设置占空比从0到65535,占空比为 duty_u16/65535, (当前为 75%)

duty_ns = pwm0.duty_ns()   # 获取当前脉冲宽度,单位纳秒ns
pwm0.duty_ns(250_000)      # 以纳秒为单位设置脉冲宽度,从 0 到 1_000_000_000/频率,(现在为 25%)

pwm0.deinit()              # 关闭引脚上的PWM

pwm2 = PWM(Pin(2), freq=20000, duty=512)  # 一次性创建和配置
print(pwm2)                               # 打印PWM设置

ESP 芯片有不同的硬件外设:

硬件规格ESP32ESP32-S2ESP32-C3
组数(速度模式)211
每组的计时器数量444
每组通道数888
不同的 PWM 频率(组 * 定时器)844
PWM 通道总数(引脚,职责)(组 * 通道)1686

ESP32的最大PWM通道(引脚)数为 16 个,但只有 8 个不同的 PWM 频率,其余 8 个通道的频率必须相同。另一方面,在相同频率下可以有 16 个独立的 PWM 占空比。

DAC(数模转换digital to analog conversion)

在 ESP32 上,DAC功能在引脚25、26上。在ESP32S2 上,17、18引脚上具有 DAC 功能。

使用DAC:

from machine import DAC, Pin

dac = DAC(Pin(25))  # 为管脚创建一个DAC对象
dac.write(128)      # 设置一个原始模拟值,范围0~255,当前是50%

ADC(模数转换 analog to digital conversion)

在 ESP32 上,32-39 引脚(ADC block 1)和 0、2、4、12-15 和 25-27 引脚(ADC block 2)上都有 ADC 功能。

使用machine.ADC类:

from machine import ADC

adc = ADC(pin)        # 为引脚上创建一个ADC对象
val = adc.read_u16()  # 读取一个原始值,范围0~65535
val = adc.read_uv()   # 读取一个电压模拟值,单位微伏

ADC block 2 也由WiFi使用,因此当 WiFi 处于激活状态时,尝试从block 2 引脚读取模拟值将会引发异常。

内部 ADC 基准电压通常为 1.1V,但不同封装之间略有不同。ADC 在接近基准电压时线性较差(特别是在较高衰减时),最低测量电压约为 100mV,低于或等于此值的电压读数为 0。要准确读取电压,建议使用 read_uv() 方法(见下文)。

ESP32 专用 ADC 类方法参考:

class ADC(pin, *, atten)

返回指定引脚的 ADC 对象。ESP32 不支持 ADC 采样的不同时序,因此不支持 sample_ns 关键字参数。

要读取高于参考电压的电压,可使用 atten 关键字参数应用输入衰减。有效值(以及近似线性测量范围)为:

  • ADC.ATTN_0DB:无衰减(100mV - 950mV)
  • ADC.ATTN_2_5DB:2.5 分贝衰减(100mV - 1250mV)
  • ADC.ATTN_6DB:6 分贝衰减(150mV - 1750mV)
  • ADC.ATTN_11DB:11 分贝衰减(150mV - 2450mV)

**注意:**输入引脚的绝对最大额定电压为 3.6V,接近这一界限可能会损坏集成电路!

ADC.read_uv()

这种方法利用 ADC 的已知特性和每个封装的 eFuse 值(在制造过程中设定),返回以微伏为单位的校准输入电压(衰减前)。返回值只有毫伏分辨率(即始终是 1000 微伏的倍数)。

校准仅在 ADC 的线性范围内有效。特别是,接地输入将读取高于 0 微伏的值。不过,在线性范围内,使用 read_u16()并用常数缩放结果将获得更准确、更一致的结果。

传统方法:

ADC.read()

该方法根据块的分辨率返回 ADC 原始值,例如 12 位分辨率为 0-4095。

ADC.atten(atten)

等同于 ADC.init(atten=atten)。

ADC.width(bits)

等价于 ADC.block().init(bits=bits)。

为了兼容,ADC 对象还提供了与支持的 ADC 分辨率相匹配的常量:

  • ADC.WIDTH_9BIT = 9
  • ADC.WIDTH_10BIT = 10
  • ADC.WIDTH_11BIT = 11
  • ADC.WIDTH_12BIT = 12

ESP32 端口还支持 machine.ADC API:

classADCBlock(id, *, bits)

返回具有给定 id(1 或 2)的 ADC 块对象,并将其初始化为指定分辨率(9 至 12 位,取决于 ESP32 系列),如果未指定,则返回支持的最高分辨率。

ADCBlock.connect(pin)
ADCBlock.connect(channel)
ADCBlock.connect(channel, pin)

返回指定 ADC 引脚或通道号的 ADC 对象。不支持将 ADC 通道任意连接到 GPIO,因此指定未连接到该模块的引脚或指定不匹配的通道和引脚将引发异常。

SPI软总线

软SPI(使用位操作)可在所有引脚上工作,通过machine.SoftSPI类访问:

from machine import Pin, SoftSPI

# 在给定的引脚上构建一个软SPI总线
# polarity is the idle state of SCK(串行时钟Serial Clock)
# phase=0 means sample on the first edge of SCK, phase=1 means the second
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)      # 读取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并同时读取内容到缓冲区
spi.write_readinto(buf, buf) # 写buf内容到MOSI并读取MISO内容到buf

**警告:**目前,在初始化软件 SPI 时必须指定sckmosimiso

SPI硬总线

有两个硬件SPI通道支持更快的传输速率(高达 80Mhz)。这些通道可用于任何支持所需方向且未使用的IO引脚(参见引脚和 GPIO),但如果未配置为默认引脚,则需要通过额外的 GPIO 多路复用层,这会影响其高速运行时的可靠性。硬件 SPI 通道在下列默认引脚之外的引脚上使用时,频率限制为40MHz。

HSPI(id=1)VSPI(id=2)
sck1418
mosi1323
miso1219

硬件SPI通过machine.SPI类访问,并且有跟上面软SPI同样的方法:

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

I2C软总线

软I2C(使用 bit-banging)可以工作在所有可输出引脚,通过machine.SoftI2C类进行访问:

from machine import Pin, SoftI2C

i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)

i2c.scan()              # 扫描设备

i2c.readfrom(0x3a, 4)   # 从地址为0x3a的设备读取4个字节
i2c.writeto(0x3a, '12') # 想地址为0x3a的设备写入'12'

buf = bytearray(10)     # 创建一个10字节的缓冲区
i2c.writeto(0x3a, buf)  # 将缓冲区的内容写入外设

I2C硬总线

这里有两个两个不同的硬总线外设0和1,任何可以输出的端口都可以被用于SCL和SDA,缺省情况如下:

||I2C(0)|I2c(1)|
|scl|18|25|
|sda|19|26|

驱动程序通过machine.I2C类进行访问,方法跟上面的软I2C相同:

from machine import Pin, I2C

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

I2S总线

使用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) # 创建I2S对象
i2s.write(buf)             # 将音频采样缓冲区写入I2S设备

i2s = I2S(1, sck=Pin(33), ws=Pin(25), sd=Pin(32), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # 创建I2S对象
i2s.readinto(buf)          # 从I2S设备填充到音频采样缓冲区

I2S类当前只有在技术预览版可用,在预览期间鼓励用户反馈问题,基于用户的反馈,I2S类相关的API实现可能会有调整。

实时时钟(RTC Real time clock)

使用machine.RTC

from machine import RTC

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

看门狗(WDT Watchdog timer)

使用machine.WDT

from machine import WDT

# 启用超时时间为5秒的看门狗(最小为1秒)
wdt = WDT(timeout=5000)
wdt.feed()

深度休眠模式(Deep-sleep mode)

以下代码可用于休眠、唤醒和检查复位原因:

import machine

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

# 让设备进入深度休眠模式10秒
machine.deepsleep(10000)

注意:

  • 调用deepsleep()方法时,如果没有参数将使设备处于无限期休眠状态。
  • 软件复位不会改变复位原因。

一些 ESP32 引脚(0、2、4、12-15、25-27、32-39)在深度睡眠期间连接到 RTC,并可使用 esp32 模块中的 wake_on_ 功能唤醒设备。在进入深度休眠状态时,具有输出功能的 RTC 引脚(除 34-39 引脚外的所有引脚)也将保留上拉或下拉电阻配置。

如果在深度休眠期间不需要上拉电阻,而且上拉电阻可能会导致电流泄漏(例如,上拉电阻通过开关连接到地),则应在进入深度休眠模式前禁用上拉电阻,以节省电能:

from machine import Pin, deepsleep

# 配置输入RTC引脚,启动时上拉
pin = Pin(2, Pin.IN, Pin.PULL_UP)

# 禁用上拉功能并让设备休眠 10 秒钟
pin.init(pull=None)
machine.deepsleep(10000)

如果使用 Pin.init() 的 hold=True 参数启用了焊盘保持,则输出配置的 RTC 引脚也将在深度休眠状态下保持其输出方向和电平。

进入深度休眠时,非 RTC GPIO 引脚将默认断开连接。非 RTC 引脚的配置(包括输出电平)可通过在引脚上启用焊盘保持和在深度休眠期间启用 GPIO 焊盘保持来保留:

from machine import Pin, deepsleep
import esp32

opin = Pin(19, Pin.OUT, value=1, hold=True) # 保持输出电平
ipin = Pin(21, Pin.IN, Pin.PULL_UP, hold=True) # 保持上拉

# 为非 RTC GPIO 启用深度休眠时的焊盘保持功能
esp32.gpio_deep_sleep_hold(True)

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

从休眠状态唤醒时,引脚配置(包括焊盘保持)将被保留。有关焊盘保持的进一步讨论,请参阅上文的引脚和 GPIO。

SD卡

使用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

遥控 RTM(Remote Control)

RMT为ESP32专用,可生成分辨率为 12.5ns 的精确数字脉冲,可以用于红外遥控器。用法如下:

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)
#通道分辨率为 100ns(1/(源频率/时钟分频))。
r.write_pulses((1, 20, 2, 40), 0) # 发送 0 表示 100 毫秒,1 表示 2000 毫秒,0 表示 200 毫秒,1 表示 4000 毫秒

OneWire驱动程序

OneWire 驱动程序通过软件实现,可用于所有引脚:

from machine import Pin
import onewire

ow = onewire.OneWire(Pin(12)) # 在GPIO12创建一个OneWire总线
ow.scan()               # 返回总线上的设备列表
ow.reset()              # 重置总线
ow.readbyte()           # 读取一个字节
ow.writebyte(0x12)      # 向总线写一个字节
ow.write('123')         # 向总线写多个字节
ow.select_rom(b'12345678') # 根据ROM代码选择指定的设备

DS18S20 和 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 和 APA106 驱动程序

使用 neopixel 和 apa106 模块:

from machine import Pin
from neopixel import NeoPixel

pin = Pin(0, Pin.OUT)   # 将GPIO0设置为NeoPixels设备
np = NeoPixel(pin, 8)   # 在 GPIO0 上为 8 个像素创建 NeoPixel 驱动程序
np[0] = (255, 255, 255) # 设置第1个点为白色
np.write()              # 将数据写入所有的点
r, g, b = np[0]         # 获取第一个像素点的颜色

APA106 驱动程序扩展了 NeoPixel,但内部使用了不同的颜色顺序:

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

**警告:**默认情况下,NeoPixel 被配置为控制更常用的 800kHz 设备。在构建 NeoPixel 对象时,可以通过 timing=0 来控制其他设备(通常为 400kHz)。

有关 NeoPixel 的底层驱动,参见 machine.bitstream。该底层驱动程序默认使用 RMT 通道,要进行配置,参见RMT.bitstream_channel

APA102 (DotStar) 使用不同的驱动器,它有一个额外的时钟引脚。

电容触摸(Capacitive touch)

machine模块中使用TouchPad类:

from machine import TouchPad, Pin

t = TouchPad(Pin(14))
t.read()              # 触摸时返回较小的数字

TouchPad.read 返回一个与电容变化相关的值。当引脚被触摸时,通常是小数(通常为几十),而当没有触摸时,则是大数(超过一千)。不过,数值是相对的,会因电路板和周围环境的不同而变化,因此可能需要进行一些校准。

ESP32上有10个支持电容式触摸的引脚:0、2、4、12、13、14、15、27、32、33。尝试为其他引脚赋值将导致ValueError

请注意,触摸板可用于从睡眠状态唤醒 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 进入休眠状态,直到触摸板被触摸

DHT 驱动

DHT 驱动程序由软件实现,可在所有引脚上运行:

import dht
import machine

d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # 例如: 23 (°C)
d.humidity()    # 例如: 41 (% RH)

d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # 例如: 23.6 (°C)
d.humidity()    # 例如: 41.3 (% RH)

网络浏览器交互 WebREPL(web browser interactive prompt)

WebREPL(WebSockets 上的 REPL,可通过网络浏览器访问)是 ESP32 端口的一项实验性功能。从 https://github.com/micropython/webrepl 下载 Web 客户端(托管版本可从 http://micropython.org/webrepl 获取),并通过执行以下操作进行配置:

import webrepl_setup

并按照屏幕上的说明操作。重启后,即可连接。如果禁用了开机自动启动功能,则可以使用以下命令按需运行配置的守护进程:

import webrepl
webrepl.start()

# or, start with a specific password
webrepl.start(password='mypass')

WebREPL 守护进程监听所有活动接口,这些接口可以是 STA 或 AP。这样,您就可以通过路由器(STA 接口)连接到 ESP32,或直接连接到 ESP32 的接入点。

除了终端/命令提示符访问外,WebREPL 还提供文件传输(上传和下载)功能。网络客户端有相应功能的按钮,也可以使用上面软件仓库中的命令行客户端 webrepl_cli.py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/368351.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

会计的记账凭证

目录 一. 记账凭证的填制与审核1.1 收付款凭证1.2 转账凭证1.3 单式记账凭证 二. 记账凭证的编号 \quad 一. 记账凭证的填制与审核 \quad \quad 1.1 收付款凭证 \quad 注意︰ 凡是涉及货币资金之间收付款的业务如将库存现金存入银行或从银行提取现金等类经济业务。在实际工作中…

探索设计模式的魅力:为什么你应该了解装饰器模式-代码优化与重构的秘诀

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 开篇 在一个常常需要在不破坏封装的前提下扩展对象功能的编程世界&#xff0c;有一个模式悄无声息地成为了高级编程技术的隐形冠军。我们日复一日地享受着它带来的便利&#xff0c;却往往对其背后的复杂性视而不见。它是怎样…

幻兽帕鲁服务器多少钱?价格PK阿里云腾讯云华为云

2024年幻兽帕鲁服务器价格表更新&#xff0c;阿里云、腾讯云和华为云Palworld服务器报价大全&#xff0c;4核16G幻兽帕鲁专用服务器阿里云26元、腾讯云32元、华为云26元&#xff0c;阿腾云atengyun.com分享幻兽帕鲁服务器优惠价格表&#xff0c;多配置报价&#xff1a; 幻兽帕鲁…

【C++】C++入门— 类与对象初步介绍

C入门 1 认识面向对象2 类的引入3 类的定义类的定义方式 4 类的访问限定符及封装访问限定符封装 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 1 认识面向对象 C语言是面向过程的&#xff0c;关注…

位运算之妙用:识别独特数字(寻找单身狗)

目录 找单身狗1 图解&#xff1a; 代码如下&#xff1a; 找单身狗2 图解&#xff1a; 代码如下&#xff1a; 寻找单身狗1 从数组中 的1 2 3 4 5 1 2 3 4 中找出没有另一个相同的数与其匹配的数 这个问题的原理是利用异或运算的性质。异或运算&#xff08;XOR&#xff09…

java学习03 判断和循环

一 流程控制语句 1.流程控制语句分类 顺序结构 判断和选择结构(if, switch) 循环结构(for, while, do…while) 2. 顺序结构 顺序结构是程序中最简单最基本的流程控制&#xff0c;没有特定的语法结构&#xff0c;按照代码的先后顺序&#xff0c;依次执行&#xff0c;程序中…

Blender使用Rigify和Game Rig Tool基础

做动画需要的几个简要步骤&#xff1a; 1.建模 2.绑定骨骼 3.绘制权重 4.动画 有一个免费的插件可以处理好给引擎用&#xff1a;Game Rig Tool 3.6和4.0版本的 百度网盘 提取码&#xff1a;vju8 1.Rigify是干嘛用的&#xff1f; 》 绑定骨骼 2.Game Rig Tool干嘛用的&#xf…

Revit中使用依赖注入

依赖注入的技术已经很成熟&#xff0c;本文主要是说明一下Revit中的适用版本与介绍相关的开源项目。 版本问题 版本 目前的依赖注入包无法支持Revit 2020 以下的版本&#xff0c;原因是因为包中的依赖项与Revit本身的依赖项不一致导致的&#xff0c;所以说如果使用Revit DI…

2V2无人机红蓝对抗仿真

两架红方和蓝方无人机分别从不同位置起飞&#xff0c;蓝方无人机跟踪及击毁红方无人机 2020a可正常运行 2V2无人机红蓝对抗仿真资源-CSDN文库

探索Gin框架:Golang使用Gin完成文件上传

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 前言 在之前的文章中&#xff0c;我们讲解了Gin框架的快速入门使用&#xff0c;今天我们来聊聊如何使用…

单细胞scATAC-seq测序基础知识笔记

单细胞scATAC-seq测序基础知识笔记 单细胞ATAC测序前言scATAC-seq数据怎么得出的&#xff1f; 该笔记来源于 Costa Lab - Bioinformatics Course 另一篇关于scRNA-seq的请移步 单细胞ATAC测序前言 因为我的最终目的是scATAC-seq的数据&#xff0c;所以这部分只是分享下我刚学…

c++类继承

一、继承的规则 &#xff08;1&#xff09;基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如&#xff0c;当继承方式为protected时&#xff0c;那么基类成员在派生类中的访问权限最高也为protected&#xff0c;高于protected会降级为protected&#xff0c;但低…

阿里云部署的幻兽帕鲁服务器,为什么没有一键更新游戏服务端、导入存档、可视化的游戏配置

如果有的朋友发现自己用阿里云部署的幻兽帕鲁服务器&#xff0c;找不到一键更新游戏服务端、一键导入存档、以及可视化的游戏配置。其实答案很简单&#xff0c;因为你的“阿里云计算巢”版本需要更新。你只需要更新到最新版&#xff0c;就可以拥有这些便捷的功能了。 具体的操…

【备战蓝桥杯】——循环结构终篇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-yl4Tqejg4LkjZLAM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

一文辨析清楚LORA、Prompt Tuning、P-Tuning、Adapter 、Prefix等大模型微调方法

本文探讨了大模型微调的核心概念和方法&#xff0c;详细介绍了如LoRA、Adapter Tuning、Prefix Tuning等多种微调策略。每种方法的原理、优势及适用场景都有详尽阐述&#xff0c;大家可以根据不同的应用需求和计算资源&#xff0c;选择到最合适自己的微调途径。 希望本文能对想…

Linux下grep命令详解

grep #文件内容过滤显示 #在指定的普通文件中查找并显示含有指定字符串的行&#xff0c;也可与管道符一起使用格式&#xff1a; grep-参数 查找条件 文件名 参数&#xff1a; 示例&#xff1a; [rootnode1 ~]# grep -n "root" /etc/passwd # -n&a…

LangChain结合通义千问的自建知识库

LangChain结合通义千问的自建知识库 在使用了通义千问API了之后&#xff0c;下一步就是构建知识库文档&#xff0c;使用了比较有名的LangChian&#xff0c;最后成果将自己的txt生成了知识向量库&#xff0c;最后我还把自己的论文生成了一个知识向量库&#xff0c;然后问他我的…

Java 基于 SpringBoot+Vue 的前后端分离的火车订票管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Cambalache in Ubuntu

文章目录 前言apt install flatpak这很ok后记 前言 gtkmm4相比gtkmm3有很多改革, 代码也干净了许多, 但在windows上开发 有ui设计器那自然方便很多, 但glade又不支持gtkmm4, windows上装Cambalache很是困难. 各种问题都找不到答案.于是 我用VMware虚拟机Ubuntu20.xx安装Cambal…

C++集群聊天服务器 网络模块+业务模块+CMake构建项目 笔记 (上)

跟着施磊老师做C项目&#xff0c;施磊老师_腾讯课堂 (qq.com) 一、网络模块ChatServer chatserver.hpp #ifndef CHATSERVER_H #define CHATSERVER_H#include <muduo/net/TcpServer.h> #include <muduo/net/EventLoop.h> using namespace muduo; using namespace …