使用微信公众号控制你的Arduino

导读

本文介绍了如何使用微信公众号前台控制arduino,包括读取传感器数据或者如何控制马达,舵机等设备


目录

  • 总体架构
  • arduino 设备侧实现
  • OneNets设备云配置
  • 自有云服务器后台
  • 微信公众号前台网页 -- 实现对arduino的控制和信息读取

一. 总体架构

adminIOT.png

二. arduino 设备侧实现

Word is cheap, Let me show you code first:
Device code on Github

设备端代码基于AdminIOT修改,感谢原作者的无私分享,原作者网站:https://adminiot.com.cn/

先上一张图说明下arduino板子连线
我用的是WeMos D1板子,接口和arduino uno等原装板子类似的,不了解的同学百度下即可,包括Arduino IDE的配置,这里就不详细说明了

wemos.jpg

额,线有点乱,看不清楚,我列个接线表说明下

连接的传感器
DHT -- 湿度温度传感器
Servo -- 舵机

WeMos DHT Servo
D4 out /
3.3V + /
GND - /
D5 / control(PWM)
5V / +
GND / GND

代码中一些重要文件和重要函数说明

iotweb.ino

void setup()
{
    Serial.begin(9600);
    delay(10);

    Serial.println("board boot up , hello iot!\n");

    //wifi setup
    if(!setupWIFI()) die("setup WIFI fail\n");

    //All sensor init
    sensorInit();
    
    //Mqtt init
    MqttProtocolInit();

    //Delay enough time for mqtt init done
    delay(5000);
}

WeMos使用Mqtt协议和OneNet云平台通讯,使用到的
Mqtt OneNet官方SDK
Mqtt OneNet协议

void loop()
{
    // Wait a few seconds between measurements.
    delay(1000);

    MqttDataRecvLoop();//Board receive cmd or publish from server then reply and excute

    MqttDataPublish(cnt);//Board publish data to server every few seconds.

    cnt++;
    if( cnt > 1000 )
    {
        cnt = 0;
    }    
}

MqttDataRecvLoop():轮询读取OneNet Server发过来的数据包(例如publish,command等),然后进行对应处理。
MqttDataPublish():主动循环上报传感器数值,可以设定定时发送。

mqtt_sample_layer.cpp 封装mqtt sdk,处理协议流程,提供对外接口

在解释该文件前,先说下WifiClient这个类,本案例使用它来连接WIFI和收发TCP数据包,具体可以参考
MqttSample_RecvPkt 和MqttSample_SendPkt 使用了client.read 和 client.write来收发,我们可以直接得到tcp segment数据

static int MqttSample_RecvPkt(void *arg, void *buf, uint32_t count)
{

   uint32_t previousMillis = millis();
   while(!client.available()) 
   {
     //yield();
     uint32_t currentMillis = millis();
     if(currentMillis - previousMillis >= ((int32_t) 2 * 1000))
     {
       printf("Recv time out.\n");
       return false;
     }
   }
   int read_size = 0;
   if(client.available())
   {
      read_size = client.read((uint8_t *)buf, count); 
   }
   return read_size;
}

