文章目录
1. 前言
在这个智能硬件和物联网时代,MicroPython和树莓派PICO正以其独特的优势引领着嵌入式开发的新潮流。MicroPython作为一种精简优化的Python 3语言,为微控制器和嵌入式设备提供了高效开发和简易调试的
当我们结合WIZnet W5100S/W5500网络模块,MicroPython和树莓派PICO的开发潜力被进一步放大。这两款模块都内置了TCP/IP协议栈,使得在嵌入式设备上实现网络连接变得更加容易。无论是进行数据传输、远程控制,还是构建物联网应用,它们都提供了强大的支持。
本章我们将以WIZnet W5100S为例,以MicroPython的开发方式,连接至阿里云的物联网平台上,并定时上报DHT11传感器的温湿度信息以及平台下发指令控制LED灯亮灭。
2. 平台操作流程
第一步:创建产品
第二步:定义物模型
第三步:创建设备
第四步:记录参数
参数名 | 参数值 |
---|---|
mqttHostUrl | iot-06z00dbroeg8dx3.mqtt.iothub.aliyuncs.com |
port | 1883 |
clientId | ieojgBm5q2c.W5100S_W5500|securemode=2,signmethod=hmacsha256,timestamp=1701222846581| |
username | W5100S_W5500&ieojgBm5q2c |
passwd | fdac6b605808aed345f4b98078519b349db65688604c64fc375c12b326e821ff |
发布主题 | /sys/ieojgBm5q2c/${deviceName}/thing/event/property/post |
订阅主题 | /sys/ieojgBm5q2c/${deviceName}/thing/service/property/set |
注意:需要把物模型的主题中的${deviceName}替换成平台上的设备名
3. WIZnet以太网芯片
WIZnet 主流硬件协议栈以太网芯片参数对比
Model | Embedded Core | Host I/F | TX/RX Buffer | HW Socket | Network Performance |
---|---|---|---|---|---|
W5100S | TCP/IPv4, MAC & PHY | 8bit BUS, SPI | 16KB | 4 | Max 25Mbps |
W6100 | TCP/IPv4/IPv6, MAC & PHY | 8bit BUS, Fast SPI | 32KB | 8 | Max 25Mbps |
W5500 | TCP/IPv4, MAC & PHY | Fast SPI | 32KB | 8 | Max 15Mbps |
- W5100S/W6100 支持 8bit数据总线接口,网络传输速度会优于W5500。
- W6100 支持IPV6,与W5100S 硬件兼容,若已使用W5100S的用户需要支持IPv6,可以Pin to Pin兼容。
- W5500 拥有比 W5100S更多的 Socket数量以及发送与接收缓存
相较于软件协议栈,WIZnet的硬件协议栈以太网芯片有以下优点:
- 硬件TCP/IP协议栈:WIZnet的硬件协议栈芯片提供了一种硬件实现的TCP/IP协议栈,这种硬件实现的协议栈比软件实现的协议栈具有更好的性能和稳定性。
- 不需要额外的嵌入式系统软件栈和内存资源:由于所有的以太网传输和接收操作都由独立的以太网控制器处理,因此不需要额外的嵌入式系统软件栈和内存资源。
- 抵抗网络环境变化和DDoS攻击:与易受网络环境变化和DDoS攻击影响的软件TCP/IP协议栈相比,硬件协议栈芯片能够提供更稳定的以太网性能。
- 适用于低规格的嵌入式系统:即使在低规格的嵌入式系统中,使用WIZnet的硬件协议栈芯片也可以比使用软件TCP/IP协议栈的高规格系统显示出更高效的互联网应用操作性能。
4. 示例讲解以及使用
4.1 程序流程图
4.2 测试准备
软件:
- Thonny
- 阿里云物联网平台
硬件:
- W5100S IO模块 + RP2040 树莓派Pico开发板 或者 WIZnet W5100S-EVB-Pico开发板
- DHT11温湿度传感器
- Micro USB 接口的数据线
- 网线
4.3 连接方式
- 通过数据线连接PC的USB口
- 当使用W5100S/W5500 IO模块连接RP2040时
- RP2040 GPIO 16 <----> W5100S/W5500 MISO
- RP2040 GPIO 17 <----> W5100S/W5500 CS
- RP2040 GPIO 18 <----> W5100S/W5500 SCK
- RP2040 GPIO 19 <----> W5100S/W5500 MOSI
- RP2040 GPIO 20 <----> W5100S/W5500 RST
- DHT11连接RP2040
- RP2040 GPIO 2 <----> DHT11 data
- RP2040 3V3 <----> DHT11 VCC
- RP2040 GND <----> DHT11 GND
- 通过网线直接连接PC网口(或:PC和设备都通过网线连接交换机或路由器LAN口)
4.4 相关代码
我们直接打开mqtt_aliyun.py文件。
第一步:可以看到在w5x00_init()函数中,进行了SPI的初始化。以及将spi相关引脚和复位引脚注册到库中,后续则是激活网络,并使用DHCP配置网络地址信息,当DHCP失败时,则配置静态网络地址信息。当未配置成功时,会打印出网络地址相关寄存器的信息,可以帮助我们更好的排查问题。
第二步:连接阿里云MQTT服务器,连接失败则进入复位程序。
第三步:订阅主题,绑定消息回调函数,开启定时器。
第四步:再主循环中监听是否有消息,如果有则进入消息回调函数进行处理。当定时器达到设定值时上报温湿度信息至云平台。
需注意:要将MQTT参数定义改为您的阿里云平台的MQTT服务器参数
from umqttsimple import MQTTClient
from usocket import socket
from machine import Pin,SPI,Timer
import dht
import network
import time
import json
#mqtt config
mqtt_params = {}
mqtt_params['url'] = 'iot-06z00dbroeg8dx3.mqtt.iothub.aliyuncs.com'
mqtt_params['port'] = 1883
mqtt_params['clientid'] = 'ieojgBm5q2c.W5100S_W5500|securemode=2,signmethod=hmacsha256,timestamp=1701222846581|'
mqtt_params['username'] = 'W5100S_W5500&ieojgBm5q2c'
mqtt_params['passwd'] = 'fdac6b605808aed345f4b98078519b349db65688604c64fc375c12b326e821ff'
mqtt_params['pubtopic'] = '/sys/ieojgBm5q2c/W5100S_W5500/thing/event/property/post'
mqtt_params['subtopic'] = '/sys/ieojgBm5q2c/W5100S_W5500/thing/service/property/set'
mqtt_params['pubqos'] = 0
mqtt_params['subqos'] = 0
#LED definitions
led = Pin(25,Pin.OUT)
#Timer-related definitions
message_interval = 5
timer_1s_count = 0
tim = Timer()
#DHT11 definitions
pin = Pin(2,Pin.OUT)
sensor = dht.DHT11(pin)
client = None
"""
W5x00 chip initialization.
param: None
returns: None
"""
def w5x00_init():
spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
nic = network.WIZNET5K(spi,Pin(17),Pin(20)) #spi,cs,reset pin
nic.active(True)
try:
#DHCP
print("\r\nConfiguring DHCP")
nic.ifconfig('dhcp')
except:
#None DHCP
print("\r\nDHCP fails, use static configuration")
nic.ifconfig(('192.168.1.20','255.255.255.0','192.168.1.1','8.8.8.8'))#Set static network address information
#Print network address information
print("IP :",nic.ifconfig()[0])
print("Subnet Mask:",nic.ifconfig()[1])
print("Gateway :",nic.ifconfig()[2])
print("DNS :",nic.ifconfig()[3],"\r\n")
#If there is no network connection, the register address information is printed
while not nic.isconnected():
time.sleep(1)
print(nic.regs())
"""
Subscribe to the topic message callback function. This function is entered when a message is received from a subscribed topic.
param1: The topic on which the callback is triggered
param2: Message content
returns: None
"""
def sub_cb(topic, msg):
topic = topic.decode('utf-8')
msg = msg.decode('utf-8')
if topic == mqtt_params['subtopic']:
print("\r\ntopic:",topic,"\r\nrecv:", msg)
parsed = json.loads(msg)
if(parsed["params"]["LEDSwitch"] == 1):
print("LED ON!")
led.value(1)
else:
print("LED OFF!")
led.value(0)
sendmsg = '{"id": "123","version": "1.0","params": {"LEDSwitch": %d},"method": "thing.event.property.post"}'%led.value()
client.publish(mqtt_params['pubtopic'],sendmsg,qos = mqtt_params['pubqos'])
print("send:",sendmsg)
"""
1-second timer callback function.
param1: class timer
returns: None
"""
def tick(timer):
global timer_1s_count
global client
timer_1s_count += 1
if timer_1s_count >= message_interval:
timer_1s_count = 0
sensor.measure()
sendmsg = '{"id": "123","version": "1.0","params": {"CurrentTemperature": %s,CurrentHumidity:%s},"method": "thing.event.property.post"}'%(str(sensor.temperature()),str(sensor.humidity()))
try:
client.publish(mqtt_params['pubtopic'],sendmsg,qos = mqtt_params['pubqos'])
print("send:",sendmsg)
except:
print("publish error!please wait reset")
machine.reset()
"""
Connect to the MQTT server.
param: None
returns: None
"""
def mqtt_connect():
client = MQTTClient(mqtt_params['clientid'], mqtt_params['url'], mqtt_params['port'],mqtt_params['username'],mqtt_params['passwd'],keepalive=60)
client.connect()
print('Connected to %s MQTT Broker'%(mqtt_params['url']))
return client
"""
Connection error handler.
param: None
returns: None
"""
def reconnect():
print('Failed to connected to Broker. Reconnecting...')
time.sleep(5)
machine.reset()
"""
Subscribe to Topics.
param: None
returns: None
"""
def subscribe():
client.set_callback(sub_cb)
client.subscribe(mqtt_params['subtopic'],mqtt_params['subqos'])
print('subscribed to %s'%mqtt_params['subtopic'])
def main():
global client
print("WIZnet chip MQTT of Aliyun example")
w5x00_init()
try:
client = mqtt_connect()
except OSError as e:
reconnect()
subscribe()
tim.init(freq=1, callback=tick)
while True:
client.wait_msg()
client.disconnect()
if __name__ == "__main__":
main()
4.5 烧录验证
要测试以太网示例,必须将开发环境配置为使用Raspberry Pi Pico。
- 所需的开发环境
- 如果你必须编译MicroPython,则必须使用Linux或Unix环境。
注意:因为MicroPython的print函数是启用了stdout缓冲的,所以有时候并不会第一时间打印出内容。
运行该脚本必须要有umqttsimple.py库支持,如何添加umqttsimple.py库请查看MQTT协议示例
第一步:将程序复制到Thonny中,然后选择环境为Raspberry Pi Pico,再运行
第二步:可以看到此时每间隔5秒上报了一次温湿度信息,并且平台上也会实时更新。
第三步:通过平台下发指令控制LED灯开关状态。
5. 注意事项
- 如果采用的是WIZnet的W5500来实现本章的示例,则只需烧录W5500的固件并运行示例程序即可。
6. 相关链接
想了解更多,评论留言哦!