1. 概述:
Alarm模块,主要针对场景监测,进行报警和恢复的动作
例如,高温监测
系统处于监测工作中,监测到温度高于80℃并持续一分钟,系统触发报警
系统处于报警状态时,监测到温度低于60℃并持续一分钟,系统恢复正常

2. 测试:
示例:
秒数的滚动轮询是0-59-0-59-…
秒数小于或等于10并且维持2秒时报警,就相当于时间点处于1S的时候会报警;
秒数大于或等于30并且维持2秒时恢复,就相当于时间点处于31S的时候会恢复

3. 接口:
Alarm模块接口,见头文件,持续完善,欢迎补充

/*From : https://github.com/paiminlin/PMFrom : https://blog.csdn.net/lpaim/article/details/122160744Author : PaiMin.linDate : 2022.7.16
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>#ifdef __cplusplus
extern "C"{#endif#ifndef ALARM_H_
#define ALARM_H_#define AlarmTask_MAXNUM                100     /* 支持最多管理的报警对象数量 */typedef struct Alarm_Interval
{int Threshold;                              /* 阈值 */int duration;                               /* 维持时间 duration * Alarm_Run */
} Alarm_Interval;typedef int (*AlarmGetData_Fun)(void);typedef int (*AlarmSill_Fun)(void);typedef int (*AlarmResume_Fun)(void);typedef struct AlarmTask_Info
{Alarm_Interval AlarmSill;                   /* 报警阈值/维持时间 */Alarm_Interval AlarmResume;                 /* 回滞阈值/维持时间 */AlarmGetData_Fun AlarmGetDataFun;           /* 获取报警对象 返回报警对象数据 */AlarmSill_Fun AlarmSillFun;                 /* 触发报警 */AlarmResume_Fun AlarmResumeFun;             /* 触发回滞 */
} AlarmTask_Info;int Alarm_Run(void);int Alarm_Start(void);int Alarm_Stop(void);int Alarm_Init(void);int Alarm_DeInit(void);int Alarm_CreatTask(AlarmTask_Info * pstAlarmTaskInfo);int Alarm_DestroyTask(int TaskNum, AlarmTask_Info * pstAlarmTaskInfo);bool Alarm_GetTaskStatus(int TaskNum);#endif /* ALARM_H_ */#ifdef __cplusplus
}
#endif
/*From : https://github.com/paiminlin/PMFrom : https://blog.csdn.net/lpaim/article/details/122160744Author : PaiMin.linDate : 2022.7.16
*/#include "Alarm.h"#ifdef __cplusplus
extern "C"{#endiftypedef enum
{Alarm_Sill_Mode         = 0,Alarm_Resume_Mode       = 1,Alarm_Invalid_Mode      = 2,
}Alarm_Mode;typedef struct Alarm_Info
{bool bAlarmInit;bool bAlarmStart;bool bAlarmTaskStatus[AlarmTask_MAXNUM];
} Alarm_Info;static int s_AlarmCounter[AlarmTask_MAXNUM] = {0};
static Alarm_Mode s_enLastAlarmMode[AlarmTask_MAXNUM] = {0};static Alarm_Info s_stAlarmInfo = {0};
static AlarmTask_Info s_stAlarmTaskInfo[AlarmTask_MAXNUM] = {0};int Alarm_Run(void)
{if(s_stAlarmInfo.bAlarmInit == false || s_stAlarmInfo.bAlarmStart == false)return 0;int TaskNum = 0;for(TaskNum = 0; TaskNum <AlarmTask_MAXNUM; TaskNum ++){if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun != NULL){/*报警阈值 > 恢复阈值;*/if(s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold > s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold){if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun() >= s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold){if(s_enLastAlarmMode[TaskNum] != Alarm_Sill_Mode)s_AlarmCounter[TaskNum] = 0;if(s_stAlarmInfo.bAlarmTaskStatus[TaskNum] == false){s_AlarmCounter[TaskNum] ++;if(s_AlarmCounter[TaskNum] == s_stAlarmTaskInfo[TaskNum].AlarmSill.duration){s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = true;s_AlarmCounter[TaskNum] = 0;if(s_stAlarmTaskInfo[TaskNum].AlarmSillFun != NULL)s_stAlarmTaskInfo[TaskNum].AlarmSillFun();}}s_enLastAlarmMode[TaskNum] = Alarm_Sill_Mode;}else if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun() <= s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold){if(s_enLastAlarmMode[TaskNum] != Alarm_Resume_Mode)s_AlarmCounter[TaskNum] = 0;if(s_stAlarmInfo.bAlarmTaskStatus[TaskNum] == true){s_AlarmCounter[TaskNum] ++;if(s_AlarmCounter[TaskNum] == s_stAlarmTaskInfo[TaskNum].AlarmResume.duration){s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_AlarmCounter[TaskNum] = 0;if(s_stAlarmTaskInfo[TaskNum].AlarmResumeFun != NULL)s_stAlarmTaskInfo[TaskNum].AlarmResumeFun();}}s_enLastAlarmMode[TaskNum] = Alarm_Resume_Mode;}}/*报警阈值 < 恢复阈值;*/if(s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold < s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold){if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun() <= s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold){if(s_enLastAlarmMode[TaskNum] != Alarm_Sill_Mode)s_AlarmCounter[TaskNum] = 0;if(s_stAlarmInfo.bAlarmTaskStatus[TaskNum] == false){s_AlarmCounter[TaskNum] ++;if(s_AlarmCounter[TaskNum] == s_stAlarmTaskInfo[TaskNum].AlarmSill.duration){s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = true;s_AlarmCounter[TaskNum] = 0;if(s_stAlarmTaskInfo[TaskNum].AlarmSillFun != NULL)s_stAlarmTaskInfo[TaskNum].AlarmSillFun();}}s_enLastAlarmMode[TaskNum] = Alarm_Sill_Mode;}else if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun() >= s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold){if(s_enLastAlarmMode[TaskNum] != Alarm_Resume_Mode)s_AlarmCounter[TaskNum] = 0;if(s_stAlarmInfo.bAlarmTaskStatus[TaskNum] == true){s_AlarmCounter[TaskNum] ++;if(s_AlarmCounter[TaskNum] == s_stAlarmTaskInfo[TaskNum].AlarmResume.duration){s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_AlarmCounter[TaskNum] = 0;if(s_stAlarmTaskInfo[TaskNum].AlarmResumeFun != NULL)s_stAlarmTaskInfo[TaskNum].AlarmResumeFun();}}s_enLastAlarmMode[TaskNum] = Alarm_Resume_Mode;}}}}return 0;
}int Alarm_Start(void)
{if(s_stAlarmInfo.bAlarmInit == false)return -1;s_stAlarmInfo.bAlarmStart = true;return 0;
}int Alarm_Stop(void)
{if(s_stAlarmInfo.bAlarmInit == false)return -1;s_stAlarmInfo.bAlarmStart = false;return 0;
}int Alarm_Init(void)
{if(s_stAlarmInfo.bAlarmInit == true)return 0;int TaskNum = 0;s_stAlarmInfo.bAlarmInit = true;s_stAlarmInfo.bAlarmStart = false;for(TaskNum = 0; TaskNum <AlarmTask_MAXNUM; TaskNum ++){s_AlarmCounter[TaskNum] = 0;s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_enLastAlarmMode[TaskNum] = Alarm_Invalid_Mode;s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmSill.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmSillFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmResumeFun = NULL;}return 0;
}int Alarm_DeInit(void)
{if(s_stAlarmInfo.bAlarmStart == true)return -1;if(s_stAlarmInfo.bAlarmInit == false)return 0;int TaskNum = 0;s_stAlarmInfo.bAlarmInit = false;s_stAlarmInfo.bAlarmStart = false;for(TaskNum = 0; TaskNum <AlarmTask_MAXNUM; TaskNum ++){s_AlarmCounter[TaskNum] = 0;s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_enLastAlarmMode[TaskNum] = Alarm_Invalid_Mode;s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmSill.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmSillFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmResumeFun = NULL;}return 0;
}int Alarm_CreatTask(AlarmTask_Info * pstAlarmTaskInfo)
{if(s_stAlarmInfo.bAlarmInit == false)return -1;int TaskNum = 0;if(pstAlarmTaskInfo == NULL)return -1;for(TaskNum = 0; TaskNum <AlarmTask_MAXNUM; TaskNum ++){if(s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun == NULL&& s_stAlarmTaskInfo[TaskNum].AlarmSillFun == NULL&& s_stAlarmTaskInfo[TaskNum].AlarmResumeFun == NULL){s_AlarmCounter[TaskNum] = 0;s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_enLastAlarmMode[TaskNum] = Alarm_Invalid_Mode;s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold = pstAlarmTaskInfo->AlarmSill.Threshold;s_stAlarmTaskInfo[TaskNum].AlarmSill.duration = pstAlarmTaskInfo->AlarmSill.duration;s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold = pstAlarmTaskInfo->AlarmResume.Threshold;s_stAlarmTaskInfo[TaskNum].AlarmResume.duration = pstAlarmTaskInfo->AlarmResume.duration;s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun = pstAlarmTaskInfo->AlarmGetDataFun;s_stAlarmTaskInfo[TaskNum].AlarmSillFun = pstAlarmTaskInfo->AlarmSillFun;s_stAlarmTaskInfo[TaskNum].AlarmResumeFun = pstAlarmTaskInfo->AlarmResumeFun;return TaskNum;}}return -1;
}int Alarm_DestroyTask(int TaskNum, AlarmTask_Info * pstAlarmTaskInfo)
{if(s_stAlarmInfo.bAlarmInit == false)return -1;if( TaskNum < 0 || TaskNum >= AlarmTask_MAXNUM|| pstAlarmTaskInfo == NULL)return -1;if(s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold == pstAlarmTaskInfo->AlarmSill.Threshold&& s_stAlarmTaskInfo[TaskNum].AlarmSill.duration == pstAlarmTaskInfo->AlarmSill.duration&& s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold == pstAlarmTaskInfo->AlarmResume.Threshold&& s_stAlarmTaskInfo[TaskNum].AlarmResume.duration == pstAlarmTaskInfo->AlarmResume.duration&& s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun == pstAlarmTaskInfo->AlarmGetDataFun&& s_stAlarmTaskInfo[TaskNum].AlarmSillFun == pstAlarmTaskInfo->AlarmSillFun&& s_stAlarmTaskInfo[TaskNum].AlarmResumeFun == pstAlarmTaskInfo->AlarmResumeFun){s_AlarmCounter[TaskNum] = 0;s_stAlarmInfo.bAlarmTaskStatus[TaskNum] = false;s_enLastAlarmMode[TaskNum] = Alarm_Invalid_Mode;s_stAlarmTaskInfo[TaskNum].AlarmSill.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmSill.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.Threshold = 0;s_stAlarmTaskInfo[TaskNum].AlarmResume.duration = 0;s_stAlarmTaskInfo[TaskNum].AlarmGetDataFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmSillFun = NULL;s_stAlarmTaskInfo[TaskNum].AlarmResumeFun = NULL;return 0;}return -1;
}bool Alarm_GetTaskStatus(int TaskNum)
{if(TaskNum < 0 || TaskNum >= AlarmTask_MAXNUM)return -1;return s_stAlarmInfo.bAlarmTaskStatus[TaskNum];
}#define ALARM_MAIN_DEBUG
#ifdef ALARM_MAIN_DEBUG#include <time.h>int AlarmGetDataFun(void)
{time_t seconds = time((time_t *)NULL);struct tm * gmt;gmt = localtime(&seconds);return gmt->tm_sec;
}int AlarmSillFun(void)
{time_t seconds = time((time_t *)NULL);struct tm * gmt;gmt = localtime(&seconds);printf("%s-%d-",__func__, __LINE__);printf("%02d:%02d:%02d\n",gmt->tm_hour,gmt->tm_min,gmt->tm_sec);return 0;
}int AlarmResumeFun(void)
{time_t seconds = time((time_t *)NULL);struct tm * gmt;gmt = localtime(&seconds);printf("%s-%d-",__func__, __LINE__);printf("%02d:%02d:%02d\n",gmt->tm_hour,gmt->tm_min,gmt->tm_sec);return 0;
}int main()
{Alarm_Init();Alarm_Start();/*时间秒数小于或等于10时,维持2次(*1s)->报警时间秒数大于或等于30时,维持2次(*1s)->回滞*/AlarmTask_Info stAlarmTaskInfo = {0};stAlarmTaskInfo.AlarmSill.Threshold = 10;stAlarmTaskInfo.AlarmSill.duration = 2;stAlarmTaskInfo.AlarmResume.Threshold = 30;stAlarmTaskInfo.AlarmResume.duration = 2;stAlarmTaskInfo.AlarmGetDataFun = AlarmGetDataFun;stAlarmTaskInfo.AlarmSillFun = AlarmSillFun;stAlarmTaskInfo.AlarmResumeFun = AlarmResumeFun;int TaskNum = Alarm_CreatTask(&stAlarmTaskInfo);while(1){Alarm_Run();if(Alarm_GetTaskStatus(TaskNum) == true){printf("Task in Alarm\n");}sleep(1);}Alarm_DestroyTask(TaskNum, &stAlarmTaskInfo);Alarm_Stop();Alarm_DeInit();return 0;
}
#endif#ifdef __cplusplus
}
#endif

