MQTT協議發送GPS坐標到服務器
一、配置GPS

個人感覺USB的GPS好一些,感覺不好找的同學我這還有淘寶鏈接,賣家沒給錢,只是為了方便同學們,
第一步買回來照著上圖連線即可,我用了四根杜邦線:
USB的TXD連接GPS模塊的RXD,USB的RXD連接GPS模塊的TXD,USB的GND連接GPS模塊的GND,USB的VCC連接GPS模塊的VCC,連好之后GPS天線放窗外,不然沒信號;USB插在樹莓派上,
第二部要用樹莓派讀取到GPS的信號
首先查看一下這個USB,命令列輸入:
ls -l /dev/tty*

安裝minicom
sudo apt-get install minicom
安裝好后使用minicom命令獲取串口上的資料
minicom -b 9600 -o -D /dev/ttyUSB0
順利的話會出現下圖這種資料:

第三部用Python實時讀取GPS資料
在終端依次輸入
mkdir GPS
cd GPS
touch GPS_test.py
gedit GPS_test.py
把下面代碼粘進去
import serial #匯入serial模塊
ser = serial.Serial("/dev/ttyUSB0",9600)#打開串口,存放到ser中,/dev/ttyUSB0是埠名,9600是波特率
while True:
line = str(str(ser.readline())[2:]) # readline()是用于讀取整行
# 這里如果從頭取的話,就會出現b‘,所以要從第三個字符進行讀取
if line.startswith('$GPGGA'):
line = str(line).split(',') # 將line以“,”為分隔符
Longitude = float(line[4][:3]) + float(line[4][3:])/60
# 讀取第5個字串資訊,從0-2為經度,再加上后面的一串除60將分轉化為度
Latitude = float(line[2][:2]) + float(line[2][2:])/60
# 緯度同理
print("經度:",Longitude)
print("維度:",Latitude)
輸出結果:

二、配置MQTT
接下來配置MQTT,MQTT小伙伴們可以去百度百科看一下,MQTT的話題、訊息比較形象的例子是微信公眾號,如果你關注了央視新聞,那么央視新聞發的訊息都會給你推送;如果央視新聞也關注了你,那么你們就是互相關注,你發的訊息也會給央視新聞推送,
下面來看一下如何用python實作使用MQTT協議收發訊息:
需要用到的包為paho-mqtt
在樹莓派終端輸入
pip install paho-mqtt
來安裝paho-mqtt
在終端輸入
mkdir MQTT
cd MQTT
touch subscriber.py
gedit subscriber.py
把下面的代碼粘進去
# subscriber.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
# 訂閱,需要放在 on_connect 里
# 如果與 broker 失去連接后重連,仍然會繼續訂閱 raspberry/topic 主題
client.subscribe("raspberry/topic")
# 回呼函式,當收到訊息時,觸發該函式
def on_message(client, userdata, msg):
print(f"{msg.topic} {msg.payload}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# 設定遺囑訊息,當樹莓派斷電,或者網路出現例外中斷時,發送遺囑訊息給其他客戶端
client.will_set('raspberry/status', "OFF")
# 創建連接,三個引數分別為 broker 地址,broker 埠號,保活時間
client.connect("broker.emqx.io", 1883, 60)
# 設定網路回圈堵塞,在呼叫 disconnect() 或程式崩潰前,不會主動結束程式
client.loop_forever()
運行結果:

code 0表示連接成功,其他數字不對,
到MQTTX官網下載MQTTX客戶端給話題raspberry/topic發訊息,測驗能不能收到,
下載安裝好之后按照下圖輸入:
Client ID是隨機的,

然后點擊右上角Connect:


這時,回到樹莓派終端運行
python3 subscriber.py
然后用客戶端發送訊息,觀察終端是否顯示剛剛發布的訊息,成功的話應該是這樣的:

下面來試試用樹莓派發送訊息:
在終端輸入
cd MQTT
touch publisher.py
gedit publisher.py
把下面的代碼粘進去
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.emqx.io", 1883, 60)
# 每間隔 2 秒鐘向 raspberry/topic 發送一個訊息,連續發送 10 次
for i in range(10):
# 四個引數分別為:主題,發送內容,QoS, 是否保留訊息
client.publish('raspberry/topic', payload=i, qos=0, retain=False)
print(f"send {i} to raspberry/topic")
time.sleep(2)
client.loop_forever()
運行
python3 publisher.py
再打開一個終端進入MQTT檔案夾
python3 publisher.py
結果:

想用客戶端查看的話


點擊 Confirm之后就能看到

三、用MQTT協議發送GPS到服務器
現在一般用json格式來傳送資料,下面代碼就是將GPS坐標進行簡單的封裝之后發送到服務器,
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import serial # 匯入serial模塊
import json
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
start_time = time.time()
flag = 17
#jing = 105.753739
#wei = 37.474912
GPIO.setup(flag, GPIO.IN)
# GPIO.add_event_detect(flag, GPIO.RISING)
ser = serial.Serial("/dev/ttyUSB0", 9600)
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
# 訂閱,需要放在 on_connect 里
# 如果與 broker 失去連接后重連,仍然會繼續訂閱 raspberry/topic 主題
client.subscribe("raspberry/topic")
def on_message(client, userdata, msg):
# print(f"{msg.topic} {msg.payload}")
print("主題:" + msg.topic + " 訊息:" + str(msg.payload.decode('utf-8')))
print(f"receive message from raspberry/topic")
def on_subscribe(client, userdata, mid, granted_qos):
print("On Subscribed: qos = %d" % granted_qos)
start_time = time.time()
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.emqx.io", 1883, 60)
#client.connect("broker.emqx.io", 1883, 60)
client.on_message = on_message
client.will_set('raspberry/status', "OFF")
while True:
client.on_message = on_message
client.loop_start()
line = str(str(ser.readline())[2:]) # readline()是用于讀取整行
# print(line)
# 這里如果從頭取的話,就會出現b‘,所以要從第三個字符進行讀取
if line.startswith('$GPGGA'):
# 我這里用的GPGGA,有的是GNGGA
# print('接收的資料:' + str(line))
line = str(line).split(',') # 將line以“,”為分隔符
jing = float(line[4][:3]) + float(line[4][3:]) / 60
# 讀取第5個字串資訊,從0-2為經度,即經度為116,再加上后面的一串除60將分轉化為度
wei = float(line[2][:2]) + float(line[2][2:]) / 60
# 緯度同理
# print(jing)
data1 = {
"type": 1, # 1表示軌跡
"data": {
"latitude": (wei),
# 緯度
"longitude": (jing)
# 經度
}
}
param1 = json.dumps(data1)
client.publish("raspberry/topic", payload=param1, qos=0)
print(f"send message to raspberry/topic")
time.sleep(4)
if GPIO.input(flag) == GPIO.LOW:
data2 = {
"type": 2, # 2表示作業情況
"data": {
"worktime": ((time.time() - start_time) / 3600), # 表示作業3小時
"working_area": ((time.time() - start_time) * 1.12 * 6 * 0.0015)
# 表示作業面積畝
}
}
param2 = json.dumps(data2)
# print("主題:"+msg.topic+" 訊息:"+str(msg.payload.decode('utf-8')))
print(f"data2")
client.publish("raspberry/topic", payload=param2, qos=0)
while True:
print(f"OFF")
time.sleep(10)
GPIO.cleanup()
client.loop_forever()
運行結果:


客戶端接收到訊息,
本次心得就分享到這,有什么不對的地方歡迎各位同學指正,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/108704.html
標籤:其他
