MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。
MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。
MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。
使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。
总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
MicroPython的esp是指针对ESP8266和ESP32芯片的MicroPython固件和相关软件库。ESP8266和ESP32是一类广泛应用于物联网和嵌入式系统的低成本、低功耗的Wi-Fi和蓝牙模块。MicroPython的esp为这两种芯片提供了高级的脚本编程环境,使开发者能够使用Python语言进行快速原型设计和开发。
ESP8266:是一款低成本、低功耗的Wi-Fi模块/芯片,由Espressif Systems开发。它内置了TCP/IP协议栈,可以用于连接互联网,并具备较强的处理能力。MicroPython的esp提供了针对ESP8266的固件和相关软件库,使开发者可以使用MicroPython语言进行ESP8266应用的开发。
ESP32:是Espressif Systems推出的一款高度集成的Wi-Fi和蓝牙模块/芯片,与ESP8266相比,它具备更强大的处理能力、更多的外设接口和更多的内存。MicroPython的esp也提供了针对ESP32的固件和相关软件库,使开发者可以使用MicroPython语言进行ESP32应用的开发。
MicroPython的esp固件:是专门针对ESP8266和ESP32芯片的MicroPython固件版本。这些固件经过了针对性的优化,使得它们可以在ESP8266和ESP32上运行,并提供了与硬件交互、网络通信和外设控制等功能的API。
软件库:MicroPython的esp还提供了一系列与ESP8266和ESP32硬件相关的软件库,用于简化和加速开发过程。这些软件库提供了丰富的功能接口,涵盖了Wi-Fi、蓝牙、GPIO(通用输入输出)、I2C、SPI、PWM等常用的硬件和通信协议,使开发者可以方便地访问和控制硬件资源。
MicroPython的esp32.RMT()是一个用于在ESP32模块上控制RMT(Remote Control)模块的功能。它有以下主要特点、应用场景和注意事项:
主要特点:
esp32.RMT()是一个类,它的构造函数可以创建一个表示RMT通道的对象,并配置相关的参数,如引脚、时钟分频、空闲电平、载波频率等。
esp32.RMT()对象可以使用write_pulses()方法来发送一系列的高低电平脉冲,或者使用read_pulses()方法来接收一系列的高低电平脉冲。
esp32.RMT()对象可以使用loop()方法来设置是否循环发送或接收脉冲,或者使用wait_done()方法来等待发送或接收完成。
esp32.RMT()对象可以使用deinit()方法来释放RMT通道和引脚资源。
应用场景:
esp32.RMT()的功能最初设计用于发送和接收红外遥控信号,因此可以用于实现红外遥控器或红外接收器的功能,例如控制电视机、空调等设备。
esp32.RMT()的功能由于设计灵活且脉冲生成非常准确(低至12.5ns),因此还可以用于传输或接收许多其他类型的数字信号,例如WS2812 LED灯带、DHT11温湿度传感器、NEC编码等。
esp32.RMT()的功能还可以用于实现一些需要高速或精确时序的应用,例如PWM(脉冲宽度调制)、PPM(脉冲位置调制)、PCM(脉冲编码调制)等。
注意事项:
esp32.RMT()的功能需要注意与其他占用RMT通道或引脚的功能的冲突,例如SPI、I2C、UART等。
esp32.RMT()的功能需要注意与其他占用CPU时间或内存资源的功能的影响,例如网络通信、文件系统、垃圾回收等。
esp32.RMT()的功能需要注意与其他需要中断服务或定时器服务的功能的协调,例如机器定时器、机器中断等。
以下是几个使用MicroPython的esp32.RMT()功能的实际运用程序案例:
案例一:使用esp32.RMT()来发送一个NEC编码的红外遥控信号,控制电视机开关。
# 导入必要的模块
import esp32
from machine import Pin
# 定义一个NEC编码函数,将命令和地址转换为高低电平脉冲序列
def nec_encode(cmd, addr):
# 定义NEC编码中不同位对应的高低电平脉冲长度(单位为微秒)
# 0: 562us low, 562us high
# 1: 562us low, 1687us high
# start: 9000us low, 4500us high
# stop: 562us low, high until next start
pulse0 = (562, 562)
pulse1 = (562, 1687)
pulse_start = (9000, 4500)
pulse_stop = (562,)
# 定义一个空列表,用于存储高低电平脉冲序列
pulses = []
# 添加起始位
pulses += pulse_start
# 添加地址位,共16位,先低字节后高字节,先低位后高位
for i in range(16):
# 判断地址的第i位是0还是1,并添加相应的脉冲
if addr & (1 << i):
pulses += pulse1
else:
pulses += pulse0
# 添加命令位,共16位,先低字节后高字节,先低位后高位
for i in range(16):
# 判断命令的第i位是0还是1,并添加相应的脉冲
if cmd & (1 << i):
pulses += pulse1
else:
pulses += pulse0
# 添加结束位
pulses += pulse_stop
# 返回高低电平脉冲序列
return pulses
# 定义一个发送红外遥控信号的函数,使用esp32.RMT()对象来发送高低电平脉冲序列
def ir_send(pulses):
# 创建一个esp32.RMT()对象,使用第0个通道,绑定到第18号引脚
rmt = esp32.RMT(0, pin=Pin(18))
# 调用write_pulses()方法来发送高低电平脉冲序列,start参数为True表示立即发送
rmt.write_pulses(pulses, start=True)
# 调用wait_done()方法来等待发送完成
rmt.wait_done()
# 调用deinit()方法来释放RMT通道和引脚资源
rmt.deinit()
# 定义一个控制电视机开关的函数,使用NEC编码中的0x00FF为命令,0x0000为地址
def tv_toggle():
# 调用nec_encode()函数来生成NEC编码的高低电平脉冲序列
pulses = nec_encode(0x00FF, 0x0000)
# 调用ir_send()函数来发送红外遥控信号
ir_send(pulses)
# 调用tv_toggle()函数来控制电视机开关
tv_toggle()
案例二:使用esp32.RMT()来接收一个DHT11温湿度传感器的数字信号,并解析出温度和湿度的值。
# 导入必要的模块
import esp32
from machine import Pin
# 定义一个读取DHT11传感器数据的函数,使用esp32.RMT()对象来接收数字信号,并返回温度和湿度的值
def dht11_read(pin):
# 创建一个esp32.RMT()对象,使用第1个通道,绑定到指定的引脚
rmt = esp32.RMT(1, pin=Pin(pin))
# 生成一个开始信号,即拉低数据线18毫秒,然后拉高40微秒
start_signal = (0, 18000, 1, 40)
# 发送开始信号,start参数为True表示立即发送
rmt.write_pulses(start_signal, start=True)
# 等待发送完成
rmt.wait_done()
# 切换到接收模式,准备接收传感器数据
rmt.init(rx_idle_thresh=50)
# 接收40个数据位,每个数据位由50微秒的低电平和不同长度的高电平组成,
# 高电平长度为26-28微秒表示0,长度为70微秒表示1,
# 返回一个元组列表,每个元组包含两个整数,分别表示高低电平的时长(单位为微秒)
data_pulses = rmt.read_pulses(40)
# 释放RMT通道和引脚资源
rmt.deinit()
# 定义一个空列表,用于存储数据位的值(0或1)
data_bits = []
# 遍历接收到的数据脉冲
for low, high in data_pulses:
# 判断高电平时长是否在合理范围内(50-90微秒),如果不是,则返回错误提示
if not 50 <= high <= 90:
return 'Invalid pulse length.'
# 如果高电平时长在26-28微秒之间,则认为是0,并添加到数据位列表中
elif 26 <= high <= 28:
data_bits.append(0)
# 如果高电平时长在70微秒左右,则认为是1,并添加到数据位列表中
elif high >= 70:
data_bits.append(1)
# 判断数据位列表的长度是否为40,如果不是,则返回错误提示
if len(data_bits) != 40:
return 'Invalid bit count.'
# 将数据位列表分割为5个字节,分别表示湿度整数部分、湿度小数部分、温度整数部分、温度小数部分和校验和
humidity_int, humidity_dec, temp_int, temp_dec, checksum = [int(''.join(map(str, data_bits[i:i+8])), 2) for i in range(0, 40, 8)]
# 计算前四个字节的和,并与校验和比较,如果不相等,则返回错误提示
if (humidity_int + humidity_dec + temp_int + temp_dec) & 0xFF != checksum:
return 'Invalid checksum.'
# 计算湿度和温度的值,并返回结果
humidity = humidity_int + humidity_dec / 10
temp = temp_int + temp_dec / 10
return humidity, temp
# 调用dht11_read()函数,并打印出结果
print(dht11_read(19))
案例三:使用machine.Timer类来创建一个定时器中断,并在IRAM中执行一个回调函数,该回调函数会在每次中断时打印出一个计数值。
# 导入必要的模块
import machine
# 定义一个全局变量,用于存储计数值
count = 0
# 定义一个回调函数,并使用@micropython.viper
# 装饰器来指示使用native code emitter,并使用@micropython.alloc_emergency_exception_buf(size)
# 装饰器来分配一些IRAM空间,用于处理异常
@micropython.viper
@micropython.alloc_emergency_exception_buf(256)
def callback(timer):
# 声明全局变量
global count
# 将计数值加一,并打印出结果
count += 1
print(count)
# 创建一个定时器对象,使用第0号定时器,设置为周期模式
timer = machine.Timer(0, mode=machine.Timer.PERIODIC)
# 初始化定时器,设置周期为1000毫秒,设置回调函数为callback
timer.init(period=1000, callback=callback)
这是一个使用MicroPython的esp32.HEAP_EXEC功能的实际运用程序案例,它可以在ESP32模块上实现一个定时器中断,并在IRAM中执行一个回调函数。该回调函数会在每次中断时打印出一个计数值,从而展示了esp32.HEAP_EXEC功能的用法和效果。
案例四:发送红外信号:
import machine
import esp32
# 初始化RMT通道
rmt = machine.RMT(0, pin=machine.Pin(14), clock_div=80)
# 创建红外信号模式
carrier_freq = 38000
signal = esp32.RMT.Signal(carrier_freq, [1, 0, 1, 0, 1, 0, 1, 0])
# 发送红外信号
rmt.write_pulses(signal, start_level=0)
在这个例子中,我们使用esp32.RMT()初始化一个RMT通道。我们通过传递通道号、引脚和时钟分频器来创建一个machine.RMT对象。然后,我们使用esp32.RMT.Signal()创建一个红外信号模式,其中包含载波频率和脉冲序列。最后,我们使用write_pulses()方法将红外信号发送出去。
案例五:接收红外信号:
import machine
import esp32
# 初始化RMT通道
rmt = machine.RMT(0, pin=machine.Pin(14), clock_div=80)
# 启用接收模式
rmt_rx = rmt.rx_start(20)
# 接收红外信号
while True:
if rmt.rx_waiting():
pulses = rmt.read_pulses()
print("接收到的脉冲序列:", pulses)
在这个例子中,我们使用esp32.RMT()初始化一个RMT通道。我们通过传递通道号、引脚和时钟分频器来创建一个machine.RMT对象。然后,我们使用rx_start()方法启用接收模式,并指定接收缓冲区的大小。接下来,我们使用一个循环来检查是否有接收到的红外信号。如果有,我们使用read_pulses()方法读取脉冲序列,并打印出来。
案例六:发送脉冲序列:
import machine
import esp32
# 初始化RMT通道
rmt = machine.RMT(0, pin=machine.Pin(14), clock_div=80)
# 创建自定义脉冲序列
pulses = [10, 5, 20, 10, 15, 5, 30, 20]
# 发送脉冲序列
rmt.write_pulses(pulses, start_level=0)
在这个例子中,我们使用esp32.RMT()初始化一个RMT通道。我们通过传递通道号、引脚和时钟分频器来创建一个machine.RMT对象。然后,我们创建一个自定义的脉冲序列,其中包含一系列脉冲的持续时间。最后,我们使用write_pulses()方法将脉冲序列发送出去。
案例七:发送红外信号:
import esp32
from machine import Pin
from esp32 import RMT
# 设置红外遥控器发射器引脚
ir_pin = Pin(14, Pin.OUT, Pin.PULL_DOWN) # 根据实际引脚连接情况设置
# 创建 RMT 实例
rmt = RMT(0, pin=ir_pin, clock_div=80) # 根据实际需求设置 RMT 控制器编号和时钟分频
# 定义红外信号数据
data = [0x00, 0xFF, 0x00] # 根据实际需要定义红外信号的数据
# 发送红外信号
rmt.write_pulses(data, start_level=1)
案例八: 接收红外信号:
import esp32
from machine import Pin
from esp32 import RMT
# 设置红外遥控器接收器引脚
ir_pin = Pin(15, Pin.IN, Pin.PULL_UP) # 根据实际引脚连接情况设置
# 创建 RMT 实例
rmt = RMT(1, pin=ir_pin)
# 启用红外遥控器接收功能
rmt.rx_start()
# 等待接收到红外信号
while not rmt.rx_received():
pass
# 获取接收到的红外信号数据
data = rmt.rx_get_values()
print("接收到的红外信号:", data)
案例九:设置红外信号参数:
import esp32
from machine import Pin
from esp32 import RMT
# 设置红外遥控器发射器引脚
ir_pin = Pin(14, Pin.OUT, Pin.PULL_DOWN) # 根据实际引脚连接情况设置
# 创建 RMT 实例
rmt = RMT(0, pin=ir_pin, clock_div=80) # 根据实际需求设置 RMT 控制器编号和时钟分频
# 设置红外信号的重复次数
rmt.loop_count(3) # 设置红外信号重复发送 3 次
# 设置红外信号的占空比
rmt.carrier_duty_percent(50) # 设置红外信号的占空比为 50%
# 定义红外信号数据
data = [0x00, 0xFF, 0x00] # 根据实际需要定义红外信号的数据
# 发送红外信号
rmt.write_pulses(data, start_level=1)
这些示例程序展示了如何使用 esp32.RMT() 类来控制 ESP32 的红外遥控器发射和接收功能。根据实际需求,您可以调整和扩展这些示例程序,以满足特定的红外遥控应用场景。