主要記錄初次接觸樹莓派和MQTT的一些操作。
以下操作都是在root賬號下的命令記錄,如何開啟樹莓派的root賬號,參考這篇文章:樹莓派啟用root賬號
1. 樹莓派上安裝Mosquitto
參考官方文檔:Mosquitto Debian 倉庫,可直接apt-get安裝。
apt-get 安裝過程中,提示依賴錯誤:
apt-get install mosquitto
正在讀取軟件包列表... 完成
正在分析軟件包的依賴關(guān)系樹
正在讀取狀態(tài)信息... 完成
有一些軟件包無法被安裝。如果您用的是 unstable 發(fā)行版,這也許是
因為系統(tǒng)無法達(dá)到您要求的狀態(tài)造成的。該版本中可能會有一些您需要的軟件
包尚未被創(chuàng)建或是它們已被從新到(Incoming)目錄移出。
下列信息可能會對解決問題有所幫助:
下列軟件包有未滿足的依賴關(guān)系:
mosquitto : 依賴: libssl1.0.0 (>= 1.0.0) 但無法安裝它
依賴: libwebsockets3 (>= 1.2) 但無法安裝它
E: 無法修正錯誤,因為您要求某些軟件包保持現(xiàn)狀,就是它們破壞了軟件包間的依賴關(guān)系。
解決方案參考:https://github.com/eclipse/mosquitto/issues/529#issuecomment-331590876
wget http://security-cdn.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u11_armhf.deb
wget http://ftp.nz.debian.org/debian/pool/main/libw/libwebsockets/libwebsockets3_1.2.2-1_armhf.deb
dpkg -i libssl1.0.0_1.0.1t-1+deb8u11_armhf.deb
dpkg -i libwebsockets3_1.2.2-1_armhf.deb
apt-get install mosquitto mosquitto-clients
如果執(zhí)行上面的命令失敗,可以直接訪問http://security-cdn.debian.org/debian-security/pool/updates/main/o/openssl/,查找最新的openssl
訪問http://ftp.nz.debian.org/debian/pool/main/libw/libwebsockets/,查找最新的websockets
替換命令中的對應(yīng)安裝包,即可完成安裝
2. PC端安裝Mosquitto服務(wù)
訪問官網(wǎng):https://mosquitto.org/
下載頁有windows安裝包https://mosquitto.org/download/,寫作本文時最新的是1.6.3版本
下載符合你的windows系統(tǒng)的對應(yīng)安裝文件,一路Next即可安裝。
默認(rèn)安裝在
C:\Program Files\mosquitto
雙擊 mosquitto.exe可運行
3. 初次進行MQTT通信
-------------------------角色------------------------------IP地址-----------------端口-------------
windowsPC--------MQTT消息轉(zhuǎn)發(fā)服務(wù)器-------192.168.43.131----1883------------
windowsPC--------MQTT消息發(fā)布者--------------192.168.43.131----1883-----------
樹莓派---------------MQTT消息訂閱者--------------192.168.43.100----1883-----------
3.1 windowsPC啟動Mosquitto服務(wù)
cd C:\Program Files\mosquitto
C:\Program Files\mosquitto>mosquitto.exe -v
1561059204: mosquitto version 1.6.3 starting
1561059204: Using default config.
1561059204: Opening ipv6 listen socket on port 1883.
1561059204: Opening ipv4 listen socket on port 1883.
3.2 樹莓派啟動MosquittoSub,獲取該消息
mosquitto_sub -v -t gpio -h 192.168.43.131
執(zhí)行上面的命令啟動后,mosquitto就可以輸入獲取消息的指令了。
gpio {"index":17, "value":0}
3.3 windowsPC啟動MosquittoPub,發(fā)布對應(yīng)消息,樹莓派就會收到該消息
windows PC,命令行
cd C:\Program Files\mosquitto
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":0}"
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":1}"
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":0}"
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":1}"
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":0}"
樹莓派,顯示收到
gpio {"index":17, "value":0}
gpio {"pin":17,"value":0}
gpio {"pin":17,"value":1}
gpio {"pin":17,"value":0}
gpio {"pin":17,"value":1}
gpio {"pin":17,"value":0}
所以,只要PC端的Pub一直推送消息給PC端的轉(zhuǎn)發(fā)服務(wù)器,樹莓派就能夠不斷收到相應(yīng)的訂閱消息。
4 第一次總結(jié)
4.1 上面在做什么
首先了解發(fā)布者和訂閱者的含義,發(fā)布者是消息的發(fā)出者,或者是指令的發(fā)出者,訂閱者是被動接受消息或者指令的。上文就是一個例子:PC端作為發(fā)布者發(fā)出指令,樹莓派作為訂閱者,當(dāng)收到PC端的指令時,執(zhí)行該指令的相關(guān)動作。
然后了解MQTT代理服務(wù)的含義,他就是一個平臺的概念。好比QQ聊天,你和你的朋友的QQ并不會隨時都登陸,但是騰訊的QQ服務(wù)器是一直在工作的。你QQ上線后,將朋友的QQ設(shè)置為特別關(guān)注對象,當(dāng)他上線時就要提醒你。這就跟我們剛才的實驗一樣。PC端的消息轉(zhuǎn)發(fā)服務(wù)器,就是騰訊的QQ服務(wù)器,樹莓派就是你的QQ,已經(jīng)上線了。PC端的發(fā)布者客戶端,就是朋友的QQ,他隨時可能上線,只要發(fā)消息給了PC端的消息轉(zhuǎn)發(fā)服務(wù)器,你的樹莓派訂閱了,就可以收到該消息。
補充知識:
GPIO(英語:General-purpose input/output),通用型之輸入輸出的簡稱,功能類似8051的P0—P3,其接腳可以供使用者由程控自由使用,PIN腳依現(xiàn)實考量可作為通用輸入(GPI)或通用輸出(GPO)或通用輸入與輸出(GPIO),如當(dāng)clk generator, chip select等。https://baike.baidu.com/item/gpio/4723219?fr=aladdin

