前言:
经过一天的努力,终于弄懂了怎么接入机智云,写博客记录一下,防止自己以后会忘记。
功能简介:
使用32单片机和ESP8266-01S接入机智云,将传感器采集的光照数据上传到机智云APP,同时实现远程控制LED灯。
前期准备:
1、注册机智云账号
2、ESP8266烧写机智云的官方固件
3、在机智云上创建新产品
4、准备一个写有串口3、定时3的工程模板
主要硬件准备:
1、STM32C8T6最小系统板
2、ESP8266-01S模块
3、BH1750光照传感器
模块接线:
ESP8266-01S模块:
VCC–3.3V GND–GND TX–PB11 RX–PB10
BH1750光照传感器:
VCC–3.3V GND–GNG SCL–PB6 SDA–PB7 ADDR–不接
1、注册机智云账号
进入官网注册
2、ESP8266烧写机智云的官方固件
机智云固件下载地址
下载的资源如下:
用ESP8266-01S模块的烧写第2个固件
ESP8266烧录模式的接线:
建议大家可以买个ESP8266的下载烧录器,省去接线的麻烦。
如果是其他串口模块,烧录模式的接线如下:
将TX接到串口模块的RX上,
将RX接到串口模块的TX上,
EN和VCC接3.3V
GND和IO0接GND
其余脚无视即可。
使用ESPFlashDownloadTool_v3.6.4.exe软件烧写固件
双击运行软件后,选择第1个
导入8Mb的固件后,按下图配置,点START开始烧写
判断是否烧录成功:
出现有FF FF 00 05开头的数据,说明已经成功烧录机智云的固件
3、在机智云上创建新产品
进入开发者中心
右上角的+创建新产品
产品分类可以不改,填写产品名称,选择WiFi/移动网络方案,最后点击保存
点击保存后会自动来到这个页面,点击去添加数据点
新建数据点
LED开关的数据点如下:
再添加一个光照值的数据点
点击应用 保存数据点
先来测试一下创建的产品是否可以和机智云APP通信
下载官方的Demo APP进行虚拟设备测试和后面的实际设备测试
下载后安装、注册账号,这个账号不是我们在机智云官网开发者中心注册的账号,需要另外注册。
启动虚拟设备
点击显示二维码后,使用手机上的机智云APP扫码绑定
点击推送可以将平台的数据发给手机APP
手机APP界面
接下来是移植机智云的代码到开发板中
拷贝产品密钥
粘贴刚刚拷贝的产品密钥,硬件平台选STM32F103C8X,后点击生成代码包
下载代码
下载的压缩包如下:
解压后,将这两个文件夹拷贝到我们准备好的工程模板(带串口3和定时3)中
4、准备一个写有串口3、定时3的工程模板
已放入工程模板中
打开我们的工程模板,新增两组文件夹,后添加对应的源文件(.c)
添加头文件路径
编译代码后会出现两处错误
第1处错误修改:
第2处错误修改:
再次运行编译后出现10个错误
把报错的注释掉,同时将修改 dataPoint_t currentDataPoint;
main.c文件中添加对应的头文件和定义设备状态结构体
继续根据错误 注释和修改
将HAL_NVIC_SystemReset();更改为NVIC_SystemReset();
接下来将233行到291行的都注释掉
被注释的函数有
PUTCHAR_PROTOTYPE
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
void timerInit(void)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
void uartInit(void)
在int32_t uartWrite(uint8_t *buf, uint32_t len)函数里面注释掉for()循环,添加新的for循环
for(i=0; i<len; i++)//添加
{
USART_SendData(USART3,buf[i]);
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
if(i >=2 && buf[i] == 0xFF)
{
//实现串口发送函数,将0x55发送到模组
USART_SendData(USART3,0x55);
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
}
}
再次编译后- 0 Error(s), 3 Warning(s)
警告可以不理,有强迫症的看下:
第1处警告
直接注释掉,没有用到这个变量
第2、3处警告
添加volatile关键字,防止编译器优化
继续优化代码
将void userHandle(void)放在main.c文件中
在userHandle()函数里添加需要上传到机智云平台的数据
我这里需要上传光照数据和LED1(PC13)状态值
//用户数据采集
void userHandle(void)
{
//光照数据采集
float light = LIght_Intensity();
currentDataPoint.valueLight = light; //添加传感器数据采集
//判断当前LED1开关量
if(LED1==0)
currentDataPoint.valueLEDSwitch = 1; //开
else
currentDataPoint.valueLEDSwitch = 0; //关
}
串口3中断服务函数编写
添加gizPutData(&res, 1)函数,并且在文件上方加入对应的头文件#include “gizwits_product.h”
//串口3中断服务函数
void USART3_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
{
res =USART_ReceiveData(USART3);
gizPutData(&res, 1);//数据写入到缓冲区
}
}
定时器3中断服务函数编写
//定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
gizTimerMs();
}
}
在main.c文件中定义一个协议初始化函数Gizwits_Init()
//协议初始化
void Gizwits_Init(void)
{
TIM3_Init(9,7199);//1MS系统定时
USART3_Init(9600);//WIFI初始化
memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));//设备状态结构体初始化
gizwitsInit();//缓冲区初始化
}
机智云平台下发开关灯命令的处理
文件上方写上LED的头文件
添加头文件
main.c文件
/**********************************************
STM32接入机智云--实现数据上传和命令下发
********************************************/
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "timer3.h"
#include "usart.h"
#include "bh1750.h"
#include "gizwits_product.h" //需要包含的头文件
/* 用户区当前设备状态结构体*/
dataPoint_t currentDataPoint;
//协议初始化
void Gizwits_Init(void)
{
TIM3_Init(9,7199);//1MS系统定时
USART3_Init(9600);//WIFI初始化
memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));//设备状态结构体初始化
gizwitsInit();//缓冲区初始化
}
//用户数据采集
void userHandle(void)
{
//光照数据采集
float light = LIght_Intensity();
currentDataPoint.valueLight = light; //添加传感器数据采集
//判断当前LED1开关量
if(LED1==0)
currentDataPoint.valueLEDSwitch = 1; //开
else
currentDataPoint.valueLEDSwitch = 0; //关
}
int main(void)
{
u8 keyValue;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
USART1_Init(9600);
LED_GPIO_Config(); //LED初始化
KEY_GPIO_Config(); //按键初始化
BH1750_Init();
Gizwits_Init();
printf("--------机智云-协议移植LED测试实验----------\r\n");
printf("KB0:AirLink连接模式\t KB1:WIFI复位\r\n\r\n");
while(1)
{
userHandle(); //用户数据采集
gizwitsHandle((dataPoint_t *)¤tDataPoint);//协议处理
keyValue = KEY_Scan(); //扫描按键是否按下
if(keyValue==KB0_Value) //KB0按键按下
{
printf("WIFI进入AirLink连接模式\r\n");
gizwitsSetMode(WIFI_AIRLINK_MODE);//Air-link模式接入
}
if(keyValue==KB1_Value) //KB1按键按下
{
printf("WIFI复位,请重新配置连接\r\n");
gizwitsSetMode(WIFI_RESET_MODE);//WIFI复位
}
delay_ms(200);
}
}
key.c文件
#include "key.h"
#include "delay.h"
/*key初始化*/
void KEY_GPIO_Config(void)
{
//定义结构体变量,注意:只能放在{后面
GPIO_InitTypeDef GPIO_InitStruct;
//配置时钟
RCC_APB2PeriphClockCmd(KEY_GPIO_CLK, ENABLE);
//配置引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //上拉输入模式
GPIO_InitStruct.GPIO_Pin = KEY_GPIO_PIN;
//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
}
u8 KEY_Scan()
{
if(KB0==0||KB1==0) //任意一个按键按下
{
delay_ms(5);
if(KB0==0)
{
while(KB0==0);//等待手松开
return KB0_Value;
}
else if(KB1==0)
{
while(KB1==0);
return KB1_Value;
}
//while(!GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PIN)); //等待手松开
}
return 0;
}
key.h文件
#ifndef __KEY_H_
#define __KEY_H_
#include "stm32f10x.h"
#include "sys.h"
#define KEY_GPIO_PIN (GPIO_Pin_0|GPIO_Pin_1)
#define KEY_GPIO_PORT GPIOB
#define KEY_GPIO_CLK RCC_APB2Periph_GPIOB
//使用位操作定义
#define KB0 PBin(0)
#define KB1 PBin(1)
//定义各个按键值
#define KB0_Value 1
#define KB1_Value 2
void KEY_GPIO_Config(void); //key初始化
u8 KEY_Scan(void);
#endif
下载程序到单片机上
打开串口助手,方便我们看输出的信息
按下复位按键后输出如下:
用一台手机A充当路由器。设置好手机A热点:不含中文、2.4G频段、保证这个热点能够上网
使用另外一台手机B连接手机A开的热点,手机B要提前装好机智云APP。手机B打开机智云APP
连上热点后,手机B的操作如下:
输入WIFI密码,后点击下一步
ESP8266-01S的选择乐鑫
先按下单片机的PB0按键,让WIFI进入AirLink连接模式,再点击“我已完成上述操作”
按下PB0按键后进入AirLink连接模式,串口输出的信息:
耐心等待
成功连接到设备,点击进入
在此处可以远程控制LED1的开关和收到光照数据
自此设备上电就会自动连上刚刚设置的热点,不用再“一键配置”了。如果需要重新配置,按下PB1按键,即可重新配置连接。手机连上与设备相同的热点,就能在机智云APP上收到来自设备的数据和控制设备。
解释下AirLink模式
最后:
个人觉得机智云不是很方便,因为想要上传新的数据或者是添加其他控制,都要重新生成代码包、下载、移植、改错…,前面做的事又要做一部分。
需要源码的可以自行下载。代码下载链接
下载操作: