|
|
|
@ -15,22 +15,27 @@ |
|
|
|
|
#include "tim.h" |
|
|
|
|
#include "adc.h" |
|
|
|
|
#include "oled.h" |
|
|
|
|
#include "ufb/fb_text.h" |
|
|
|
|
|
|
|
|
|
// TODO averaging
|
|
|
|
|
/* DMA dest */ |
|
|
|
|
static volatile uint16_t adc_values[4]; |
|
|
|
|
static volatile uint16_t adc_values_snapshot[4]; |
|
|
|
|
|
|
|
|
|
const float r_current_sensor = 98.2f; // Ohm TODO measure
|
|
|
|
|
const float V_REFINT = 1.23f; |
|
|
|
|
|
|
|
|
|
#define AVERAGEBUF_DEPTH 32 |
|
|
|
|
|
|
|
|
|
static struct App { |
|
|
|
|
float oven_temp; |
|
|
|
|
float soc_temp; |
|
|
|
|
float v_sensor; |
|
|
|
|
float v_current_reference; |
|
|
|
|
float sensor_current; |
|
|
|
|
float r_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]; |
|
|
|
|
} s_app = {}; |
|
|
|
|
|
|
|
|
|
#define TSENSE_LOOKUP_LEN 101 |
|
|
|
@ -38,25 +43,117 @@ static struct App { |
|
|
|
|
#define TSENSE_T_MIN 0.0f |
|
|
|
|
#define TSENSE_T_MAX 500.0f |
|
|
|
|
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = { |
|
|
|
|
100.0f, 101.9527f, 103.9025f, 105.8495f, 107.7935f, 109.7347f, 111.6729f, 113.6083f, 115.5408f, 117.4704f, 119.3971f, 121.321f, |
|
|
|
|
123.2419f, 125.16f, 127.0751f, 128.9874f, 130.8968f, 132.8033f, 134.7069f, 136.6077f, 138.5055f, 140.4005f, 142.2925f, 144.1817f, |
|
|
|
|
146.068f, 147.9514f, 149.8319f, 151.7096f, 153.5843f, 155.4562f, 157.3251f, 159.1912f, 161.0544f, 162.9147f, 164.7721f, 166.6267f, |
|
|
|
|
168.4783f, 170.3271f, 172.1729f, 174.0159f, 175.856f, 177.6932f, 179.5275f, 181.359f, 183.1875f, 185.0132f, 186.8359f, 188.6558f, |
|
|
|
|
190.4728f, 192.2869f, 194.0981f, 195.9065f, 197.7119f, 199.5145f, 201.3141f, 203.1109f, 204.9048f, 206.6958f, 208.4839f, 210.2692f, |
|
|
|
|
212.0515f, 213.831f, 215.6075f, 217.3812f, 219.152f, 220.9199f, 222.6849f, 224.4471f, 226.2063f, 227.9627f, 229.7161f, 231.4667f, |
|
|
|
|
233.2144f, 234.9592f, 236.7011f, 238.4402f, 240.1763f, 241.9096f, 243.6399f, 245.3674f, 247.092f, 248.8137f, 250.5325f, 252.2485f, |
|
|
|
|
253.9615f, 255.6717f, 257.3789f, 259.0833f, 260.7848f, 262.4834f, 264.1791f, 265.872f, 267.5619f, 269.249f, 270.9331f, 272.6144f, |
|
|
|
|
274.2928f, 275.9683f, 277.6409f, 279.3107f, 280.9775f |
|
|
|
|
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 r_to_c(float r){ |
|
|
|
|
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 >= r) { |
|
|
|
|
if (cur >= val) { |
|
|
|
|
float prev = TSENSE_LOOKUP[i-1]; |
|
|
|
|
|
|
|
|
|
float ratio = (r - prev) / (cur - prev); |
|
|
|
|
float ratio = (val - prev) / (cur - prev); |
|
|
|
|
return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -64,32 +161,45 @@ static float r_to_c(float r){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 */ |
|
|
|
|
uint16_t refint = adc_values_snapshot[3]; |
|
|
|
|
const float vrefint = 1.2f; |
|
|
|
|
float scale = vrefint / (float)refint; |
|
|
|
|
float refint = s_app.adc_averages[3]; |
|
|
|
|
float scale = V_REFINT / refint; |
|
|
|
|
|
|
|
|
|
const float avg_slope = 4.3f; |
|
|
|
|
const float avg_slope = 4.3f * scale; |
|
|
|
|
const float v25 = 1.43f; |
|
|
|
|
const float v_tsen = (float) adc_values_snapshot[2] * scale; |
|
|
|
|
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 = (float)adc_values_snapshot[0] * scale; |
|
|
|
|
s_app.v_current_reference = (float)(adc_values_snapshot[1] - adc_values_snapshot[0]) * scale; |
|
|
|
|
s_app.v_sensor = s_app.adc_averages[0] * scale; // good for debug/tuning
|
|
|
|
|
|
|
|
|
|
s_app.sensor_current = s_app.v_current_reference / r_current_sensor; |
|
|
|
|
s_app.r_sensor = s_app.v_sensor / s_app.sensor_current; |
|
|
|
|
s_app.oven_temp = r_to_c(s_app.r_sensor); |
|
|
|
|
// 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]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) |
|
|
|
|
{ |
|
|
|
|
// notify
|
|
|
|
|
memcpy((void*) adc_values_snapshot, (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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
@ -119,17 +229,14 @@ void app_main_task(void *argument) |
|
|
|
|
|
|
|
|
|
calculate_analog_values(); |
|
|
|
|
|
|
|
|
|
printf("Knob %d (P=%d), ADC %d %d %d %d, oven %.2f°C, soc %.2f°C, vPt %.3fV, v_iref %.3f, I %.6fA, rPt %.2f Ohm \r\n", |
|
|
|
|
(int) s_app.wheel, s_app.push, |
|
|
|
|
adc_values[0], adc_values[1], adc_values[2], adc_values[3], |
|
|
|
|
|
|
|
|
|
s_app.oven_temp, |
|
|
|
|
s_app.soc_temp, |
|
|
|
|
s_app.v_sensor, |
|
|
|
|
s_app.v_current_reference, |
|
|
|
|
s_app.sensor_current, |
|
|
|
|
s_app.r_sensor |
|
|
|
|
); |
|
|
|
|
// 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
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
invert = !invert; |
|
|
|
|
|
|
|
|
@ -143,9 +250,15 @@ void app_main_task(void *argument) |
|
|
|
|
fb_frame(s_app.wheel % FBW, 0, 15, 15, 1, 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char tmp[100]; |
|
|
|
|
sprintf(tmp, "%d°C", (int) s_app.oven_temp); |
|
|
|
|
|
|
|
|
|
fb_text(0, 20, tmp, 0, 1); |
|
|
|
|
|
|
|
|
|
fb_blit(); |
|
|
|
|
|
|
|
|
|
vTaskDelay(250); |
|
|
|
|
vTaskDelay(100); |
|
|
|
|
|
|
|
|
|
// beep
|
|
|
|
|
htim2.Instance->ARR = 12000 + (int16_t)s_app.wheel * 100; |
|
|
|
|