wip refactors
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rtc.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the rtc.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RTC_H__
|
||||
#define __RTC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_RTC_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RTC_H__ */
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
/*#define HAL_HCD_MODULE_ENABLED */
|
||||
/*#define HAL_PWR_MODULE_ENABLED */
|
||||
/*#define HAL_RCC_MODULE_ENABLED */
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
/*#define HAL_RTC_MODULE_ENABLED */
|
||||
/*#define HAL_SD_MODULE_ENABLED */
|
||||
/*#define HAL_MMC_MODULE_ENABLED */
|
||||
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
+21
-224
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
@@ -12,218 +11,27 @@
|
||||
|
||||
#include "ufb/framebuffer.h"
|
||||
#include "iwdg.h"
|
||||
#include "tim.h"
|
||||
#include "adc.h"
|
||||
#include "oled.h"
|
||||
#include "ufb/fb_text.h"
|
||||
|
||||
/* DMA dest */
|
||||
static volatile uint16_t adc_values[4];
|
||||
|
||||
const float V_REFINT = 1.23f;
|
||||
|
||||
#define AVERAGEBUF_DEPTH 16
|
||||
#define OVENTEMP_HISTORY_DEPTH 10
|
||||
#include "app_analog.h"
|
||||
#include "app_knob.h"
|
||||
#include "app_buzzer.h"
|
||||
#include "app_heater.h"
|
||||
|
||||
static struct App {
|
||||
bool heating;
|
||||
float oven_temp;
|
||||
int16_t set_temp;
|
||||
int16_t wheel_normed;
|
||||
float oven_temp;
|
||||
float soc_temp;
|
||||
float v_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;
|
||||
bool heating;
|
||||
} s_app = {};
|
||||
|
||||
#define TSENSE_LOOKUP_LEN 101
|
||||
#define TSENSE_T_STEP 5.0f
|
||||
#define TSENSE_T_MIN 0.0f
|
||||
#define TSENSE_T_MAX 500.0f
|
||||
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
|
||||
0.092678405931418f,
|
||||
0.0943174479327356f,
|
||||
0.095948157844312f,
|
||||
0.0975706768542549f,
|
||||
0.0991848957506647f,
|
||||
0.100791037522732f,
|
||||
0.102388993070241f,
|
||||
0.103978983136042f,
|
||||
0.105560980458654f,
|
||||
0.107135039851509f,
|
||||
0.108701215616829f,
|
||||
0.110259642413441f,
|
||||
0.111810211533421f,
|
||||
0.113353137226489f,
|
||||
0.114888310929339f,
|
||||
0.11641594480226f,
|
||||
0.117936009906507f,
|
||||
0.119448557132363f,
|
||||
0.120953636903929f,
|
||||
0.122451377845456f,
|
||||
0.12394167187544f,
|
||||
0.125424725109556f,
|
||||
0.126900429638119f,
|
||||
0.128368989630084f,
|
||||
0.129830374697352f,
|
||||
0.131284632150064f,
|
||||
0.132731808872517f,
|
||||
0.134172027901771f,
|
||||
0.135605181883591f,
|
||||
0.13703146935069f,
|
||||
0.138450783142958f,
|
||||
0.139863319976468f,
|
||||
0.14126904821384f,
|
||||
0.142668011892657f,
|
||||
0.144060254660872f,
|
||||
0.145445894373796f,
|
||||
0.146824824486877f,
|
||||
0.14819723645253f,
|
||||
0.149563023938454f,
|
||||
0.150922376699229f,
|
||||
0.15227526202401f,
|
||||
0.153621720954182f,
|
||||
0.15496179417407f,
|
||||
0.156295594725426f,
|
||||
0.157623016940038f,
|
||||
0.158944245649448f,
|
||||
0.160259175412251f,
|
||||
0.16156798947087f,
|
||||
0.162870654195634f,
|
||||
0.164167207880495f,
|
||||
0.165457688491696f,
|
||||
0.166742204592451f,
|
||||
0.168020651444079f,
|
||||
0.169293207677971f,
|
||||
0.170559768793747f,
|
||||
0.171820511933356f,
|
||||
0.173075402684405f,
|
||||
0.174324476817747f,
|
||||
0.175567769803026f,
|
||||
0.176805386030345f,
|
||||
0.178037221732226f,
|
||||
0.179263449725904f,
|
||||
0.180483966491086f,
|
||||
0.181698943447122f,
|
||||
0.182908345518766f,
|
||||
0.184112206156428f,
|
||||
0.185310558533273f,
|
||||
0.186503503145257f,
|
||||
0.187690937227925f,
|
||||
0.188873028139146f,
|
||||
0.190049673368296f,
|
||||
0.191221038959601f,
|
||||
0.192387089280576f,
|
||||
0.193547855644572f,
|
||||
0.194703369109397f,
|
||||
0.195853726532112f,
|
||||
0.196998826174689f,
|
||||
0.19813883026229f,
|
||||
0.199273637315452f,
|
||||
0.200403408323351f,
|
||||
0.201528107189346f,
|
||||
0.20264776325594f,
|
||||
0.203762405629782f,
|
||||
0.204872127762998f,
|
||||
0.205976828960191f,
|
||||
0.207076666615101f,
|
||||
0.208171540293999f,
|
||||
0.209261606226334f,
|
||||
0.210346827933364f,
|
||||
0.211427232937629f,
|
||||
0.212502848543705f,
|
||||
0.213573765013592f,
|
||||
0.214639882704581f,
|
||||
0.215701354457324f,
|
||||
0.216758080892489f,
|
||||
0.217810213752734f,
|
||||
0.218857716249547f,
|
||||
0.219900614222686f,
|
||||
0.220938933310224f,
|
||||
0.221972760781578f,
|
||||
0.223001998051553f,
|
||||
};
|
||||
|
||||
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 ratio = (val - prev) / (cur - prev);
|
||||
return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP;
|
||||
}
|
||||
}
|
||||
return TSENSE_T_MAX;
|
||||
}
|
||||
|
||||
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];
|
||||
sums[1] += s_app.adc_averagebuf[i + 1];
|
||||
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;
|
||||
|
||||
/* r_pt100, r_ref, internal_temp, v_ref_int */
|
||||
float refint = s_app.adc_averages[3];
|
||||
float scale = V_REFINT / refint;
|
||||
|
||||
const float avg_slope = 4.3f * scale;
|
||||
const float v25 = 1.43f;
|
||||
const float v_tsen = s_app.adc_averages[2] * scale;
|
||||
|
||||
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.
|
||||
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)
|
||||
{
|
||||
// notify
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* Enable the rotary encoder */
|
||||
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
|
||||
|
||||
/* Enable buzzer PWM */
|
||||
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||
app_analog_init();
|
||||
app_buzzer_init();
|
||||
app_heater_init();
|
||||
app_knob_init();
|
||||
|
||||
/* Prepare the framebuffer and OLED interface */
|
||||
oled_init();
|
||||
@@ -236,22 +44,13 @@ void app_main_task(void *argument)
|
||||
|
||||
/* Infinite loop */
|
||||
for (;;) {
|
||||
//HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||
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,
|
||||
// s_app.adc_averages[0], s_app.adc_averages[1], s_app.adc_averages[2], s_app.adc_averages[3],
|
||||
//
|
||||
// s_app.oven_temp,
|
||||
// s_app.soc_temp,
|
||||
// s_app.v_sensor
|
||||
// );
|
||||
|
||||
calculate_analog_values();
|
||||
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 = htim4.Instance->CNT;
|
||||
s_app.wheel = app_knob_get_raw();
|
||||
|
||||
int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel);
|
||||
|
||||
@@ -264,10 +63,16 @@ void app_main_task(void *argument)
|
||||
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);
|
||||
//s_app.push = 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
|
||||
|
||||
if (wheel_change != 0 || i == 0) {
|
||||
fb_clear();
|
||||
@@ -301,15 +106,7 @@ void app_main_task(void *argument)
|
||||
s_app.heating = false;
|
||||
}
|
||||
|
||||
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;
|
||||
*/
|
||||
app_heater_set(s_app.heating);
|
||||
|
||||
// feed dogs
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "app_analog.h"
|
||||
#include "adc.h"
|
||||
|
||||
/* DMA dest */
|
||||
static volatile uint16_t adc_values[4];
|
||||
|
||||
const float V_REFINT = 1.23f;
|
||||
|
||||
#define AVERAGEBUF_DEPTH 16
|
||||
#define OVENTEMP_HISTORY_DEPTH 10
|
||||
|
||||
static struct App {
|
||||
float oven_temp;
|
||||
float soc_temp;
|
||||
float v_sensor;
|
||||
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_analog = {};
|
||||
|
||||
#define TSENSE_LOOKUP_LEN 101
|
||||
#define TSENSE_T_STEP 5.0f
|
||||
#define TSENSE_T_MIN 0.0f
|
||||
#define TSENSE_T_MAX 500.0f
|
||||
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
|
||||
0.092678405931418f,
|
||||
0.0943174479327356f,
|
||||
0.095948157844312f,
|
||||
0.0975706768542549f,
|
||||
0.0991848957506647f,
|
||||
0.100791037522732f,
|
||||
0.102388993070241f,
|
||||
0.103978983136042f,
|
||||
0.105560980458654f,
|
||||
0.107135039851509f,
|
||||
0.108701215616829f,
|
||||
0.110259642413441f,
|
||||
0.111810211533421f,
|
||||
0.113353137226489f,
|
||||
0.114888310929339f,
|
||||
0.11641594480226f,
|
||||
0.117936009906507f,
|
||||
0.119448557132363f,
|
||||
0.120953636903929f,
|
||||
0.122451377845456f,
|
||||
0.12394167187544f,
|
||||
0.125424725109556f,
|
||||
0.126900429638119f,
|
||||
0.128368989630084f,
|
||||
0.129830374697352f,
|
||||
0.131284632150064f,
|
||||
0.132731808872517f,
|
||||
0.134172027901771f,
|
||||
0.135605181883591f,
|
||||
0.13703146935069f,
|
||||
0.138450783142958f,
|
||||
0.139863319976468f,
|
||||
0.14126904821384f,
|
||||
0.142668011892657f,
|
||||
0.144060254660872f,
|
||||
0.145445894373796f,
|
||||
0.146824824486877f,
|
||||
0.14819723645253f,
|
||||
0.149563023938454f,
|
||||
0.150922376699229f,
|
||||
0.15227526202401f,
|
||||
0.153621720954182f,
|
||||
0.15496179417407f,
|
||||
0.156295594725426f,
|
||||
0.157623016940038f,
|
||||
0.158944245649448f,
|
||||
0.160259175412251f,
|
||||
0.16156798947087f,
|
||||
0.162870654195634f,
|
||||
0.164167207880495f,
|
||||
0.165457688491696f,
|
||||
0.166742204592451f,
|
||||
0.168020651444079f,
|
||||
0.169293207677971f,
|
||||
0.170559768793747f,
|
||||
0.171820511933356f,
|
||||
0.173075402684405f,
|
||||
0.174324476817747f,
|
||||
0.175567769803026f,
|
||||
0.176805386030345f,
|
||||
0.178037221732226f,
|
||||
0.179263449725904f,
|
||||
0.180483966491086f,
|
||||
0.181698943447122f,
|
||||
0.182908345518766f,
|
||||
0.184112206156428f,
|
||||
0.185310558533273f,
|
||||
0.186503503145257f,
|
||||
0.187690937227925f,
|
||||
0.188873028139146f,
|
||||
0.190049673368296f,
|
||||
0.191221038959601f,
|
||||
0.192387089280576f,
|
||||
0.193547855644572f,
|
||||
0.194703369109397f,
|
||||
0.195853726532112f,
|
||||
0.196998826174689f,
|
||||
0.19813883026229f,
|
||||
0.199273637315452f,
|
||||
0.200403408323351f,
|
||||
0.201528107189346f,
|
||||
0.20264776325594f,
|
||||
0.203762405629782f,
|
||||
0.204872127762998f,
|
||||
0.205976828960191f,
|
||||
0.207076666615101f,
|
||||
0.208171540293999f,
|
||||
0.209261606226334f,
|
||||
0.210346827933364f,
|
||||
0.211427232937629f,
|
||||
0.212502848543705f,
|
||||
0.213573765013592f,
|
||||
0.214639882704581f,
|
||||
0.215701354457324f,
|
||||
0.216758080892489f,
|
||||
0.217810213752734f,
|
||||
0.218857716249547f,
|
||||
0.219900614222686f,
|
||||
0.220938933310224f,
|
||||
0.221972760781578f,
|
||||
0.223001998051553f,
|
||||
};
|
||||
|
||||
void app_analog_init()
|
||||
{
|
||||
HAL_ADCEx_Calibration_Start(&hadc1);
|
||||
|
||||
/* Start periodic reading of the ADC channels */
|
||||
HAL_ADC_Start_DMA(&hadc1, (uint32_t *) (void *) adc_values, 4);
|
||||
}
|
||||
|
||||
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 ratio = (val - prev) / (cur - prev);
|
||||
return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP;
|
||||
}
|
||||
}
|
||||
return TSENSE_T_MAX;
|
||||
}
|
||||
|
||||
float app_analog_get_temp()
|
||||
{
|
||||
uint32_t sums[4] = {};
|
||||
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];
|
||||
}
|
||||
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;
|
||||
|
||||
/* r_pt100, r_ref, internal_temp, v_ref_int */
|
||||
float refint = s_analog.adc_averages[3];
|
||||
float scale = V_REFINT / refint;
|
||||
|
||||
const float avg_slope = 4.3f * scale;
|
||||
const float v25 = 1.43f;
|
||||
const float v_tsen = s_analog.adc_averages[2] * scale;
|
||||
|
||||
s_analog.soc_temp = (v25 - v_tsen) / avg_slope + 25.f;
|
||||
s_analog.v_sensor = s_analog.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.
|
||||
float actual_temp = val_to_c(s_analog.adc_averages[0] / s_analog.adc_averages[1]);
|
||||
|
||||
s_analog.oventemp_history[s_analog.oventemp_history_ptr] = actual_temp;
|
||||
s_analog.oventemp_history_ptr = (s_analog.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH;
|
||||
|
||||
float sum = 0;
|
||||
for (int i = 0; i < OVENTEMP_HISTORY_DEPTH; i++) {
|
||||
sum += s_analog.oventemp_history[i];
|
||||
}
|
||||
sum /= OVENTEMP_HISTORY_DEPTH;
|
||||
s_analog.oven_temp = sum;
|
||||
|
||||
return s_analog.oven_temp;
|
||||
}
|
||||
|
||||
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
// notify
|
||||
memcpy((void *) &s_analog.adc_averagebuf[s_analog.averagebuf_ptr * 4], (const void *) adc_values, 8);
|
||||
s_analog.averagebuf_ptr = (s_analog.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "app_buzzer.h"
|
||||
#include "tim.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
void app_buzzer_init()
|
||||
{
|
||||
/* Enable buzzer PWM */
|
||||
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||
}
|
||||
|
||||
void app_buzzer_beep() {
|
||||
|
||||
// TODO make this non-blocking
|
||||
TIM2->ARR = 25714;
|
||||
TIM2->CCR1 = TIM2->ARR/2;
|
||||
vTaskDelay(50);
|
||||
TIM2->CCR1 = 0;
|
||||
vTaskDelay(50);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#ifndef BLUEPILLTROUBA_APP_BUZZER_H
|
||||
#define BLUEPILLTROUBA_APP_BUZZER_H
|
||||
|
||||
void app_buzzer_init();
|
||||
|
||||
|
||||
void app_buzzer_beep();
|
||||
|
||||
#endif //BLUEPILLTROUBA_APP_BUZZER_H
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "app_heater.h"
|
||||
#include "tim.h"
|
||||
|
||||
void app_heater_init()
|
||||
{
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
||||
TIM3->ARR = 25714;
|
||||
}
|
||||
|
||||
|
||||
void app_heater_set(bool active)
|
||||
{
|
||||
if (active) {
|
||||
TIM3->CCR1 = TIM3->ARR / 2; // testing - 50%
|
||||
} else {
|
||||
TIM3->CCR1 = 0;
|
||||
}
|
||||
|
||||
//HAL_GPIO_WritePin(HEATER_GPIO_Port, HEATER_Pin, active);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#ifndef BLUEPILLTROUBA_APP_HEATER_H
|
||||
#define BLUEPILLTROUBA_APP_HEATER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void app_heater_init();
|
||||
|
||||
void app_heater_set(bool active);
|
||||
|
||||
#endif //BLUEPILLTROUBA_APP_HEATER_H
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "main.h"
|
||||
#include "app_knob.h"
|
||||
#include "tim.h"
|
||||
|
||||
static struct {
|
||||
uint16_t wheel;
|
||||
bool push;
|
||||
} s_knob = {};
|
||||
|
||||
void app_knob_init()
|
||||
{
|
||||
/* Enable the rotary encoder */
|
||||
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
|
||||
}
|
||||
|
||||
uint16_t app_knob_get_raw() {
|
||||
return htim4.Instance->CNT;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*/
|
||||
|
||||
#ifndef BLUEPILLTROUBA_APP_KNOB_H
|
||||
#define BLUEPILLTROUBA_APP_KNOB_H
|
||||
|
||||
void app_knob_init();
|
||||
|
||||
uint16_t app_knob_get_raw();
|
||||
|
||||
#endif //BLUEPILLTROUBA_APP_KNOB_H
|
||||
@@ -0,0 +1,108 @@
|
||||
#include "app_pid.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
static void clampOutput(struct PID *self)
|
||||
{
|
||||
if (self->Output > self->outMax) { self->Output = self->outMax; }
|
||||
else if (self->Output < self->outMin) { self->Output = self->outMin; }
|
||||
}
|
||||
|
||||
static void clampIterm(struct PID *self)
|
||||
{
|
||||
if (self->ITerm > self->outMax) { self->ITerm = self->outMax; }
|
||||
else if (self->ITerm < self->outMin) { self->ITerm = self->outMin; }
|
||||
}
|
||||
|
||||
void PID_Compute(struct PID *self, float Input)
|
||||
{
|
||||
if (!self->ctlMode) { 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) {
|
||||
/*Compute all the working error variables*/
|
||||
float error = self->Setpoint - Input;
|
||||
self->ITerm += (self->ki * error);
|
||||
|
||||
clampIterm(self);
|
||||
|
||||
float dInput = (Input - self->lastInput);
|
||||
|
||||
/*Compute PID Output*/
|
||||
self->Output = self->kp * error + self->ITerm - self->kd * dInput;
|
||||
|
||||
clampOutput(self);
|
||||
|
||||
/*Remember some variables for next time*/
|
||||
self->lastInput = Input;
|
||||
self->lastTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
void PID_SetSetpoint(struct PID *self, float 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;
|
||||
self->kp = Kp;
|
||||
self->ki = Ki * SampleTimeInSec;
|
||||
self->kd = Kd / SampleTimeInSec;
|
||||
|
||||
if (self->controllerDirection == PID_REVERSE) {
|
||||
self->kp = -self->kp;
|
||||
self->ki = -self->ki;
|
||||
self->kd = -self->kd;
|
||||
}
|
||||
}
|
||||
|
||||
void PID_SetSampleTime(struct PID *self, uint32_t NewSampleTime)
|
||||
{
|
||||
if (NewSampleTime > 0) {
|
||||
float ratio = (float) NewSampleTime
|
||||
/ (float) self->SampleTime;
|
||||
self->ki *= ratio;
|
||||
self->kd /= ratio;
|
||||
self->SampleTime = (uint32_t) NewSampleTime;
|
||||
}
|
||||
}
|
||||
|
||||
void PID_SetOutputLimits(struct PID *self, float Min, float Max)
|
||||
{
|
||||
if (Min > Max) { return; }
|
||||
self->outMin = Min;
|
||||
self->outMax = Max;
|
||||
|
||||
clampOutput(self);
|
||||
clampIterm(self);
|
||||
}
|
||||
|
||||
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*/
|
||||
PID_Initialize(self);
|
||||
}
|
||||
self->ctlMode = newAuto;
|
||||
}
|
||||
|
||||
void PID_Initialize(struct PID *self)
|
||||
{
|
||||
self->lastInput = self->Input;
|
||||
self->ITerm = self->Output;
|
||||
|
||||
clampIterm(self);
|
||||
}
|
||||
|
||||
void PID_SetControllerDirection(struct PID *self, enum PIDDirection Direction)
|
||||
{
|
||||
self->controllerDirection = Direction;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* adapted from the Arduino PID library
|
||||
*
|
||||
* Created on 2020/01/08.
|
||||
*/
|
||||
|
||||
#ifndef ARDUINOPID_H
|
||||
#define ARDUINOPID_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum PIDCtlMode {
|
||||
PID_MANUAL = 0,
|
||||
PID_AUTOMATIC = 1,
|
||||
};
|
||||
|
||||
enum PIDDirection {
|
||||
PID_DIRECT = 0,
|
||||
PID_REVERSE = 1,
|
||||
};
|
||||
|
||||
struct PID {
|
||||
/*working variables*/
|
||||
uint32_t lastTime;
|
||||
float Input, Output, Setpoint;
|
||||
float ITerm, lastInput;
|
||||
float kp, ki, kd;
|
||||
uint32_t SampleTime; // millis
|
||||
float outMin, outMax;
|
||||
enum PIDCtlMode ctlMode; // false
|
||||
enum PIDDirection controllerDirection;
|
||||
};
|
||||
|
||||
#define PID_DEFAULT() { .SampleTime = 1000, .ctlMode=PID_MANUAL, .controllerDirection=PID_DIRECT }
|
||||
|
||||
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_SetOutputLimits(struct PID *self, float Min, float Max);
|
||||
|
||||
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_SetControllerDirection(struct PID *self, enum PIDDirection Direction);
|
||||
|
||||
#endif //ARDUINOPID_H
|
||||
+2
-7
@@ -22,7 +22,6 @@
|
||||
#include "adc.h"
|
||||
#include "dma.h"
|
||||
#include "iwdg.h"
|
||||
#include "rtc.h"
|
||||
#include "spi.h"
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
@@ -105,7 +104,6 @@ int main(void)
|
||||
MX_DMA_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_TIM2_Init();
|
||||
MX_RTC_Init();
|
||||
MX_TIM3_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
/* USER CODE END 2 */
|
||||
@@ -142,11 +140,9 @@ void SystemClock_Config(void)
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
|
||||
|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
@@ -170,8 +166,7 @@ void SystemClock_Config(void)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rtc.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the RTC instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "rtc.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
RTC_HandleTypeDef hrtc;
|
||||
|
||||
/* RTC init function */
|
||||
void MX_RTC_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN RTC_Init 0 */
|
||||
|
||||
/* USER CODE END RTC_Init 0 */
|
||||
|
||||
RTC_TimeTypeDef sTime = {0};
|
||||
RTC_DateTypeDef DateToUpdate = {0};
|
||||
|
||||
/* USER CODE BEGIN RTC_Init 1 */
|
||||
|
||||
/* USER CODE END RTC_Init 1 */
|
||||
|
||||
/** Initialize RTC Only
|
||||
*/
|
||||
hrtc.Instance = RTC;
|
||||
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
|
||||
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
|
||||
if (HAL_RTC_Init(&hrtc) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Check_RTC_BKUP */
|
||||
|
||||
/* USER CODE END Check_RTC_BKUP */
|
||||
|
||||
/** Initialize RTC and set the Time and Date
|
||||
*/
|
||||
sTime.Hours = 0x0;
|
||||
sTime.Minutes = 0x0;
|
||||
sTime.Seconds = 0x0;
|
||||
|
||||
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
|
||||
DateToUpdate.Month = RTC_MONTH_JANUARY;
|
||||
DateToUpdate.Date = 0x1;
|
||||
DateToUpdate.Year = 0x0;
|
||||
|
||||
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN RTC_Init 2 */
|
||||
|
||||
/* USER CODE END RTC_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
|
||||
{
|
||||
|
||||
if(rtcHandle->Instance==RTC)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_MspInit 0 */
|
||||
|
||||
/* USER CODE END RTC_MspInit 0 */
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
/* Enable BKP CLK enable for backup registers */
|
||||
__HAL_RCC_BKP_CLK_ENABLE();
|
||||
/* RTC clock enable */
|
||||
__HAL_RCC_RTC_ENABLE();
|
||||
/* USER CODE BEGIN RTC_MspInit 1 */
|
||||
|
||||
/* USER CODE END RTC_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
|
||||
{
|
||||
|
||||
if(rtcHandle->Instance==RTC)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END RTC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_RTC_DISABLE();
|
||||
/* USER CODE BEGIN RTC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END RTC_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
+2
-2
@@ -123,7 +123,7 @@ void MX_TIM3_Init(void)
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 32768;
|
||||
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)
|
||||
@@ -274,7 +274,7 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
|
||||
*/
|
||||
GPIO_InitStruct.Pin = HEATER_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(HEATER_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN TIM3_MspPostInit 1 */
|
||||
|
||||
Reference in New Issue
Block a user