【雕爷学编程】MicroPython手册之 SAMD21 OneWire驱动

在这里插入图片描述
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进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述
SAMD21是一系列使用32位ARM® Cortex®-M0+处理器的低功耗微控制器,由Microchip Technology公司开发。SAMD21的技术参数如下:

1、处理器:32位ARM® Cortex®-M0+,最高工作频率为48MHz,每兆赫兹可达2.46 Coremark。
2、存储器:闪存容量从32KB到256KB不等,SRAM容量从4KB到32KB不等。
3、电源管理:支持多种低功耗模式,如空闲和待机模式,最低功耗为3.5μA/MHz。
4、外设:拥有丰富的智能和灵活的外设,如直接内存访问控制器(DMAC)、事件系统、定时器/计数器(TC/TCC)、实时时钟(RTC)、看门狗定时器(WDT)、CRC-32生成器、通用串行总线(USB)2.0接口、串行通信接口(SERCOM)、Inter-IC Sound(I2S)接口、模数转换器(ADC/DAC)、模拟比较器(AC)和外设触摸控制器(PTC)。
5、封装:支持多种封装形式,从32引脚到64引脚不等,包括TQFP、QFN、UFBGA和WLCSP。
6、标准:符合AEC-Q100 Grade 1的汽车级标准,工作温度范围为-40°C到+125°C。

在这里插入图片描述

MicroPython是一种适用于嵌入式系统的Python语言的变体,它可以在SAMD21微控制器上运行,实现各种功能。OneWire是一种串行通信协议,它只需要一根数据线和地线,就可以连接多个设备,如温度传感器、湿度传感器、电表等。MicroPython提供了onewire和ds18x20两个模块,用于驱动OneWire协议和DS18x20系列的温度传感器。

主要特点:

硬件支持:SAMD21 OneWire驱动通过SAMD21微控制器的硬件外设实现,具有硬件支持的特点。这使得OneWire通信协议能够在硬件层面上得到有效的支持,提供更高的性能和稳定性。
简单接口:SAMD21 OneWire驱动提供简单易用的接口,使得开发者能够方便地通过MicroPython代码进行OneWire通信的操作。这简化了OneWire应用的开发过程,降低了学习和使用的门槛。
多设备支持:SAMD21 OneWire驱动通常支持连接多个OneWire设备。通过合适的硬件连接和软件控制,可以同时与多个OneWire设备进行通信,实现多设备间的数据交换。
低功耗:OneWire通信协议本身具有低功耗的特点,而SAMD21微控制器也支持低功耗模式。因此,SAMD21 OneWire驱动在低功耗应用中具有一定的优势。

应用场景:

温度传感器:OneWire通信协议广泛应用于各种温度传感器,如DS18B20等。SAMD21 OneWire驱动可以用于与这些温度传感器进行通信,获取温度数据并进行处理。
计时器/计数器:OneWire通信协议还可用于连接计时器或计数器设备,如DS2406等。通过SAMD21 OneWire驱动,可以实现对这些设备的读取和控制,方便地进行时间测量和计数操作。
物联网设备:由于OneWire通信协议具有简单和低功耗的特点,SAMD21 OneWire驱动在物联网设备中具有广泛的应用前景。它可以用于与各种传感器、执行器等设备进行通信,实现物联网系统的数据采集和控制功能。

注意事项:

引脚配置:在使用SAMD21 OneWire驱动之前,需要正确配置相关的GPIO引脚。确保所选的引脚与OneWire设备的连接正确,并满足引脚的电压和功能要求。
软件实现复杂性:尽管OneWire通信协议相对简单,但实现一个稳定和可靠的OneWire驱动仍然需要开发者具备一定的软件开发和调试能力。在使用SAMD21 OneWire驱动时,需要进行充分的测试和验证,确保其稳定性和可靠性。

综上所述,MicroPython的SAMD21 OneWire驱动通过SAMD21微控制器的硬件外设实现,具有硬件支持、简单接口、多设备支持和低功耗等特点。适用于温度传感器、计时器/计数器和物联网设备等应用场景。在使用SAMD21 OneWire驱动时,需要注意正确配置GPIO引脚、具备一定的软件开发和调试能力,以确保OneWire通信的稳定性和可靠性。

在这里插入图片描述

案例1:读取温度传感器的数据

from machine import Pin, I2C
import onewire


# 初始化I2C和OneWire对象
i2c = I2C(scl=Pin(5), sda=Pin(4))
ow = OneWire(i2c)

# 重置OneWire
ow.reset()

# 设置温度传感器的地址
TEMP_ADDR = 0x90

# 读取温度数据
temp = ow.read_temp_and_humidity(TEMP_ADDR)

# 打印温度数据
print("Temperature: {0:.2f} C".format(temp[0]))

解读:这个程序首先导入了必要的库,然后初始化了I2C和OneWire对象。接着,它重置OneWire并设置了温度传感器的地址。最后,它读取温度数据并打印出来。

案例2:写入数字温度传感器的数据