static int MqttSample_SendPkt(void *arg, const struct iovec *iov, int iovcnt)
{
    int bytes;
    int i=0,j=0;

    //get length to send
    int length = 0;
    //printf("Send count = %d\n", iovcnt);
    for(i=0; i

下面这个函数就是直接处理OneNet平台Command的地方,注意发送给板子的命令字符串必须以“:”作为结束符

void MqttSample_pollingCmd()
{

    if(bitRead(ctx->eventType,MQTT_EVENT_TYPE_GETCMD))
    {
        bitClear(ctx->eventType,MQTT_EVENT_TYPE_GETCMD);
        char rsp[]="ok";

        if(!MqttSample_respcommand(rsp))
        {
            LOG(ERROR,"CMD response error, resend it!\n");
        }
        else
        {
            if(strstr(ctx->cmd,CMD_GET_ALL_DATA))//OneNet request to get all data from Arduino
            {
                MqttSample_sendDHTdata();
                MqttSample_sendServoPos();
                //Send other sensor data following
            }
            else if(strstr(ctx->cmd, CMD_GET_DTH_DATA))
            {
                MqttSample_sendDHTdata();
            }
            /* You can handle other  command  following */
            else if(strstr(ctx->cmd, CMD_GET_SERVO_POSTION))
            {
                MqttSample_sendServoPos();
            }
            else if(strstr(ctx->cmd, CMD_SET_SERVO_POSITION))
            {
                int pos_value = MqttSample_readCmdPos(ctx->cmd);
                MqttSample_setServoPos(pos_value);
            }
            /* Command handle end */
            else
            {
                
LOG(ERROR,"CMD string error, resend it!\n");
            }
        }
    }
}

下面这部分是读取传感器并主动上报的函数部分,DHT的library已经在github上分享:DHT library

void MqttSample_sendServoPos()
{
    //capture sensor data ...
    printf("<%s>: come in\r\n", __FUNCTION__);
    int pos = -1;
    pos = myservo.read();
    
    // Check if any reads failed and exit early (to try again).
    if (pos < 0 || pos > 180)
    {
        LOG(ERROR,"Posistion data error!");
        return;
    }

    //report data to oneNet
  //  LOG(DEBUG,"publish sensor data:\n");
    if(!MqttSample_pulish_ServoData(pos))
    {
        LOG(ERROR,"publish servor data fail\n");
    }
}


void MqttSample_sendDHTdata()
{
    //capture sensor data ...
    printf("<%s>: come in\r\n", __FUNCTION__);
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t))
    {
        LOG(ERROR,"Failed to read from DHT sensor!");
        return;
    }

    //report data to oneNet
  //  LOG(DEBUG,"publish sensor data:\n");
![device.PNG](https://upload-images.jianshu.io/upload_images/16642078-dd8d2256a5a31773.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    if(!MqttSample_pulish_SensorData(h,t))
    {
        LOG(ERROR,"publish sensor data fail\n");
    }

}

Arduino设备代码的分享就到这了,下面介绍OneNet设备云部分。
IOT平台操作基本类似

三.OneNet云平台配置

1.新建产品

产品编辑.PNG

2.新建设备

添加完产品后,就可以添加设备,鉴权信息填写后要记录。


device.PNG

好了,现在产品和设备都添加完了,我们整理下代码中用到的OneNet平台上显示的一些SN,KEY之类的一一对应:

代码中 OneNet
devid_temp 设备ID
API_KEY 产品--Master-APIkey
PROD_ID 产品ID
SN 鉴权信息

根据现在arduino板子连接的传感器,我们设定了如下三个数据流来显示传感器数据。


数据流.PNG

OneNet还有个功能就是创建应用来显示设备数据或控制设备


应用.PNG

OneNet配置就是以上这么多了,如果有其他相关想了解的,可以自行查阅开发文档

四.自有云服务器后台的实现

代码采用Express架构实现,链接:https://github.com/zguogang/api4onenet

api.js提供前台http get route, 包括获取设备列表,接收command命令等的处理与反馈数据
onenetApi.js 提供了对onenet 平台api调用的接口,* iotApi.js* 未使用
oneNet api开发文档链接:https://open.iot.10086.cn/doc/art528.html#108

五.微信公众号前台网页

一个H5网页,使用公众号菜单跳转。
H5网页代码链接:https://github.com/zguogang/web2onenet

首先来看下前台页面UI,比较简单,只是提供一个实时显示数据和发送控制命令的功能


image.png

image.png

image.png

命令是以字符串形式发送的

架构:VUE
具体这边就不多解释了,对照着后台代码一看就懂。

六.总结

成文草草,难免有错漏,欢迎各位大牛,同道一起讨论,指正。

你可能感兴趣的:(使用微信公众号控制你的Arduino)