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.

222 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
  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. float resonant_frequency; //谐振频率点
  17. float 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_done()) {
  99. context.resonant_frequency = get_resonant_frequency(25000, 100, 35000);
  100. printf("----------Summarize--------\n");
  101. printf("-resonant_frequency: %f\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. }
  109. static state_machine_state_t* processWorkingState(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
  110. /**
  111. * @brief
  112. *
  113. * ([expertpower+window,expertpower-window])
  114. *
  115. */
  116. if (event == ENTER_STATE) {
  117. /**
  118. * @brief
  119. */
  120. if (context.nowfreq < context.resonant_frequency) {
  121. context.nowfreq = context.resonant_frequency;
  122. }
  123. port_ozone_pwm_set_duty(context.nowfreq, 5000);
  124. port_ozone_pwm_start();
  125. context.adjustedToTheProperPower = false;
  126. } else if (event == TIME_EVENT) {
  127. if (context.adjustedToTheProperPower) {
  128. /**
  129. * ([expertpower+window,expertpower-window])
  130. */
  131. float nowpower = mf_get_ozone_power();
  132. if (nowpower < get_expect_power() - const_windonws || nowpower > get_expect_power() + const_windonws) {
  133. context.adjustedToTheProperPower = false;
  134. if (nowpower < get_expect_power()) {
  135. context.changefreqdirection = true;
  136. } else {
  137. context.changefreqdirection = false;
  138. }
  139. }
  140. } else {
  141. /**
  142. *
  143. */
  144. if (context.changefreqdirection) {
  145. float nowpower = mf_get_ozone_power();
  146. if (nowpower < get_expect_power()) {
  147. context.nowfreq += 100;
  148. if (context.nowfreq > const_max_freq) context.nowfreq = const_max_freq;
  149. printf("change freq to match power,freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
  150. port_ozone_pwm_set_duty(context.nowfreq, 5000);
  151. } else {
  152. context.adjustedToTheProperPower = true;
  153. }
  154. } else {
  155. float nowpower = mf_get_ozone_power();
  156. if (nowpower > get_expect_power()) {
  157. context.nowfreq -= 100;
  158. if (context.nowfreq < context.resonant_frequency) context.nowfreq = context.resonant_frequency;
  159. printf("change freq to match power,freq %d, power %f-->%f \n", context.nowfreq, nowpower, get_expect_power());
  160. port_ozone_pwm_set_duty(context.nowfreq, 5000);
  161. } else {
  162. context.adjustedToTheProperPower = true;
  163. }
  164. }
  165. }
  166. } else if (event == EXIT_STATE) {
  167. port_ozone_pwm_stop();
  168. }
  169. }
  170. static state_machine_state_t* state_machine_process_event(state_machine_t* machine, state_machine_state_t* nowstate, int event) {
  171. /**
  172. * @brief Start和Stop事件
  173. */
  174. if (event == PRV_START_EVENT || event == PRV_STOP_EVENT) {
  175. if (event == PRV_START_EVENT) {
  176. printf("start\n");
  177. return &m_states[kBeforeWorkingStateSweepFrequency];
  178. } else {
  179. printf("stop\n");
  180. return &m_states[kIdleState];
  181. }
  182. }
  183. /**
  184. * @brief
  185. */
  186. if /* */ (nowstate == &m_states[kIdleState]) {
  187. } else if (nowstate == &m_states[kBeforeWorkingStateSweepFrequency]) {
  188. return processBeforeWorkingStateSweepFrequency(machine, nowstate, event);
  189. } else if (nowstate == &m_states[kWorkingState]) {
  190. return processWorkingState(machine, nowstate, event);
  191. }
  192. return NULL;
  193. }
  194. /***********************************************************************************************************************
  195. * ======================================================Export======================================================= *
  196. ***********************************************************************************************************************/
  197. void ozone_control_init() { state_machine_init(&m_statemachine, m_states, ZARR_SIZE(m_states), state_machine_process_event); }
  198. void ozone_control_start() { state_machine_trigger_event(&m_statemachine, PRV_START_EVENT); }
  199. void ozone_control_stop() { state_machine_trigger_event(&m_statemachine, PRV_STOP_EVENT); }
  200. void ozone_control_schedule() {
  201. static uint32_t ticket = 0;
  202. if (systicket_haspassedms(&ticket) > 10 * 1000) {
  203. ticket = systicket_get_now_ms();
  204. state_machine_schedule_each10ms(&m_statemachine);
  205. }
  206. }