一、介绍
使用pi pico 搭配扩展板以及各种传感器模块,再加上网络相关模块将搜集到的数据上传云端,完成一个简易的云端温湿度监测站。
二、软件安装
安装thonny ide以及mircopython firmware的刻录。
三、硬件配置
我们这次会使用到的模块有sht3x温湿度模块、1.3吋 oled、led灯模块以及am7020 nbiot网络模块,接线方式如下对照图表所示。
实际功能为将读取到的温湿度数据显示到1.3吋 oled上,以及定时将数据透过am7020上传云端,并且提供远程网页控制led灯的功能,除了控制led灯外也可结合继电器实现控制家电(e.g.电灯、电扇、浇水设备……等)。
四、云端设定
这次我们会使用adafruit io做为云端平台,它将会存放温度、湿度,以及led灯控制讯息相关数据,并且透过内建服务dashboard将数据以图形化方式呈现。
进到adafruit io官网新增三个feed,分别为「temperature」、「humidity」、「led」,如下图所示。
接着请新增一个dashboard,名称为「pico」,如下图所示。
继续在pico dashboard内新增折线图表以及按钮开关,折线图数据源选择feed「temperature」、「humidity」,按钮开关数据源选择feed「led」,如下图所示。
五、程序撰写
本篇所用到的范例程序代码可至下列连结下载。
https://github.com/jiekanghuang/pi_pico_adafruitio_nbiot
(一)加载相关library
为了简化程序代码复杂度,我们将会使用am7020、sht31、oled 的micropython library 来处理driver 的部分,请将这三个library 预先存入pi pico内以便之后主程序呼叫。
首先使用thonny从本机开启要存入的档案,并选择档案>>另存新檔>>raspberry pi pico>>输入文件名(需与原档名相同)。
pico library档案结构如下图所示。
第一层为lib文件夹
lib文件夹里为「am7020」文件夹、「sht31.py」、「ssd1306.py」。
am7020文件夹里为「am7020_modem.py」、「am7020_mqtt.py」、「am7020_nb.py」。
(二)程序设计
开启打开范例「example/adafriotio_pico.py」并执行。
1 fromutime import ticks_ms, sleep_ms
2 fromam7020.am7020_nb import am7020nb
3 fromam7020.am7020_mqtt import am7020mqtt
4
5 importsht31
6 frommachine import pin, i2c
7 fromssd1306 import ssd1306_i2c
8
9 sht31_i2c= i2c(1, scl=pin(7), sda=pin(6), freq=400000)
10sensor = sht31.sht31(sht31_i2c, addr=0x44)
11
12 width= 128 # oled 显示宽度
13height = 64 #oled 显示高度
14
15 # 初始化 i2c 物件 i2c0 scl =1, i2c0 sda = gp0
16oled_i2c = i2c(0, scl=pin(9), sda=pin(8), freq=200000)
17
18 oled= ssd1306_i2c(width, height, oled_i2c)
19
20 led =pin(20, pin.out)
21
22 #nbiot 相关设定
23 apn =twm.nbiot # 存取点名称
24 band= 28 # 通讯频道
25check_net_interval_ms = 1000 # 网络检查间隔时间
26
27#相关设定
28mqtt_broker = io.adafruit.com
29 port= 1883
30 mqtt_username=
31mqtt_password =
32temp_topic = mqtt_username + /feeds/pico.temperature
33hum_topic = mqtt_username + /feeds/pico.humidity
34led_topic = mqtt_username + /feeds/pico.led
35upload_interval_ms = 30000 # 讯息上传间隔时(毫秒)
36
37 nb =am7020nb(0, 9600, 0, 1, 3, false) # 建立连接对象
38 mqtt= am7020mqtt(nb) # 建立 mqtt 通讯对象
39
40
41 defnbconnect(): # ⾃订联机程序
42 print(initializing modem...)
43 while((not nb.init() or (notnb.nbiotconnect(apn, band)))):
44 print(.)
45
46 print(waiting for network...)
47 while(not nb.waitfornetwork()):
48 print(.)
49 sleep_ms(5000)
50
51 print( success)
52
53
54 defreconnbroker(): # mqtt broker 重新联机程序
55 print(connecting to,mqtt_broker, end=...)
56 if(mqtt.connbroker(mqtt_broker, port,mqtt_username, mqtt_password, mqtt_id=icshop_am7020_mqtt_id)):
57 print( success)
58 print(subscribe: ,led_topic, end=)
59 if(mqtt.subscribe(led_topic,mqttcallback)):
60 print( success)
61 else:
62 print( fail)
63 else:
64 print( fail)
65
66 #mqtt 订阅内容讯息回调函数
67
68
69 defmqttcallback(msg):
70 print(led_topic, :, msg)
71 if(msg == on):
72 led.on()
73 else:
74 led.off()
75
76
77chk_net_timer = 0 # 联机状态查询周期定时器
78pub_data_timer = 0 # 讯息发布周期定时器
79
80 oled.fill(0) # 清除画面
81oled.text(init modem..., 0, 0)
82oled.show()
83
84print(initializing modem...)
85while(not nb.init()):
86 print(.)
87
88while(true):
89 # show sht31 data
90 oled.fill(0) # 清除画面
91
92 t = round(sensor.get_temp_humi()[0], 1)
93 h = round(sensor.get_temp_humi()[1], 1)
94 # print(temperature: {}.format(t))
95 # print(humidity:{}.format(h))
96
97 if(ticks_ms() > chk_net_timer): # 联机状态查询周期
98 chk_net_timer = ticks_ms() +check_net_interval_ms
99 if(not nb.chknet()):
100 oled.fill(0) # 清除画面
101 oled.text(isp connecting, 0, 0)
102 oled.show()
103 nbconnect()
104 oled.fill(0) # 清除画面
105 oled.text(ispconnected, 0, 0)
106 oled.show()
107 if(not mqtt.chkconnbroker()):
108 oled.fill(0) # 清除画面
109 oled.text(mqttconnecting, 0, 0)
110 oled.show()
111 reconnbroker()
112 oled.fill(0) # 清除画面
113 oled.text(mqttconnected, 0, 0)
114 oled.show()
115
116 if(ticks_ms() > pub_data_timer): # 讯息发布周期
117 pub_data_timer = pub_data_timer +upload_interval_ms
118 print(publish: , t,end=)
119 if(mqtt.publish(temp_topic, str(t))):
120 print( success)
121 else:
122 print( fail)
123 print(publish: , h,end=)
124 if(mqtt.publish(hum_topic, str(h))):
125 print( success)
126 else:
127 print( fail)
128 mqtt.procsubs() # 检查订阅频道状态
129 oled.text(mqtt connected, 0,0)
130 # 加入文字内容
131 oled.text(temp: , 0, 10)
132 oled.text(str(t), 50, 10)
133 oled.text(*c, 90, 10)
134
135 oled.text(humi: , 0, 20)
136 oled.text(str(h), 50, 20)
137 oled.text(%, 90, 20)
138 oled.show() # 显示绘制内容
程序代码说明:
1. 引入这次实作所需模块。
2. 建立并传入i2c1建立sht31对象,用来读取温湿度;建立并传入i2c0建立oled对象,用来操作oled,oled设定宽高为128*64;建立led对象,pin设定为20,并设为输出,用来显示网页控制开关状态。
3. 设定nbiot 模块所使用的apn、band(不同电信商会不一样,此为台湾大哥大,band 28),设定mqtt相关参数,broker 使用adafruit io,port 使用1883,账号密码请自行修改,设定温湿度、led topic,请务必与云端设定相同,35行设定数据上传云端的间隔,使用者可自行依需求调整,这里设为30秒上传一次;建立am7020、am7020mqtt对象,用来将数据发送至云端平台。
4. 定义nbiot 联机程序,呼叫am7020对象init 初始化方法以及nbiotconnect 方法直到成功,接着呼叫waitfornetwork 方法等待联机完成。
5. 定义mqtt 重新联机程序,使用am7020mqtt对象的connbroker 方法联机到指定broker,这里须注意每个装置的mqtt_id不可相同,若相同broker 将会剔除上一次的联机,联机完毕后使用am7020mqtt 对象的subscribe 方法订阅led的 topic,并传入callback(于下一段说明),用以接收led开关状态。
6. 定义led数据的callback,当am7020mqtt对象收到led主题数据时就会呼叫此方法,在此方法里面判断讯息并控制led亮灭。
7. 建立检查联机状态、发布数据的定时器;将oled画面清除并显示初始化讯息,并等待nbiot模块初始化成功。
8. 进入无穷循环,92~93行读取温湿度数据,97~114定时检查nbiot以及mqtt的联机状态,若中间有断线便会呼叫上面定义的重新联机方法,并透过oled显示目前状态。
9. 透过定时器的方式定时发送温湿度数据到云端(默认为30秒上传一次),发送数据使用am7020mqtt对象的publish方法,参数带入目标topic以及要发布的讯息。
10. 128行使用am7020mqtt对象的procsubs方法检查是否有订阅数据到达;将温湿度数据显示到oled上。
六、执行结果
完成以上步骤,并执行范例程序代码,我们就可以在oled及云端上看到温湿度数据,并且可以直接透过网页按钮控制pico 的led灯,如下图所示。
信通电子IPO成功过会
F007运放组成的水分检测器电路图
动态ip、静态ip、pppoe拨号的区别
业界最低功耗的视频放大器(TI)
一文看懂数据库原理与应用
基于Raspberry Pi Pico的云端温湿度监测站设计
户外LED大显示屏的特点是什么
夏普四原色液晶电视技术定名Quattron
四款嵌入式中应用常见的网络协议栈
SBO2连接器与车用连接器产品介绍
荣耀卷土重来 小米迎伺强敌 瑞银“补刀”
RF组件制造商正在开发无源表面安装式带通滤波器
上半年中国混动汽车市场概览
汽车正快速进入全新的ADAS世界
莫仕工业自动化解决方案, 通向工业4.0的道路
三季度智能音箱出货量约829万台,同比下降14.7%
宽电压降压型恒压驱动芯片 AP8852
麦捷科技拟购安可远100%股权和金之川20%股权
电机节能的六种方案
NVIDIA宣布推出面向游戏笔记本电脑的GeForce® GTX® 1660 Ti 和1650 Turing GPU