非物联网平台自建MQTT代理服务器控制树莓派LED
微信小程序 阿里云服务器 非物联网平台自建MQTT代理服务器控制树莓派LED
本人大三,临近毕业季,日后希望从事物联网和嵌入式相关工作,所以自己构想了一个项目来练手,之前做大创的时候学了一点微信小程序,大二的时候玩过一段时间的树莓派,寒假的时候买没顶住阿里云服务器的学生优惠买了一年的阿里云的服务器。之前的大创也是一个物联网的相关项目,当时使用的是中国移动的OneNet的物联网平台。
所以我灵机一动,就想到了自己搭建MQTT的代理通过微信小程序来控制树莓派的IO口的项目( •̀ ω •́ )✧
前排提示:我也是个萌新,可能走了很多弯路,如果有迷惑操作欢迎指正相互学习哦(~ ̄▽ ̄)~
前期准备
1.硬件准备
首先说一下完成这个项目我们所需要的硬件
1. 手机一台(IOS/Android皆可)
2. 树莓派(我用的4B 4G版,理论上其他型号也无所谓)
3. LED灯、杜邦线若干
我的成品如图
2.软件准备
下载微信开发者工具
直接下载对应版本微信开发者工具
给树莓派安装系统
树莓派官网系统
我使用的是树莓派官方系统(之前用Ubuntu20.04 64位碰了很多壁⊙﹏⊙∥),这个地方萌新推荐安装Raspberry Pi OS (32-bit) with desktop and recommended software这个带推荐软件的版本,虽然大但啥都装好了对萌新友好
给树莓派安装MQTT库
本来我是直接尝试建立TCP协议后直接给服务器发报文的,但是我不知道错在了哪里报文倒是能发送过去,但是一直连不上服务器,于是我又在网上搜了一圈发现了MQTT在Linux下有一个C库,于是我准备直接用这个库(其实是在EMQX官网翻文档的时候找到的,官方文档真是个好东西!)
点开官网:Paho C库
怎么安装官网写的很详细,这里不再赘述,有问题自行百度或留言
注意:安装paho需要openssl请先自行安装openssl
EMQX官网有一个例程代码:paho例程
如果你包含头文件 #include “MQTTClient.h” 没有报错恭喜你成功安装!
购买阿里云服务器
云服务器ECS
点开买就行了,这个不用我来教吧
我买的1核2G
系统装Ubuntu 18.04 64位
安装MQTT的代理
这个地方很多人用的代理是mosquitto,网上的教程也基本是mosquitto的,但是由于mosquitto与微信的对接我搞了很久都没成功,所以我找了另一个代理EMQ,这是国内一个公司搞得,虽然网上没找到搭建代理的教程,它有API方便和小程序对接,结合官方文档还是大概能折腾出来
按照自己的系统对应下载:
代理下载
我选的Ubuntu18.04,至于安装官网文档写的很清楚:安装文档
能看上面这句话恭喜你成功了!
给服务器安装图形界面
这一步主要是方便萌新操作(对,就是我),大佬请直接命令行
控制台的实例菜单里面点远程连接
点击立即登录输入密码,登录!
依次输入如下命令
apt-get update
apt-get upgrade
apt-get install ubuntu-desktop
reboot
重启之后还是在控制台点远程连接,不过这次我们选VNC连接
注意!:在VNC连接之前请先用刚刚的命令行新建立一个新的用户,因为阿里云的VNC连接是无法登录root用户的,所以你需要一个新的用户,同时注意将这个新建的用户加入root权限组,不然之后的操作寸步难行!
sudo adduser username
输入密码,确认密码(注意这个地方密码不会显示出来),填信息(可填可不填)一路Enter,完成
接下来把我们刚刚新建的这个用户加入管理员用户组
sudo adduser username sudo
注意这个username是可以任意取的
现在可以vnc连接了
成功的话如图
打开浏览器输入127.0.0.1:18083如果你的EMQX正确运行了那么应该能看到控制台,默认用户admin
密码public,输入登录,成功后如下图
恭喜你完成了服务器这边的搭建!
配置安全组
搭建完了代理,我们需要打开我们用到的端口
打开阿里云控制台,实例>更多>网络和安全>安全组配置
点击配置规则>添加安全组,加入1883和8081两个端口,他们分别是MQTT的监听端口,和API监听端口
至此服务器端设置完成
代码实现
树莓派部分
因为这个项目涉及到控制树莓派硬件所以请先安装树莓派的IO控制库wiringPI
这个教程太多了我就不赘述了,如果你装的我推荐的系统,wiringpi默认装好了,但如果你和我一样用的4B那么你需要更新wiringpi
更新方法
cd /tmp wget https://project-downloads.drogon.net/wiringpi-latest.deb sudo dpkg -i wiringpi-latest.deb
完成后
终端输入
gpio -v sudo gpio readall
出现下图说明你更新成功
以下为树莓派LED的控制代码
#include <wiringPi.h> int IO_init() { wiringPiSetup () ; // 初始化 这个必须写在最前面 pinMode (0, OUTPUT) ; // 设置GPIO.0 为输出 return 1; } void light_on() { digitalWrite (0, HIGH); // GPIO.0 输出高 } void light_off() { digitalWrite (0, LOW); // GPIO.0 输出低 }
以下为树莓派订阅MQTT服务器的代码
由Paho的例程修改而来
因为默认支持匿名访问,所以这个地方的CLIENTID可以不用改
需要更改请自行参照EMQX官网的配置文件修改,不赘述
函数具体解释请参看文档
已加入LED控制
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "MQTTClient.h" #include "led.h" #define ADDRESS "tcp://你的服务器IP:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "test" #define PAYLOAD "Hello World!" #define QOS 0 #define TIMEOUT 10000L volatile MQTTClient_deliveryToken deliveredtoken; int light_flag=0; void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { // printf("Message arrived\n"); // printf(" topic: %s\n", topicName); // printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); if(strcmp((char*)message->payload, "LIGHT") == 0)//微信小程序发送一个LIGHT字符串 { light_flag=!light_flag;//每次收到信号时LED标志位反转 printf("ok\n");//接收到命令打印ok if(light_flag==1) { light_on();//灯亮 } else { light_off();//灯灭 } } MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause) { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; int rc; IO_init(); if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) { printf("Failed to create client, return code %d\n", rc); rc = EXIT_FAILURE; goto exit; } if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) { printf("Failed to set callbacks, return code %d\n", rc); rc = EXIT_FAILURE; goto destroy_exit; } conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); rc = EXIT_FAILURE; goto destroy_exit; } printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS); if ((rc = MQTTClient_subscribe(client, TOPIC, QOS)) != MQTTCLIENT_SUCCESS) { printf("Failed to subscribe, return code %d\n", rc); rc = EXIT_FAILURE; } else { int ch; do { ch = getchar(); } while (ch!='Q' && ch != 'q'); if ((rc = MQTTClient_unsubscribe(client, TOPIC)) != MQTTCLIENT_SUCCESS) { printf("Failed to unsubscribe, return code %d\n", rc); rc = EXIT_FAILURE; } } if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) { printf("Failed to disconnect, return code %d\n", rc); rc = EXIT_FAILURE; } destroy_exit: MQTTClient_destroy(&client); exit: return rc; }
更多的例程可以在paho的文件夹下面的Sample文件夹找到,如果有需要可以在这个文件架下面找到更多的例程
引入一个led.h文件在主函数里声明需要用到的函数
#include <wiringPi.h> int IO_init(void); void light_on(void); void light_off(void);
为了方便同时也是为了学习,这里采用make编译因此在当前文件夹下我又现学先买写了一个Makefile文件
Raspi_IOT:raspi_subscribe.o led.o
gcc -Wall raspi_subscribe.o led.o -o Raspi_IOT -lpaho-mqtt3c -lwiringPi
raspi_subscribe.o:raspi_subscribe.c
gcc -Wall -c raspi_subscribe.c -o raspi_subscribe.o
led.o:led.c
gcc -Wall -c led.c -o led.o
clean: rm -rf *.o
第一次写Makefile文件,如果有什么错误和不合理的地方欢迎留言指正的(。^▽^)
在当前目录下直接执行make命令,生成一个名为Raspi_IOT的可执行文件
./Raspi_IOT直接执行
如果你的执行效果如上图,未出现报错信息的话,恭喜你成功了!
微信小程序部分
微信小程序部分因为有API可以用,所以总体来说还是比较简单的
打开微信开发者工具新建一个项目
AppID用测试号,选一个你心仪的位置创建工程
创建好以后点击右上角详情,本地设置勾选不校验域名
微信小程序需要用到html CSS JavaScript的知识,这个请自行学习
因为要用EMQX的API所以我们先翻看他的API手册,在写程序之前,我们先用API调试工具进行测试,这里我使用的是Postman,因为EMQX的API需要通过Basic认证所以我们在postman的认证栏里写上认证信息默认用户密码如图
注意:官网文档这个地方用户名拼写错误,请注意不要直接复制粘贴
连接成功后会返回Status Code:200
官网还有很多API有兴趣可以自己拿调试工具试着玩,这里我们主要使用发送报文的API,我们可以通过另一个工具查看推送是否成功串口网络调试工具
我们向test主题推送一条信息
在调试助手中可以收到消息
调试成功以后我们就可以开始写程序了
以下为微信小程序代码
Page({ changeLED: function(){ wx.request({//通过get方式访问服务器 url: 'http://你的服务器IP:8081/api/v4/mqtt/publish', method:'POST', header:{ 'Authorization': 'Basic YWRtaW46cHVibGlj' }, data: { 'topic':'test', 'payload':'LIGHT'//向服务器发送LIGHT字符串 }, success(res){ console.log(res) }, }) } })
最终测试
我们运行树莓派端的程序,同时打开微信开发者工具,点击真机调试手机扫码,不要点预览,预览需要在后台设置允许访问的域名,点击按钮可以看见控制台打印“ok”,同时树莓派接的灯也开始亮灭翻转
最后附上整个工程的github地址
https://github.com/DevilAC/Raspi_IOT/tree/master
本文地址:https://blog.csdn.net/weixin_42138122/article/details/107881513