esp32 firmware for a toaster reflow oven WIP!!!!!

firehazard.c 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "firehazard.h"
  2. #include "arduinopid.h"
  3. #include <stdio.h>
  4. #include <stdbool.h>
  5. #include <math.h>
  6. #include <esp_log.h>
  7. #include <nvs.h>
  8. #include "driver/ledc.h"
  9. #include "esp_err.h"
  10. static const char *TAG = "fire";
  11. static struct PID pid = PID_DEFAULT();
  12. static void pwm_init(void);
  13. static void pwm_set(float duty);
  14. void fire_get_tuning(float *kp, float *ki, float *kd) {
  15. *kp = pid.kp;
  16. *ki = pid.ki;
  17. *kd = pid.kd;
  18. }
  19. void fire_init() {
  20. printf("Regulator init");
  21. PID_Initialize(&pid);
  22. PID_SetOutputLimits(&pid, 0, 1);
  23. PID_SetCtlMode(&pid, PID_MANUAL);
  24. PID_SetTunings(&pid, 0.3, 0.01, 0.1); // TODO load from nvs
  25. pwm_init();
  26. fire_setlevel(20);
  27. // fire_enable(true);
  28. }
  29. void fire_set_tuning(float kp, float ki, float kd) {
  30. ESP_LOGI(TAG, "PID set tuning Kp=%.3f, Ki=%.3f, Kd=%.3f", kp, ki, kd);
  31. PID_SetTunings(&pid, kp, ki, kd);
  32. }
  33. float fire_get_setpoint(bool off_is_zero) {
  34. if (off_is_zero) {
  35. return pid.ctlMode == PID_MANUAL ? 0 : pid.Setpoint;
  36. } else {
  37. return pid.Setpoint;
  38. }
  39. }
  40. void fire_setlevel(float cels) {
  41. ESP_LOGI(TAG, "PID set target %.3f°C", cels);
  42. if (cels < 0) cels = 0;
  43. if (cels > MAX_SETPOINT) cels = MAX_SETPOINT;
  44. PID_SetSetpoint(&pid, cels);
  45. }
  46. void fire_enable(bool enable) {
  47. ESP_LOGI(TAG, "Heater %s", enable ? "enable" : "disable");
  48. PID_SetCtlMode(&pid, enable ? PID_AUTOMATIC : PID_MANUAL);
  49. }
  50. bool fire_enabled() {
  51. return pid.ctlMode == PID_AUTOMATIC;
  52. }
  53. void fire_regulate(float cels) {
  54. PID_Compute(&pid, cels);
  55. if (cels > MAX_TSENSE || cels < MIN_TSENSE) {
  56. ESP_LOGE(TAG, "Tsense out of bounds! Stopping.");
  57. fire_enable(false);
  58. }
  59. if (pid.ctlMode == PID_MANUAL) {
  60. pwm_set(0);
  61. } else {
  62. printf("PID in %.2f°C, out %.3f, I %.3f\n", cels, pid.Output, pid.ITerm);
  63. pwm_set(pid.Output);
  64. }
  65. }
  66. #define PWM_CHANNEL LEDC_CHANNEL_1
  67. #define PWM_TIMER LEDC_TIMER_1
  68. #define PWM_BIT_NUM LEDC_TIMER_12_BIT
  69. #define PWM_PIN GPIO_NUM_14
  70. static void pwm_init(void)
  71. {
  72. ledc_channel_config_t ledc_channel_left = {0};
  73. ledc_channel_left.gpio_num = PWM_PIN;
  74. ledc_channel_left.speed_mode = LEDC_HIGH_SPEED_MODE;
  75. ledc_channel_left.channel = PWM_CHANNEL;
  76. ledc_channel_left.intr_type = LEDC_INTR_DISABLE;
  77. ledc_channel_left.timer_sel = PWM_TIMER;
  78. ledc_channel_left.duty = 0;
  79. ledc_timer_config_t ledc_timer = {0};
  80. ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
  81. ledc_timer.duty_resolution = PWM_BIT_NUM;
  82. ledc_timer.timer_num = PWM_TIMER;
  83. ledc_timer.freq_hz = 1; // TODO ??
  84. ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_left) );
  85. ESP_ERROR_CHECK( ledc_timer_config(&ledc_timer) );
  86. }
  87. static void pwm_set(float duty)
  88. {
  89. uint32_t max_duty = (1 << PWM_BIT_NUM);// - 1
  90. uint32_t dutycycle = lroundf((duty) * (float)max_duty);
  91. printf("Dutycycle %d\n", dutycycle);
  92. ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL, dutycycle) );
  93. ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL) );
  94. }