MCU Alarm报警监测相关推荐

  1. 用c语言编声光报警子程序,C语言编程的智能火灾报警监测系统

    用C语言来编写程序的火灾报警系统 智能火灾报警监测系统 [摘 要]本系统由检测装置烟雾传感器SS-168.光电传感器ST-178和温度传感器DS18B20,显示装置LCD和声光报警装置组成,并由单片机 ...

  2. 故障报警系统C语言编程,C语言编程的智能火灾报警监测系统.doc

    智能火灾报警监测系统 [摘 要]本系统由检测装置烟雾传感器SS-168.光电传感器ST-178和温度传感器DS18B20,显示装置LCD和声光报警装置组成,并由单片机AT89S51来控制.单片机巡回检 ...

  3. 14-TDengine安装报警模块实现报警监测Webhook回调与邮件推送

    背景 在之前的关于 TDengine 的系列文章中,我们只介绍到了 Server 端与 Client 端,除此之外,官方还有一个报警模块,用以根据用户定义的规则实现近实时的报警监测.本文是结合 TDe ...

  4. 中药配方颗粒设备报警监测如何实现?

    中药调剂设备的安全.效率及可靠性往往取决于其自动化的调剂执行机构,即调剂头.市面上常见的中药调剂设备的执行机构大多为驱动器+步进电机的构成. 这种系统组成存在的问题是,欠缺对系统的差错控制及意外情况处 ...

  5. LiveGBS国标GB/T28181国标视频流媒体平台-功能报警告警订阅查询报警预案截图保存视频及REDIS消息订阅

    LiveGBS国标GB/T28181国标视频流媒体平台-功能报警告警订阅查询报警预案截图保存视频及REDIS消息订阅 1.报警信息 1.1.报警查询 1.2.配置开启报警订阅 1.2.1.国标设备编辑 ...

  6. autosar的alarm配置

    Alarm报警,主要实现的是定时功能,在预定时间到达时候触发相关操作,例如:设置事件,激活任务,进行回调等操作,创建不同的OsAlarm

  7. 应用于供氧中心的医用气体监测系统ZWACS医气监控

    医用气体对临床抢救.手术工作中为人类生命安全起到致关重要的作用,实现监控远程报警,实时监控气体超限情况.气体漏气情况,为供氧中心等气源提供安全配置是非常有必要的,以保证患者的用气安全.且不应有数据丢失 ...

  8. 锅炉设备如何实现远程报警监控

    锅炉是利用燃料把其他能源的热能给水或者蒸汽设备加热多用于生活.火车站.工矿企业且锅炉行业采用清洁燃烧技术,让用生活材料和生物质锅炉的市场潜力巨大.我国目前规模以上锅炉生产企业达到1200家,设备超40 ...

  9. LiveGBS流媒体平台GB/T28181功能-摄像头报警告警预案触发图片截取视频录制海康大华华为宇视等摄像头报警触发截图录像

    LiveGBS摄像头报警告警预案触发图片截取视频录制海康大华华为宇视等摄像头报警触发截图录像 1.报警信息 1.1.报警查询 1.2.配置开启报警订阅 1.2.1.国标设备编辑 1.2.2.勾选订阅项 ...

