You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

483 lines
18 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. #include <stdbool.h> //定义布尔
  2. #include <string.h>
  3. #include "board.h"
  4. //
  5. #include "zes8p5066lib/basic.h"
  6. #include "zes8p5066lib/gpio.h"
  7. #include "zes8p5066lib/key.h"
  8. #include "zes8p5066lib/systicket.h"
  9. #include "zes8p5066lib/uart0.h"
  10. //
  11. #include "service/human_computer_interaction_service.h"
  12. #include "service/ozone_control_service.h"
  13. #include "service/thisdevice.h"
  14. #include "test.h"
  15. #include "zsimple_timer/zsimple_timer.h"
  16. /***********************************************************************************************************************
  17. * =========================================================================================================== *
  18. ***********************************************************************************************************************/
  19. void onkey(zkey_t* key, zkey_state_t key_state);
  20. /***********************************************************************************************************************
  21. * =========================================================================================================== *
  22. ***********************************************************************************************************************/
  23. static zkey_t s_keys[] = {
  24. ZKEY_INIT("powerkey", port_gpio_get_power_key_state), //电源按键
  25. ZKEY_INIT("levelkey", port_gpio_get_level_key_state), //左1
  26. ZKEY_INIT("timerkey", port_gpio_get_timer_key_state), //左2
  27. ZKEY_INIT("intervalkey", port_gpio_get_interval_key_state), //左3
  28. };
  29. zkey_module_t key_module = ZMODULE_INIT(s_keys, onkey);
  30. static int m_fanerronum = 0;
  31. /***********************************************************************************************************************
  32. * =============================================================================================================== *
  33. ***********************************************************************************************************************/
  34. static float mf_fan_get_power() {
  35. float fanpower = 0;
  36. for (size_t i = 0; i < 20; i++) {
  37. fanpower += port_adc_get_fan_power();
  38. }
  39. return fanpower / 20;
  40. }
  41. /***********************************************************************************************************************
  42. * ===================================================COUNT_COMPUTE=================================================== *
  43. ***********************************************************************************************************************/
  44. static uint32_t compute_countdown_num(int countdowns) { return countdowns / kconst_countdown_step_s + !!(countdowns % kconst_countdown_step_s); }
  45. static void increase_and_assign_countdonwnum() {
  46. if (thisDevice.countdonwnum == 4) {
  47. thisDevice.countdonwnum = 0;
  48. thisDevice.countdonwnum_s = 0;
  49. thisDevice.countdonw_setting_num = 0;
  50. } else {
  51. thisDevice.countdonwnum_s = (thisDevice.countdonwnum + 1) * kconst_countdown_step_s;
  52. thisDevice.countdonwnum = thisDevice.countdonwnum + 1;
  53. thisDevice.countdonw_setting_num = thisDevice.countdonwnum;
  54. thisDevice.countdonw_start_ticket = systicket_get_now_ms();
  55. }
  56. }
  57. static void mf_set_countdown(int countdownnum) {
  58. thisDevice.countdonwnum = countdownnum;
  59. thisDevice.countdonwnum_s = thisDevice.countdonwnum * kconst_countdown_step_s;
  60. thisDevice.countdonw_setting_num = thisDevice.countdonwnum;
  61. thisDevice.countdonw_start_ticket = systicket_get_now_ms();
  62. }
  63. /***********************************************************************************************************************
  64. * ===================================================POWER_CONTROL=================================================== *
  65. ***********************************************************************************************************************/
  66. //设备开始工作
  67. static void startwork() {
  68. port_fan_set(true);
  69. ozone_control_start();
  70. thisDevice.working = true;
  71. m_fanerronum = 0;
  72. }
  73. //停止设备工作
  74. static void stopwork() {
  75. ozone_control_stop();
  76. port_fan_set(false);
  77. thisDevice.working = false;
  78. }
  79. //关机
  80. static void shutdwon() {
  81. printf("power off\n");
  82. thisDevice.poweron = false;
  83. stopwork();
  84. }
  85. //开机
  86. static void poweron() {
  87. printf("power on\n");
  88. thisDevice.poweron = true;
  89. thisDevice.level = klevel2;
  90. thisDevice.mode = knormal;
  91. thisDevice.error = knoneException;
  92. startwork();
  93. }
  94. /***********************************************************************************************************************
  95. * =================================================KEY_EVENT_PROCESS================================================= *
  96. ***********************************************************************************************************************/
  97. //电源按键处理
  98. static void mf_process_poweron_key(zkey_t* key) {
  99. printf("on %s \n", key->name);
  100. if (!thisDevice.poweron) {
  101. poweron();
  102. } else {
  103. shutdwon();
  104. }
  105. return;
  106. }
  107. //等级按键处理
  108. static void mf_process_level_key(zkey_t* key) {
  109. if (!thisDevice.poweron) return;
  110. if (thisDevice.error != knoneException) return;
  111. printf("on %s \n", key->name);
  112. /**
  113. * @brief
  114. */
  115. if (thisDevice.level == klevel1) {
  116. printf("changet level to level2\n");
  117. thisDevice.level = klevel2;
  118. //更改臭氧状态
  119. } else if (thisDevice.level == klevel2) {
  120. printf("changet level to level1\n");
  121. thisDevice.level = klevel1;
  122. //更改臭氧状态
  123. }
  124. hcis_active_input(kchange_level_input);
  125. return;
  126. }
  127. //定时按键处理
  128. static void mf_process_timer_key(zkey_t* key) {
  129. if (!thisDevice.poweron) return;
  130. if (thisDevice.error != knoneException) return;
  131. printf("on %s \n", key->name);
  132. if (!thisDevice.working) {
  133. startwork();
  134. }
  135. if (thisDevice.mode != ktimingMode) {
  136. mf_set_countdown(0);
  137. }
  138. increase_and_assign_countdonwnum();
  139. if (thisDevice.countdonwnum_s == 0) {
  140. hcis_active_input(knone_active);
  141. thisDevice.mode = knormal;
  142. } else {
  143. hcis_active_input(kchange_countdonw_time_input);
  144. thisDevice.mode = ktimingMode;
  145. }
  146. }
  147. //间隔按键处理
  148. static void mf_process_interval_key(zkey_t* key) {
  149. if (!thisDevice.poweron) return;
  150. if (thisDevice.error != knoneException) return;
  151. printf("on %s \n", key->name);
  152. if (!thisDevice.working) {
  153. startwork();
  154. }
  155. if (thisDevice.mode != kintermittentMode) {
  156. mf_set_countdown(0);
  157. }
  158. increase_and_assign_countdonwnum();
  159. if (thisDevice.countdonwnum_s == 0) {
  160. hcis_active_input(knone_active);
  161. thisDevice.mode = knormal;
  162. } else {
  163. hcis_active_input(kchange_intermittentmode_time_input);
  164. thisDevice.mode = kintermittentMode;
  165. }
  166. }
  167. static void onkey(zkey_t* key, zkey_state_t key_state) {
  168. if /* */ (strcmp(key->name, "powerkey") == 0 && zks_rising_edge == key_state) {
  169. mf_process_poweron_key(key);
  170. } else if (strcmp(key->name, "levelkey") == 0 && zks_rising_edge == key_state) {
  171. mf_process_level_key(key);
  172. } else if (strcmp(key->name, "timerkey") == 0 && zks_rising_edge == key_state) {
  173. mf_process_timer_key(key);
  174. } else if (strcmp(key->name, "intervalkey") == 0 && zks_rising_edge == key_state) {
  175. mf_process_interval_key(key);
  176. }
  177. }
  178. /***********************************************************************************************************************
  179. * ===============================================THIS_MODULE_SCHEDULE================================================ *
  180. ***********************************************************************************************************************/
  181. static void mf_try_autoshutdown() {
  182. if (thisDevice.poweron) {
  183. if (thisDevice.countdonwnum_s == 0) {
  184. shutdwon();
  185. }
  186. }
  187. }
  188. static void mf_try_autostop() {
  189. //间歇模式下,定时到达定时时间,停止工作
  190. if (thisDevice.countdonwnum_s == 0) stopwork();
  191. }
  192. static void mf_try_auto_restart() {
  193. //间歇模式下,设备工作一定时间后,休息一定时间
  194. DO_IT_EACH_MS(3000) {
  195. printf("try auto restart [%d->%d]\n",
  196. systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000 - thisDevice.countdonw_setting_num * kconst_countdown_step_s,
  197. thisDevice.countdonw_setting_num * kconst_countdown_step_s);
  198. }
  199. END();
  200. if (systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000 > //
  201. (/*设备工作时间:*/ thisDevice.countdonw_setting_num * kconst_countdown_step_s + //
  202. /*设备休息时间*/ thisDevice.countdonw_setting_num * kconst_countdown_step_s)) {
  203. mf_set_countdown(thisDevice.countdonw_setting_num);
  204. startwork();
  205. }
  206. }
  207. static void mf_update_countdown() {
  208. if /* */ (thisDevice.mode == knormal) {
  209. thisDevice.countdonwnum = 0;
  210. thisDevice.countdonwnum_s = 0;
  211. } else if (thisDevice.mode == ktimingMode || thisDevice.mode == kintermittentMode) {
  212. if (thisDevice.countdonwnum_s != 0) {
  213. thisDevice.countdonwnum_s = //
  214. thisDevice.countdonw_setting_num * kconst_countdown_step_s - systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000;
  215. thisDevice.countdonwnum = compute_countdown_num(thisDevice.countdonwnum_s);
  216. }
  217. }
  218. }
  219. void this_module_schedule() {
  220. if (thisDevice.error != knoneException) {
  221. return;
  222. }
  223. /**
  224. * @brief
  225. */
  226. if (thisDevice.mode == ktimingMode) {
  227. //定时自动关机
  228. mf_update_countdown();
  229. mf_try_autoshutdown();
  230. }
  231. /**
  232. * @brief ,
  233. */
  234. if (thisDevice.mode == kintermittentMode) {
  235. mf_update_countdown();
  236. if (thisDevice.working) {
  237. mf_try_autostop();
  238. } else {
  239. mf_try_auto_restart();
  240. }
  241. }
  242. };
  243. /***********************************************************************************************************************
  244. * =======================================================MAIN======================================================== *
  245. ***********************************************************************************************************************/
  246. static void mf_do_debug_light_state() {
  247. static uint8_t debug_led_state = 1;
  248. debug_led_state = !debug_led_state;
  249. port_debug_set(debug_led_state);
  250. }
  251. static void mf_init_all_subdevice_state() {
  252. port_debug_set(false);
  253. port_fan_set(false);
  254. port_led0_set(false);
  255. port_led1_set(false);
  256. port_led2_set(false);
  257. port_led3_set(false);
  258. port_led_r_set(false);
  259. port_led_g_set(false);
  260. port_led_b_set(false);
  261. }
  262. void WDTInit(void) {
  263. IWDT_InitStruType x;
  264. x.WDT_Tms = 10000;
  265. x.WDT_IE = Enable; /* IWDT中断使能 */
  266. x.WDT_Rst = Enable; /* IWDT复位使能 */
  267. x.WDT_Clock = IWDT_CLOCK_WDT; /* LRC */
  268. IWDT_Init(&x);
  269. /* 使能IWDT */
  270. IWDT_Enable();
  271. }
  272. // static float mf_get_ozone_generator_power() {
  273. // float fanpower = 0;
  274. // for (size_t i = 0; i < 20; i++) {
  275. // fanpower += port_adc_get_ozone_generator_power();
  276. // }
  277. // return fanpower / 20;
  278. // }
  279. static const char* errorToStr(error_t exception) {
  280. if (exception == knoneException) {
  281. return "kNoError";
  282. }
  283. if (exception == kOzonePrimaryCircuitAnomaly) {
  284. return "kOzonePrimaryCircuitAnomaly";
  285. }
  286. if (exception == kOzoneSecondaryCircuitAnomaly) {
  287. return "kOzoneSecondaryCircuitAnomaly";
  288. }
  289. if (exception == kfanIsBroken) {
  290. return "kfanIsBroken";
  291. }
  292. if (exception == kPowerOutOfControl) {
  293. return "kPowerOutOfControl";
  294. }
  295. return "kUnknownException";
  296. }
  297. void trigger_exception(error_t exception) {
  298. thisDevice.error = exception;
  299. printf("======================DeviceSnapshot==========================\n");
  300. /*Exception*/
  301. printf("= Exception\n");
  302. printf("=\terror :%s\n", errorToStr(exception));
  303. //
  304. printf("= IOState\n");
  305. printf("=\tFan :%d\n", port_fan_get());
  306. /*Power*/
  307. printf("= Power\n");
  308. printf("=\tfanpower :%f\n", mf_fan_get_power());
  309. printf("=\tozonepower :%f\n", ozone_control_get_ozone_power());
  310. /*ThisDevice*/
  311. printf("= ThisDevice\n");
  312. printf("=\tworking :%d\n", thisDevice.working);
  313. printf("=\tmode :%d\n", thisDevice.mode);
  314. printf("=\tlevel :%d\n", thisDevice.level);
  315. printf("=\tpoweron :%d\n", thisDevice.poweron);
  316. printf("=\tcountdonwnum :%d\n", thisDevice.countdonwnum);
  317. printf("=\tcountdonwnum_s :%d\n", thisDevice.countdonwnum_s);
  318. printf("=\tcountdonw_setting_num :%d\n", thisDevice.countdonw_setting_num);
  319. printf("=\tcountdonw_start_ticket :%d\n", thisDevice.countdonw_start_ticket);
  320. printf("=\tactive_input :%d\n", thisDevice.active_input);
  321. printf("=\tactive_start_ticket :%d\n", thisDevice.active_start_ticket);
  322. /*ozone_control*/
  323. printf("= OZONE CONTROL\n");
  324. printf("=\tworking_state_id :%d\n", ozone_control_get_working_state_id());
  325. printf("=\tnowfreq :%d\n", ozone_control_get_working_state()->nowfreq);
  326. printf("=\tchangefreqdirection :%d\n", ozone_control_get_working_state()->changefreqdirection);
  327. printf("=\tadjustedToTheProperPower:%d\n", ozone_control_get_working_state()->adjustedToTheProperPower);
  328. printf("=\tresonant_frequency :%d\n", ozone_control_get_working_state()->resonant_frequency);
  329. printf("=\tslope_when_freq40k :%f\n", ozone_control_get_working_state()->slope_when_freq40k);
  330. printf("=\tavarage_power :%f\n", ozone_control_get_working_state()->avarage_power);
  331. printf("=\texpect_power :%f\n", ozone_control_get_expect_power());
  332. printf("=\n");
  333. // reset device
  334. thisDevice.mode = knormal;
  335. stopwork();
  336. }
  337. void exception_monitor_schedule() {
  338. if (!thisDevice.poweron) {
  339. return;
  340. }
  341. if (thisDevice.error != knoneException) {
  342. return;
  343. }
  344. // printf("FanPower:%f,OzonePower:%f\n", fan_get_power(), mf_get_ozone_generator_power());
  345. /*****************************************************************************************************************
  346. * ================================================================================================= *
  347. *****************************************************************************************************************/
  348. if (port_fan_get()) {
  349. float fanpower = mf_fan_get_power();
  350. /**
  351. * @brief 1.50.3
  352. *
  353. * http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/风扇功率日志-正常工作和阻转时候的功率变化.png
  354. * http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/风扇不工作时候的功率.png
  355. *
  356. */
  357. if (fanpower > 3 || fanpower < 0.6) {
  358. m_fanerronum++;
  359. printf("fanpower error: %f ,%d\n", fanpower, m_fanerronum);
  360. if (m_fanerronum > 3) {
  361. trigger_exception(kfanIsBroken);
  362. return;
  363. }
  364. }
  365. } else {
  366. m_fanerronum = 0;
  367. }
  368. /*****************************************************************************************************************
  369. * ========================================================================================= *
  370. *****************************************************************************************************************/
  371. if (ozone_control_get_working_state_id() == kWorkingState) {
  372. /**
  373. * @brief
  374. */
  375. if (ozone_control_get_working_state()->avarage_power < 0.2) {
  376. trigger_exception(kOzonePrimaryCircuitAnomaly);
  377. return;
  378. }
  379. /**
  380. * @brief
  381. * -0.000344
  382. */
  383. if (ozone_control_get_working_state()->slope_when_freq40k < -0.000200) {
  384. trigger_exception(kOzoneSecondaryCircuitAnomaly);
  385. return;
  386. }
  387. /**
  388. * @brief
  389. * ,,
  390. */
  391. if (ozone_control_get_ozone_power() > (ozone_control_get_expect_power() + EXPECT_POWER_WINDONWS) && //
  392. ozone_control_get_working_state()->nowfreq == ozone_control_get_working_state()->resonant_frequency) {
  393. trigger_exception(kPowerOutOfControl);
  394. return;
  395. }
  396. }
  397. }
  398. void dumpfanpower() { printf("%f\n", mf_fan_get_power()); }
  399. int main(void) {
  400. SystemInit(); //配置系统时钟
  401. DeviceClockAllEnable(); //打开所有外设时钟
  402. systicket_init();
  403. /*系统初始化*/
  404. zgpio_init_all_gpio(); //
  405. port_init(); //
  406. mf_init_all_subdevice_state(); //
  407. printf("==========OZONE_GENERATOR==========\n"); //
  408. printf("= manufactor: iflytop\n"); //
  409. printf("= version : %s\n", VERSION); //
  410. printf("=\n"); //
  411. /*组件初始化*/
  412. zkey_init(&key_module); //按键初始化
  413. ozone_control_init();
  414. /**
  415. * @brief
  416. * 20k起步50hz100ms计算功率
  417. */
  418. WDTInit();
  419. while (true) {
  420. //按键扫描逻辑
  421. DO_IT_EACH_MS(KEY_PERIOD) { zkey_do_loop_in_each_period(NULL); }
  422. END();
  423. //调试指示灯
  424. DO_IT_EACH_MS(150) { mf_do_debug_light_state(); }
  425. END();
  426. //臭氧控制逻辑Schedule
  427. ozone_control_schedule();
  428. //人机交互逻辑Schedule
  429. hcis_shcedule();
  430. //当前模块逻辑Schedule
  431. this_module_schedule();
  432. DO_IT_EACH_MS(1000) { exception_monitor_schedule(); }
  433. END();
  434. // port_fan_set(true);
  435. // DO_IT_EACH_MS(100) { dumpfanpower(); }
  436. // END();
  437. //喂狗
  438. if (0x01 == IWDT_GetFlagStatus()) IWDT_Clear();
  439. }
  440. }