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.

235 lines
8.0 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
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 "ozone_control_service.h"
  2. #include "../zes8p5066lib/basic.h"
  3. #include "../zes8p5066lib/systicket.h"
  4. #include "frequency_sweep_service.h"
  5. #include "kalmanFilter.h"
  6. #include "state_machine.h"
  7. /**
  8. * @brief
  9. *
  10. * :
  11. * ------> ---->
  12. *
  13. **/
  14. #define PRV_START_EVENT (STATE_MACHINE_PUBLIC_EVENT + 1)
  15. #define PRV_STOP_EVENT (STATE_MACHINE_PUBLIC_EVENT + 2)
  16. typedef struct {
  17. uint16_t resonant_frequency; //谐振频率点
  18. uint16_t nowfreq; //当前频率
  19. bool changefreqdirection; //频率调整方向,如果当前功率大于期望功率,则减少频率,反之亦然
  20. bool adjustedToTheProperPower; //是否已经调整到恰当的功率
  21. } Context_t;
  22. typedef enum {
  23. kIdleState,
  24. kBeforeWorkingStateSweepFrequency,
  25. kWorkingState,
  26. } StateId_t;
  27. state_machine_state_t m_states[] = {
  28. [kIdleState] =
  29. {
  30. .name = "kIdleState",
  31. .stateId = kIdleState,
  32. },
  33. [kBeforeWorkingStateSweepFrequency] =
  34. {
  35. .name = "kBeforeWorkingStateSweepFrequency",
  36. .stateId = kBeforeWorkingStateSweepFrequency,
  37. },
  38. [kWorkingState] = //
  39. {
  40. .name = "kWorkingState",
  41. .stateId = kWorkingState,
  42. }
  43. //
  44. };
  45. state_machine_t m_statemachine;
  46. static Context_t context;
  47. const static float const_windonws = 0.3;
  48. const static float const_level1_expect_power = 3.0;
  49. const static float const_level2_expect_power = 5.0;
  50. const static float const_max_freq = 38000;
  51. static uint16_t get_resonant_frequency(uint16_t startfreq, uint16_t step, uint16_t endfreq) {
  52. /**
  53. * @brief
  54. * ,
  55. *
  56. * http://192.168.1.3:3000/project_ozone_generator/doc/src/branch/master/ref/20220815频率-功率关系图.png
  57. */
  58. float minpower = 0;
  59. uint16_t retfreq = 0;
  60. bool inited = false;
  61. for (uint16_t freq = startfreq; freq <= endfreq; freq += step) {
  62. float power = frequency_sweep_get_power(freq);
  63. if (!inited) {
  64. minpower = power;
  65. retfreq = freq;
  66. inited = true;
  67. continue;
  68. }
  69. if (power < minpower) {
  70. minpower = power;
  71. retfreq = freq;
  72. }
  73. }
  74. return retfreq;
  75. }
  76. static KFP KFPConfig = KALMAN_FILTER_PARA;
  77. static float __mf_get_ozone_power() {
  78. float powersum = 0;
  79. for (size_t i = 0; i < 10; i++) {
  80. powersum += port_adc_get_ozone_generator_power();
  81. }
  82. return powersum / 10;
  83. }
  84. static void mf_get_ozone_power_reset_filter() { KFPConfig.LastP = __mf_get_ozone_power(); }
  85. static float mf_get_ozone_power() { return kalmanFilter(&KFPConfig, __mf_get_ozone_power()); }
  86. float get_expect_power() {
  87. float expectpower = 0;
  88. if (thisDevice.level == klevel1) {
  89. expectpower = const_level1_expect_power;
  90. } else if (thisDevice.level == klevel2) {
  91. expectpower = const_level2_expect_power;
  92. }
  93. return expectpower;
  94. }
  95. static state_machine_state_t* processBeforeWorkingStateSweepFrequency(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
  96. /**
  97. * @brief
  98. */
  99. if (event == ENTER_STATE) {
  100. frequency_sweep_start(20000, 100, 40000, 3000);
  101. } else if (event == TIME_EVENT) {
  102. if (frequency_sweep_is_finished()) {
  103. context.resonant_frequency = get_resonant_frequency(25000, 100, 35000);
  104. printf("----------Summarize--------\n");
  105. printf("-resonant_frequency: %d\n", context.resonant_frequency);
  106. context.nowfreq = context.resonant_frequency;
  107. return &m_states[kWorkingState];
  108. }
  109. } else if (event == EXIT_STATE) {
  110. frequency_sweep_stop();
  111. }
  112. return NULL;
  113. }
  114. static state_machine_state_t* processWorkingState(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
  115. /**
  116. * @brief
  117. *
  118. * ([expertpower+window,expertpower-window])
  119. *
  120. */
  121. if (event == ENTER_STATE) {
  122. /**
  123. * @brief
  124. */
  125. if (context.nowfreq < context.resonant_frequency) {
  126. context.nowfreq = context.resonant_frequency;
  127. }
  128. port_ozone_pwm_set_duty(context.nowfreq, 5000);
  129. port_ozone_pwm_start();
  130. context.adjustedToTheProperPower = false;
  131. mf_get_ozone_power_reset_filter();
  132. printf("----------start working--------\n");
  133. } else if (event == TIME_EVENT) {
  134. if (context.adjustedToTheProperPower) {
  135. /**
  136. * ([expertpower+window,expertpower-window])
  137. */
  138. float nowpower = mf_get_ozone_power();
  139. if (nowpower < (get_expect_power() - const_windonws) || //
  140. nowpower > (get_expect_power() + const_windonws)) {
  141. context.adjustedToTheProperPower = false;
  142. if (nowpower < get_expect_power()) {
  143. context.changefreqdirection = true;
  144. } else {
  145. context.changefreqdirection = false;
  146. }
  147. }
  148. } else {
  149. /**
  150. *
  151. */
  152. if (context.changefreqdirection) {
  153. float nowpower = mf_get_ozone_power();
  154. if (nowpower < get_expect_power()) {
  155. context.nowfreq += 25;
  156. if (context.nowfreq > const_max_freq) context.nowfreq = const_max_freq;
  157. printf("change freq [ up ],freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
  158. port_ozone_pwm_set_duty(context.nowfreq, kconst_pwm_work_dutyns);
  159. } else {
  160. // printf("reach %f->%f\n", nowpower, get_expect_power());
  161. context.adjustedToTheProperPower = true;
  162. }
  163. } else {
  164. float nowpower = mf_get_ozone_power();
  165. if (nowpower > get_expect_power()) {
  166. context.nowfreq -= 25;
  167. if (context.nowfreq < context.resonant_frequency) context.nowfreq = context.resonant_frequency;
  168. printf("change freq [down],freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
  169. port_ozone_pwm_set_duty(context.nowfreq, kconst_pwm_work_dutyns);
  170. } else {
  171. // printf("reach %f->%f\n", nowpower, get_expect_power());
  172. context.adjustedToTheProperPower = true;
  173. }
  174. }
  175. }
  176. } else if (event == EXIT_STATE) {
  177. port_ozone_pwm_stop();
  178. }
  179. return NULL;
  180. }
  181. static state_machine_state_t* state_machine_process_event(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
  182. /**
  183. * @brief Start和Stop事件
  184. */
  185. if (event == PRV_START_EVENT || event == PRV_STOP_EVENT) {
  186. if (event == PRV_START_EVENT) {
  187. printf("start\n");
  188. return &m_states[kBeforeWorkingStateSweepFrequency];
  189. } else {
  190. printf("stop\n");
  191. return &m_states[kIdleState];
  192. }
  193. }
  194. /**
  195. * @brief
  196. */
  197. if /* */ (nowstate == &m_states[kIdleState]) {
  198. } else if (nowstate == &m_states[kBeforeWorkingStateSweepFrequency]) {
  199. return processBeforeWorkingStateSweepFrequency(machine, nowstate, event);
  200. } else if (nowstate == &m_states[kWorkingState]) {
  201. return processWorkingState(machine, nowstate, event);
  202. }
  203. return NULL;
  204. }
  205. /***********************************************************************************************************************
  206. * ======================================================Export======================================================= *
  207. ***********************************************************************************************************************/
  208. void ozone_control_init() { state_machine_init(&m_statemachine, m_states, ZARR_SIZE(m_states), state_machine_process_event); }
  209. void ozone_control_start() { state_machine_trigger_event(&m_statemachine, PRV_START_EVENT); }
  210. void ozone_control_stop() { state_machine_trigger_event(&m_statemachine, PRV_STOP_EVENT); }
  211. void ozone_control_schedule() {
  212. static uint32_t ticket = 0;
  213. if (systicket_haspassedms(ticket) > 10) {
  214. ticket = systicket_get_now_ms();
  215. state_machine_schedule_each10ms(&m_statemachine);
  216. }
  217. frequency_sweep_schedule();
  218. }