diff --git a/Core/Src/app.c b/Core/Src/app.c index 0378768..725d2f3 100644 --- a/Core/Src/app.c +++ b/Core/Src/app.c @@ -22,20 +22,23 @@ static volatile uint16_t adc_values[4]; const float V_REFINT = 1.23f; -#define AVERAGEBUF_DEPTH 32 +#define AVERAGEBUF_DEPTH 16 +#define OVENTEMP_HISTORY_DEPTH 10 static struct App { + bool heating; + int16_t set_temp; + int16_t wheel_normed; float oven_temp; float soc_temp; float v_sensor; -// float v_current_reference; -// float sensor_current; -// float r_sensor; uint16_t wheel; bool push; uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4]; uint8_t averagebuf_ptr; float adc_averages[4]; + float oventemp_history[OVENTEMP_HISTORY_DEPTH]; + uint8_t oventemp_history_ptr; } s_app = {}; #define TSENSE_LOOKUP_LEN 101 @@ -146,12 +149,13 @@ static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = { 0.223001998051553f, }; -static float val_to_c(float val){ +static float val_to_c(float val) +{ // TODO use binary search.. lol for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) { float cur = TSENSE_LOOKUP[i]; if (cur >= val) { - float prev = TSENSE_LOOKUP[i-1]; + float prev = TSENSE_LOOKUP[i - 1]; float ratio = (val - prev) / (cur - prev); return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP; @@ -160,7 +164,8 @@ static float val_to_c(float val){ return TSENSE_T_MAX; } -void calculate_analog_values() { +void calculate_analog_values() +{ uint32_t sums[4] = {}; for (int i = 0; i < AVERAGEBUF_DEPTH * 4; i += 4) { sums[0] += s_app.adc_averagebuf[i]; @@ -168,10 +173,10 @@ void calculate_analog_values() { sums[2] += s_app.adc_averagebuf[i + 2]; sums[3] += s_app.adc_averagebuf[i + 3]; } - s_app.adc_averages[0] = (float)sums[0] / AVERAGEBUF_DEPTH; - s_app.adc_averages[1] = (float)sums[1] / AVERAGEBUF_DEPTH; - s_app.adc_averages[2] = (float)sums[2] / AVERAGEBUF_DEPTH; - s_app.adc_averages[3] = (float)sums[3] / AVERAGEBUF_DEPTH; + s_app.adc_averages[0] = (float) sums[0] / AVERAGEBUF_DEPTH; + s_app.adc_averages[1] = (float) sums[1] / AVERAGEBUF_DEPTH; + s_app.adc_averages[2] = (float) sums[2] / AVERAGEBUF_DEPTH; + s_app.adc_averages[3] = (float) sums[3] / AVERAGEBUF_DEPTH; /* r_pt100, r_ref, internal_temp, v_ref_int */ float refint = s_app.adc_averages[3]; @@ -184,15 +189,26 @@ void calculate_analog_values() { s_app.soc_temp = (v25 - v_tsen) / avg_slope + 25.f; s_app.v_sensor = s_app.adc_averages[0] * scale; // good for debug/tuning + // using a voltage divider, so assuming the reference resistor is measured well, // we can just use the ratio and the exact voltage value is not important. - s_app.oven_temp = val_to_c(s_app.adc_averages[0] / s_app.adc_averages[1]); + float actual_temp = val_to_c(s_app.adc_averages[0] / s_app.adc_averages[1]); + + s_app.oventemp_history[s_app.oventemp_history_ptr] = actual_temp; + s_app.oventemp_history_ptr = (s_app.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH; + + float sum = 0; + for (int i = 0; i < OVENTEMP_HISTORY_DEPTH; i++) { + sum += s_app.oventemp_history[i]; + } + sum /= OVENTEMP_HISTORY_DEPTH; + s_app.oven_temp = sum; } -void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { // notify - memcpy((void*) &s_app.adc_averagebuf[s_app.averagebuf_ptr * 4], (const void*) adc_values, 8); + memcpy((void *) &s_app.adc_averagebuf[s_app.averagebuf_ptr * 4], (const void *) adc_values, 8); s_app.averagebuf_ptr = (s_app.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH; } @@ -201,7 +217,7 @@ static void hw_init() HAL_ADCEx_Calibration_Start(&hadc1); /* Start periodic reading of the ADC channels */ - HAL_ADC_Start_DMA(&hadc1, (uint32_t*)(void*)adc_values, 4); + HAL_ADC_Start_DMA(&hadc1, (uint32_t *) (void *) adc_values, 4); /* Enable the rotary encoder */ HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); @@ -219,15 +235,8 @@ void app_main_task(void *argument) hw_init(); /* Infinite loop */ - bool invert = 0; - for(;;) - { - HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); - - s_app.wheel = htim4.Instance->CNT; - s_app.push = 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin); - - calculate_analog_values(); + for (;;) { + //HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // printf("Knob %d (P=%d), ADC %.2f %.2f %.2f %.2f, oven %.2f°C, soc %.2f°C, divider %.3f V \r\n", // (int) s_app.wheel, s_app.push, @@ -238,33 +247,69 @@ void app_main_task(void *argument) // s_app.v_sensor // ); - invert = !invert; + calculate_analog_values(); + + for (int i = 0; i < 50; i++) { + uint16_t old_wheel = s_app.wheel; + s_app.wheel = htim4.Instance->CNT; + + int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel); - fb_clear(); - if (s_app.push) { - fb_rect(s_app.wheel % FBW, 0, 15, 15, 1); - } else { - if (invert) { - fb_frame(s_app.wheel % FBW, 0, 15, 15, 2, 1); - } else { - fb_frame(s_app.wheel % FBW, 0, 15, 15, 1, 1); + if (wheel_change != 0) { + s_app.wheel_normed += wheel_change; + if (s_app.wheel_normed < 0) { + s_app.wheel_normed = 0; + } + if (s_app.wheel_normed > 500) { + s_app.wheel_normed = 500; + } + + s_app.set_temp = (s_app.wheel_normed / 2) * 5; + } + + s_app.push = 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin); + + if (wheel_change != 0 || i == 0) { + fb_clear(); + + char tmp[100]; + + sprintf(tmp, "Mereni: %d°C", (int) s_app.oven_temp); + fb_text(10, 10, tmp, 0, 1); + + sprintf(tmp, " Cil: %d°C", s_app.set_temp); + fb_text(10, 25, tmp, 0, 1); + + if (s_app.heating) { + fb_frame(0, 0, FBW, FBH, 2, 1); + } + + fb_blit(); } + + vTaskDelay(10); } - char tmp[100]; - sprintf(tmp, "%d°C", (int) s_app.oven_temp); + // regulation - fb_text(0, 20, tmp, 0, 1); + float set_f = (float) s_app.set_temp; - fb_blit(); + if (!s_app.heating && s_app.oven_temp < set_f - 5.0f) { /* hysteresis */ + s_app.heating = true; + } + if (s_app.heating && s_app.oven_temp >= set_f) { + s_app.heating = false; + } - vTaskDelay(100); + HAL_GPIO_WritePin(HEATER_GPIO_Port, HEATER_Pin, s_app.heating); + /* // beep htim2.Instance->ARR = 12000 + (int16_t)s_app.wheel * 100; htim2.Instance->CCR1 = htim2.Instance->ARR/2; vTaskDelay(50); htim2.Instance->ARR = 0; + */ // feed dogs HAL_IWDG_Refresh(&hiwdg); diff --git a/Makefile b/Makefile index 9c165b5..0749da0 100644 --- a/Makefile +++ b/Makefile @@ -154,7 +154,7 @@ C_INCLUDES = \ # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections +CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Wextra -fdata-sections -ffunction-sections ifeq ($(DEBUG), 1) CFLAGS += -g -gdwarf-2