mostly working PID now

fake-chip
Ondřej Hruška 1 year ago
parent 38139e3923
commit a7749c08ef
  1. 10
      BluepillTrouba.ioc
  2. 114
      Core/Src/app.c
  3. 19
      Core/Src/app_analog.h
  4. 25
      Core/Src/app_buzzer.c
  5. 12
      Core/Src/app_gui.c
  6. 10
      Core/Src/app_gui.h
  7. 111
      Core/Src/app_heater.c
  8. 16
      Core/Src/app_heater.h
  9. 5
      Core/Src/app_knob.c
  10. 1
      Core/Src/app_knob.h
  11. 122
      Core/Src/app_main.c
  12. 61
      Core/Src/app_pid.c
  13. 16
      Core/Src/app_pid.h
  14. 46
      Core/Src/app_temp.c
  15. 27
      Core/Src/app_temp.h
  16. 115
      Core/Src/freertos.c
  17. 2
      Core/Src/tim.c
  18. 7
      Makefile

@ -27,8 +27,12 @@ Dma.ADC1.0.Priority=DMA_PRIORITY_MEDIUM
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.Request0=ADC1
Dma.RequestsNb=1
FREERTOS.IPParameters=Tasks01,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configUSE_NEWLIB_REENTRANT
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configUSE_NEWLIB_REENTRANT,FootprintOK,Mutexes01,Queues01,Timers01
FREERTOS.Mutexes01=heaterMutex,Static,heaterMutexControlBlock
FREERTOS.Queues01=guiEventQue,16,8,1,Static,guiEventQueBuffer,guiEventQueControlBlock
FREERTOS.Tasks01=mainTsk,24,128,app_task_main,As weak,NULL,Static,defaultTaskBuffer,defaultTaskControlBlock;heaterTsk,24,128,app_task_heater,As external,NULL,Static,heaterTskBuffer,heaterTskControlBlock;guiTsk,40,128,app_task_gui,As external,NULL,Static,guiTskBuffer,guiTskControlBlock
FREERTOS.Timers01=beepTimer,app_beep_end,osTimerOnce,As external,NULL,Static,beepTimerControlBlock
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
FREERTOS.configUSE_NEWLIB_REENTRANT=1
@ -236,7 +240,7 @@ TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Pulse-PWM Generation1 CH1,Period
TIM3.Period=64000
TIM3.Prescaler=2000
TIM3.Pulse-PWM\ Generation1\ CH1=32000
TIM3.Pulse-PWM\ Generation1\ CH1=0
TIM4.IC2Filter=15
TIM4.IPParameters=IC2Filter,Prescaler
TIM4.Prescaler=0

@ -1,114 +0,0 @@
/**
* Main task
*/
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "app.h"
#include "ufb/framebuffer.h"
#include "iwdg.h"
#include "oled.h"
#include "ufb/fb_text.h"
#include "app_analog.h"
#include "app_knob.h"
#include "app_buzzer.h"
#include "app_heater.h"
static struct App {
float oven_temp;
int16_t set_temp;
int16_t wheel_normed;
uint16_t wheel;
bool heating;
} s_app = {};
static void hw_init()
{
app_analog_init();
app_buzzer_init();
app_heater_init();
app_knob_init();
/* Prepare the framebuffer and OLED interface */
oled_init();
fb_clear();
}
void app_main_task(void *argument)
{
hw_init();
/* Infinite loop */
for (;;) {
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
s_app.oven_temp = app_analog_get_temp();
for (int i = 0; i < 50; i++) {
uint16_t old_wheel = s_app.wheel;
s_app.wheel = app_knob_get_raw();
int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel);
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;
}
int16_t old_temp = s_app.set_temp;
s_app.set_temp = (s_app.wheel_normed / 2) * 5;
if (old_temp != s_app.set_temp) {
app_buzzer_beep();
}
}
//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);
}
// regulation
float set_f = (float) s_app.set_temp;
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;
}
app_heater_set(s_app.heating);
// feed dogs
HAL_IWDG_Refresh(&hiwdg);
}
}

