序言:
MQTT是基于二进制消息的发布/订阅编程模式的消息协议;由于规范很简单,非常适合需要低功耗和网络带宽有限的IoT场景,比如:智能家居、智慧城市和医疗医护;深受广大童鞋的青睐和喜爱。下面我们以SIM7020为例实现和阿里云的MQTT通信。
SIM7020X NB-IoT HAT 通过MQTT携手阿里云
硬件准备
软件准备
通信步骤
1.硬件连接
- 把NB卡和天线接入 SIM7020C NB-IoT HAT
- 把 SIM7020C NB-IoT HAT模块通过2*20PIN排针接入树莓派
2.阿里云物联网平台功能配置
- 进入阿里云物联网平台平台->登录->快速入门
- 注册设备
- 选择开发包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LVYoswRv-1607995333363)(http://note.youdao.com/yws/public/resource/a31a19c733f24b0335b72cb5c65aeab9/xmlnote/F15AF4817F364020AC30D552AF5A7929/27744)] - SDK下载
- 配置与测试
- 完成产品创建
- 添加设备
- 填写产品名称、设备名称和备注名称
- 查看设备
- 自定义Topic->操作权选择发布和订阅->名字这里改为TEST1
3.通过MQTT和阿里云平台通信
- 三元组准备,下面的步骤有用到的直接复制粘贴过去
{
"ProductKey": "a1Z8aFEGJm2",
"DeviceName": "7020",
"DeviceSecret": "a7ed94ab30288a80e17bbe4004775a00"
}
- 创建 TCP 连接
AT+CMQNEW="a1Z8aFEGJm2.iot-as-mqtt.cn-shanghai.aliyuncs.com","1883",12000,1024
- 设置阿里云设备参数
AT+CMQALICFG=0,"a1Z8aFEGJm2","7020","a7ed94ab30288a80e17bbe4004775a00"
- 发送 MQTT 请求,连接阿里云
AT+CMQALICON=0,600,1
连接成功后设备状态由未激活-》在线
- 订阅主题
AT+CMQSUB=0,"/a1Z8aFEGJm2/7020/user/TEST1",1
- 发布消息
AT+CMQPUB=0,"/a1Z8aFEGJm2/7020/user/TEST1",1,0,0,16,"3132333435363738"
- 取消订阅主题
AT+CMQUNSUB=0,"/a128aFEGJm2/7020/user/TEST1"
- 断开MQTT连接,当发送其它命令error时,可以用这个命令先断开即可
AT+CMQDISCON=0
- 在树莓派测试minicom接收信息,阿里云设备->Topic列表->发送消息"Spring 30 niang",树莓派minicom界面收到息"Spring 30 niang"。
- 树莓派程序测试,将以下代码拷贝到树莓派运行
#!/usr/bin/python
import RPi.GPIO as GPIO
import serial
import time
ser = serial.Serial('/dev/ttyS0',9600)
ser.flushInput()
powerKey = 4
rec_buff = ''
Message = 'www.waveshare.com'
def powerOn(powerKey):
print('SIM7020X is starting:')
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(powerKey,GPIO.OUT)
time.sleep(0.1)
GPIO.output(powerKey,GPIO.HIGH)
time.sleep(1)
GPIO.output(powerKey,GPIO.LOW)
time.sleep(5)
ser.flushInput()
def powerDown(powerKey):
print('SIM7020X is loging off:')
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(powerKey,GPIO.OUT)
GPIO.output(powerKey,GPIO.HIGH)
time.sleep(2)
GPIO.output(powerKey,GPIO.LOW)
time.sleep(5)
print('Good bye')
def sendAt(command,back,timeout):
rec_buff = ''
ser.write((command+'\r\n').encode())
time.sleep(timeout)
if ser.inWaiting():
time.sleep(0.1 )
rec_buff = ser.read(ser.inWaiting())
if rec_buff != '':
if back not in rec_buff.decode():
print(command + ' back:\t' + rec_buff.decode())
return 0
else:
print(rec_buff.decode())
return 1
else:
print(command + ' no responce')
def checkStart():
while True:
# simcom module uart may be fool,so it is better to send much times when it starts.
ser.write( 'AT\r\n'.encode() )
time.sleep(1)
ser.write( 'AT\r\n'.encode() )
time.sleep(1)
ser.write( 'AT\r\n'.encode() )
time.sleep(1)
if ser.inWaiting():
time.sleep(0.01)
recBuff = ser.read(ser.inWaiting())
print('SOM7020X is ready\r\n')
print( 'try to start\r\n' + recBuff.decode() )
if 'OK' in recBuff.decode():
recBuff = ''
break
else:
powerOn(powerKey)
try:
checkStart()
print('wait for signal')
time.sleep(3)
sendAt('AT+CSQ','OK',1)
# sendAt('AT+CPSI?','OK',1)
sendAt('AT+CGREG?','+CGREG: 0,1',0.5)
sendAt('AT+CMQNEW=\"a1Z8aFEGJm2.iot-as-mqtt.cn-shanghai.aliyuncs.com\",\"1883\",12000,1024','OK',1)
sendAt('AT+CMQALICFG=0,\"a1Z8aFEGJm2\",\"7020\",\"a7ed94ab30288a80e17bbe4004775a00\" ','OK',1)
sendAt('AT+CMQALICON=0,600,1','OK',1)
sendAt('AT+CMQSUB=0,\"/a1Z8aFEGJm2/7020/user/TEST1\",1 ', 'OK',1)
sendAt('AT+CMQPUB=0,\"/a1Z8aFEGJm2/7020/user/TEST1\",1,0,0,16,\"3132333435363738\" ','OK',1)
time.sleep(6)
print('send message successfully!')
sendAt('AT+CMQUNSUB=0,\"/a128aFEGJm2/7020/user/TEST1\" ','OK',1)
ser.write(Message.encode())
time.sleep(10);
powerDown(powerKey)
except:
if ser != None:
ser.close()
powerDown(powerKey)
GPIO.cleanup()
- 在树莓派运行python程序发送信息到阿里云,发送12345678(hex:0x3132333435363738)
- 阿里云日志服务收到"12345678"