基于机智云远程设备控制与数据上传的分析
来源:互联网 发布:重庆知联大厦二手房 编辑:程序博客网 时间:2024/04/28 01:07
一、机智云二次开发的基本流程
申请开发者账号
创建产品
创建数据点
下载源码并修改源码
编译 下载
调试 发布
完成
主要讲下修改源码
源码架构:
整个云端自动生成的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源码里面需要关心也就这几个主要的地方,模块联网以及底层驱动均不需要开发者去处理和修改。
二、如何实现远程控制
/**
* @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; i<info->num; 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<us; 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");
}
}
三、如何实现数据上传
具体代码,可参考源程序。 因为数据运行的平台不一样,只要是三个平台 设备——传输介质——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<dataLen/2;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;
}
}
}
设备端与自云端的数据交互过程中,一些特殊类型(bool和enum类型)的数据点原始数据只有被特殊处理后才可被云端解析,所以设备端在接收云端数据时要进行数据的解压处理;在向云端发送数据时进行数据的压缩处理。
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开发做准备
上面所讲的都是在设备本地进行的操作。
看一个无线模块
参数:
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)的数据交互桥梁。
在局域网和广域网的运行方式如下:
现在看看GAgent的结构(以移植到CC3200mod上的代码为例):
数据处理过程
至此,设备端的分析基本完毕,数据搭载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注册手机用户时,获取手机短信验证码的时候会用到。
整个的流程如下:
参考文件:http://docs.gizwits.com/zh-cn/overview/overview.html
- 基于机智云远程设备控制与数据上传的分析
- 基于UCOSIII+机智云的远程空调遥控器
- 基于UCOSIII+机智云的远程空调遥控器
- 基于电力线载波的数据通讯与远程控制
- 物联网平台机智云Android开源框架入门之旅(二)详细分析在设备列表的代码块,如何修改设备默认图片。
- VC++远程控制软件的通信架构与源码分析
- 基于缺陷数据的度量与分析
- 基于Predix云远程控制边缘节点的实践
- 物联网平台机智云Android开源框架入门之旅(三)分析设备详情界面的中如何发送各种指令到云端。
- 物联网平台机智云Android开源框架入门之旅(五) 分析怎么样把云端设备的信息状态同步到手机显示。
- 基于Java及BACnet协议的智能建筑远程控制的可行分析
- 基于web的远程led控制
- 基于JAVA的远程控制软件
- 基于虚拟机的labview远程控制
- 数据收集与分析:可穿戴设备的真正意义
- 基于DTMF技术与射频技术的远程控制的实现
- 基于套接字通信的远程截屏显示与控制技术
- 基于套接字通信的远程截屏显示与控制技术
- 2017,我要毕业啦
- Windows下如何使用git管理github
- 阻止a标签跳转,且将a的get提交方式转化为post提交
- edittext
- 欢迎使用CSDN-markdown编辑器
- 基于机智云远程设备控制与数据上传的分析
- POJ 1562
- Ubuntu-jdk+tomcat+eclipse软件包安装
- C#语言基础总结-2
- 补码、反码的相关问题
- [BZOJ 1036][ZJOI2008]树的统计Count(树链剖分)
- Error: Finish can only be called once
- 从零移植uboot 2017 到nuc970(第十六天)
- 九度1007:奥运排序问题