基于机智云远程设备控制与数据上传的分析

一、机智云二次开发的基本流程

        申请开发者账号

        创建产品

        创建数据点

       下载源码并修改源码

        编译 下载

        调试 发布

         完成


主要讲下修改源码

           源码架构:

基于机智云远程设备控制与数据上传的分析_第1张图片

整个云端自动生成的SOC源码里面,用户只需要关心文件路径为“GizLamp\app”下面的几个地方:

如果你需要添加8266的外设,只需要在

  • “GizLamp\app\driver”文件目录下添加相应外设的驱动的.c文件
  • “GizLamp\app\include\driver文件目录下添加相应外设的驱动的.h文件

App通过云端下发控制事件处理,可以在

  • “GizLamp\app\Gizwits”文件目录下“gizwits_product.c”文件里面的
  • “gizwitsEventProcess()函数里添加驱动外设执行事件函数即可实现控制设备

上报云端状态事件处理,可以在

  • “GizLamp\app\user”文件目录下“user_main.c”文件里面的“userTimerFunc()函数里添加数据状态上报函数即可以实现状态上报。

在这套SOC源码里面需要关心也就这几个主要的地方,模块联网以及底层驱动均不需要开发者去处理和修改。


二、如何实现远程控制

    基于机智云远程设备控制与数据上传的分析_第2张图片

/**

* @brief 该函数被Gagent模块调用,接收来自云端或APP端下发的相关协议数据

* @param[in] inData 输入的协议数据

* @param[in] inLen 输入数据的长度

* @param[out] outData输出的协议数据

* @param[out] outLen 输出数据的长度

* @return 0, 执行成功, 非 0, 失败

*/

int32_tICACHE_FLASH_ATTR gizIssuedProcess(uint8_t *inData, uint32_t inLen,uint8_t*outData,int32_t *outLen)

{

    gizwitsIssued_t *gizIssuedData=(gizwitsIssued_t *)&inData[1];

    if(NULL == gizIssuedData)

    {

        os_printf("!!! IssuedProcess Error\n");

        return -1;

    }

 

    if((NULL == outData) || (NULL == outLen))

    {

        os_printf("!!! IssuedProcess Error\n");

 

        return -1;

    }

 

    switch(inData[0])

    {

        case ACTION_CONTROL_DEVICE:

            gizDataPoint2Event(gizIssuedData,&gizwitsProtocol.issuedProcessEvent,&gizwitsProtocol.gizCurrentDataPoint);

           

            system_os_post(USER_TASK_PRIO_2, SIG_ISSUED_DATA,0);

            *outLen = 0;

            break;

           

        case ACTION_READ_DEV_STATUS:

            gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,&gizwitsProtocol.reportData.devStatus);

            gizwitsProtocol.reportData.action =ACTION_READ_DEV_STATUS_ACK;

            os_memcpy(outData, (uint8_t *)&gizwitsProtocol.reportData,sizeof(gizwitsReport_t));

            *outLen = sizeof(gizwitsReport_t);

            break;

           

        case ACTION_W2D_TRANSPARENT_DATA: //透传

           os_memcpy(gizwitsProtocol.transparentBuff, &inData[1], inLen-1);

            gizwitsProtocol.transparentLen =inLen-1;

 

            system_os_post(USER_TASK_PRIO_2,SIG_PASSTHROUGH, 0);

            *outLen = 0;

 

 

调用 SIG_ISSUED_DATA

 

switch(events->sig)

    {

    case SIG_ISSUED_DATA:

        gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent,(uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t));

        //clean event info

        os_memset((uint8_t*)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t));

        break;

    case SIG_PASSTHROUGH:

       gizwitsProtocol.issuedProcessEvent.event[0] = TRANSPARENT_DATA;

       gizwitsProtocol.issuedProcessEvent.num = 1;

        gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent,(uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen);

 

        os_memset((uint8_t*)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t));

        os_memset((uint8_t*)gizwitsProtocol.transparentBuff, 0, BUFFER_LEN_MAX);

       gizwitsProtocol.transparentLen = 0;

        break;

    case SIG_IMM_REPORT:

       gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,(devStatus_t *)&gizwitsProtocol.reportData.devStatus);

        gizwitsProtocol.reportData.action= ACTION_REPORT_DEV_STATUS;

        gagentUploadData((uint8_t*)&gizwitsProtocol.reportData, sizeof(gizwitsReport_t));

        break;

 

 

 

