目录
- 硬件准备
- 机智云平台准备
- 接下来就是手机端
- 机智云网页
硬件准备
- STM32F4开发板一个(我用的是这个,原子哥的也可以的,好吧,没钱买原子哥的┗|`O′|┛ 嗷~)
- ESP8266一块(已经烧录机智云固件)我用的是这个,原子哥的ATK—ESP8266也可以的
机智云平台准备
我准备就是用机智云控制32F4开发板的led灯的亮灭,以及DHT11温湿度模块数据的上报
- 注册机智云账号,进入开发者中心创建自己的产品
- 填写项目名称(仅支持中文、英文字母、数字及下划线),技术方案及通信方式选择WIFI,因为咱们使用的是ESP8266WIFI模块。数据传输选择定长,因为定长是固定一段时间上传数据,而变长是只上传变化的数据点。所以建议使用定长的传输方式,选择好之后,保存。
- 保存之后选择创建数据点:数据点是设备产品的功能的抽象,用于描述产品功能及其参数。创建数据 点后,设备与云端通讯的数据格式即可确定,设备、机智云可以相互识别设备与机智云互通的数据(数据点就是你要控制的量,这里咱们选择 控制LED的亮灭还有DHT11数据的读取,所以咱们创建温度读取和湿度读取),
- 读写类型:定义数据点的作用范围,包含有 4 种类型,分别是:只读、可写、报警、故障。
由于咱们要控制开发板的LED的亮灭,所以选择可写,读取DHT11的数据则需要设置为可读。
.官方给对读写类型介绍:
① 只读:表示该数据点为非控制,数据只支持从设备上报。
② 可写:表示该数据点可控制。设备端可上报数据点数据,云端/客户端(移动端)可对该数 据点数据做出下发控制。
③ 报警:表示该数据点非控制,数据只支持从设备(设备端)上报,数据类型需为布尔值。
④ 故障:表示该数据点非控制,数据只支持从设备(设备端)上报,数据类型需为布尔值。 云端对设备上报的该数据点做统计,可在“运行状态”查看。
官方对数据点的介绍
① 只读:表示该数据点为非控制,数据只支持从设备上报。
② 可写:表示该数据点可控制。设备端可上报数据点数据,云端/客户端(移动端)可对该数 据点数据做出下发控制。
③ 报警:表示该数据点非控制,数据只支持从设备(设备端)上报,数据类型需为布尔值。
④ 故障:表示该数据点非控制,数据只支持从设备(设备端)上报,数据类型需为布尔值。 云端对设备上报的该数据点做统计,可在“运行状态”查看。
>分辨率自己设置,这里我设置为1.
切记更改数据点要点击应用,这里可以看到我把显示名称更改了,这个自己随便设置,这个是显示到app上面的。切记每次更新数据点之后都要点击应用
- 接下来我们可以看到数据点底下有虚拟设备,这个是能模拟 真实设备的上传数据行为,快速的验证接口功能的开发。终端设备没做好,但是想验证功能逻辑,那么虚拟设备功能就可以派上用场了,在产品开发前会显得尤其重要。
这里需要机智云手机app,在机智云下载中心去下载
接下来进入虚拟设备并点击显示二维码,打开安装好的app,扫描生成的app,然后手机如果没有显示连接,就推出网页上的虚拟设备,重新打开虚拟设备,这是就可以看到手机上的页面显示其上线,手机上的页面如下所示,这是我们点击led灯的开关在虚拟设备旁边的通信日志上面就可以看到咱们所上传的数据
5.平台上的都已经基本完成了,接下来就到了开发板代码了,(⁄ ⁄•⁄ω⁄•⁄ ⁄),机智云有代码生成工具,嗯,这个可以降低开发者的开发门槛,缩短开发周期,降低开发资源投入,机智云(Gizwits)推出可 代码自动生成服务。云端会根据产品定义的数据点生成对应产品的设备端代码。自动生成的代码实现了机智云(Gizwits)通讯协议的解析与封包、传感器数据与通信数据的 转换逻辑,并封装成了简单的 API,且提供了多种平台的实例代码。当设备收到云端或 APP 端 的数据后,程序会将数据装换成对应的事件并通知应用层, 开发者只需要在对应的事件处理逻 辑中添加传感器的控制函数,就可以完成产品的开发。
这里我使用的是STM32F4,而上面有一个生成F4代码,但是我没有选择它,因为它生成的代码是使用HAL库,而我一直使用的是标准库,所以这里咱们选择生成其他平台,这个里面使用的是标准库。
Product Secret在基本信息里面获取
生成代码即可
- 接下来就是代码移植,这里我会在文章开头上传一个我移植好的代码,将生成的压缩包解压并且将这两个黑框文件复制到我上传的文件中,并添加进工程.还要把DHT11添加进工程(DHT11我也会上传)
7.接下来就是 简单修改代码了
>先修改gizwits_product.c
/**
************************************************************
* @file gizwits_product.c
* @brief Gizwits control protocol processing, and platform-related hardware initialization
* @author Gizwits
* @date 2017-07-19
* @version V03030000
* @copyright Gizwits
*
* @note Gizwits is only for smart hardware
* Gizwits Smart Cloud for Smart Products
* Links | Value Added | Open | Neutral | Safety | Own | Free | Ecology
* www.gizwits.com
*
***********************************************************/
#include <stdio.h>
#include <string.h> //在这里添加 #include "usart3.h"(必添加) #include "led.h"(用到了所以添加)
#include "gizwits_product.h"
static uint32_t timerMsCount;
/** Current datapoint */
dataPoint_t currentDataPoint; //给这个前面添加extern
//给这个添加extern u8 wifi_sta;
/**@} */
/**@name Gizwits User Interface
* @{
*/
/**
* @brief Event handling interface
* Description:
* 1. Users can customize the changes in WiFi module status
* 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface
* @param [in] info: event queue
* @param [in] data: protocol data
* @param [in] len: protocol data length
* @return NULL
* @ref gizwits_protocol.h
*/
int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len)
{
uint8_t i = 0;
dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata;
moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata;
protocolTime_t *ptime = (protocolTime_t *)gizdata;
#if MODULE_TYPE
gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata;
#else
moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata;
#endif
if((NULL == info) || (NULL == gizdata))
{
return -1;
}
for(i=0; i<info->num; i++)
{
switch(info->event[i])
{
case EVENT_LED_on_off:
currentDataPoint.valueLED_on_off = dataPointPtr->valueLED_on_off;
GIZWITS_LOG("Evt: EVENT_LED_on_off %d \n", currentDataPoint.valueLED_on_off);
if(0x01 == currentDataPoint.valueLED_on_off)
{
//user handle
LED0=1;//这块添加这行代码,用来控制LED
}
else
{
//user handle
LED0=0;//这块添加这行代码,用来控制LED
}
break;
case WIFI_SOFTAP:
break;
case WIFI_AIRLINK:
break;
case WIFI_STATION:
break;
case WIFI_CON_ROUTER:
break;
case WIFI_DISCON_ROUTER:
break;
case WIFI_CON_M2M:
//给这行添加 wifi_sta=1; //wifi设备已连接
break;
case WIFI_DISCON_M2M: //给这行添加 wifi_sta=0; //wifi设备断开
break;
case WIFI_RSSI:
GIZWITS_LOG("RSSI %d\n", wifiData->rssi);
break;
case TRANSPARENT_DATA:
GIZWITS_LOG("TRANSPARENT_DATA \n");
//user handle , Fetch data from [data] , size is [len]
break;
case WIFI_NTP:
GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp);
break;
case MODULE_INFO:
GIZWITS_LOG("MODULE INFO ...\n");
#if MODULE_TYPE
GIZWITS_LOG("GPRS MODULE ...\n");
//Format By gprsInfo_t
#else
GIZWITS_LOG("WIF MODULE ...\n");
//Format By moduleInfo_t
GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType);
#endif
break;
default:
break;
}
}
return 0;
}
/**
* User data acquisition
* Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm
* @param none
* @return none
*/
void userHandle(void) //从这行开始删除 包括这行
{
/*
currentDataPoint.valuetemp = ;//Add Sensor Data Collection
currentDataPoint.valuehum = ;//Add Sensor Data Collection
*/
}
//删除到这里结束,包括这行
/**
* Data point initialization function
* In the function to complete the initial user-related data
* @param none
* @return none
* @note The developer can add a data point state initialization value within this function
*/
void userInit(void)
{
memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));
/** Warning !!! DataPoint Variables Init , Must Within The Data Range **/
/*
currentDataPoint.valueLED_on_off = ;
currentDataPoint.valuetemp = ;
currentDataPoint.valuehum = ;
*/
}
/**
* @brief gizTimerMs
* millisecond timer maintenance function ,Millisecond increment , Overflow to zero
* @param none
* @return none
*/
void gizTimerMs(void)
{
timerMsCount++;
}
/**
* @brief gizGetTimerCount
* Read system time, millisecond timer
* @param none
* @return System time millisecond
*/
uint32_t gizGetTimerCount(void)
{
return timerMsCount;
}
/**
* @brief mcuRestart
* MCU Reset function
* @param none
* @return none
*/
void mcuRestart(void)
{ //下面两行添加进去
__set_FAULTMASK(1);//关闭所有中断
NVIC_SystemReset();//复位
}
/**@} */
/**
* @brief TIMER_IRQ_FUN
* Timer Interrupt handler function
* @param none
* @return none
*/
void TIMER_IRQ_FUN(void)
{
gizTimerMs();
}
/**
* @brief UART_IRQ_FUN
* UART Serial interrupt function 锛孎or Module communication
* Used to receive serial port protocol data between WiFi module
* @param none
* @return none
*/
void UART_IRQ_FUN(void)
{
uint8_t value = 0;
//value = USART_ReceiveData(USART2);//STM32 test demo
gizPutData(&value, 1);
}
/**
* @brief uartWrite
* Serial write operation, send data to the WiFi module
* @param buf : Data address
* @param len : Data length
*
* @return : Not 0,Serial send success;
* -1锛孖nput Param Illegal
*/
int32_t uartWrite(uint8_t *buf, uint32_t len) //从这行开始注释
{
uint32_t i = 0;
if(NULL == buf)
{
return -1;
}
#ifdef PROTOCOL_DEBUG
GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
for(i=0; i<len; i++)
{
GIZWITS_LOG("%02x ", buf[i]);
}
GIZWITS_LOG("\n");
#endif
for(i=0; i<len; i++)
{
//USART_SendData(UART, buf[i]);//STM32 test demo
//Serial port to achieve the function, the buf[i] sent to the module
if(i >=2 && buf[i] == 0xFF)
{
//Serial port to achieve the function, the 0x55 sent to the module
//USART_SendData(UART, 0x55);//STM32 test demo
}
}
return len;
}
//注释到这里,包括这行
给gizwits_product.c最下方添加以下代码
int32_t uartWrite(uint8_t *buf, uint32_t len)
{
uint32_t i = 0;
if(NULL == buf)
{
return -1;
}
#ifdef PROTOCOL_DEBUG
GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
for(i=0; i<len; i++)
{
GIZWITS_LOG("%02x ", buf[i]);
if(i >=2 && buf[i] == 0xFF)
{
GIZWITS_LOG("%02x ", 0x55);
}
}
GIZWITS_LOG("\n");
#endif
for(i=0; i<len; i++)
{
// UART_Transmit_IT(&huart2, (uint8_t *)&buf[i], 1);
USART_SendData(USART3,buf[i]);
while (USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);//Loop until the end of transmission
if(i >=2 && buf[i] == 0xFF)
{
USART_SendData(USART3,0x55);
while (USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);//Loop until the end of transmission
}
}
return len;
}
在gizwits_product.h中加入 void gizTimerMs(void);
void userInit(void);
void userHandle(void);
void mcuRestart(void);
void gizTimerMs(void);//这个是添加的
- 接下来就是修改主函数以及添加外设(DHT11)
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "usart3.h"
#include "gizwits_product.h"
//在这里添加#include "dht11.h"
dataPoint_t currentDataPoint;
u8 wifi_sta=0;
void Gizwits_Init(void)
{
TIM3_Int_Init(10-1,8400-1); //1MS系统定时
usart3_init(9600);//WIFI初始化
memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));//设备状态结构体初始化
gizwitsInit();//缓冲区初始化
}
//数据采集
void userHandle(void)
{ //添加以下代码
static u8 t=0;
static u8 temp,hum;
DHT11_Read_Data(&temp,&hum);
LCD_ShowxNum(70,150+50+10,temp,3,16,0);
LCD_ShowxNum(70,175+50+10+5,hum,3,16,0);
currentDataPoint.valuetemp=temp;
currentDataPoint.valuehum=hum;
}
//主函数
int main(void)
{
int key;
u8 wifi_con=0;//记录WIFI连接状态
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED端口
KEY_Init(); //初始化按键
Gizwits_Init(); //协议初始化
while(1)
{
userHandle();//用户采集
if(wifi_con!=wifi_sta)
{
wifi_con=wifi_sta;
wifi_con?printf("connect"):printf("close");
}
gizwitsHandle((dataPoint_t *)¤tDataPoint);//协议处理
key = KEY_Scan(0);
if(key==KEY2_PRES)//KEY2按键
{
printf("WIFI进入AirLink连接模式\r\n");
gizwitsSetMode(WIFI_AIRLINK_MODE);//Air-link模式接入可以进这个函数修改模式
}
if(key==WKUP_PRES)//KEY_UP按键
{
printf("WIFI复位,请重新配置连接\r\n");
gizwitsSetMode(WIFI_RESET_MODE);//WIFI复位
}
delay_ms(200);
}
}
至此就修改完了,在文章开头,我会上传模板,以及我按照这个步骤移植完成的代码
接下来就是手机端
注意第一次连接需要用手机给8266配置网络,所以要使用手机和8266连接同一个WIFI;
- 在代码下载并运行,按开发板的复位按键。
- 打开手机机智云APP进去之后可以看到这样的页面(因为我不会上传视频到这里,所以我直接上传到我发的资源包里面)
- 点击右上角的加号-一键配置输入密码(注意:此时的手机也连接的是这个路由器),下一步,选择对应的WIFI,如果没有就选择其他。接下来就按步骤连接
- 连接成功就可以看到这个页面你的设备,然后就可以进行控制了
演示视频在我上传的压缩包里面
配置一次就可以了,下次上电8266会自动连接
机智云网页
在网页可以看到设备的运行日志,还有个好玩的就是设备可以共享的