start working with monitoring

This commit is contained in:
eddyem 2020-10-29 00:57:31 +03:00
parent 4f3332737f
commit f65617cca5
10 changed files with 329 additions and 27 deletions

View File

@ -98,16 +98,16 @@ uint32_t getU5(){
* @return
*/
int16_t getNTC(int nch){
#define NKNOTS (9)
const int16_t ADU[NKNOTS] = {427, 468, 514, 623, 754, 910, 1087, 1295, 1538};
const int16_t T[NKNOTS] = {-200, -180, -159, -116, -72, -26, 23, 75, 132};
#define NKNOTS (14)
const int16_t ADU[NKNOTS] = {732, 945, 1197, 2035, 2309, 2542, 2739, 2859, 2969, 3068, 3154, 3228, 3293, 3347};
const int16_t T[NKNOTS] = {100, 160, 227, 438, 508, 571, 628, 666, 702, 738, 772, 805, 837, 869};
/*
* coefficients: 0.050477 0.045107 0.039150 0.033639 0.029785 0.027017 0.024996 0.023522 0.022514
* coefficients: 0.028261 0.026536 0.025136 0.025738 0.027044 0.028922 0.031038 0.033255 0.036056 0.039606 0.044173 0.050296 0.058920 0.071729
* use
* [N D] = rat(K*10); printf("%d, ", N); printf("%d, ", D);
* [N D] = rat(K*10); printf("N="); printf("%d, ", N); printf("\nD="); printf("%d, ", D);printf("\n");
*/
const int16_t N[NKNOTS] = {1377, 295, 258, 110, 291, 77, 1657, 191, 120};
const int16_t D[NKNOTS] = {2728, 654, 659, 327, 977, 285, 6629, 812, 533};
const int16_t N[NKNOTS] = {13, 95, 185, 96, 43, 153, 347, 141, 128, 261, 235, 85, 393, 307};
const int16_t D[NKNOTS] = {46, 358, 736, 373, 159, 529, 1118, 424, 355, 659, 532, 169, 667, 428};
if(nch < 0 || nch > 3) return -30000;
uint16_t val = getADCval(nch);

View File

@ -25,6 +25,7 @@
#include "hardware.h"
#include "proto.h"
volatile uint32_t Cooler1RPM; // Cooler1 RPM counter by EXTI @PA7
buzzer_state buzzer = BUZZER_OFF; // buzzer state
void adc_setup(){
@ -103,9 +104,6 @@ static inline void timers_setup(){
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable clocking
TIM1->PSC = 19; // F=48/20 = 2.4MHz
TIM1->ARR = 100; // PWM frequency = 2.4/101 = 23.76kHz
TIM1->CCR1 = 20; // near 20% PWM duty cycle
TIM1->CCR2 = 20; // near 20% PWM duty cycle
//TIM1->CCR3 = 20; // CCR3 is zero - should be activated on cooler3 settings
// PWM mode 1 (OCxM = 110), preload enable
TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE |
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;

View File

@ -75,8 +75,7 @@ typedef enum{
#define SHORT_BUZZER_PAUSE (9500)
extern volatile uint32_t Tms;
extern volatile uint32_t Cooler0speed;
extern volatile uint32_t Cooler1speed;
extern volatile uint32_t Coolerspeed[2];
extern volatile uint32_t Cooler1RPM;
extern buzzer_state buzzer;

View File

@ -20,20 +20,23 @@
*/
#include "hardware.h"
#include "monitor.h"
#include "proto.h"
#include "usb.h"
#include "usb_lib.h"
volatile uint32_t Tms = 0;
volatile uint32_t Coolerspeed[2]; // RPM of cooler0/1
/* Called when systick fires */
void sys_tick_handler(void){
static uint32_t actr = 0;
++Tms;
if(++actr == 1000){ // RPM counter
Cooler0speed = TIM3->CNT/2;
Coolerspeed[0] = TIM3->CNT/2;
TIM3->CNT = 0;
Cooler1speed = Cooler1RPM/2;
Coolerspeed[1] = Cooler1RPM/2;
Cooler1RPM = 0;
actr = 0;
}
@ -73,7 +76,7 @@ static char *get_USB(){
}
int main(void){
//uint32_t lastT = 0;
uint32_t lastT = 0;
char *txt;
sysreset();
SysTick_Config(6000, 1);
@ -82,12 +85,15 @@ int main(void){
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
iwdg_setup();
ON(COOLER0); // turn on power, manage only by PWM
ON(COOLER1);
while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
/*if(lastT && (Tms - lastT > 199)){
LED_off(LED0);
lastT = 0;
}*/
if(Tms - lastT > MONITOR_PERIOD){
process_monitor();
lastT = Tms;
}
usb_proc();
if((txt = get_USB())){
IWDG->KR = IWDG_REFRESH;

View File

@ -0,0 +1,180 @@
/*
* This file is part of the SockFans project.
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adc.h"
#include "monitor.h"
#include "proto.h"
// when critical T reached wait for TturnOff ms and after that turn off system
#define TturnOff (20000)
// don't mind when button 2 pressed again after t<5s
#define TbtnPressed (5000)
// settings
// T0 - CPU, T1 - HDD, T2 - inner T, T3 - power source
static const int16_t Thysteresis = 30; // hysteresis by T=3degC
static const int16_t tmin[3] = {400, 350, 350}; // turn off fans when T[x]<tmin[x]+Th, turn on when >tmin+Th
static const int16_t tmax[3] = {900, 800, 600}; // critical T, turn off power after TturnOff milliseconds
static const int16_t t3max = 850;
static uint8_t dontprocess = 0; // don't process monitor
static uint32_t TOff = 0; // time to turn off power
static void chkOffRelay(){
if(Tms > TOff){
TOff = 0;
OFF(RELAY);
SEND("Turn off power");
buzzer = BUZZER_OFF;
}else SEND("TCRITSHUTDOWNn");
NL();
}
static void startOff(){
SEND("TCRITSHUTDOWN"); NL();
TOff = Tms + TturnOff;
if(TOff == 0) TOff = 1;
buzzer = BUZZER_LONG;
}
// check buttons state
static void chkButtons(){
static uint32_t Tpressed = 0;
if(CHK(BUTTON0) == 0){ // button 0 pressed - turn on power if was off
if(CHK(RELAY) == 0){
ON(RELAY);
SEND("Button0: relay ON");NL();
}
dontprocess = 0;
}
if(CHK(BUTTON1) == 0){ // button 1 - all OFF
if(Tpressed){ // already pressed recently
if(Tms - Tpressed < TbtnPressed) return;
}
Tpressed = Tms;
if(Tpressed == 0) Tpressed = 1;
buzzer = BUZZER_OFF;
TIM1->CCR1 = 0; TIM1->CCR2 = 0; TIM1->CCR3 = 0;
OFF(RELAY);
dontprocess = 1;
SEND("Everything is OFF immediately");NL();
}else Tpressed = 0;
}
// monitor temperatures and do something
void process_monitor(){
chkButtons();
if(dontprocess) return;
int16_t T;
static uint8_t coolerproblem[2] = {0,0}; // cooler don't run
static uint8_t offreason[4] = {0}; // whos T was critical for turning power off
// check all 4 temperatures
// T0..1 - coolers
for(int x = 0; x < 2; ++x){
T = getNTC(x);
volatile uint32_t *ccr = (x == 0) ? &TIM1->CCR1 : &TIM1->CCR2;
uint32_t RPM = *ccr;
uint32_t speed = Coolerspeed[x];
if(T < tmin[x] - Thysteresis){ // turn off fan
*ccr = 0;
}else if(T > tmax[x] + Thysteresis){
if(TOff){
chkOffRelay();
}else{
offreason[x] = 1;
startOff();
*ccr = 100;
}
}else{
offreason[x] = 0;
// check working fan
int chk = (x==0) ? CHK(COOLER0) : CHK(COOLER1);
if(chk){ // fan is working, check RPM
if(RPM && speed == 0){
SEND("RPM: "); printu(RPM); SEND(", speed: "); printu(speed); newline();
SEND("Cooler"); bufputchar('0'+x); SEND(" died!");NL();
buzzer = BUZZER_SHORT;
coolerproblem[x] = 1;
}else if(coolerproblem[x]){
buzzer = BUZZER_OFF;
coolerproblem[x] = 0;
SEND("Cooler OK");NL();
}
}else{ // turn on fan
SEND("Turn fan ON"); NL();
if(x==0) ON(COOLER0);
else ON(COOLER1);
}
if(T > tmin[x] && T < tmax[x]){ // T between tmin and tmax
int32_t tx = 80*(T - tmin[x]);
tx /= (tmax[x] - tmin[x]);
uint32_t pwm = 20 + tx;
if(pwm < 20) pwm = 20;
else if(pwm > 100) pwm = 100;
SEND("Set pwm"); bufputchar('0'+x);SEND(" to "); printu(pwm);NL();
*ccr = pwm;
}
}
}
// T2 - not controlled cooler
T = getNTC(2);
if(T < tmin[2] - Thysteresis){ // turn off fan
TIM1->CCR3 = 0;
}else if(T > tmax[2] + Thysteresis){
if(TOff){
chkOffRelay();
}else{
offreason[2] = 1;
startOff();
TIM1->CCR3 = 100;
}
}else{ // T between tmin and tmax
offreason[2] = 0;
if(T > tmin[2] && T < tmax[2]){
int32_t tx = 60*(T - tmin[2]);
tx /= (tmax[2] - tmin[2]);
uint32_t pwm = 40 + tx;
if(pwm < 40) pwm = 40;
else if(pwm > 100) pwm = 100;
SEND("Set pwm3 to "); printu(pwm);NL();
TIM1->CCR3 = pwm;
}
}
// T3 - turn off power after TturnOff
if(getNTC(3) > t3max){
if(TOff){
chkOffRelay();
}else{
offreason[3] = 1;
startOff();
}
}else offreason[3] = 0;
// check offreason
if(TOff){
uint8_t stillbad = 0;
for(int x = 0; x < 4; ++x)
if(offreason[x]){
stillbad = 1;
break;
}
if(!stillbad){
SEND("No reason to panic");NL();
TOff = 0;
buzzer = BUZZER_OFF;
}
}
}

View File

@ -0,0 +1,28 @@
/*
* This file is part of the SockFans project.
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef MONITOR_H__
// run monitor each 1s
#define MONITOR_PERIOD (999)
void process_monitor();
#define MONITOR_H__
#endif // MONITOR_H__

View File

@ -29,9 +29,6 @@
static char buff[BUFSZ+1], *bptr = buff;
static uint8_t blen = 0;
volatile uint32_t Cooler0speed; // RPM of cooler0
volatile uint32_t Cooler1RPM; // Cooler1 RPM counter by EXTI @PA7
volatile uint32_t Cooler1speed; // RPM of cooler0
void sendbuf(){
IWDG->KR = IWDG_REFRESH;
@ -171,11 +168,7 @@ static inline void coolerRPM(char n){
SEND("RPM");
bufputchar(n);
bufputchar('=');
if(n == '0'){ // cooler0
printu(Cooler0speed);
}else{ // cooler1
printu(Cooler1speed);
}
printu(Coolerspeed[n - '0']);
}
// change Coolerx RPM
@ -227,6 +220,15 @@ static inline void buzzercmd(char cmd){
}
}
static inline void gett(char chno){
if(chno < '0' || chno > '3'){
SEND("Temperature channel should be 0..3");
return;
}
bufputchar('T'); bufputchar(chno); bufputchar('=');
printi(getNTC(chno - '0'));
}
/**
* @brief cmd_parser - command parsing
* @param txt - buffer with commands & data
@ -266,6 +268,10 @@ void cmd_parser(char *txt){
changeRPM(txt+1);
goto eof;
break;
case 't':
gett(txt[1]);
goto eof;
break;
}
if(txt[1] != '\n') *txt = '?'; // help for wrong message length
switch(_1st){
@ -326,6 +332,7 @@ void cmd_parser(char *txt){
"'rx' - relay on/off (x=1/0) or get status\n"
"'Sx y' - set coolerx RPM to y\n"
"'T' - get time from start (ms)\n"
"'tx' - get temperature x (0..3)\n"
"'V' - get voltage\n"
"'Z' - reinit ADC\n"
);
@ -351,6 +358,15 @@ void printu(uint32_t val){
addtobuf(bufptr);
}
// print 32bit signed int
void printi(int32_t val){
if(val < 0){
val = -val;
bufputchar('-');
}
printu(val);
}
// print 32bit unsigned int as hex
void printuhex(uint32_t val){
addtobuf("0x");

View File

@ -46,6 +46,7 @@ void cmd_parser(char *buf);
void addtobuf(const char *txt);
void bufputchar(char ch);
void printu(uint32_t val);
void printi(int32_t val);
void printuhex(uint32_t val);
void sendbuf();

Binary file not shown.

View File

@ -181,6 +181,80 @@ TRUE_INLINE void StartHSI48(){
#define GPIO_MODER_MODER15_O ((uint32_t)0x40000000)
#define GPIO_MODER_MODER15_AF ((uint32_t)0x80000000)
/******************* Bit definition for GPIO_PUPDR register *****************/
// no/pullup/pulldown/reserved
// for n in $(seq 0 15); do echo "#define GPIO_PUPDR${n}_PU ((uint32_t)(1<<$((n*2))))";
// echo "#define GPIO_PUPDR${n}_PD ((uint32_t)(1<<$((n*2+1))))"; done
// alt+select column -> delete
#define GPIO_PUPDR0_PU ((uint32_t)(1<<0))
#define GPIO_PUPDR0_PD ((uint32_t)(1<<1))
#define GPIO_PUPDR1_PU ((uint32_t)(1<<2))
#define GPIO_PUPDR1_PD ((uint32_t)(1<<3))
#define GPIO_PUPDR2_PU ((uint32_t)(1<<4))
#define GPIO_PUPDR2_PD ((uint32_t)(1<<5))
#define GPIO_PUPDR3_PU ((uint32_t)(1<<6))
#define GPIO_PUPDR3_PD ((uint32_t)(1<<7))
#define GPIO_PUPDR4_PU ((uint32_t)(1<<8))
#define GPIO_PUPDR4_PD ((uint32_t)(1<<9))
#define GPIO_PUPDR5_PU ((uint32_t)(1<<10))
#define GPIO_PUPDR5_PD ((uint32_t)(1<<11))
#define GPIO_PUPDR6_PU ((uint32_t)(1<<12))
#define GPIO_PUPDR6_PD ((uint32_t)(1<<13))
#define GPIO_PUPDR7_PU ((uint32_t)(1<<14))
#define GPIO_PUPDR7_PD ((uint32_t)(1<<15))
#define GPIO_PUPDR8_PU ((uint32_t)(1<<16))
#define GPIO_PUPDR8_PD ((uint32_t)(1<<17))
#define GPIO_PUPDR9_PU ((uint32_t)(1<<18))
#define GPIO_PUPDR9_PD ((uint32_t)(1<<19))
#define GPIO_PUPDR10_PU ((uint32_t)(1<<20))
#define GPIO_PUPDR10_PD ((uint32_t)(1<<21))
#define GPIO_PUPDR11_PU ((uint32_t)(1<<22))
#define GPIO_PUPDR11_PD ((uint32_t)(1<<23))
#define GPIO_PUPDR12_PU ((uint32_t)(1<<24))
#define GPIO_PUPDR12_PD ((uint32_t)(1<<25))
#define GPIO_PUPDR13_PU ((uint32_t)(1<<26))
#define GPIO_PUPDR13_PD ((uint32_t)(1<<27))
#define GPIO_PUPDR14_PU ((uint32_t)(1<<28))
#define GPIO_PUPDR14_PD ((uint32_t)(1<<29))
#define GPIO_PUPDR15_PU ((uint32_t)(1<<30))
#define GPIO_PUPDR15_PD ((uint32_t)(1<<31))
// OSPEEDR
// for n in $(seq 0 15); do echo "#define GPIO_OSPEEDR${n}_MED ((uint32_t)(1<<$((n*2))))";
// echo "#define GPIO_OSPEEDR${n}_HIGH ((uint32_t)(3<<$((2*n))))"; done
#define GPIO_OSPEEDR0_MED ((uint32_t)(1<<0))
#define GPIO_OSPEEDR0_HIGH ((uint32_t)(3<<0))
#define GPIO_OSPEEDR1_MED ((uint32_t)(1<<2))
#define GPIO_OSPEEDR1_HIGH ((uint32_t)(3<<2))
#define GPIO_OSPEEDR2_MED ((uint32_t)(1<<4))
#define GPIO_OSPEEDR2_HIGH ((uint32_t)(3<<4))
#define GPIO_OSPEEDR3_MED ((uint32_t)(1<<6))
#define GPIO_OSPEEDR3_HIGH ((uint32_t)(3<<6))
#define GPIO_OSPEEDR4_MED ((uint32_t)(1<<8))
#define GPIO_OSPEEDR4_HIGH ((uint32_t)(3<<8))
#define GPIO_OSPEEDR5_MED ((uint32_t)(1<<10))
#define GPIO_OSPEEDR5_HIGH ((uint32_t)(3<<10))
#define GPIO_OSPEEDR6_MED ((uint32_t)(1<<12))
#define GPIO_OSPEEDR6_HIGH ((uint32_t)(3<<12))
#define GPIO_OSPEEDR7_MED ((uint32_t)(1<<14))
#define GPIO_OSPEEDR7_HIGH ((uint32_t)(3<<14))
#define GPIO_OSPEEDR8_MED ((uint32_t)(1<<16))
#define GPIO_OSPEEDR8_HIGH ((uint32_t)(3<<16))
#define GPIO_OSPEEDR9_MED ((uint32_t)(1<<18))
#define GPIO_OSPEEDR9_HIGH ((uint32_t)(3<<18))
#define GPIO_OSPEEDR10_MED ((uint32_t)(1<<20))
#define GPIO_OSPEEDR10_HIGH ((uint32_t)(3<<20))
#define GPIO_OSPEEDR11_MED ((uint32_t)(1<<22))
#define GPIO_OSPEEDR11_HIGH ((uint32_t)(3<<22))
#define GPIO_OSPEEDR12_MED ((uint32_t)(1<<24))
#define GPIO_OSPEEDR12_HIGH ((uint32_t)(3<<24))
#define GPIO_OSPEEDR13_MED ((uint32_t)(1<<26))
#define GPIO_OSPEEDR13_HIGH ((uint32_t)(3<<26))
#define GPIO_OSPEEDR14_MED ((uint32_t)(1<<28))
#define GPIO_OSPEEDR14_HIGH ((uint32_t)(3<<28))
#define GPIO_OSPEEDR15_MED ((uint32_t)(1<<30))
#define GPIO_OSPEEDR15_HIGH ((uint32_t)(3<<30))
/****************** FLASH Keys **********************************************/
#define RDP_Key ((uint16_t)0x00A5)