从零开始开发物联网项目(7)——使用Mqtt协议控制Arduino

上节末说到这次要讲树莓派搭建mqtt服务器,然后使用端口映射就可以从外网访问到树莓派搭建的服务器了,不过实现起来太过于麻烦,所以我接下去会来讲使用云服务器来搭建自己的物联网项目,树莓派之类的就局域网内玩玩吧。
这一节我们就继续来讲Arduino吧,上一节讲到使用Arudino和ESP8266作为一个数据发送终端,那么这节就来讲讲如何使用mqtt协议来控制Arduino吧,类似于我们可以用手机或者电脑打开一个网页就可以来控制家里的电器了。
其实思路很简单,就是让Arduino的终端订阅一个主题就可以了,然后通过收到的数据进行控制就行了,实现起来也超级简单,程序和上一节的几乎一样,修改其中的几行就可以了。
首先呢在变量定义的地方加一个mqtt订阅的指令:

   //以下语句加在程序中定义变量的地方

unsigned char mqttsubscribe[8]={0x82, 0x06, 0x00, 0x01, 0x00, 0x01, 0x73, 0x00};//mqtt消息订阅指令

再将mqttdata数组增加到6,因为接收数据时长度会达到6

unsigned char mqttdata[6];//用于接收mqtt数据

然后我们先来实现简单的D13管脚的输出(D13管脚接了板载的LED),也就是控制Arduino板载的LED。所以要在setup函数里添加下面两句:

//以下语句加在setup函数中

  pinMode(13,OUTPUT);

  digitalWrite(13,LOW);

最后再修改一下mqttsend函数中关于if(mi>0)中的部分,修改成如下:

 if (mi > 0)                             //如果收到了mqtt服务器返回的数据
  {
    mi = 0;
    if (mqttdata[0] == 0x20 )     //方便起见,只判断返回数据的第一位,如果是20则是刚链接上
    {
      Serial1.write(mqttsubscribe,8);   //订阅主题为s的消息
    }
    else if (mqttdata[0] == 0xd0)   //心跳信号返回数据
    {
           Serial1.write(mqttpublish, 13);         //发布数据
    }
       else if (mqttdata[0] == 0x90)       //订阅主题成功
    {
      }
       else if (mqttdata[0] == 0x30)   //收到订阅主题的消息
    {
         if(mqttdata[5]==0x30)        //收到的第6位为消息,如果收到的消息为“0”,则关灯
         {
          digitalWrite(13,LOW);
         }
         else if(mqttdata[5]==0x31)    //如果收到的消息为“1”,则开灯
         {
          digitalWrite(13,HIGH);
         }
    }
    else if (mqttdata[0] == 0x40)             //由于用了QoS=01,所以mqtt服务器会返回数据
    {
      timebefor = millis();                     //收到数据后重新计时
    }
  }

改好后将程序烧入Arduino mega2560,然后再打开emqx控制网页里的websocket页面或者手机端的mqtt软件,发送一个主题为"s",内容为“1”的消息,然后就可以看到Arduino上的led灯被点亮了,再发送“0”就可以关闭led。

当然这里只实现了最基本的功能,如果真的要做成一个作品,还需要考虑很多,例如如何保证设备一直在线,在发现设备掉线后要如何重启连接程序,还得判断是mqtt服务器掉线还是tcp服务器掉线…等等,还有关灯成功后还得返回一个数据来告诉控制方…但是不管怎么说,最基本的功能已经实现,后续的只是不断完善的工作罢了。

你可能感兴趣的:(物联网,物联网,arduino)