回答

收藏

【体验】生成代码体验第二弹

机智云GoKit 机智云GoKit 3120 人阅读 | 0 人回复 | 2018-03-04

本帖最后由 day_day 于 2018-3-4 09:56 编辑

(一)时间获取方案
我的目标项目核心之一是定时功能,之前曾经探索过一个解决方案:通过网络接口每秒获取一次网络时间,具体可以看我之前在机制云社区的帖子:
http://club.gizwits.com/thread-8038-1-1.html
但现在回过头来想,一直调用这个接口估计对服务器压力挺大的,一台两台设备还好,如果是大量的设备马不停蹄地申请网络时间,估计服务器就不干了。
实际上我猜想这个网络接口仅仅是用来进行一些时间校准功能,不停地申请时间并不是一个正常的做法。现在就考虑使用单片机自己的资源定时。
实际上做过定时实验就知道,如果是按照时分秒定时,为了防止时间溢出,判断逻辑总是很麻烦的。所幸系统有个时基单元:
  1. static uint32_t timerMsCount;
复制代码
在定时器中断中被调用,每毫秒加一。作为一个无符号32位整型,算一下,可以整整维持接近50天连续开机的计算。

(二)只读节点操作
只读节点操作只需要在userHandle()修改结构体:
  1. /** User Area Device State Structure */
  2. typedef struct {
  3.   bool valuestart_pool;
  4.   bool valuepause;
  5.   bool valuewater_in;
  6.   bool valuepooling;
  7.   bool valuewate_out;
  8. } dataPoint_t;
复制代码
这个结构体在gizwits_produte.c文件里实例化为currentDataPoint变量。生成的协议就会自动循环上报,不需要操心。具体实现形式可以参考上面提到的帖子,虽然库文件版本修改,但本质上实现没有太大出入。

(三)硬件初始化
机智云使用HAL库的原因之一就是自带的CubeMX工程。

可以使用CubeMX便捷地初始化接口。

当然我只是初始化三个IO口就没必要这么麻烦。
在main里面的,MX_GPIO_Init();里面累死地添加IO初始化代码即可。
由于gokit二代的功能板引出了A0-A5的IO口,我就初始化A0-A2对应PA0、PA1、PA4。
  1. /*Configure GPIO pin : water_in */
  2.         GPIO_InitStruct.Pin = GPIO_PIN_0;
  3.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  4.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  5.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  6.         
  7.         /*Configure GPIO pin : POOLING */
  8.         GPIO_InitStruct.Pin = GPIO_PIN_1;
  9.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  10.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  11.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  12.         
  13.         /*Configure GPIO pin : water_out */
  14.         GPIO_InitStruct.Pin = GPIO_PIN_4;
  15.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  16.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  17.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
复制代码
(四)具体实现
IO操作、只读数据节点修改等一系列操作都在userHandle里面解决:
在gizwits_product.c声明:
  1. unsigned int current_state;                //定义目前状态
  2. uint32_t assist_timeresist;                //协助计时
复制代码
实现两个更新函数——数据节点更新、IO状态更新:
  1. void update_io(void)
  2. {
  3.         switch(current_state)
  4.         {
  5.                 case 0:
  6.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
  7.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
  8.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
  9.                         break;
  10.                 case 1:
  11.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
  12.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
  13.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
  14.                         break;
  15.                 case 2:
  16.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
  17.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
  18.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
  19.                         break;
  20.                 case 3:
  21.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
  22.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
  23.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
  24.                         break;
  25.         }
  26. }

  27. void update_state(void)
  28. {
  29.         if(timerMsCount>=assist_timeresist+10000){
  30.                 current_state = (current_state+1)%4;
  31.                 assist_timeresist = timerMsCount;
  32.                
  33.                 switch(current_state)
  34.                 {
  35.                         case 0:
  36.                                 currentDataPoint.valuewater_in = 0;
  37.                                 currentDataPoint.valuepooling = 0;
  38.                                 currentDataPoint.valuewate_out = 0;
  39.                                 break;
  40.                         case 1:
  41.                                 currentDataPoint.valuewater_in = 1;
  42.                                 currentDataPoint.valuepooling = 0;
  43.                                 currentDataPoint.valuewate_out = 0;
  44.                                 break;
  45.                         case 2:
  46.                                 currentDataPoint.valuewater_in = 0;
  47.                                 currentDataPoint.valuepooling = 1;
  48.                                 currentDataPoint.valuewate_out = 0;
  49.                                 break;
  50.                         case 3:
  51.                                 currentDataPoint.valuewater_in = 0;
  52.                                 currentDataPoint.valuepooling = 0;
  53.                                 currentDataPoint.valuewate_out = 1;
  54.                                 break;
  55.                 }
  56.         }
  57. }
复制代码

在userHandle()内添加:
  1. if(currentDataPoint.valuestart_pool && !currentDataPoint.valuepause)
  2. {
  3.                         update_state();
  4.                         update_io();
  5. }
复制代码
可写数据节点,在gizwitsEventProcess里编写:
  1. case EVENT_start_pool:
  2.         currentDataPoint.valuestart_pool = dataPointPtr->valuestart_pool;
  3.         GIZWITS_LOG("Evt: EVENT_start_pool %d \n", currentDataPoint.valuestart_pool);
  4.         if(0x01 == currentDataPoint.valuestart_pool)
  5.         {
  6.                         assist_timeresist = timerMsCount;        //user handle
  7.                         current_state = 0;
  8.         }
  9.         else
  10.         {
  11.                         currentDataPoint.valuewater_in = 0;
  12.                         currentDataPoint.valuepooling = 0;
  13.                         currentDataPoint.valuewate_out = 0; //user handle   
  14.         }
  15.         break;
复制代码
编译。

(五)展示功能

分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条