收藏官网首页
查看: 758|回复: 0

[分享] 基于单片机的机智云联网以及配置上下发数据教程(超详...

67

主题

75

帖子

2817

积分

金牌会员

Rank: 6Rank: 6

积分
2817
跳转到指定楼层
楼主
 楼主| 发表于 2024-1-26 12:37:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
免费使用STM32、APP自动代码生成工具
基于单片机的机智云联网以及配置上下发数据教程(超详细)

一、何谓机智云
机智云是致力于物联网、智能硬件云服务的开发平台,为开发者提供自助式智能硬件开发工具和开放的云端服务(完全免费)。
二、代码自动生产工具
为了降低开发者的开发门槛,缩短开发周期,降低开发资源投入,机智云(Gizwits)推出可代码自动生成服务。云端会根据产品定义的数据点生成对应产品的设备端代码。

三、目前自动生成代码支持硬件设备方案
独立MCU方案  WIFI依靠串口与MCU进行通信(本次云家居使用此方案)
SOC方案  (esp8266、ESP32 )




四、使用机智云开发产品



五、创建产品(重点开始)
  • 打开机智云官网

机智云官网:机智云|物联网云平台,智能IoT开发云平台,智能IoT软件开发平台,智能IoT开发云平台,工业物联网解决方案

2、找到开发者平台,创建个人账号



如有账号可直接登陆,如无账号请注册后登录




3、点击创建产品,创建一个新产品




注:可用标准方案也可使用自定义方案

标准方案为机智云设定的功能定义模板,自由度低

自定义方案为用户自定义功能,自由度高

四、选择自定义方案,并如图设置



5、进入到新建产品中,点击去编辑添加数据点(功能定义)



6、添加所需要数据点 --- 即添加功能

添加完如图所示:


到此创建产品完成。

六、调试设备
  • 返回开发者中心首页,点击“下载中心”
  • 下载APP调试工具



3、下载完成后,打开虚拟设备调试


4、进入产品生成调试二维码








点击生成调试二维码:


5、手机端调试APP扫描二维码绑定设备


6、返回开发者中心进行调试,到此调查步骤完成。


七、移植代码准备

1、刷入机智云联网固件

下载固件 --- 下载中心

这个固件是给wifi模块烧录的,本次教学,使用的是ESP8266-01s,详细烧录过程。

八、自动生成Gizwits代码

        这是机智云自动生成的代码,也就是我们配置的一下功能,机智云已经帮我们生成程序,我们只需要移植到我们的工程和找到对应的功能位置进行修改添加,便可联网成功。

1、生产代码

下载完解压:


以上为自动生成代码内容,此图PDF为代码移植步骤


九、移植代码准备

单片机需满足大于2kbyte的SRAM,机智云代码有环形缓冲区

准备好与WIFI模块连接的代码串口,需开启接收中断  波特率必须时9600

准备一个定时器,并开启1ms更新中断,为数据传输提供时基

OK完事开始移植

WIFI模块接在USART2(接在哪个模块,同学们可自由选择,本次教学以串口2为模板)

十、工程代码移植

1、打开下载好的代码,选中标蓝的两个文件夹,如图

2、把复制的两个文件夹放到工程目录中

开工程配置设备虚拟树

注:因为每个人创建的工程目录习惯不一样,所以大家的目录可能各不相同,同学们只需要把我第一步的两个文件移植进来即可

4、添加对应.c文件


5、包含相关头文件路径

魔法棒---C/C++---include

6、编写USART2代码 ---- 注意波特率必须为9600

  1. void Usart2_Init(void)
  2. {
  3.        
  4.         GPIO_InitTypeDef GPIO_InitStruct;//定义结构体变量名
  5.         USART_InitTypeDef usart_InitTypeDef;
  6.        
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//打开GPIOA时钟
  9. //        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  10.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//通用推挽输出
  11.         GPIO_InitStruct.GPIO_Pin =GPIO_Pin_2;//配置9号
  12.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//速度50Mhz
  13.         GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA
  14.        
  15.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//通用推挽输出
  16.         GPIO_InitStruct.GPIO_Pin =GPIO_Pin_3;//配置10号管脚
  17.         GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA
  18.        
  19.   usart_InitTypeDef.USART_BaudRate = 9600;
  20.         usart_InitTypeDef.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  21.         usart_InitTypeDef.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  22.         usart_InitTypeDef.USART_Parity = USART_Parity_No;
  23.         usart_InitTypeDef.USART_StopBits = USART_StopBits_1;
  24.         usart_InitTypeDef.USART_WordLength = USART_WordLength_8b;
  25.         USART_Init(USART2,&usart_InitTypeDef);
  26.         USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
  27. //        USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);
  28.        
  29.        
  30.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  31.         NVIC_InitTypeDef NVIC_InitStruct={0};
  32.         NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
  33.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  34.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
  35.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
  36.         NVIC_Init(&NVIC_InitStruct);
  37.         USART_Cmd(USART2,ENABLE);
  38.        
  39. }


  40. void USART2_IRQHandler(void)
  41. {
  42.         static u8 data;
  43.         if(USART_GetITStatus(USART2,USART_IT_RXNE))
  44.         {
  45.                 USART_ClearITPendingBit(USART2,USART_IT_RXNE);
  46.                 data = USART_ReceiveData(USART2);
  47.                        

  48.         }

  49. }
复制代码

7、编写1ms定时器更新中断

  1. void TIM1_Update(void)
  2. {
  3.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//打开TIM4时钟
  4.        
  5.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct={0};
  6.         TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
  7.         TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1;
  8.         TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//72Mhz  T=1/f = 1000hz
  9.         TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
  10.        
  11.         TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
  12.        
  13.         NVIC_InitTypeDef NVIC_InitStruct={0};
  14.         NVIC_InitStruct.NVIC_IRQChannel = TIM1_UP_IRQn;//中断源
  15.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能中断源
  16.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
  17.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//次级优先级
  18.         NVIC_Init(&NVIC_InitStruct);
  19.        
  20.         TIM_Cmd(TIM1,ENABLE);

  21. }


  22. void TIM1_UP_IRQHandler(void)
  23. {
  24.         if(TIM_GetITStatus(TIM1,TIM_IT_Update) != RESET)
  25.         {
  26.                 TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
  27.                
  28.         }
  29. }
复制代码

完成准备工作:


配置USART2代码并打开接收中断

完成TIM1 1ms更新中断代码

十一、移植步骤

移植代码说明:


实现与模组通信串口驱动(中断收数据写入环形缓冲区;实现uartWrite()串口发送函数) ->USART2

实现串口打印函数printf();

实现1ms定时器,gizTimerMs()维护系统时间 (提供时基)

实现MCU复位函数,模组可请求MCU复位

实现配置入网功能,调用gizwitsSetMode()函数实现模组配网功能

实现userHandle()数据的采集(上行逻辑)

实现 gizwitsEventProcess()控制命令的具体执行(下行逻辑)

具体参考官方移植过程


开始移植


1、WIFI串口接收数据写入缓冲区


        将wifi 串口接收到数据写入到缓冲区中,而写入缓冲区的函数为gizPutData(),函数位置在gizwits_protocol.c文件下


注意:需在usart2.c文件里包含gizwits_protocol.h文件(要不调用函数为gizPutData()会报错)

2、实现uartWrite()串口发送数据


        在uartWrite()函数中.协议通信会用到这个函数,而这函数会涉及数据帧数据的发送。这里需我们提供串口的发送函数(这里我们用的是串口2), uartWrite()函数具体位置在gizwits_product.c文件下


3、实现毫秒定时

        协议层的运行需要一个系统时间。事件单位为1毫秒,所以我们需要实现毫秒定时器(必须是 1ms的精确定时,若不准确,会影响到超时重发、定时上报等处理).gizTimerMs()函数具体位置在gizwits_product.c文件下

注意:原文件gizTimerMs();函数没有定义记得定义一次先,就是在gizwits_product.h文件进行定义


4、实现芯片复位函数


        根据串口协议文档规定, 模组可以发送命令复位设备 MCU, 所以用户需要实现

mcuRestart()接口完成设备的复位。此函数在gizwits_product.h中

找到函数,添加对应内容


5、实现配置入网


        模组支持 SoftAp 和 AirLink 两种方式配置入网, 相应接口为 gizwitsSetMode(), 建议采用按键的方式, 相应的按键动作触发执行具体的模式设置。另外, 可以通过 gizwitsSetMode()接口复位模组,此函数在gizwits_protocol.h中


WIFI_RESET_MODE                恢复默认出厂设置


WIFI_SOFTAP_MODE            热点配网


WIFI_AIRLINK_MODE            手机广播配网


这里我们选择的手机广播配网,(我使用的是按键控制联网)

  1. key = key_scan();
  2.                 if(key == 1)//设置配网模式
  3.                 {
  4.                         gizwitsSetMode(WIFI_AIRLINK_MODE);
  5.                         printf("WIFI_AIRLINK_MODE OK\r\n");
  6.                 }
  7.                 if(key == 2)//恢复出厂设置
  8.                 {
  9.                         gizwitsSetMode(WIFI_RESET_MODE);
  10.                         printf("WIFI_RESET_MODE OK\r\n");
  11.                 }
复制代码

6、协议处理

        根据采集到的数据。然后调用函数 gizwitsHandle()、userHandle()上报,函数位置在gizwits_protocol.c文件中,该函数主要完成协议数据的处理及数据主动上报的相关操作。

返回main.c

在main.c进行外部**

在while(1)调用gizwitsHandle()和userHandle()上报数据

  1. gizwitsHandle(¤tDataPoint);
  2. userHandle();
复制代码

注意:自己亦可封装这两个函数,需要联网操作都需要调用这两个函数

7、初始化

自己建立一个机智云初始化函数,函数内容如下图, 内容亦是我之前上面所说的


  1. //机智云初始化
  2. void Gizwits_Init(void)
  3. {
  4.         TIM1_Update();//TIM1初始化
  5.         Usart2_Init();//USART2初始化
  6.         memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));
  7.         gizwitsInit();
  8. }
复制代码
到这一步,配网就基本完成了

只是配网还不行,我们还需要进行数据上发到我们的机智云端,将数据显示在我们的app上,以及app如何下发命令控制我们单片机。这些都需要配置的。

十二、数据上下发配置
一、单片机上发数据到机智云云端

上发数据用到的函数为userHandle(),也就是我上面所说要放到while(1)里面的函数,只有这样我们的数据才能一直上发到云端,这个函数是在gizwits_protocol.c




如我所示,我是将自己的温湿度、二氧化碳浓度等数据上传到机智云端。

二、app下发命令配置

需要配置的文件gizwits_protocol.c

如我们在刚刚网页配置时,设置了一个0和1控制水泵打开,那机智云会生产对应的0和1操作,我们只需要找到对应的位置,然后往0和1里添加自己的开关便可,如下图所示:


十三、配置成功
到这一步,基本已经配置成功了,是不是很简单,只需要按照程序来做,大家都能顺利成功配网。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表