最新文章

  1. 发现“郝茵晴”:屌丝们的社会性传播实验
  2. 无法向会话状态服务器发出会话状态请求
  3. Batch Normalization的一些个人理解
  4. 【zookeeper系列】centos7安装zookeeper
  5. oracle 9i standby,Oracle 9I dataguard(standby)
  6. 设备激活错误。物理文件名 'D:\LOG\ShoppingDB_Log.ldf' 可能有误。
  7. python编写代码实现文件的拷贝功能_如何使用Python脚本实现文件拷贝
  8. 总结: C++ 中如何把输出结果写入到文件中
  9. Excel下拉列表式的动态图表,你会制作吗?
  10. Dolby与DTS杜比环绕与DTS环绕音响
  11. 二级下拉菜单布局(纵向、横向)
  12. Frequency domain enhancement
  13. 紫光同创 FPGA 开发跳坑指南(五)—— DDR3 控制器 IP 的仿真
  14. Visdom 介绍 | 二
  15. Linux--自旋锁(介绍及API简介)
  16. 淘宝推广方法大全,教你如何做淘宝(转)
  17. 批量论文自动下载——从dblp数据库中查找并爬取论文
  18. 大厂HR:我让你测试一个(电梯、杯子、笔、桌子、洗衣机),你会怎么测试它?
  19. 领英个人简介如何支持html,普通外贸业务员怎么在领英上写一份完美的自我简介( Summary)?...
  20. 利用代理页面解决html iframe跨域访问网站问题

热门文章

  1. 比MySQL快801倍,字节阿里争相 部署,真香!
  2. assign 组合逻辑和always@(*)组合逻辑的区别
  3. arcgis之地理配准
  4. ResponseEntity
  5. “21 天好习惯”第一期-4
  6. 【原创】从头开始,使用安卓系统WebView做一个功能强大的Epub阅读器(一)
  7. 女 大三,抱金砖~呵~
  8. linux inactive,linux – systemctl status显示inactive dead
  9. 关于alpine如何制作JDK镜像
  10. 06年注册安全工程师试题