MQTT协议发送GPS坐标到服务器

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()

运行结果:
在这里插入图片描述

在这里插入图片描述
客户端接收到消息。
本次心得就分享到这,有什么不对的地方欢迎各位同学指正。

猜你喜欢

转载自blog.csdn.net/qq_38129331/article/details/108679889