@ -1,19 +0,0 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_APP_ANALOG_H
#define BLUEPILLTROUBA_APP_ANALOG_H
void app_analog_init();
/**
* Get current oven temp.
*
* A slow float calculation is done here - call only when needed, at a roughly constant rate (e.g. 1s) to make smoothing work properly.
*
* @return the value in celsius
*/
float app_analog_get_temp();
#endif //BLUEPILLTROUBA_APP_ANALOG_H

@ -6,20 +6,35 @@
#include "app_buzzer.h"
#include "tim.h"
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os2.h"
#include "timers.h"
extern osTimerId_t beepTimerHandle;
//void app_beep_end(void *argument);
//static TimerHandle_t s_timer;
void app_buzzer_init()
{
/* Enable buzzer PWM */
TIM2->CCR1 = 0;
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
// s_timer = xTimerCreate("beep", 50, 0, NULL, app_beep_end);
}
void app_buzzer_beep() {
// TODO make this non-blocking
TIM2->ARR = 25714;
TIM2->CCR1 = TIM2->ARR/2;
vTaskDelay(50);
osTimerStop(beepTimerHandle);
osTimerStart(beepTimerHandle, pdMS_TO_TICKS(10));
// xTimerStart(s_timer, pdMS_TO_TICKS(1000));
}
void app_beep_end(TimerHandle_t timerHandle) {
TIM2->CCR1 = 0;
vTaskDelay(50);
}

@ -0,0 +1,12 @@
/**
* TODO file description
*/
#include "app_gui.h"
#include "cmsis_os2.h"
void app_task_gui(void *argument) {
while (1) {
osDelay(1000);
}
}

@ -0,0 +1,10 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_APP_GUI_H
#define BLUEPILLTROUBA_APP_GUI_H
void app_task_gui(void *argument);
#endif //BLUEPILLTROUBA_APP_GUI_H