/** 用户区当前设备状态结构体*/

extern dataPoint_t currentDataPoint;

 

/**@name Gizwits 用户API接口

* @{

*/

 

/**

* @brief 事件处理接口

 

* 说明:

 

* 1.用户可以对WiFi模组状态的变化进行自定义的处理

 

* 2.用户可以在该函数内添加数据点事件处理逻辑,如调用相关硬件外设的操作接口

 

* @param[in] info : 事件队列

* @param[in] data : 协议数据

* @param[in] len : 协议数据长度

* @return NULL

* @ref gizwits_protocol.h

*/

int8_t ICACHE_FLASH_ATTR gizwitsEventProcess(eventInfo_t *info, uint8_t *data,uint32_t len)

{

  uint8_t i = 0;

  dataPoint_t *dataPointPtr =(dataPoint_t *)data;

  moduleStatusInfo_t *wifiData =(moduleStatusInfo_t *)data;

 

  if((NULL == info) || (NULL ==data))

  {

    return -1;

  }

 

  for(i=0; inum; i++)

  {

    switch(info->event[i])

    {

      case EVENT_LED_ONOFF:

       currentDataPoint.valueLED_OnOff = dataPointPtr->valueLED_OnOff;

        os_printf("Evt:EVENT_LED_ONOFF %d \n", currentDataPoint.valueLED_OnOff);

        if(0x01 ==currentDataPoint.valueLED_OnOff)

        {

            rgbControl(254, 0, 0);

        }

        else

        { 

            rgbControl(0, 0,0);  

        }

        break;

 

      case EVENT_LED_COLOR:

        currentDataPoint.valueLED_Color= dataPointPtr->valueLED_Color;

        os_printf("Evt:EVENT_LED_COLOR %d\n", currentDataPoint.valueLED_Color);

       switch(currentDataPoint.valueLED_Color)

        {

          case LED_COLOR_VALUE0:

            rgbControl(currentDataPoint.valueLED_R,currentDataPoint.valueLED_G,currentDataPoint.valueLED_B);

            break;

          case LED_COLOR_VALUE1:

            rgbControl(254, 254, 0);

            break;

          case LED_COLOR_VALUE2:

            rgbControl(254, 0, 70);

            break;

          case LED_COLOR_VALUE3:

            rgbControl(238, 30, 30);

            break;

          default:

            break;

        }

        break;

 

      case EVENT_LED_R:

        currentDataPoint.valueLED_R= dataPointPtr->valueLED_R;

       os_printf("Evt:EVENT_LED_R %d\n",currentDataPoint.valueLED_R);

       rgbControl(currentDataPoint.valueLED_R,currentDataPoint.valueLED_G,currentDataPoint.valueLED_B);

        break;

      case EVENT_LED_G:

        currentDataPoint.valueLED_G= dataPointPtr->valueLED_G;

       os_printf("Evt:EVENT_LED_G %d\n",currentDataPoint.valueLED_G);

       rgbControl(currentDataPoint.valueLED_R,currentDataPoint.valueLED_G,currentDataPoint.valueLED_B);

        break;

      case EVENT_LED_B:

        currentDataPoint.valueLED_B= dataPointPtr->valueLED_B;

       os_printf("Evt:EVENT_LED_B %d\n",currentDataPoint.valueLED_B);

       rgbControl(currentDataPoint.valueLED_R,currentDataPoint.valueLED_G,currentDataPoint.valueLED_B);

        break;

      case EVENT_MOTOR_SPEED:

       currentDataPoint.valueMotor_Speed = dataPointPtr->valueMotor_Speed;

       os_printf("Evt:EVENT_MOTOR_SPEED%d\n",currentDataPoint.valueMotor_Speed);

        motorControl(currentDataPoint.valueMotor_Speed);

        break;

 

      case WIFI_SOFTAP:

        break;

      case WIFI_AIRLINK:

        break;

      case WIFI_STATION:

        break;

      case WIFI_CON_ROUTER:

        rgbControl(0, 0, 0);

        break;

      case WIFI_DISCON_ROUTER:

        break;

      case WIFI_CON_M2M:

        break;

      case WIFI_DISCON_M2M:

        break;

      case WIFI_RSSI:

        os_printf("RSSI%d\n", wifiData->rssi);

        break;

      case TRANSPARENT_DATA:

        os_printf("TRANSPARENT_DATA\n");

        //user handle , Fetch datafrom [data] , size is [len]

        break;

      default:

        break;

    }

  }

  system_os_post(USER_TASK_PRIO_0,SIG_UPGRADE_DATA, 0);

  return 0;

}

 

