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.

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