@ -1,23 +1,114 @@
/**
* TODO file description
*/
#include <stdio.h>
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "app_temp.h"
#include "app_pid.h"
#include "app_heater.h"
#include "cmsis_os2.h"
#include "tim.h"
void app_heater_init()
extern osMutexId_t heaterMutexHandle;
static void heater_pwm_init()
{
HAL_TIM_Base_Start(&htim3);
htim3.Instance->CCR1 = 0; // OFF
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
}
static void heater_pwm_set_perc(float perc)
{
uint16_t perc_u = (uint16_t) perc;
if (perc_u > 100) {
perc_u = 100;
}
// (TIM3->ARR / 100)
TIM3->CCR1 = 640 * perc_u;
}
static struct {
float oven_temp;
float soc_temp;
// these will be loaded from flash and stored back
float tuning_p;
float tuning_i;
float tuning_d;
// PID state
struct PID pid;
} state = {
.tuning_p = 10.0f,
.tuning_i = 0.052f,
.tuning_d = 100.0f,
.pid = {
.SampleTimeTicks = pdMS_TO_TICKS(1000),
.outMax = 100.0f,
.outMin = 0.0f,
.ctlMode = PID_MANUAL,
.controllerDirection = PID_DIRECT,
},
};
static inline void heaterEnterCritical() {
osMutexAcquire(heaterMutexHandle, portMAX_DELAY);
}
static inline void heaterExitCritical() {
osMutexRelease(heaterMutexHandle);
}
void app_heater_set_tuning(float p, float i, float d) {
heaterEnterCritical();
PID_SetTunings(&state.pid, p, i, d);
heaterExitCritical();
}
void app_heater_enable(bool enable) {
printf("Set heater enabled = %d\r\n", (int) enable);
heaterEnterCritical();
PID_SetCtlMode(&state.pid, enable ? PID_AUTOMATIC : PID_MANUAL);
heaterExitCritical();
}
void app_heater_set_target(float target) {
printf("Set heater target = %d\r\n", (int) target);
heaterEnterCritical();
PID_SetSetpoint(&state.pid, target);
heaterExitCritical();
}
void app_heater_set(bool active)
void app_task_heater(void *argument)
{
if (active) {
TIM3->CCR1 = TIM3->ARR / 2; // testing - 50%
} else {
TIM3->CCR1 = 0;
heater_pwm_init();
heaterEnterCritical();
// TODO load from flash
PID_SetTunings(&state.pid, state.tuning_p, state.tuning_i, state.tuning_d);
PID_Initialize(&state.pid);
heaterExitCritical();
uint32_t wake_time = xTaskGetTickCount();
while (1) {
app_temp_sample();
state.oven_temp = app_temp_read_oven();
state.soc_temp = app_temp_read_soc();
heaterEnterCritical();
PID_Compute(&state.pid, state.oven_temp);
if (state.pid.ctlMode == PID_AUTOMATIC) {
printf("temp %d, output %d\r\n", (int) state.oven_temp, (int) state.pid.Output);
heater_pwm_set_perc(state.pid.Output);
} else {
// turn it off
heater_pwm_set_perc(0);
}
heaterExitCritical();
// TODO notify UI thread of the new temperature and heating percent
vTaskDelayUntil(&wake_time, pdMS_TO_TICKS(500));
}
}

@ -1,5 +1,5 @@
/**
* TODO file description
* Heater PWM control & regulation + temp sensing loop
*/
#ifndef BLUEPILLTROUBA_APP_HEATER_H
@ -7,8 +7,18 @@
#include <stdbool.h>
void app_heater_init();
void app_task_heater(void *argument);
void app_heater_set(bool active);
/// Set heater regulator tuning.
/// Mutex is locked internally.
void app_heater_set_tuning(float p, float i, float d);
/// Set heater on/off.
/// Mutex is locked internally.
void app_heater_enable(bool enable);
/// Set heater setpoint
/// Mutex is locked internally.
void app_heater_set_target(float target);
#endif //BLUEPILLTROUBA_APP_HEATER_H

@ -21,3 +21,8 @@ void app_knob_init()
uint16_t app_knob_get_raw() {
return htim4.Instance->CNT;
}
bool app_knob_pushed() {
return 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
}

@ -8,5 +8,6 @@
void app_knob_init();
uint16_t app_knob_get_raw();
bool app_knob_pushed();
#endif //BLUEPILLTROUBA_APP_KNOB_H

@ -0,0 +1,122 @@
/**
* Main task
*/
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "app.h"
#include "ufb/framebuffer.h"
#include "iwdg.h"
#include "oled.h"
#include "ufb/fb_text.h"
#include "app_temp.h"
#include "app_knob.h"
#include "app_buzzer.h"
#include "app_heater.h"
#include "cmsis_os2.h"
static struct App {
float oven_temp;
int16_t set_temp;
int16_t wheel_normed;
uint16_t wheel;
bool run;
} s_app = {};
static void redraw_display() {
fb_clear();
char tmp[100];
sprintf(tmp, "Mereni: %d°C", (int) s_app.oven_temp);
fb_text(10, 5, tmp, 0, 1);
sprintf(tmp, " Cil: %d°C", s_app.set_temp);
fb_text(10, 20, tmp, 0, 1);
sprintf(tmp, " Stav: %s", s_app.run ? "ZAP" : "VYP");
fb_text(10, 35, tmp, 0, 1);
if (s_app.run) {
fb_frame(0, 0, FBW, FBH, 2, 1);
}
fb_blit();
}
void app_task_main(void *argument)
{
app_analog_init();
app_buzzer_init();
app_knob_init();
/* Prepare the framebuffer and OLED interface */
oled_init();
fb_clear();
/* Infinite loop */
bool old_pushed = app_knob_pushed();
bool any_change = true;
uint32_t last_redraw = osKernelGetTickCount();
for (;;) {
// sampling is done in the heater loop
s_app.oven_temp = app_temp_read_oven();
uint16_t old_wheel = s_app.wheel;
s_app.wheel = app_knob_get_raw();
// TODO do this with interrupt and/or debouncing
bool pushed = app_knob_pushed();
if (pushed && !old_pushed) {
s_app.run ^= 1;
app_heater_enable(s_app.run);
app_buzzer_beep();
any_change = true;
}
old_pushed = pushed;
int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel);
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;
}
int16_t old_temp = s_app.set_temp;
s_app.set_temp = (s_app.wheel_normed / 2) * 5;
if (old_temp != s_app.set_temp) {
app_buzzer_beep();
app_heater_set_target((float) s_app.set_temp);
any_change = true;
}
}
uint32_t now = osKernelGetTickCount();
if (any_change || (now - last_redraw > pdMS_TO_TICKS(500))) {
last_redraw = now;
redraw_display();
any_change = false;
// Blink
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
vTaskDelay(pdMS_TO_TICKS(10));
// feed dogs
HAL_IWDG_Refresh(&hiwdg);
}
}

