基于Raspberry Pi Pico的云端温湿度监测站设计

电子说

1.3w人已加入

描述

 

 

一、介绍

使用Pi Pico 搭配扩展板以及各种传感器模块,再加上网络相关模块将搜集到的数据上传云端,完成一个简易的云端温湿度监测站。

二、软件安装

安装Thonny IDE以及MircoPython Firmware的刻录。

三、硬件配置

我们这次会使用到的模块有SHT3x温湿度模块、1.3 OLEDLED灯模块以及AM7020 NBIoT网络模块,接线方式如下对照图表所示。

 

监测站

监测站

实际功能为将读取到的温湿度数据显示到1.3 OLED上,以及定时将数据透过AM7020上传云端,并且提供远程网页控制LED灯的功能,除了控制LED灯外也可结合继电器实现控制家电(e.g.电灯、电扇、浇水设备……等)。

四、云端设定

这次我们会使用Adafruit IO做为云端平台,它将会存放温度、湿度,以及LED灯控制讯息相关数据,并且透过内建服务Dashboard将数据以图形化方式呈现。

进到Adafruit IO官网新增三个Feed,分别为「temperature」、「humidity」、「led」,如下图所示。

 

监测站

接着请新增一个Dashboard,名称为「pico」,如下图所示。

 

监测站

继续在pico Dashboard内新增折线图表以及按钮开关,折线图数据源选择Feedtemperature」、「humidity」,按钮开关数据源选择Feedled」,如下图所示。

 

监测站

五、程序撰写

本篇所用到的范例程序代码可至下列连结下载。

https://github.com/JiekangHuang/pi_pico_adafruitIO_nbiot

 ()加载相关Library

为了简化程序代码复杂度,我们将会使用AM7020SHT31OLED 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

5 importsht31

6 frommachine import Pin, I2C

7 fromssd1306 import SSD1306_I2C

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对象,用来操作OLEDOLED设定宽高为128*64;建立LED对象,pin设定为20,并设为输出,用来显示网页控制开关状态。

 

监测站

3. 设定NBIoT 模块所使用的APNBand(不同电信商会不一样,此为台湾大哥大,Band 28),设定MQTT相关参数,Broker 使用Adafruit IOPort 使用1883,账号密码请自行修改,设定温湿度、LED Topic,请务必与云端设定相同,35行设定数据上传云端的间隔,使用者可自行依需求调整,这里设为30秒上传一次;建立AM7020AM7020MQTT对象,用来将数据发送至云端平台。

 

监测站

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灯,如下图所示。

 

监测站

监测站

 

 

  审核编辑:汤梓红
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分