/**@} */


接着往下就是调用相应的驱动函数,执行动作了,比如控制led,电机等等。
贴一个控制LED的驱动文件。

/*********************************************************

*

* @file      hal_rgb_led.c

* @author    Gizwtis

* @version   V3.0

* @date      2016-03-09

*

* @brief     机智云 只为智能硬件而生

*            Gizwits Smart Cloud  for Smart Products

*            链接|增值|开放|中立|安全|自有|自由|生态

*            www.gizwits.com

*

*********************************************************/

 

#include"driver/hal_rgb_led.h"

#include"osapi.h"

 

static voidICACHE_FLASH_ATTR rgbDelay(unsigned int us)

{

    /* Define your delay function */

    volatile unsigned int i=0;

       

    for(i=0; i

}

 

 

/************generation clock *********************/

static voidICACHE_FLASH_ATTR clkProduce(void)

{

    SCL_LOW;   // SCL=0

    rgbDelay(40);

    SCL_HIGH;     // SCL=1

    rgbDelay(40);

}

 

 

/**********  send 32 zero ********************/

static voidICACHE_FLASH_ATTR send_32zero(void)

{

    uint8_t i;

       

    SDA_LOW;  // SDA=0

    for (i=0; i<32; i++)

        {

               clkProduce();

        }

       

}

 

 

/********* invert thegrey value of the first two bits ***************/

static uint8_tICACHE_FLASH_ATTR takeAntiCode(uint8_t dat)

{

    uint8_t tmp = 0;

 

    tmp=((~dat) & 0xC0)>>6;

    return tmp;

}

 

 

/****** send graydata *********/

static void ICACHE_FLASH_ATTRdataSend(uint32 dx)

{

    uint8_t i;

 

    for (i=0; i<32; i++)

    {

        if ((dx & 0x80000000) != 0)

        {

 

            SDA_HIGH;     // SDA=1;

        }

        else

        {

            SDA_LOW;    // SDA=0;

        }

 

        dx <<= 1;

        clkProduce();

    }

}

 

 

/******* dataprocessing  ********************/

static voidICACHE_FLASH_ATTR dataDealwithSend(uint8_t r, uint8_t g, uint8_t b)

{

    uint32 dx = 0;

 

    dx |= (uint32)0x03 << 30;             // The front of the two bits 1 isflag bits

    dx |= (uint32)takeAntiCode(b) << 28;

    dx |= (uint32)takeAntiCode(g) << 26;

    dx |= (uint32)takeAntiCode(r) << 24;

 

    dx |= (uint32)b << 16;

    dx |= (uint32)g << 8;

    dx |= r;

 

    dataSend(dx);

}

 

 

void ICACHE_FLASH_ATTRrgbControl(uint8_t R, uint8_t G, uint8_t B)

{

    //contron power

   

    send_32zero();

    dataDealwithSend(R, G, B);   //display red

    dataDealwithSend(R, G, B);   //display red

}

 

 

voidICACHE_FLASH_ATTR rgbLedInit(void)

{

    //contron power

 

    send_32zero();

    dataDealwithSend(0, 0, 0);   // display red

    dataDealwithSend(0, 0, 0);

}

 

 

voidICACHE_FLASH_ATTR rgbGpioInit(void)

{

    /* Migrate your driver code */

 

    // SCL/SDA

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U,FUNC_GPIO15);

 

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4);

 

    gpio_output_set(0, 0,GPIO_ID_PIN(GPIO_RGB_SCL) | GPIO_ID_PIN(GPIO_RGB_SDA), 0); //|GPIO_ID_PIN(GPIO_RGB_POW)

 

    os_printf("rgbGpioInit \r\n");

}

 

