基于MQTT阿里云服务器的物联网关灯项目--舵机

一、关灯神器

本文章由作者李建华所编写,用到的服务器是阿里云部署好的mqtt,链接如有失效,请联系作者微信:Likz777777

要求:不破坏原有功能、可以接入苹果、网页小程序均可控制

设备:香橙派、舵机

具体实现方法

  • 1.局域网控制:把香橙派作为服务器->客户端发标志位服务器->服务器收到匹配的标志位控制舵机开灯

  • 2.小程序控制:香橙派作为客户端,小程序作为客户端,用MQTT协议,连接阿里云服务器,进行消息分发

MQTT协议

MQTT是基于服务端/客户端订阅发布通信协议,建立在TCP/ip协议之上,最大的优点在于用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。

本编文章采用的是MQTT C库进行开发(第二套方案)

编写程序连接MQTT服务器

  • 创建客户端

  • 配置连接使用的结构体(主要参数:用户名,用户名密码)

  • 设置回调函数,连接后用于收发消息,及连接失败的信息

  • 连接服务器

  • 订阅主题(用于订阅发布者,就能收到发布者信息)

  • 发布主题(用于发布信息)

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "MQTTClient.h"
​
#define MQTT_Uri    "i66105e6.cn-hangzhou.emqx.cloud:15200"   // MQTT服务器的地址和端口号
#define ClientId    "lijianhua"                  // ClientId需要唯一
#define UserName    "用户名"                     // 用户名
#define PassWord    "对应密码"                   // 用户名对应的密码
#define Publish     "publish"                  //发布主题
#define Subscribe   "subscribe"                //订阅主题
​
 //1.定义一个MQTT客户端结构体指针
    MQTTClient client;
​
// 失去连接回调函数
void connect_lost(void *context, char *cause)
{
    printf("Connection lost,The reason: %s \n",cause);
}
​
// 收到主题信息回调函数
int message_arrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    //printf("Receive topic: %s, message data: \n", topicName);//打印订阅主题
   // printf("%.*s\n", message->payloadlen, (char*)message->payload);//接受到的消息
​
    if(!strcmp((char*)message->payload,"open"))//用于判断接收的消息
    {
            printf("OPEN LIGHT\n");
    }
    
     if(!strcmp((char*)message->payload,"close"))
    {
            printf("CLOSE LIGHT\n");
    }
    
    if(!strcmp((char*)message->payload,"closeClient"))
    {
          // 10、断开连接
          MQTTClient_disconnect(client, 10000);//1000:断开的超时时间
          printf("Close Client\n");
          MQTTClient_freeMessage(&message);
          MQTTClient_free(topicName);
   
           exit(0);
    }
​
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
   
    return 1;
}
​
// 主题发布成功回调函数
void delivery_complete(void *context, MQTTClient_deliveryToken dt)
{
    printf("publish topic success,token = %d \n", dt);
}
​
int main(int argc, char* argv[])
{
    //2.创建一个MQTT客户端
    int rc;
    if ((rc = MQTTClient_create(&client, MQTT_Uri, ClientId, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to create client, return code %d\n", rc);
        exit(EXIT_FAILURE);
        return 0;
    }
​
    //3.创建一个MQTT连接配置结构体,并配置其参数
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    conn_opts.username = UserName;          // 用户名 
    conn_opts.password = PassWord;          // 用户名对应的密码
    conn_opts.keepAliveInterval = 60;       // 心跳时间
    conn_opts.cleansession = 1;             // 清除会话
​
    //4.设置MQTT连接时的回调函数
    if ((rc = MQTTClient_setCallbacks(client, NULL, connect_lost, message_arrived, delivery_complete)) != MQTTCLIENT_SUCCESS)
    {
        printf("设置回调函数失败, return code %d\n", rc);
        rc = EXIT_FAILURE;
        MQTTClient_destroy(&client);//销毁
​
    }
    //5.开始连接到MQTT服务器
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("连接失败, return code %d\n", rc);
        exit(EXIT_FAILURE);
        MQTTClient_destroy(&client);//销毁
​
    }
    else
    {
            printf("连接成功\n");
    }
​
    //6.定义一个主题消息存储结构体
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
​
    char mag_data[256];
  //pubmsg.payload = mag_data;
  //pubmsg.payloadlen = (int)sizeof(mag_data);
    pubmsg.qos = 1;                 // qos等级为1 
    pubmsg.retained = 0;            // 服务器不保留消息
    MQTTClient_deliveryToken token; // 标记MQTT消息的值,用来检查消息是否发送成功
   
    while(1)
    {
​
       /*这里我只需要订阅主题,就放在while里面了,如果你的代码需要同时发布订阅,可以写创建一个进程
         我推荐创建两个线程,节约不少资源       
       */
       
        /*memset(mag_data,'\0',sizeof(mag_data));  
        printf("请发送你要的数据:");    
        gets(mag_data);
        pubmsg.payload = mag_data;//设置发送消息
        pubmsg.payloadlen = (int)strlen(mag_data);//发送的长度
​
    //7.发布主题信息
         if ((rc = MQTTClient_publishMessage(client, Publish &pubmsg, &token)) != MQTTCLIENT_SUCCESS)
        {
                //printf("Failed to publish message, return code %d\n", rc);
                printf("%s\n",mag_data);
                exit(EXIT_FAILURE);
        }*/
​
    //8.订阅主题
         if ((rc = MQTTClient_subscribe(client, Subscribe, 1)) != MQTTCLIENT_SUCCESS)
        {
                printf("订阅主题失败, return code %d\n", rc);
                rc = EXIT_FAILURE;
        }else
         {
                printf("订阅主题成功!\n");
         }
​
    }
​
/* //9.等待输入'Q'或'q'退出
    printf("Press Q or q + <Enter> to quit\n\n");
    int ch;
    do
    {
            ch = getchar();
    } while (ch!='Q' && ch != 'q');
​
    if ((rc = MQTTClient_unsubscribe(client, Subscribe)) != MQTTCLIENT_SUCCESS)//取消订阅
    {
            printf("Failed to unsubscribe, return code %d\n", rc);
            rc = EXIT_FAILURE;
    }*/
​
}

 

编写小程序连接MQTT服务器

微信小程序用的是JavaScript写的,我不擅长这方面代码,借鉴的:使用微信小程序连接到部署 | EMQX Cloud 文档

这写的太全了,我只需要小程序发布,就改了一下,可以到这里下载:百度网盘 请输入提取码 密码:mqtt

  • 小程序用的是websocket,所以要用对应的服务器端口号,wss报错,用wxs

  • 在微信公众平台->开发管理添加服务器的域名,用wss://

  • 上传代码提交审核

设备端详细代码

请到这里下载:百度网盘 请输入提取码 密码:mqtt

香橙派设置自启动

  • sudo nano /etc/systemd/system/my_program.service

  • 在Unit文件中,添加以下内容

    [Unit]
    Description=My Program
    After=multi-user.target
    ​
    [Service]
    ExecStart=/home/pi/my_program //这里是你可执行程序的绝对地址
    Restart=always
    User=root //我用的root
    ​
    [Install]
    WantedBy=multi-user.target
  • 运行以下命令以重新加载Systemd管理的服务列表:sudo systemctl daemon-reload

  • 启用并启动您的服务,使其在引导时自动启动:

  • sudo systemctl enable my_program //使能
    sudo systemctl start  my_program  //启动
    sudo systemctl stop   my_program   //停止
    sudo systemctl disable my_program //不在自启动,会禁用服务

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

No Iverson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值