from machine import Pin, I2C
import onewire

# 初始化I2C和OneWire对象
i2c = I2C(scl=Pin(5), sda=Pin(4))
ow = OneWire(i2c)

# 重置OneWire
ow.reset()

# 设置数字温度传感器的地址
TEMP_ADDR = 0x30

# 要写入的温度数据
temp_data = [25.0, 26.0, 27.0]

# 将温度数据转换为字节数组
temp_bytes = bytearray(temp_data)

# 写入温度数据
ow.write_byte(TEMP_ADDR, temp_bytes)

解读:这个程序与第一个案例类似,但它读取的是一个数字温度传感器的数据。首先,它将温度数据转换为字节数组,然后使用write_byte方法将数据写入传感器。

案例3:读取湿度传感器的数据

from machine import Pin, I2C
import onewire

# 初始化I2C和OneWire对象
i2c = I2C(scl=Pin(5), sda=Pin(4))
ow = OneWire(i2c)

# 重置OneWire
ow.reset()

# 设置湿度传感器的地址
HUMIDITY_ADDR = 0x40

# 读取湿度数据
humidity = ow.read_humidity(HUMIDITY_ADDR)

# 打印湿度数据
print("Humidity: {0:.2f} %".format(humidity))

解读:这个程序与前两个案例类似,但它读取的是一个湿度传感器的数据。首先,它设置了湿度传感器的地址,然后使用read_humidity方法读取数据。最后,它打印出湿度数据。

案例4:使用OneWire驱动读取DS18B20温度传感器的温度值

import machine  
import onewire  
import ds18x20  
  
# 设置GPIO引脚为OneWire通信引脚  
pin = machine.Pin(1, machine.Pin.OUT)  
ow = onewire.OneWire(pin)  
  
# 搜索DS18B20设备  
roms = ow.search()  
if not roms:  
    print("No DS18B20 devices found.")  
else:  
    # 读取第一个DS18B20设备的温度值  
    ds = ds18x20.DS18X20(ow, roms[0])  
    temperature = ds.temperature()  
    print("Temperature:", temperature)

要点解读:
首先导入所需的模块,包括machine、onewire和ds18x20。
然后将GPIO引脚1设置为OneWire通信引脚,并创建一个OneWire对象。
使用ow.search()方法搜索DS18B20设备,如果没有找到设备则打印错误信息。
如果找到了设备,则创建一个DS18X20对象并读取其温度值。最后打印出温度值。

案例五:使用OneWire驱动控制Max6675 K型热电偶温度传感器

import machine  
import onewire  
import max6675  
  
# 设置GPIO引脚为OneWire通信引脚  
pin = machine.Pin(1, machine.Pin.OUT)  
ow = onewire.OneWire(pin)  
  
# 搜索Max6675设备  
roms = ow.search()  
if not roms:  
    print("No Max6675 devices found.")  
else:  
    # 创建Max6675对象并读取温度值  
    max = max6675.MAX6675(ow, roms[0])  
    temperature = max.temperature()  
    print("Temperature:", temperature)

要点解读:
首先导入所需的模块,包括machine、onewire和max6675。
然后将GPIO引脚1设置为OneWire通信引脚,并创建一个OneWire对象。
使用ow.search()方法搜索Max6675设备,如果没有找到设备则打印错误信息。
如果找到了设备,则创建一个MAX6675对象并读取其温度值。最后打印出温度值。

案例六:使用OneWire驱动控制DHT11温湿度传感器

import machine  
import onewire  
import dht  
  
# 设置GPIO引脚为OneWire通信引脚  
pin = machine.Pin(1, machine.Pin.OUT)  
ow = onewire.OneWire(pin)  
  
# 搜索DHT11设备  
roms = ow.search()  
if not roms:  
    print("No DHT11 devices found.")  
else:  
    # 创建DHT对象并读取温湿度值  
    dht_device = dht.DHT11(ow, roms[0])  
    temperature, humidity = dht_device.read()  
    print("Temperature:", temperature)  
    print("Humidity:", humidity)

要点解读:
首先导入所需的模块,包括machine、onewire和dht。
然后将GPIO引脚1设置为OneWire通信引脚,并创建一个OneWire对象。
使用ow.search()方法搜索DHT11设备,如果没有找到设备则打印错误信息。
如果找到了设备,则创建一个DHT11对象并读取其温湿度值。最后打印出温湿度值。

案例7:测量并显示单个DS18B20温度传感器的温度值

import time
import machine
import onewire, ds18x20

# 创建一个Pin对象,连接到数据线上
dat = machine.Pin(12)

# 创建一个OneWire对象
ow = onewire.OneWire(dat)

# 创建一个DS18X20对象
ds = ds18x20.DS18X20(ow)

# 扫描总线上的设备,返回一个列表
roms = ds.scan()

# 如果列表不为空,说明找到了至少一个设备
if roms:
    # 取出列表中的第一个设备的rom号
    rom = roms[0]
    # 循环10次,每次测量并显示温度值
    for i in range(10):
        # 启动温度转换,需要等待至少750毫秒
        ds.convert_temp()
        time.sleep_ms(750)
        # 读取温度值,单位为摄氏度
        temp = ds.read_temp(rom)
        # 打印温度值
        print(temp)