voidICACHE_FLASH_ATTR rgbSensorTest(uint8_t rgbcou)

{

    /* Test LOG model */

 

    if (0 == rgbcou)

    {

        rgbControl(0, 0, 250);

//      GAgent_Printf(GAGENT_CRITICAL, "RGB: B");

    }

    else if (1 == rgbcou)

    {

        rgbControl(0, 250, 0);

//      GAgent_Printf(GAGENT_CRITICAL, "RGB: G");

    }

    else if (2 == rgbcou)

    {

        rgbControl(250, 0, 0);

//      GAgent_Printf(GAGENT_CRITICAL, "RGB: R");

    }

}

 

三、如何实现数据上传

基于机智云远程设备控制与数据上传的分析_第3张图片


具体代码,可参考源程序。 因为数据运行的平台不一样,只要是三个平台 设备——传输介质——APP所以在接受或者发送数据时,存在数据类型转换,压缩及解压缩处理。比如在机智云中,使设备功能定义更加简单直接,使用户输入的数值转换成设备能够识别的uint类型,这套算法的核心公式是:y=kx+m (y:显示值;x:传输值;k:分辨率;m:增量


/**

* @brief 16位数据字节序转换

*

* @param [in] value : 需要转换的数据

*

* @return  tmp_value: 转换后的数据

*/

static uint16_t ICACHE_FLASH_ATTR gizProtocolExchangeBytes(uint16_t value)

{

    uint16_t    tmp_value;

    uint8_t     *index_1, *index_2;

 

    index_1 = (uint8_t*)&tmp_value;

    index_2 = (uint8_t *)&value;

 

    *index_1 = *(index_2+1);

    *(index_1+1) = *index_2;

 

    return tmp_value;

}

 

 

 

/**

* @brief 32位数据字节序转换

*

* @param [in] value : 需要转换的数据

*

* @return  tmp_value: 转换后的数据

*/

static uint32_t ICACHE_FLASH_ATTR gizExchangeWord(uint32_t  value)

{

    return ((value & 0x000000FF)<< 24) |

        ((value & 0x0000FF00)<< 8) |

        ((value & 0x00FF0000)>> 8) |

        ((value & 0xFF000000) >> 24) ;

}

 

 

 

/**

* @brief 数组缓冲区网络字节序转换

*

* @param [in] *buf     : buf地址

* @param [in] dataLen  : 字节长度

*

* @return 正确 : 0

          失败 : -1

*/

static int8_t ICACHE_FLASH_ATTR gizByteOrderExchange(uint8_t *buf,uint32_tdataLen)

{

   uint32_t i = 0;

    uint8_t preData = 0;

    uint8_t aftData = 0;

 

    if(NULL == buf)

    {

       os_printf("gizByteOrderExchange Error , Illegal Param\n");

        return -1;

    }

 

    for(i = 0;i

    {

        preData = buf[i];

        aftData = buf[dataLen - i - 1];

        buf[i] = aftData;

        buf[dataLen - i - 1] =preData;

    }

 

    return 0;

}

 

/**

* @brief 转化为协议中的x值及实际通讯传输的值

*

* @param [in] ratio    : 修正系数k

* @param [in] addition : 增量m

* @param [in] preValue : 作为协议中的y值, 是App UI界面的显示值

*

* @return aft_value    : 作为协议中的x值, 是实际通讯传输的值

*/

static uint32_t ICACHE_FLASH_ATTR gizY2X(uint32_t ratio, int32_t addition,int32_t preValue)

{

    uint32_t aftValue = 0;

 

    //x=(y - m)/k

    aftValue = ((preValue -addition) / ratio);

 

    return aftValue;

}

 

 

/**

* @brief 转化为协议中的y值及App UI界面的显示值

*

* @param [in] ratio    : 修正系数k

* @param [in] addition : 增量m

* @param [in] preValue : 作为协议中的x值, 是实际通讯传输的值

*

* @return aftValue : 作为协议中的y值, 是App UI界面的显示值

*/

static int32_t ICACHE_FLASH_ATTR gizX2Y(uint32_t ratio, int32_t addition,uint32_t preValue)

{

    int32_t aftValue = 0;

 

    //y=k * x + m

    aftValue = (preValue * ratio +addition);

 

    return aftValue;

}

 

 

/**

* @brief 转化为协议中的x值及实际通讯传输的值,只用作对浮点型数据做处理

*

* @param [in] ratio    : 修正系数k

* @param [in] addition : 增量m

* @param [in] preValue : 作为协议中的y值, 是App UI界面的显示值

*

* @return  aft_value : 作为协议中的x值, 是实际通讯传输的值

*/

static uint32_t ICACHE_FLASH_ATTR gizY2XFloat(float ratio, float addition,float preValue)

{

    uint32_t aftValue = 0;

 

    //x=(y - m)/k

    aftValue = ((preValue -addition) / ratio);

 

    return aftValue;

}

 

/**

* @brief 转化为协议中的y值及App UI界面的显示值,只用作对浮点型数据做处理

*

* @param [in] ratio : 修正系数k

* @param [in] addition : 增量m

* @param [in] preValue : 作为协议中的x值, 是实际通讯传输的值

*

* @return : 作为协议中的y值, 是App UI界面的显示值

*/

static float ICACHE_FLASH_ATTR gizX2YFloat(float ratio, float addition,uint32_t preValue)

{

    float aftValue = 0;

 

    //y=k * x + m

    aftValue = (preValue * ratio +addition);

 

    return aftValue;

}

 

/**

* @brief 数据点跨字节判断

*

* @param [in] bitOffset     : 位偏移

* @param [in] bitLen        : 占用位长度

*

* @return 未跨字节 : 0

            跨字节 : 1

*/

static uint8_t ICACHE_FLASH_ATTR gizAcrossByteJudge(uint32_tbitOffset,uint32_t bitLen)

{

    if((0 == bitOffset)||(0 ==bitOffset%8))

    {

        if(bitLen <= 8)

        {

            return 0;

        }

        else

        {

            return 1;

        }

    }

    else

    {

        if(8 - bitOffset%8 >=bitLen)

        {

            return 0;

        }

        else

        {

            return 1;

        }

    }

}

 

设备端与自云端的数据交互过程中,一些特殊类型(boolenum类型)的数据点原始数据只有被特殊处理后才可被云端解析,所以设备端在接收云端数据时要进行数据的解压处理;在向云端发送数据时进行数据的压缩处理。

 

static int32_t ICACHE_FLASH_ATTRgizDecompressionValue(uint32_tbyteOffset,uint32_t bitOffset,uint32_t bitLen,uint8_t *arrayAddr,uint32_tarrayLen)

{

    uint8_t ret = 0;

    uint8_t highBit = 0 ,lowBit = 0;

    uint8_tdestBufTemp[COUNT_W_BIT];

    int32_t destValue = 0;

   

    if(NULL == arrayAddr || 0 ==arrayLen)

    {

       os_printf("gizDecompressionValue Error , Illegal Param\n");

        return -1;

    }

 

   memcpy(destBufTemp,arrayAddr,arrayLen);

    if(arrayLen > 1)// Judge Byteorder conversion

    {

        if(-1 ==gizByteOrderExchange(destBufTemp,arrayLen))

        {

            os_printf("gizDecompressionValuegizByteOrderExchange Error \n");

            return -1;

        }

    }

    ret =gizAcrossByteJudge(bitOffset,bitLen);//Judge Byte Step

    if(0 == ret)

    {

        destValue |=((destBufTemp[byteOffset] >> (bitOffset%8)) & (0xff >> (8 -bitLen)));

    }

    else if(1 == ret)

    {

        /* 暂时只支持最多跨2字节 */

        highBit =destBufTemp[byteOffset + 1]& (0xFF >> (8-(bitLen-(8-bitOffset%8))));

        lowBit =destBufTemp[byteOffset]>> (bitOffset%8);

        destValue |=  (highBit << (8-bitOffset%8));

        destValue |= lowBit;

    }

    //os_printf("ReturngizDecompressionValue = 0x%08x \n",destValue);

    return destValue;

}

 

/**

* @brief bool和enum类型数据点数据压缩

*

* @param [in] byteOffset    : 字节偏移

* @param [in] bitOffset     : 位偏移

* @param [in] bitLen        : 占用位长度

* @param [out] *arrayAddr   : 数组地址

* @param [in] srcData       : 原始数据

*

* @return : 0,正确返回;-1,错误返回

*/

static int32_t ICACHE_FLASH_ATTR gizCompressValue(uint32_tbyteOffset,uint32_t bitOffset,uint32_t bitLen,uint8_t *bufAddr,uint32_tsrcData)

{

    uint8_t highBit = 0 ,lowBit = 0;

    uint8_t ret = 0;

    if(NULL == bufAddr)

    {

       os_printf("gizCompressValue Error , Illegal Param\n");

        return -1;

    }

    ret =gizAcrossByteJudge(bitOffset,bitLen);

    if(0 == ret)

    {

        bufAddr[byteOffset] |=(((uint8_t)srcData)<<(bitOffset%8));

    }

    else if(1 == ret)

    {

        /* 暂时支持最多跨两字节的压缩 */

        highBit =((uint8_t)srcData)>>(8-bitOffset%8);

        lowBit = (uint8_t)srcData& (0xFF >> (8-bitOffset%8));

        bufAddr[byteOffset + 1]|=  highBit;

        bufAddr[byteOffset] |=(lowBit<<(bitOffset%8));

    }

    return 0;

}

/**

* @brief 用户数据点数据转换为机智云上报数据点数据

*

* @param [in]  dataPoints           : 用户数据点数据地址

* @param [out] devStatusPtr         : 机智云上报数据点数据地址

*

* @return 0,正确返回;-1,错误返回

*/

static int8_t ICACHE_FLASH_ATTR gizDataPoints2ReportData(dataPoint_t*dataPoints , devStatus_t *devStatusPtr)

{

    if((NULL == dataPoints) || (NULL== devStatusPtr))

    {

       os_printf("gizDataPoints2ReportData Error , Illegal Param\n");

        return -1;

    }

    memset((uint8_t*)devStatusPtr->wBitBuf,0,sizeof(devStatusPtr->wBitBuf));

    memset((uint8_t*)devStatusPtr->rBitBuf,0,sizeof(devStatusPtr->rBitBuf));

    gizCompressValue(LED_ONOFF_BYTEOFFSET,LED_ONOFF_BITOFFSET,LED_ONOFF_LEN,(uint8_t*)devStatusPtr,dataPoints->valueLED_OnOff);

   gizCompressValue(LED_COLOR_BYTEOFFSET,LED_COLOR_BITOFFSET,LED_COLOR_LEN,(uint8_t*)devStatusPtr,dataPoints->valueLED_Color);

    gizCompressValue(INFRARED_BYTEOFFSET,INFRARED_BITOFFSET,INFRARED_LEN,(uint8_t*)devStatusPtr,dataPoints->valueInfrared);

    gizByteOrderExchange((uint8_t*)devStatusPtr->wBitBuf,sizeof(devStatusPtr->wBitBuf));

    gizByteOrderExchange((uint8_t*)devStatusPtr->rBitBuf,sizeof(devStatusPtr->rBitBuf));

    devStatusPtr->valueAlert_1 =dataPoints->valueAlert_1;

    devStatusPtr->valueAlert_2 =dataPoints->valueAlert_2;

    devStatusPtr->valueFault_LED= dataPoints->valueFault_LED;

    devStatusPtr->valueFault_Motor= dataPoints->valueFault_Motor;

   devStatusPtr->valueFault_TemHum = dataPoints->valueFault_TemHum;

    devStatusPtr->valueFault_IR =dataPoints->valueFault_IR;

    devStatusPtr->valueLED_R =gizY2X(LED_R_RATIO,  LED_R_ADDITION,dataPoints->valueLED_R);

    devStatusPtr->valueLED_G =gizY2X(LED_G_RATIO,  LED_G_ADDITION,dataPoints->valueLED_G);

    devStatusPtr->valueLED_B =gizY2X(LED_B_RATIO,  LED_B_ADDITION,dataPoints->valueLED_B);

   devStatusPtr->valueTemperature = gizY2X(TEMPERATURE_RATIO,  TEMPERATURE_ADDITION,dataPoints->valueTemperature);

    devStatusPtr->valueHumidity =gizY2X(HUMIDITY_RATIO, HUMIDITY_ADDITION, dataPoints->valueHumidity);

   devStatusPtr->valueMotor_Speed =gizProtocolExchangeBytes(gizY2X(MOTOR_SPEED_RATIO,  MOTOR_SPEED_ADDITION,dataPoints->valueMotor_Speed));

 

    return 0;

}

 

 

4、搭载无线模块,GAgent程序,为APP开发做准备


上面所讲的都是在设备本地进行的操作。

看一个无线模块

基于机智云远程设备控制与数据上传的分析_第4张图片

参数:

802.11 b/g/n

WIFI @2.4 GHz, 支持 WPA/WPA2 安全模式

超小尺寸模组 11.5mm*11.5mm

内置 10 bit 高精度 ADC

内置 TCP/IP 协议栈

内置 TR 开关、 balun、 LNA、功率放大器和匹配网络

内置 PLL、稳压器和电源管理组件

802.11b 模式下+ 19.5dBm 的输出功率

支持天线分集

断电泄露电流小于10uA

内置低功率 32 位 CPU:可以兼作应用处理器

SDIO 2.0、 SPI、 UART

STBC、 1x1 MIMO、 2x1 MIMO

A-MPDU 、 A-MSDU 的聚合和 0.4 s的保护间隔

2ms之内唤醒、连接并传递数据包

待机状态消耗功率小于1.0mW (DTIM3)

工作温度范围 -40 ~ 125℃


所有的命令,都是通过2.4G的天线发射出去。

 在无线模块上,运行有一个GAgent程序

GAgent主要的作用是数据转发,是设备数据、机智云、应用端(APP)的数据交互桥梁。

 

局域网广域网的运行方式如下:

基于机智云远程设备控制与数据上传的分析_第5张图片


现在看看GAgent的结构(以移植到CC3200mod上的代码为例):

基于机智云远程设备控制与数据上传的分析_第6张图片



数据处理过程

基于机智云远程设备控制与数据上传的分析_第7张图片

至此,设备端的分析基本完毕,数据搭载2.4G传送到机智云,那么在APP端是如何控制的呢?在硬件上,手机上也同样有个2.4G的无线发射模块,在机智云上创建产品的时候,
就会得到以下几个号码

1、ProductKey
产品标识码,开发者通过机智云后台创建新产品后,自动生成的一个32位字符串。在机智云的数据库中是一个唯一的号码,开发者将ProductKey写入设备主控MCU后,机智云通过此标识码对设备进行识别并自动完成注册。
2.Product Secret
定义:产品密钥,在生成Productkey的时候云端会对应生成一个Product Secret,该参数为关键性机密参数,不应向第三方泄露。该参数在绑定远程设备(一般为GPRS接入方案)的时候会使用到。
3.DID
定义:设备号,当一个设备初次接入机智云时,机智云自动根据ProductKey以及设备Wi-Fi模块MAC地址为此设备注册一个did,此did全网唯一,用于与用户的绑定及后续操作。
4.AppID
定义:应用标识码,当开发者需要为一款智能产品开发应用(包括iOS、Android、Web应用等)时,后台会自动生成一个AppID,并与此设备进行关联。应用开发时需要填入此AppID。
解析:在云端创建一个产品的同时需要在该产品下添加一个应用,并区分Android与iOS等。AppID主要在开发APP的时候用到。并且在app中注册的所有用户绑定在该Appid下。Appid可以在机智云官网上可以查看到。
5.App Secret#
定义:应用密钥,在云端生成AppID的时候,会对应生成一个App Secret,该参数在APP端SDK注册手机用户时,获取手机短信验证码的时候会用到。


整个的流程如下:

基于机智云远程设备控制与数据上传的分析_第8张图片



 

 

 

 

参考文件:http://docs.gizwits.com/zh-cn/overview/overview.html


你可能感兴趣的:(物联网技术及行业)