@ -3,6 +3,7 @@
#include <stdint.h>
#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
static void clampOutput(struct PID *self)
{
@ -16,21 +17,29 @@ static void clampIterm(struct PID *self)
else if (self->ITerm < self->outMin) { self->ITerm = self->outMin; }
}
void PID_Compute(struct PID *self, float Input)
void PID_Compute(struct PID *self, float input)
{
if (!self->ctlMode) { return; }
self->Input = Input;
if (self->ctlMode != PID_AUTOMATIC) { return; }
self->Input = input;
uint32_t now = xTaskGetTickCount();
int32_t timeChange = (now - self->lastTime) * (uint32_t) 1000 / (uint32_t) configTICK_RATE_HZ;
if (timeChange >= self->SampleTime) {
int32_t timeChange = (now - self->lastTime);
if (timeChange >= self->SampleTimeTicks) {
printf("compute\r\n");
/*Compute all the working error variables*/
float error = self->Setpoint - Input;
float error = self->Setpoint - input;
self->ITerm += (self->ki * error);
clampIterm(self);
float dInput = (Input - self->lastInput);
float dInput = (input - self->lastInput);
printf("calc x100 %d + %d - %d\r\n",
(int) (100 * (self->kp * error)),
(int) (100 * (self->ITerm)),
(int) (100 * (self->kd * dInput))
);
/*Compute PID Output*/
self->Output = self->kp * error + self->ITerm - self->kd * dInput;
@ -38,21 +47,21 @@ void PID_Compute(struct PID *self, float Input)
clampOutput(self);
/*Remember some variables for next time*/
self->lastInput = Input;
self->lastInput = input;
self->lastTime = now;
}
}
void PID_SetSetpoint(struct PID *self, float Setpoint)
void PID_SetSetpoint(struct PID *self, float setpoint)
{
self->Setpoint = Setpoint;
self->Setpoint = setpoint;
}
void PID_SetTunings(struct PID *self, float Kp, float Ki, float Kd)
{
if (Kp < 0 || Ki < 0 || Kd < 0) { return; }
float SampleTimeInSec = ((float) self->SampleTime) / 1000;
float SampleTimeInSec = ((float) self->SampleTimeTicks) / configTICK_RATE_HZ;
self->kp = Kp;
self->ki = Ki * SampleTimeInSec;
self->kd = Kd / SampleTimeInSec;
@ -64,34 +73,34 @@ void PID_SetTunings(struct PID *self, float Kp, float Ki, float Kd)
}
}
void PID_SetSampleTime(struct PID *self, uint32_t NewSampleTime)
void PID_SetSampleTime(struct PID *self, uint32_t new_sample_time)
{
if (NewSampleTime > 0) {
float ratio = (float) NewSampleTime
/ (float) self->SampleTime;
if (new_sample_time > 0) {
float ratio = (float) new_sample_time
/ (float) self->SampleTimeTicks;
self->ki *= ratio;
self->kd /= ratio;
self->SampleTime = (uint32_t) NewSampleTime;
self->SampleTimeTicks = (uint32_t) new_sample_time;
}
}
void PID_SetOutputLimits(struct PID *self, float Min, float Max)
void PID_SetOutputLimits(struct PID *self, float min, float max)
{
if (Min > Max) { return; }
self->outMin = Min;
self->outMax = Max;
if (min > max) { return; }
self->outMin = min;
self->outMax = max;
clampOutput(self);
clampIterm(self);
}
void PID_SetCtlMode(struct PID *self, enum PIDCtlMode Mode)
void PID_SetCtlMode(struct PID *self, enum PIDCtlMode mode)
{
bool newAuto = (Mode == PID_AUTOMATIC);
if (newAuto == !self->ctlMode) { /*we just went from manual to auto*/
if (mode == PID_AUTOMATIC && self->ctlMode == PID_MANUAL) {
/*we just went from manual to auto*/
PID_Initialize(self);
}
self->ctlMode = newAuto;
self->ctlMode = mode;
}
void PID_Initialize(struct PID *self)
@ -102,7 +111,7 @@ void PID_Initialize(struct PID *self)
clampIterm(self);
}
void PID_SetControllerDirection(struct PID *self, enum PIDDirection Direction)
void PID_SetControllerDirection(struct PID *self, enum PIDDirection direction)
{
self->controllerDirection = Direction;
self->controllerDirection = direction;
}

@ -25,28 +25,28 @@ struct PID {
float Input, Output, Setpoint;
float ITerm, lastInput;
float kp, ki, kd;
uint32_t SampleTime; // millis
uint32_t SampleTimeTicks;
float outMin, outMax;
enum PIDCtlMode ctlMode; // false
enum PIDDirection controllerDirection;
};
#define PID_DEFAULT() { .SampleTime = 1000, .ctlMode=PID_MANUAL, .controllerDirection=PID_DIRECT }
#define PID_DEFAULT() { .SampleTimeMs = 1000, .ctlMode=PID_MANUAL, .controllerDirection=PID_DIRECT }
void PID_Compute(struct PID *self, float Input);
void PID_Compute(struct PID *self, float input);
void PID_SetTunings(struct PID *self, float Kp, float Ki, float Kd);
void PID_SetSampleTime(struct PID *self, uint32_t NewSampleTime);
void PID_SetSampleTime(struct PID *self, uint32_t new_sample_time);
void PID_SetOutputLimits(struct PID *self, float Min, float Max);
void PID_SetOutputLimits(struct PID *self, float min, float max);
void PID_SetCtlMode(struct PID *self, enum PIDCtlMode Mode);
void PID_SetCtlMode(struct PID *self, enum PIDCtlMode mode);
void PID_Initialize(struct PID *self);
void PID_SetSetpoint(struct PID *self, float Setpoint);
void PID_SetSetpoint(struct PID *self, float setpoint);
void PID_SetControllerDirection(struct PID *self, enum PIDDirection Direction);
void PID_SetControllerDirection(struct PID *self, enum PIDDirection direction);
#endif //ARDUINOPID_H

@ -6,7 +6,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "app_analog.h"
#include "app_temp.h"
#include "adc.h"
/* DMA dest */
@ -159,19 +159,27 @@ static float val_to_c(float val)
return TSENSE_T_MAX;
}
float app_analog_get_temp()
void app_temp_sample()
{
uint32_t sums[4] = {};
int count = 0;
for (int i = 0; i < AVERAGEBUF_DEPTH * 4; i += 4) {
sums[0] += s_analog.adc_averagebuf[i];
sums[1] += s_analog.adc_averagebuf[i + 1];
sums[2] += s_analog.adc_averagebuf[i + 2];
sums[3] += s_analog.adc_averagebuf[i + 3];
if (s_analog.adc_averagebuf[i + 3] != 0) {
sums[0] += s_analog.adc_averagebuf[i];
sums[1] += s_analog.adc_averagebuf[i + 1];
sums[2] += s_analog.adc_averagebuf[i + 2];
sums[3] += s_analog.adc_averagebuf[i + 3];
count++;
}
}
if (count == 0) {
return;
}
s_analog.adc_averages[0] = (float) sums[0] / AVERAGEBUF_DEPTH;
s_analog.adc_averages[1] = (float) sums[1] / AVERAGEBUF_DEPTH;
s_analog.adc_averages[2] = (float) sums[2] / AVERAGEBUF_DEPTH;
s_analog.adc_averages[3] = (float) sums[3] / AVERAGEBUF_DEPTH;
s_analog.adc_averages[0] = (float) sums[0] / count;
s_analog.adc_averages[1] = (float) sums[1] / count;
s_analog.adc_averages[2] = (float) sums[2] / count;
s_analog.adc_averages[3] = (float) sums[3] / count;
/* r_pt100, r_ref, internal_temp, v_ref_int */
float refint = s_analog.adc_averages[3];
@ -193,15 +201,29 @@ float app_analog_get_temp()
s_analog.oventemp_history_ptr = (s_analog.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH;
float sum = 0;
int depth = 0;
for (int i = 0; i < OVENTEMP_HISTORY_DEPTH; i++) {
sum += s_analog.oventemp_history[i];
if (s_analog.oventemp_history[i] > 0.0f) {
sum += s_analog.oventemp_history[i];
depth++;
}
}
if (depth > 0) {
sum /= depth;
}
sum /= OVENTEMP_HISTORY_DEPTH;
s_analog.oven_temp = sum;
}
float app_temp_read_oven()
{
return s_analog.oven_temp;
}
float app_temp_read_soc()
{
return s_analog.soc_temp;
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
// notify

@ -0,0 +1,27 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_APP_TEMP_H
#define BLUEPILLTROUBA_APP_TEMP_H
void app_analog_init();
/**
* Update temperature measurement.
*
* A slow float calculation is done here - call only when needed, at a roughly constant rate (e.g. 1s) to make smoothing work properly.
*
* The oven temp is further averaged internally.
*/
void app_temp_sample();
/// Read current oven temperature (celsius)
/// The value is valid after calling app_temp_sample()
float app_temp_read_oven();
/// Read current SOC temperature (celsius)
/// The value is valid after calling app_temp_sample()
float app_temp_read_soc();
#endif //BLUEPILLTROUBA_APP_TEMP_H

@ -31,6 +31,10 @@
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
typedef StaticTask_t osStaticThreadDef_t;
typedef StaticQueue_t osStaticMessageQDef_t;
typedef StaticTimer_t osStaticTimerDef_t;
typedef StaticSemaphore_t osStaticMutexDef_t;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
@ -49,20 +53,79 @@
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
/* Definitions for mainTsk */
osThreadId_t mainTskHandle;
uint32_t defaultTaskBuffer[ 128 ];
osStaticThreadDef_t defaultTaskControlBlock;
const osThreadAttr_t mainTsk_attributes = {
.name = "mainTsk",
.cb_mem = &defaultTaskControlBlock,
.cb_size = sizeof(defaultTaskControlBlock),
.stack_mem = &defaultTaskBuffer[0],
.stack_size = sizeof(defaultTaskBuffer),
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for heaterTsk */
osThreadId_t heaterTskHandle;
uint32_t heaterTskBuffer[ 128 ];
osStaticThreadDef_t heaterTskControlBlock;
const osThreadAttr_t heaterTsk_attributes = {
.name = "heaterTsk",
.cb_mem = &heaterTskControlBlock,
.cb_size = sizeof(heaterTskControlBlock),
.stack_mem = &heaterTskBuffer[0],
.stack_size = sizeof(heaterTskBuffer),
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for guiTsk */
osThreadId_t guiTskHandle;
uint32_t guiTskBuffer[ 128 ];
osStaticThreadDef_t guiTskControlBlock;
const osThreadAttr_t guiTsk_attributes = {
.name = "guiTsk",
.cb_mem = &guiTskControlBlock,
.cb_size = sizeof(guiTskControlBlock),
.stack_mem = &guiTskBuffer[0],
.stack_size = sizeof(guiTskBuffer),
.priority = (osPriority_t) osPriorityHigh,
};
/* Definitions for guiEventQue */
osMessageQueueId_t guiEventQueHandle;
uint8_t guiEventQueBuffer[ 16 * 8 ];
osStaticMessageQDef_t guiEventQueControlBlock;
const osMessageQueueAttr_t guiEventQue_attributes = {
.name = "guiEventQue",
.cb_mem = &guiEventQueControlBlock,
.cb_size = sizeof(guiEventQueControlBlock),
.mq_mem = &guiEventQueBuffer,
.mq_size = sizeof(guiEventQueBuffer)
};
/* Definitions for beepTimer */
osTimerId_t beepTimerHandle;
osStaticTimerDef_t beepTimerControlBlock;
const osTimerAttr_t beepTimer_attributes = {
.name = "beepTimer",
.cb_mem = &beepTimerControlBlock,
.cb_size = sizeof(beepTimerControlBlock),
};
/* Definitions for heaterMutex */
osMutexId_t heaterMutexHandle;
osStaticMutexDef_t heaterMutexControlBlock;
const osMutexAttr_t heaterMutex_attributes = {
.name = "heaterMutex",
.cb_mem = &heaterMutexControlBlock,
.cb_size = sizeof(heaterMutexControlBlock),
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void app_task_main(void *argument);
extern void app_task_heater(void *argument);
extern void app_task_gui(void *argument);
extern void app_beep_end(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
@ -104,6 +167,9 @@ void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Create the mutex(es) */
/* creation of heaterMutex */
heaterMutexHandle = osMutexNew(&heaterMutex_attributes);
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
@ -113,17 +179,31 @@ void MX_FREERTOS_Init(void) {
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* Create the timer(s) */
/* creation of beepTimer */
beepTimerHandle = osTimerNew(app_beep_end, osTimerOnce, NULL, &beepTimer_attributes);
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* Create the queue(s) */
/* creation of guiEventQue */
guiEventQueHandle = osMessageQueueNew (16, 8, &guiEventQue_attributes);
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* creation of mainTsk */
mainTskHandle = osThreadNew(app_task_main, NULL, &mainTsk_attributes);
/* creation of heaterTsk */
heaterTskHandle = osThreadNew(app_task_heater, NULL, &heaterTsk_attributes);
/* creation of guiTsk */
guiTskHandle = osThreadNew(app_task_gui, NULL, &guiTsk_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
@ -135,19 +215,22 @@ void MX_FREERTOS_Init(void) {
}
/* USER CODE BEGIN Header_StartDefaultTask */
/* USER CODE BEGIN Header_app_task_main */
/**
* @brief Function implementing the defaultTask thread.
* @brief Function implementing the mainTsk thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
/* USER CODE END Header_app_task_main */
__weak void app_task_main(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
app_main_task(argument);
vTaskDelete(NULL);
/* USER CODE END StartDefaultTask */
/* USER CODE BEGIN app_task_main */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END app_task_main */
}
/* Private application code --------------------------------------------------*/

@ -123,7 +123,7 @@ void MX_TIM3_Init(void)
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 32000;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Mon Mar 06 21:48:34 CET 2023]
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Tue Mar 07 00:54:18 CET 2023]
##########################################################################################################################
# ------------------------------------------------
@ -45,9 +45,10 @@ Core/Src/spi.c \
Core/Src/tim.c \
Core/Src/usart.c \
Core/Src/oled.c \
Core/Src/app.c \
Core/Src/app_main.c \
Core/Src/app_pid.c \
Core/Src/app_analog.c \
Core/Src/app_gui.c \
Core/Src/app_temp.c \
Core/Src/app_knob.c \
Core/Src/app_buzzer.c \
Core/Src/app_heater.c \

Loading…
Cancel
Save