|
|
#include <stdbool.h> //定义布尔
#include <string.h>
#include "board.h"
//
#include "zes8p5066lib/basic.h"
#include "zes8p5066lib/gpio.h"
#include "zes8p5066lib/key.h"
#include "zes8p5066lib/systicket.h"
#include "zes8p5066lib/uart0.h"
//
#include "service/human_computer_interaction_service.h"
#include "service/ozone_control_service.h"
#include "service/thisdevice.h"
#include "test.h"
#include "zsimple_timer/zsimple_timer.h"
/***********************************************************************************************************************
* =====================================================函数声明====================================================== * ***********************************************************************************************************************/ void onkey(zkey_t* key, zkey_state_t key_state); /***********************************************************************************************************************
* =====================================================全局变量====================================================== * ***********************************************************************************************************************/ static zkey_t s_keys[] = { ZKEY_INIT("powerkey", port_gpio_get_power_key_state), //电源按键
ZKEY_INIT("levelkey", port_gpio_get_level_key_state), //左1
ZKEY_INIT("timerkey", port_gpio_get_timer_key_state), //左2
ZKEY_INIT("intervalkey", port_gpio_get_interval_key_state), //左3
}; zkey_module_t key_module = ZMODULE_INIT(s_keys, onkey); static int m_fanerronum = 0;
/***********************************************************************************************************************
* =======================================================方法======================================================== * ***********************************************************************************************************************/ static float mf_fan_get_power() { float fanpower = 0; for (size_t i = 0; i < 20; i++) { fanpower += port_adc_get_fan_power(); } return fanpower / 20; }
/***********************************************************************************************************************
* ===================================================COUNT_COMPUTE=================================================== * ***********************************************************************************************************************/ static uint32_t compute_countdown_num(int countdowns) { return countdowns / kconst_countdown_step_s + !!(countdowns % kconst_countdown_step_s); }
static void increase_and_assign_countdonwnum() { if (thisDevice.countdonwnum == 4) { thisDevice.countdonwnum = 0; thisDevice.countdonwnum_s = 0; thisDevice.countdonw_setting_num = 0; } else { thisDevice.countdonwnum_s = (thisDevice.countdonwnum + 1) * kconst_countdown_step_s; thisDevice.countdonwnum = thisDevice.countdonwnum + 1; thisDevice.countdonw_setting_num = thisDevice.countdonwnum; thisDevice.countdonw_start_ticket = systicket_get_now_ms(); } }
static void mf_set_countdown(int countdownnum) { thisDevice.countdonwnum = countdownnum; thisDevice.countdonwnum_s = thisDevice.countdonwnum * kconst_countdown_step_s; thisDevice.countdonw_setting_num = thisDevice.countdonwnum; thisDevice.countdonw_start_ticket = systicket_get_now_ms(); }
/***********************************************************************************************************************
* ===================================================POWER_CONTROL=================================================== * ***********************************************************************************************************************/ //设备开始工作
static void startwork() { port_fan_set(true); ozone_control_start(); thisDevice.working = true; m_fanerronum = 0; } //停止设备工作
static void stopwork() { ozone_control_stop(); port_fan_set(false); thisDevice.working = false; } //关机
static void shutdwon() { printf("power off\n"); thisDevice.poweron = false; stopwork(); } //开机
static void poweron() { printf("power on\n"); thisDevice.poweron = true; thisDevice.level = klevel2; thisDevice.mode = knormal; thisDevice.error = knoneException; startwork(); }
/***********************************************************************************************************************
* =================================================KEY_EVENT_PROCESS================================================= * ***********************************************************************************************************************/ //电源按键处理
static void mf_process_poweron_key(zkey_t* key) { printf("on %s \n", key->name); if (!thisDevice.poweron) { poweron(); } else { shutdwon(); } return; } //等级按键处理
static void mf_process_level_key(zkey_t* key) { if (!thisDevice.poweron) return; if (thisDevice.error != knoneException) return;
printf("on %s \n", key->name); /**
* @brief 当前在不在修改状态,不在,则进入修改状态 */ if (thisDevice.level == klevel1) { printf("changet level to level2\n"); thisDevice.level = klevel2; //更改臭氧状态
} else if (thisDevice.level == klevel2) { printf("changet level to level1\n"); thisDevice.level = klevel1; //更改臭氧状态
} hcis_active_input(kchange_level_input); return; } //定时按键处理
static void mf_process_timer_key(zkey_t* key) { if (!thisDevice.poweron) return; if (thisDevice.error != knoneException) return;
printf("on %s \n", key->name); if (!thisDevice.working) { startwork(); } if (thisDevice.mode != ktimingMode) { mf_set_countdown(0); } increase_and_assign_countdonwnum(); if (thisDevice.countdonwnum_s == 0) { hcis_active_input(knone_active); thisDevice.mode = knormal; } else { hcis_active_input(kchange_countdonw_time_input); thisDevice.mode = ktimingMode; } } //间隔按键处理
static void mf_process_interval_key(zkey_t* key) { if (!thisDevice.poweron) return; if (thisDevice.error != knoneException) return; printf("on %s \n", key->name); if (!thisDevice.working) { startwork(); } if (thisDevice.mode != kintermittentMode) { mf_set_countdown(0); } increase_and_assign_countdonwnum(); if (thisDevice.countdonwnum_s == 0) { hcis_active_input(knone_active); thisDevice.mode = knormal; } else { hcis_active_input(kchange_intermittentmode_time_input); thisDevice.mode = kintermittentMode; } }
static void onkey(zkey_t* key, zkey_state_t key_state) { if /* */ (strcmp(key->name, "powerkey") == 0 && zks_rising_edge == key_state) { mf_process_poweron_key(key); } else if (strcmp(key->name, "levelkey") == 0 && zks_rising_edge == key_state) { mf_process_level_key(key); } else if (strcmp(key->name, "timerkey") == 0 && zks_rising_edge == key_state) { mf_process_timer_key(key); } else if (strcmp(key->name, "intervalkey") == 0 && zks_rising_edge == key_state) { mf_process_interval_key(key); } } /***********************************************************************************************************************
* ===============================================THIS_MODULE_SCHEDULE================================================ * ***********************************************************************************************************************/ static void mf_try_autoshutdown() { if (thisDevice.poweron) { if (thisDevice.countdonwnum_s == 0) { shutdwon(); } } }
static void mf_try_autostop() { //间歇模式下,定时到达定时时间,停止工作
if (thisDevice.countdonwnum_s == 0) stopwork(); }
static void mf_try_auto_restart() { //间歇模式下,设备工作一定时间后,休息一定时间
DO_IT_EACH_MS(3000) { printf("try auto restart [%d->%d]\n", systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000 - thisDevice.countdonw_setting_num * kconst_countdown_step_s, thisDevice.countdonw_setting_num * kconst_countdown_step_s); } END();
if (systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000 > //
(/*设备工作时间:*/ thisDevice.countdonw_setting_num * kconst_countdown_step_s + //
/*设备休息时间*/ thisDevice.countdonw_setting_num * kconst_countdown_step_s)) { mf_set_countdown(thisDevice.countdonw_setting_num); startwork(); } }
static void mf_update_countdown() { if /* */ (thisDevice.mode == knormal) { thisDevice.countdonwnum = 0; thisDevice.countdonwnum_s = 0; } else if (thisDevice.mode == ktimingMode || thisDevice.mode == kintermittentMode) { if (thisDevice.countdonwnum_s != 0) { thisDevice.countdonwnum_s = //
thisDevice.countdonw_setting_num * kconst_countdown_step_s - systicket_haspassedms(thisDevice.countdonw_start_ticket) / 1000; thisDevice.countdonwnum = compute_countdown_num(thisDevice.countdonwnum_s); } } }
void this_module_schedule() { if (thisDevice.error != knoneException) { return; } /**
* @brief 定时模式下 */ if (thisDevice.mode == ktimingMode) { //定时自动关机
mf_update_countdown(); mf_try_autoshutdown(); }
/**
* @brief 间歇模式下,自动停止,自动重启 */ if (thisDevice.mode == kintermittentMode) { mf_update_countdown(); if (thisDevice.working) { mf_try_autostop(); } else { mf_try_auto_restart(); } } };
/***********************************************************************************************************************
* =======================================================MAIN======================================================== * ***********************************************************************************************************************/ static void mf_do_debug_light_state() { static uint8_t debug_led_state = 1; debug_led_state = !debug_led_state; port_debug_set(debug_led_state); }
static void mf_init_all_subdevice_state() { port_debug_set(false); port_fan_set(false); port_led0_set(false); port_led1_set(false); port_led2_set(false); port_led3_set(false); port_led_r_set(false); port_led_g_set(false); port_led_b_set(false); }
void WDTInit(void) { IWDT_InitStruType x;
x.WDT_Tms = 10000; x.WDT_IE = Enable; /* IWDT中断使能 */ x.WDT_Rst = Enable; /* IWDT复位使能 */ x.WDT_Clock = IWDT_CLOCK_WDT; /* LRC */ IWDT_Init(&x);
/* 使能IWDT */ IWDT_Enable(); }
// static float mf_get_ozone_generator_power() {
// float fanpower = 0;
// for (size_t i = 0; i < 20; i++) {
// fanpower += port_adc_get_ozone_generator_power();
// }
// return fanpower / 20;
// }
static const char* errorToStr(error_t exception) { if (exception == knoneException) { return "kNoError"; } if (exception == kOzonePrimaryCircuitAnomaly) { return "kOzonePrimaryCircuitAnomaly"; } if (exception == kOzoneSecondaryCircuitAnomaly) { return "kOzoneSecondaryCircuitAnomaly"; } if (exception == kfanIsBroken) { return "kfanIsBroken"; } if (exception == kPowerOutOfControl) { return "kPowerOutOfControl"; } return "kUnknownException"; }
void trigger_exception(error_t exception) { thisDevice.error = exception;
printf("======================DeviceSnapshot==========================\n"); /*Exception*/ printf("= Exception\n"); printf("=\terror :%s\n", errorToStr(exception)); //
printf("= IOState\n"); printf("=\tFan :%d\n", port_fan_get()); /*Power*/ printf("= Power\n"); printf("=\tfanpower :%f\n", mf_fan_get_power()); printf("=\tozonepower :%f\n", ozone_control_get_ozone_power());
/*ThisDevice*/ printf("= ThisDevice\n"); printf("=\tworking :%d\n", thisDevice.working); printf("=\tmode :%d\n", thisDevice.mode); printf("=\tlevel :%d\n", thisDevice.level); printf("=\tpoweron :%d\n", thisDevice.poweron); printf("=\tcountdonwnum :%d\n", thisDevice.countdonwnum); printf("=\tcountdonwnum_s :%d\n", thisDevice.countdonwnum_s); printf("=\tcountdonw_setting_num :%d\n", thisDevice.countdonw_setting_num); printf("=\tcountdonw_start_ticket :%d\n", thisDevice.countdonw_start_ticket); printf("=\tactive_input :%d\n", thisDevice.active_input); printf("=\tactive_start_ticket :%d\n", thisDevice.active_start_ticket);
/*ozone_control*/ printf("= OZONE CONTROL\n"); printf("=\tworking_state_id :%d\n", ozone_control_get_working_state_id()); printf("=\tnowfreq :%d\n", ozone_control_get_working_state()->nowfreq); printf("=\tchangefreqdirection :%d\n", ozone_control_get_working_state()->changefreqdirection); printf("=\tadjustedToTheProperPower:%d\n", ozone_control_get_working_state()->adjustedToTheProperPower); printf("=\tresonant_frequency :%d\n", ozone_control_get_working_state()->resonant_frequency); printf("=\tslope_when_freq40k :%f\n", ozone_control_get_working_state()->slope_when_freq40k); printf("=\tavarage_power :%f\n", ozone_control_get_working_state()->avarage_power); printf("=\texpect_power :%f\n", ozone_control_get_expect_power());
printf("=\n");
// reset device
thisDevice.mode = knormal; stopwork(); }
void exception_monitor_schedule() { if (!thisDevice.poweron) { return; } if (thisDevice.error != knoneException) { return; }
// printf("FanPower:%f,OzonePower:%f\n", fan_get_power(), mf_get_ozone_generator_power());
/*****************************************************************************************************************
* ================================================检查风扇异常================================================= * *****************************************************************************************************************/ if (port_fan_get()) { float fanpower = mf_fan_get_power(); /**
* @brief 当前风扇阻转后功率依然不高只比正常的功率1.5大0.3 * * http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/风扇功率日志-正常工作和阻转时候的功率变化.png
* http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/风扇不工作时候的功率.png
* */ if (fanpower > 3 || fanpower < 0.6) { m_fanerronum++; printf("fanpower error: %f ,%d\n", fanpower, m_fanerronum); if (m_fanerronum > 3) { trigger_exception(kfanIsBroken); return; } }
} else { m_fanerronum = 0; } /*****************************************************************************************************************
* ============================================检查臭氧是否工作异常============================================= * *****************************************************************************************************************/ if (ozone_control_get_working_state_id() == kWorkingState) { /**
* @brief 检查一级电路是否工作正常 */ if (ozone_control_get_working_state()->avarage_power < 0.2) { trigger_exception(kOzonePrimaryCircuitAnomaly); return; }
/**
* @brief 检查二级电路是否工作正常 * -0.000344 */ if (ozone_control_get_working_state()->slope_when_freq40k < -0.000200) { trigger_exception(kOzoneSecondaryCircuitAnomaly); return; }
/**
* @brief 监控功率变化情况 * 当频率已经调整到了可调范围的最低时候,功率依然大于期望功率,则触发异常 */ if (ozone_control_get_ozone_power() > (ozone_control_get_expect_power() + EXPECT_POWER_WINDONWS) && //
ozone_control_get_working_state()->nowfreq == ozone_control_get_working_state()->resonant_frequency) { trigger_exception(kPowerOutOfControl); return; } } }
void dumpfanpower() { printf("%f\n", mf_fan_get_power()); }
int main(void) { SystemInit(); //配置系统时钟
DeviceClockAllEnable(); //打开所有外设时钟
systicket_init();
/*系统初始化*/ zgpio_init_all_gpio(); //
port_init(); //
mf_init_all_subdevice_state(); //
printf("==========OZONE_GENERATOR==========\n"); //
printf("= manufactor: iflytop\n"); //
printf("= version : %s\n", VERSION); //
printf("=\n"); //
/*组件初始化*/ zkey_init(&key_module); //按键初始化
ozone_control_init(); /**
* @brief * 频率从20k起步,递增50hz,每次等待100ms计算功率 */ WDTInit(); while (true) { //按键扫描逻辑
DO_IT_EACH_MS(KEY_PERIOD) { zkey_do_loop_in_each_period(NULL); } END(); //调试指示灯
DO_IT_EACH_MS(150) { mf_do_debug_light_state(); } END(); //臭氧控制逻辑Schedule
ozone_control_schedule(); //人机交互逻辑Schedule
hcis_shcedule(); //当前模块逻辑Schedule
this_module_schedule(); DO_IT_EACH_MS(1000) { exception_monitor_schedule(); } END(); // port_fan_set(true);
// DO_IT_EACH_MS(100) { dumpfanpower(); }
// END();
//喂狗
if (0x01 == IWDT_GetFlagStatus()) IWDT_Clear(); } }
|