5.擴展,用python接收MQTT消息,控制GPIO
5.1 安裝 python的 MQTT擴展庫
pip install paho-mqtt
5.1 借助MQTT擴展庫和樹莓派的GPIO庫,編寫下面的python代碼,保存到testgpio.py中
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import json
# BCM GPIO編號
pins = [17,18,27,22,23,24,25,4]
def gpio_setup():
# 采用BCM編號
GPIO.setmode(GPIO.BCM)
# 設(shè)置所有GPIO為輸出狀態(tài),且輸出低電平
for pin in pins:
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.LOW)
def gpio_destroy():
for pin in pins:
GPIO.output(pin, GPIO.LOW)
GPIO.setup(pin, GPIO.IN)
# 連接成功回調(diào)函數(shù)
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# 連接完成之后訂閱gpio主題
client.subscribe("gpio")
# 消息推送回調(diào)函數(shù)
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
# 獲得負(fù)載中的pin 和 value
gpio = json.loads(str(msg.payload))
if gpio['pin'] in pins:
if gpio['value'] == 0:
GPIO.output(gpio['pin'], GPIO.LOW)
else:
GPIO.output(gpio['pin'], GPIO.HIGH)
if __name__ == '__main__':
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
gpio_setup()
try:
# 請根據(jù)實際情況改變MQTT代理服務(wù)器的IP地址
client.connect("192.168.1.131", 1883, 60)
client.loop_forever()
except KeyboardInterrupt:
client.disconnect()
gpio_destroy()
5.2 在PC端發(fā)出消息,控制樹莓派GPIO 17的高電平低電平
5.2.1 樹莓派啟動我們的python代碼
python testgpio.py
testgpio.py:13: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(pin, GPIO.OUT)
Connected with result code 0
5.2.2 PC端輸入GPIO指令
C:\Program Files\mosquitto>mosquitto_pub -h 192.168.43.131 -t gpio -m "{\"pin\":17,\"value\":0}"
C:\Program Files\mosquitto>mosquitto_pub -t gpio -h 192.168.43.131 -m "{\"pin\":17,\"value\":1}"
5.2.3 樹莓派上輸出接收到對GPIO 17的指令
gpio {"pin":17,"value":0}
gpio {"pin":17,"value":1}