Browse Source

update

master
zhaohe 3 years ago
parent
commit
cc08902786
  1. 364
      APP/main.c
  2. 186
      APP/service/ozone_control_service.c
  3. 39
      APP/service/ozone_control_service.h
  4. 5
      APP/state_machine.c
  5. 66
      APP/state_machine.h
  6. 2
      zes8p5066lib

364
APP/main.c

@ -11,6 +11,7 @@
#include "zes8p5066lib/uart0.h"
//
#include "service/light_control_service.h"
#include "service/ozone_control_service.h"
#include "service/thisdevice.h"
#include "test.h"
#include "zsimple_timer/zsimple_timer.h"
@ -29,8 +30,6 @@ static zkey_t s_keys[] = {
ZKEY_INIT("intervalkey", port_gpio_get_interval_key_state), //3
};
zkey_module_t key_module = ZMODULE_INIT(s_keys, onkey);
static zsimple_timer_t zsimple_timer_mem[10]; //10
zsimple_timer_t* debuglighttimer;
/***********************************************************************************************************************
* =============================================================================================================== *
@ -40,16 +39,12 @@ static uint32_t compute_countdown_num(int countdowns) {
if (countdowns) return countdowns / kconst_countdown_step_s + !!(countdowns % kconst_countdown_step_s);
}
uint32_t freq = 34000;
uint32_t dutyns = 5000;
static void shutdwon() {
printf("power off\n");
thisDevice.poweron = false;
port_fan_set(false);
//@TODO:
port_ozone_pwm_stop();
port_ozone_pwm_set_duty(freq, dutyns);
}
static void increase_and_assign_countdonwnum() {
@ -205,351 +200,16 @@ void process_countdwonevent() {
}
};
void do_debug_light_state(zsimple_timer_t* handler) {
void ozone_control_start();
void ozone_control_stop();
void ozone_control_schedule();
void do_debug_light_state() {
static uint8_t debug_led_state = 1;
debug_led_state = !debug_led_state;
port_debug_set(debug_led_state);
}
#if 0
typedef struct {
float LastP; // 0.02
float Now_P; // 0
float out; // 0
float Kg; // 0
float Q; // 0.001
float R; // 0.543
} KFP; // Kalman Filter parameter
// 2.
KFP KFP_height = {0.02, 0, 0, 0, 0.03, 0.543};
/**
*
*@param KFP *kfp
* float input
*@return
*/
float kalmanFilter(KFP* kfp, float input) {
//k时刻系统估算协方差 = k-1 +
kfp->Now_P = kfp->LastP + kfp->Q;
// = k时刻系统估算协方差 / k时刻系统估算协方差 +
kfp->Kg = kfp->Now_P / (kfp->Now_P + kfp->R);
//k时刻状态变量的最优值 = + * -
kfp->out = kfp->out + kfp->Kg * (input - kfp->out); //
//: kfp->LastP
kfp->LastP = (1 - kfp->Kg) * kfp->Now_P;
return kfp->out;
}
float derivative(float now) {
static float last = 0;
float diff = now - last;
last = now;
return diff;
}
void printf_ozone_freq_and_power_table() {
/**
* @brief
*/
float startfreq = 10 * 1000;
float stepfreq = 100;
float nowfreq = startfreq;
port_ozone_pwm_set_duty(nowfreq, 1000);
port_ozone_pwm_start();
systicket_delay_ms(10);
bool first = true;
while (true) {
port_ozone_pwm_set_duty(nowfreq, 3000);
systicket_delay_ms(2);
float power = get_ozone_power();
// printf("%f %f\n", nowfreq, freq);
// printf("{freq power:%f,%f}\r\n", nowfreq, power);
// printf("{freq power:%f,%f}\r\n", nowfreq, power);
if (first) {
// kalmanFilter(&KFP_height, power);
KFP_height.LastP = power;
first = false;
}
float afterfilter = kalmanFilter(&KFP_height, power);
printf("%f,%f,%f,%f\r\n", nowfreq, power, afterfilter,derivative(afterfilter)*10);
// printf("{power:%f}\r\n", power);
nowfreq += stepfreq;
if (nowfreq >= 40 * 1000) break;
}
port_ozone_pwm_set_duty(33000, 3000);
port_fan_set(true);
while (true) {
}
port_ozone_pwm_stop();
while (true) {
systicket_delay_ms(2);
float power = get_ozone_power();
float afterfilter = kalmanFilter(&KFP_height, power);
nowfreq+=50;
printf("%f,%f,%f\r\n", nowfreq, power, afterfilter);
}
}
#endif
#if 0
float kalmanFilter1(float input) {
static KFP kfp = {0.02, 0, 0, 0, 0.03, 0.543};
return kalmanFilter(&kfp, input);
}
float kalmanFilter2(float input) {
static KFP kfp = {0.02, 0, 0, 0, 0.03, 0.543};
return kalmanFilter(&kfp, input);
}
float kalmanFilter3(float input) {
static KFP kfp = {0.02, 0, 0, 0, 0.03, 0.543};
return kalmanFilter(&kfp, input);
}
float kalmanFilter4(float input) {
static KFP kfp = {0.02, 0, 0, 0, 0.03, 0.543};
return kalmanFilter(&kfp, input);
}
float set_pwm_and_get_power(uint32_t freq, uint32_t dutyns) {
port_ozone_pwm_set_duty(freq, dutyns);
systicket_delay_ms(2);
float power1 = get_ozone_power();
return power1;
}
void printf_ozone_freq_and_power_table() {
/**
* @brief
*/
uint32_t startfreq = 10 * 1000;
uint32_t stepfreq = 100;
uint32_t nowfreq = startfreq;
port_ozone_pwm_set_duty(nowfreq, 1000);
// port_ozone_pwm_stop();
port_ozone_pwm_start();
systicket_delay_ms(10);
bool first = true;
while (true) {
// printf("%d,%f,%f,%f,%f\r\n", nowfreq, //
// /*kalmanFilter1*/(set_pwm_and_get_power(nowfreq, 2000)), //
// /*kalmanFilter2*/(set_pwm_and_get_power(nowfreq, 4000)), //
// /*kalmanFilter3*/(set_pwm_and_get_power(nowfreq, 6000)), //
// /*kalmanFilter4*/(set_pwm_and_get_power(nowfreq, 8000)) //
// );
// printf("{power:%f}\r\n", power);
nowfreq += stepfreq;
if (nowfreq >= 40 * 1000) break;
}
port_ozone_pwm_set_duty(33000, 3500);
port_fan_set(true);
while (true) {
}
}
// void printf_ozone_freq_and_power_table() {
// /**
// * @brief
// */
// float startfreq = 20 * 1000;
// float stepfreq = 50;
// float nowfreq = startfreq;
// // port_ozone_pwm_set_duty(nowfreq, 1000);
// // port_ozone_pwm_start();
// // systicket_delay_ms(10);
// while (true) {
// // printf("{power:%f}\r\n", nowfreq);
// printf("%d,%d\r\n", (int)nowfreq,(int)nowfreq);
// systicket_delay_ms(100);
// nowfreq += stepfreq;
// // if (nowfreq >= 40 * 1000) break;
// }
// port_ozone_pwm_stop();
// }
float s_power_table[200];
void setpower(uint16_t freq, float power) {
/**
* @brief
* [0]->20k
* [1]->20.1k
*/
uint16_t index = (freq - 20000) / 100;
if (index < 0) return;
if (index >= ARRAY_SIZE(s_power_table)) return;
s_power_table[index] = power;
}
float getpower(uint16_t freq) {
/**
* @brief
* [0]->20k
* [1]->20.1k
*/
uint16_t index = (freq - 20000) / 100;
if (index < 0) return 0;
if (index >= ARRAY_SIZE(s_power_table)) return 0;
return s_power_table[index];
}
float get_ozone_power() {
float powersum = 0;
for (size_t i = 0; i < 20; i++) {
powersum += port_adc_get_ozone_generator_power();
}
return powersum / 20;
}
float set_pwm_and_get_power(uint32_t freq, uint32_t dutyns) {
port_ozone_pwm_set_duty(freq, dutyns);
systicket_delay_ms(3);
float power1 = get_ozone_power();
return power1;
}
void create_power_table() {
/**
* @brief
*/
port_ozone_pwm_set_duty(20000, 3000);
port_ozone_pwm_start();
systicket_delay_ms(3);
for (size_t i = 0; i < 200; i++) {
nowfreq = 20000 + i * 100;
float power = set_pwm_and_get_power(nowfreq, 3000);
setpower(nowfreq, power);
}
port_ozone_pwm_stop();
printf("%d,%f\r\n", nowfreq, power);
}
void printf_ozone_freq_and_power_table() {
/**
* @brief
*/
for (size_t i = 0; i < 200; i++) {
nowfreq = 20000 + i * 100;
float power = getpower(nowfreq);
printf("%d,%f\r\n", nowfreq, power);
}
}
void checkdevice() {
/**
* @brief
*
*
* :3us扫频
* 1.35k->40k时候的功率40k的要大
* 2.35k->40k时候的功率
* 3.25k到30k扫频25k到35k的点绝大多数都比25k时候的大
* 4.
*
* :
*
* 1 35k到40k40k功率大的点的占比
* 2 35k到40k
* 3 25k到30k25k大的点的占比
* 4 25k到30k,
*
*
* :
*
*
*
* 1. 25k->40k之间找到谐振点
* 2. 5k的曲线
* 3. 40k往前5k曲线的斜率
*
*
*/
printf("checkdevice\r\n");
float indicator_1 = 0;
float indicator_2 = 0;
float indicator_3 = 0;
uint16_t resonant_frequency = 0;
{
//1 35k到40k40k功率大的点的占比
int count = 0;
size_t i = 0;
for (;; i++) {
int nowfreq = 35000 + i * 100;
float power = getpower(nowfreq);
if (power > getpower(40000)) {
count++;
}
if (nowfreq >= 40 * 1000) {
break;
}
}
indicator_1 = count * 1.0 / i * 100;
}
{
// 2 35k到40k
int count = 0;
float sumpower = 0;
size_t i = 0;
for (;; i++) {
int nowfreq = 35000 + i * 100;
float power = getpower(nowfreq);
sumpower += power;
}
indicator_2 = sumpower / i;
}
// 3 25k到30k25k大的点的占比
{
int count = 0;
size_t i = 0;
for (;; i++) {
int nowfreq = 25000 + i * 100;
float power = getpower(nowfreq);
if (power > getpower(25000)) {
count++;
}
if (nowfreq >= 30 * 1000) {
break;
}
}
indicator_3 = count * 1.0 / i * 100;
}
// 4 25k到30k,
{
size_t i = 0;
float minpower = getpower(25000);
uint16_t minpowerfreq = 25000;
for (;; i++) {
int nowfreq = 25000 + i * 100;
float power = getpower(nowfreq);
if (power < minpower) {
minpower = power;
minpowerfreq = nowfreq;
}
}
resonant_frequency = minpowerfreq;
}
}
#endif
void init_all_subdevice_state() {
port_debug_set(false);
port_fan_set(false);
@ -577,12 +237,9 @@ int main(void) {
printf("=\n"); //
/*组件初始化*/
zsimple_timer_module_init(zsimple_timer_mem, ZARR_SIZE(zsimple_timer_mem), systicket_get_now_ms); //
zkey_init(&key_module); //
debuglighttimer = zsimple_timer_alloc();
zsimple_timer_trigger_static(debuglighttimer, 300, INFINITE_TIMES /*触发次数:*/, true, do_debug_light_state);
zkey_init(&key_module); //
ozone_control_init();
/**
* @brief
* 20k起步50hz100ms计算功率
@ -593,8 +250,9 @@ int main(void) {
//
DO_IT_EACH_MS(KEY_PERIOD) { zkey_do_loop_in_each_period(NULL); }
END();
zsimple_timer_schedule();
DO_IT_EACH_MS(150) { do_debug_light_state(); }
END();
ozone_control_schedule();
lcs_shcedule();
process_countdwonevent();
// printf("countddonw %d\n", thisDevice.countdonwnum_s);

186
APP/service/ozone_control_service.c

@ -1,5 +1,6 @@
#include "ozone_control_service.h"
#include "../zes8p5066lib/basic.h"
#include "../zes8p5066lib/systicket.h"
#include "frequency_sweep_service.h"
#include "state_machine.h"
@ -8,63 +9,59 @@
* @brief
*
* :
* ------> ---->
* ^ |
* |------------------|
*
*
* -----> --> ---->
* ------> ---->
*
**/
#define PRV_START_EVENT (STATE_MACHINE_PUBLIC_EVENT + 1)
#define PRV_STOP_EVENT (STATE_MACHINE_PUBLIC_EVENT + 2)
typedef struct {
float resonant_frequency; //
float nowfreq; //
bool changefreqdirection; //
bool adjustedToTheProperPower; //
} Context_t;
typedef enum {
kIdleState,
kBeforeWorkingStateSweepFrequency,
kWorkingState,
} StateId_t;
state_machine_state_t states[] = {
state_machine_state_t m_states[] = {
[kIdleState] =
{
.name = "kIdleState",
.stateId = kIdleState,
.duration = 0,
},
[kBeforeWorkingStateSweepFrequency] =
{
.name = "kBeforeWorkingStateSweepFrequency",
.stateId = kBeforeWorkingStateSweepFrequency,
.duration = 0,
},
[kWorkingState] = //
{
.name = "kWorkingState",
.stateId = kWorkingState,
.duration = 0,
}
//
};
state_machine_t m_statemachine;
state_machine_t statemachine = {
.states = states,
.nstate = sizeof(states) / sizeof(states[0]),
.nowstate = &states[kIdleState],
.process_event = NULL,
.nextstate = NULL,
.laststate = NULL,
};
typedef struct {
float resonant_frequency;
} Context_t;
static Context_t context;
static float const_level1_expect_power;
const static float const_windonws = 0.3;
const static float const_level1_expect_power = 3.0;
const static float const_level2_expect_power = 6.0;
const static float const_max_freq = 38000;
static uint16_t get_resonant_frequency(uint16_t startfreq, uint16_t step, uint16_t endfreq) {
/**
* @brief
* ,
*
* http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/20220815-.png
*/
float minpower = 0;
uint16_t retfreq = 0;
bool inited = false;
@ -85,6 +82,24 @@ static uint16_t get_resonant_frequency(uint16_t startfreq, uint16_t step, uint16
return retfreq;
}
static float mf_get_ozone_power() {
float powersum = 0;
for (size_t i = 0; i < 10; i++) {
powersum += port_adc_get_ozone_generator_power();
}
return powersum / 10;
}
float get_expect_power() {
float expectpower = 0;
if (thisDevice.level == klevel1) {
expectpower = const_level1_expect_power;
} else if (thisDevice.level == klevel2) {
expectpower = const_level2_expect_power;
}
return expectpower;
}
static state_machine_state_t* processBeforeWorkingStateSweepFrequency(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
/**
* @brief
@ -96,48 +111,113 @@ static state_machine_state_t* processBeforeWorkingStateSweepFrequency(state_mach
context.resonant_frequency = get_resonant_frequency(25000, 100, 35000);
printf("----------Summarize--------\n");
printf("-resonant_frequency: %f\n", context.resonant_frequency);
return &states[kWorkingState];
context.nowfreq = context.resonant_frequency;
return &m_states[kWorkingState];
}
} else if (event == EXIT_STATE) {
frequency_sweep_stop();
}
}
static float mf_get_ozone_power() {
float powersum = 0;
for (size_t i = 0; i < 10; i++) {
powersum += port_adc_get_ozone_generator_power();
}
return powersum / 10;
}
static state_machine_state_t* processWorkingState(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
/**
* @brief
*
* ([expertpower+window,expertpower-window])
*
*/
static state_machine_state_t* state_machine_process_event(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
if /* */ (nowstate == &states[kIdleState]) {
} else if (nowstate == &states[kBeforeWorkingStateSweepFrequency]) {
processBeforeWorkingStateSweepFrequency(machine, nowstate, event);
} else if (nowstate == &states[kWorkingState]) {
if (event == ENTER_STATE) {
if (event == ENTER_STATE) {
/**
* @brief
*/
if (context.nowfreq < context.resonant_frequency) {
context.nowfreq = context.resonant_frequency;
}
port_ozone_pwm_set_duty(context.nowfreq, 5000);
port_ozone_pwm_start();
context.adjustedToTheProperPower = false;
} else if (event == TIME_EVENT) {
if (context.adjustedToTheProperPower) {
/**
* @brief
* ([expertpower+window,expertpower-window])
*/
port_ozone_pwm_set_duty(context.resonant_frequency, 5000);
port_ozone_pwm_start();
} else if (event == TIME_EVENT) {
float nowpower = mf_get_ozone_power();
if (nowpower < get_expect_power() - const_windonws || nowpower > get_expect_power() + const_windonws) {
context.adjustedToTheProperPower = false;
if (nowpower < get_expect_power()) {
context.changefreqdirection = true;
} else {
context.changefreqdirection = false;
}
}
} else {
/**
* @brief
*
*/
static uint32_t last_ticket = 0;
if (systicket_haspassedms(last_ticket) > 10) {
last_ticket = systicket_getms();
float power = mf_get_ozone_power();
if (context.changefreqdirection) {
float nowpower = mf_get_ozone_power();
if (nowpower < get_expect_power()) {
context.nowfreq += 100;
if (context.nowfreq > const_max_freq) context.nowfreq = const_max_freq;
printf("change freq to match power,freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
port_ozone_pwm_set_duty(context.nowfreq, 5000);
} else {
context.adjustedToTheProperPower = true;
}
} else {
float nowpower = mf_get_ozone_power();
if (nowpower > get_expect_power()) {
context.nowfreq -= 100;
if (context.nowfreq < context.resonant_frequency) context.nowfreq = context.resonant_frequency;
printf("change freq to match power,freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
port_ozone_pwm_set_duty(context.nowfreq, 5000);
} else {
context.adjustedToTheProperPower = true;
}
}
} else if (event == EXIT_STATE) {
port_ozone_pwm_stop();
}
} else if (event == EXIT_STATE) {
port_ozone_pwm_stop();
}
}
/**
* @brief
* 1.6W
*/
static state_machine_state_t* state_machine_process_event(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
/**
* @brief Start和Stop事件
*/
if (event == PRV_START_EVENT || event == PRV_STOP_EVENT) {
if (event == PRV_START_EVENT) {
printf("start\n");
return &m_states[kBeforeWorkingStateSweepFrequency];
} else {
printf("stop\n");
return &m_states[kIdleState];
}
}
/**
* @brief
*/
if /* */ (nowstate == &m_states[kIdleState]) {
} else if (nowstate == &m_states[kBeforeWorkingStateSweepFrequency]) {
return processBeforeWorkingStateSweepFrequency(machine, nowstate, event);
} else if (nowstate == &m_states[kWorkingState]) {
return processWorkingState(machine, nowstate, event);
}
return NULL;
}
/***********************************************************************************************************************
* ======================================================Export======================================================= *
***********************************************************************************************************************/
void ozone_control_init() { state_machine_init(&m_statemachine, m_states, ZARR_SIZE(m_states), state_machine_process_event); }
void ozone_control_start() { state_machine_trigger_event(&m_statemachine, PRV_START_EVENT); }
void ozone_control_stop() { state_machine_trigger_event(&m_statemachine, PRV_STOP_EVENT); }
void ozone_control_schedule() {
static uint32_t ticket = 0;
if (systicket_haspassedms(&ticket) > 10 * 1000) {
ticket = systicket_get_now_ms();
state_machine_schedule_each10ms(&m_statemachine);
}
}

39
APP/service/ozone_control_service.h

@ -4,47 +4,10 @@
#include "thisdevice.h"
typedef void (*ozone_onexception_cb_t)(error_t error);
typedef struct {
uint32_t minfreq; //
uint32_t maxfreq;
uint32_t stepfreq;
float level1_expect_power;
float level2_expect_power;
ozone_onexception_cb_t onexception;
} ozone_control_config_t;
void ozone_control_init(ozone_control_config_t *config);
void ozone_control_set_level(level_t level);
void ozone_control_init();
void ozone_control_start();
void ozone_control_stop();
float ozone_control_get_power();
void ozone_control_schedule();
/**
*
* 1
*
*
* :
* (+/2),
* (-/2),
*
*
* :
*
*
* :
*
*
*
*
*
*
*/

5
APP/state_machine.c

@ -1,9 +1,10 @@
#include "state_machine.h"
void state_machine_init(state_machine_t* machine, state_machine_state_t* statetable, size_t len, state_machine_state_t* initstate) {
void state_machine_init(state_machine_t* machine, state_machine_state_t* statetable, size_t len, state_machine_process_event_t process_event) {
machine->states = statetable;
machine->nstate = len;
machine->nowstate = initstate;
machine->nowstate = &statetable[0];
machine->process_event = process_event;
}
void state_machine_trigger_event(state_machine_t* machine, int event) {
machine->nextstate = machine->process_event(machine, machine->nowstate, event);

66
APP/state_machine.h

@ -4,38 +4,66 @@
#include <stdint.h>
#include <stdlib.h>
typedef struct state_machine_state_s state_machine_state_t;
/**
* @brief
*
* @Usage:
*
*
*/
typedef struct state_machine_state_s state_machine_state_t;
typedef struct state_machine_s state_machine_t;
typedef state_machine_state_t* (*state_machine_process_event_t)(state_machine_t* machine, state_machine_state_t* nowstate, int event);
struct state_machine_state_s {
char const* name;
int stateId;
int duration; //
char const* name; // name
int stateId; // stateID
int duration; //
};
struct state_machine_s {
state_machine_state_t* states;
int nstate;
//
state_machine_state_t* nowstate;
state_machine_process_event_t process_event;
state_machine_state_t* nextstate;
state_machine_state_t* laststate;
state_machine_state_t* states; //
int nstate; //
state_machine_state_t* nowstate; //
state_machine_process_event_t process_event; //
state_machine_state_t* nextstate; //
state_machine_state_t* laststate; //
};
/**
* @brief
* 0->1000
*/
#define TIME_EVENT 0x01 //
#define ENTER_STATE 0x02 //
#define EXIT_STATE 0x03 //
#define TIME_EVENT 0x01 //
#define ENTER_STATE 0x02 //
#define EXIT_STATE 0x03 //
#define STATE_MACHINE_PUBLIC_EVENT 1000 //
void state_machine_init(state_machine_t* machine, state_machine_state_t* statetable, size_t len, state_machine_state_t* initstate);
/**
* @brief
*
* @param machine
* @param statetable
* @param len
*/
void state_machine_init(state_machine_t* machine, state_machine_state_t* statetable, size_t len, state_machine_process_event_t process_event);
/**
* @brief
*
* @param machine
* @param event
*/
void state_machine_trigger_event(state_machine_t* machine, int event);
/**
* @brief 10ms调用一次
*
* @param machine
*/
void state_machine_schedule_each10ms(state_machine_t* machine);
//
/**
* @brief
*
* @param state
* @return uint32_t
*/
uint32_t state_machine_get_state_duration_ms(state_machine_state_t* state);

2
zes8p5066lib

@ -1 +1 @@
Subproject commit c4335bae97be7e054c6ad318a1698a7bf60cc1d3
Subproject commit d42b02a3055c9ab99c917608797208790712524f
Loading…
Cancel
Save