案例八二:测量并显示多个DS18B20温度传感器的温度值

import time
import machine
import onewire, ds18x20

# 创建一个Pin对象,连接到数据线上
dat = machine.Pin(12)

# 创建一个OneWire对象
ow = onewire.OneWire(dat)

# 创建一个DS18X20对象
ds = ds18x20.DS18X20(ow)

# 扫描总线上的设备,返回一个列表
roms = ds.scan()

# 如果列表不为空,说明找到了至少一个设备
if roms:
    # 循环10次,每次测量并显示所有设备的温度值
    for i in range(10):
        # 启动所有设备的温度转换,需要等待至少750毫秒
        ds.convert_temp()
        time.sleep_ms(750)
        # 遍历列表中的每个设备的rom号
        for rom in roms:
            # 读取温度值,单位为摄氏度
            temp = ds.read_temp(rom)
            # 打印rom号和温度值
            print(rom, temp)

案例九:设置DS18B20温度传感器的报警阈值,并检测是否触发报警

import time
import machine
import onewire, ds18x20

# 创建一个Pin对象,连接到数据线上
dat = machine.Pin(12)

# 创建一个OneWire对象
ow = onewire.OneWire(dat)

# 创建一个DS18X20对象
ds = ds18x20.DS18X20(ow)

# 扫描总线上的设备,返回一个列表
roms = ds.scan()

# 如果列表不为空,说明找到了至少一个设备
if roms:
    # 取出列表中的第一个设备的rom号
    rom = roms[0]
    # 设置该设备的报警阈值为10摄氏度和30摄氏度(高位字节和低位字节)
    ds.write_scratch(rom, b'\x0a\x1e')
    # 循环检测是否触发报警
    while True:
        # 启动温度转换,需要等待至少750毫秒
        ds.convert_temp()
        time.sleep_ms(750)
        # 读取温度值,单位为摄氏度
        temp = ds.read_temp(rom)
        # 打印温度值
        print(temp)
        # 重置总线,准备发送报警搜索命令
        ow.reset()
        # 发送报警搜索命令(0xEC),返回一个列表
        alarm_roms = ow.search_rom(0xEC)
        # 如果列表不为空,说明有设备触发了报警
        if alarm_roms:
            # 打印触发报警的设备的rom号
            print('Alarm:', alarm_roms)

这个程序的要点解读如下:
首先,导入需要的模块,包括time、machine、onewire和ds18x20。
然后,创建一个Pin对象,连接到数据线上。这里假设数据线连接到12号引脚。
接着,创建一个OneWire对象,传入Pin对象作为参数。这个对象封装了OneWire协议的底层操作,如复位、读写字节、搜索设备等。
然后,创建一个DS18X20对象,传入OneWire对象作为参数。这个对象封装了DS18X20系列温度传感器的特定操作,如启动温度转换、读取温度值、写入暂存器等。
接着,调用DS18X20对象的scan方法,扫描总线上的设备,返回一个列表。每个列表元素是一个8字节的rom号,用来唯一标识一个设备。
然后,判断列表是否为空。如果为空,说明没有找到任何设备,程序结束。如果不为空,说明找到了至少一个设备,继续执行。
接着,取出列表中的第一个设备的rom号。这里假设只有一个设备连接到总线上。如果有多个设备,可以遍历列表中的每个元素。
然后,调用DS18X20对象的write_scratch方法,写入暂存器。这个方法需要两个参数:rom号和数据。数据是一个9字节的字节串,用来设置温度传感器的配置。其中最重要的是第二字节和第三字节,分别表示报警高温阈值和报警低温阈值。这里设置为10摄氏度和30摄氏度(高位字节和低位字节),即如果温度低于10摄氏度或高于30摄氏度,则触发报警。
接着,进入一个无限循环,检测是否触发报警。
在循环中,首先调用DS18X20对象的convert_temp方法,启动所有设备的温度转换。这个方法需要等待至少750毫秒才能完成转换,所以使用time模块的sleep_ms方法暂停750毫秒。
然后,调用DS18X20对象的read_temp方法,读取温度值。这个方法需要一个参数:rom号。它会返回一个浮点数,表示温度值,单位为摄氏度。然后,使用print函数打印温度值。
接着,调用OneWire对象的reset方法,重置总线,准备发送报警搜索命令。这个命令的作用是找出触发了报警的设备,并返回它们的rom号。
然后,调用OneWire对象的search_rom方法,发送报警搜索命令。这个方法需要一个参数:命令字节。报警搜索命令的字节是0xEC。它会返回一个列表,包含触发了报警的设备的rom号。
接着,判断列表是否为空。如果为空,说明没有设备触发了报警,继续循环。如果不为空,说明有设备触发了报警,使用print函数打印触发报警的设备的rom号。

请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。确保正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/133450101