TA的每日心情 | 慵懒 2024-5-31 23:20 |
---|
签到天数: 302 天 连续签到: 2 天 [LV.8]以坛为家I
|
本帖最后由 day_day 于 2018-3-4 09:56 编辑
(一)时间获取方案
我的目标项目核心之一是定时功能,之前曾经探索过一个解决方案:通过网络接口每秒获取一次网络时间,具体可以看我之前在机制云社区的帖子:
http://club.gizwits.com/thread-8038-1-1.html
但现在回过头来想,一直调用这个接口估计对服务器压力挺大的,一台两台设备还好,如果是大量的设备马不停蹄地申请网络时间,估计服务器就不干了。
实际上我猜想这个网络接口仅仅是用来进行一些时间校准功能,不停地申请时间并不是一个正常的做法。现在就考虑使用单片机自己的资源定时。
实际上做过定时实验就知道,如果是按照时分秒定时,为了防止时间溢出,判断逻辑总是很麻烦的。所幸系统有个时基单元:- static uint32_t timerMsCount;
复制代码 在定时器中断中被调用,每毫秒加一。作为一个无符号32位整型,算一下,可以整整维持接近50天连续开机的计算。
(二)只读节点操作
只读节点操作只需要在userHandle()修改结构体:- /** User Area Device State Structure */
- typedef struct {
- bool valuestart_pool;
- bool valuepause;
- bool valuewater_in;
- bool valuepooling;
- bool valuewate_out;
- } dataPoint_t;
复制代码 这个结构体在gizwits_produte.c文件里实例化为currentDataPoint变量。生成的协议就会自动循环上报,不需要操心。具体实现形式可以参考上面提到的帖子,虽然库文件版本修改,但本质上实现没有太大出入。
(三)硬件初始化
机智云使用HAL库的原因之一就是自带的CubeMX工程。
可以使用CubeMX便捷地初始化接口。
当然我只是初始化三个IO口就没必要这么麻烦。
在main里面的,MX_GPIO_Init();里面累死地添加IO初始化代码即可。
由于gokit二代的功能板引出了A0-A5的IO口,我就初始化A0-A2对应PA0、PA1、PA4。- /*Configure GPIO pin : water_in */
- GPIO_InitStruct.Pin = GPIO_PIN_0;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /*Configure GPIO pin : POOLING */
- GPIO_InitStruct.Pin = GPIO_PIN_1;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /*Configure GPIO pin : water_out */
- GPIO_InitStruct.Pin = GPIO_PIN_4;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
复制代码 (四)具体实现
IO操作、只读数据节点修改等一系列操作都在userHandle里面解决:
在gizwits_product.c声明:- unsigned int current_state; //定义目前状态
- uint32_t assist_timeresist; //协助计时
复制代码 实现两个更新函数——数据节点更新、IO状态更新:- void update_io(void)
- {
- switch(current_state)
- {
- case 0:
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
- break;
- case 1:
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
- break;
- case 2:
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
- break;
- case 3:
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
- break;
- }
- }
- void update_state(void)
- {
- if(timerMsCount>=assist_timeresist+10000){
- current_state = (current_state+1)%4;
- assist_timeresist = timerMsCount;
-
- switch(current_state)
- {
- case 0:
- currentDataPoint.valuewater_in = 0;
- currentDataPoint.valuepooling = 0;
- currentDataPoint.valuewate_out = 0;
- break;
- case 1:
- currentDataPoint.valuewater_in = 1;
- currentDataPoint.valuepooling = 0;
- currentDataPoint.valuewate_out = 0;
- break;
- case 2:
- currentDataPoint.valuewater_in = 0;
- currentDataPoint.valuepooling = 1;
- currentDataPoint.valuewate_out = 0;
- break;
- case 3:
- currentDataPoint.valuewater_in = 0;
- currentDataPoint.valuepooling = 0;
- currentDataPoint.valuewate_out = 1;
- break;
- }
- }
- }
复制代码
在userHandle()内添加:- if(currentDataPoint.valuestart_pool && !currentDataPoint.valuepause)
- {
- update_state();
- update_io();
- }
复制代码 可写数据节点,在gizwitsEventProcess里编写:- case EVENT_start_pool:
- currentDataPoint.valuestart_pool = dataPointPtr->valuestart_pool;
- GIZWITS_LOG("Evt: EVENT_start_pool %d \n", currentDataPoint.valuestart_pool);
- if(0x01 == currentDataPoint.valuestart_pool)
- {
- assist_timeresist = timerMsCount; //user handle
- current_state = 0;
- }
- else
- {
- currentDataPoint.valuewater_in = 0;
- currentDataPoint.valuepooling = 0;
- currentDataPoint.valuewate_out = 0; //user handle
- }
- break;
复制代码 编译。
(五)展示功能
|
|