fixed tmean=NaN, constrict valid T range to med(T)+=3RMS

This commit is contained in:
Edward Emelianov 2024-09-11 11:03:13 +03:00
parent 9bfb542dfc
commit 3202beec31
5 changed files with 49 additions and 16 deletions

View File

@ -1,6 +1,7 @@
## Serial interface commands (ends with '\n'), small letter for only local processing:
- **0...7** send message to Nth controller, not broadcast (after number should be CAN command)
- **@** set/reset debug mode
- **A** allow given node to speak
- **a** get raw ADC values
- **B** send dummy CAN messages to broadcast address
- **b** get/set CAN bus baudrate
@ -9,20 +10,21 @@
- **d** get current CAN address of device
- **Ee** end temperature scan
- **Ff** turn sensors off
- **g** group (sniffer) CAN mode (print to USB terminal all incoming CAN messages with alien IDs)
- **g** sniffer CAN mode (print to USB terminal all incoming CAN messages with alien IDs)
- **Hh** switch I2C to high speed (100kHz)
- **Ii** (re)init sensors
- **Jj** get MCU temperature
- **Kk** get values of U and I
- **Ll** switch I2C to low speed (default, 10kHz)
- **Mm** change master id to 0 (**m**) / broadcast (**M**)
- **N** get build number
- **Oo** turn onboard diagnostic LEDs **O**n or **o**ff (both commands are local!)
- **P** ping everyone over CAN
- **Qq** get system time
- **Rr** reinit I2C
- **S** shut up given node
- **s** send CAN message (format: ID data[0..8], dec, 0x - hex, 0b - binary)
- **Tt** start single temperature measurement
- **U** USB status of given node (0 - off)
- **u** unique ID (default) CAN mode
- **Vv** very low speed
- **Xx** go into temperature scan mode

View File

@ -1,7 +1,12 @@
BTA mirror temperature network daemon
==================
Gather information from temperature sensors and send it over ethernet by network request like
Gather information from temperature sensors and send it over ethernet by network request.
## Protocol
Request format over http:
hostname:4444/Tx
where x is 0 for upper sensors, 1 for lower and 2 for T measured by main controller.
hostname:4444/Tmean returns mean temperature
@ -13,15 +18,18 @@ Answer format: "ID X Y T t", where
- T is measured temperature (degrees Celsium),
- t is UNIX-time of last measurement.
Also you can connect to server by regular INET socket through the same port. Send T0, T1, T2 or Tmean to get data.
After data sending server close socket.
To look graph over gnuplot utility collect gnuplot javascript files in subdirectory js of web-server
images storing directory, copy there script 'plot' and run service as
netdaemon -g -s /path/to/web /path/to/log
Every 15 minutes it will calculate average values of thermal data and plot three graphs:
T0.html with top temperatures, T1.html with bottom and Tgrad.html with their differences (T0-T1).
T0.html with top temperatures and T1.html with bottom.
** Signals
## Signals
SIGUSR1 - reread temperatures adjustment file

View File

@ -22,6 +22,7 @@
*/
#include <arpa/inet.h> // inet_ntop
#include <limits.h> // INT_xxx
#include <math.h> // isfinite, sqrt
#include <netdb.h> // addrinfo
#include <pthread.h>
#include <signal.h> // pthread_kill
@ -197,6 +198,7 @@ static void *handle_socket(void *asock){
}
pthread_mutex_unlock(&mutex);
}else if(strncmp("Tmean", found, 5) == 0){ // send user meanT
if(!isfinite(meanT) || meanT < ABS_ZERO_T) break; // wrong value
L = snprintf(tbuf, 128, "%.2f\n", meanT);
if(L != write(sock, tbuf, L)) WARN("write()");
}else if(strncmp("ReBoOt", found, 6) == 0){
@ -300,6 +302,19 @@ Item quick_select(Item *idata, int n){
#undef PIX_SORT
#undef ELEM_SWAP
// get RMS
double sigma(double *data, int n){
if(n < 2) return 0.;
double sum = 0., sum2 = 0.;
for(int i = 0; i < n; ++i){
double d = data[i];
sum += d;
sum2 += d*d;
}
sum /= n; sum2 /= n;
return sqrt(sum2 - sum*sum);
}
static void process_T(){
int i, N, p, Num = 0;
time_t tmeasmax = 0;
@ -325,22 +340,24 @@ static void process_T(){
}
// calculate mean
double Tmed = quick_select(arr, Num);
double Tbot = Tmed - 10., Ttop = Tmed + 10.;
DBG("Got %d values, Tmed=%g, tmeasmax=%zd", Num, Tmed, tmeasmax);
// throw out all more than +-10degrC and calculate meanT
double rms3 = 3. * sigma(arr, Num);
// bounds: +-3RMS
double Tbot = Tmed - rms3, Ttop = Tmed + rms3;
DBG("Got %d values, Tmed=%g, Trms=%g, tmeasmax=%zd", Num, Tmed, rms3/3., tmeasmax);
// throw out all more than +-3RMS and calculate meanT
Num = 0;
double Tsum = 0.;
// remove bad/old values of N2 controller
// remove bad/old values
for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){
if(tmeasmax - tmeasured[p][N][0] > OLDESTTM){ // not longer than 3 minutes ago!
t_last[p][N][0] = -300.;
t_last[p][N][0] = WRONG_T;
}
}
for(i = 1; i <= NCTRLR_MAX; ++i){
for(p = 0; p < 2; ++p) for(N = 0; N <= NCHANNEL_MAX; ++N){
double T = t_last[p][N][i];
if(T > Ttop || T < Tbot || tmeasmax - tmeasured[p][N][i] > OLDESTTM){ // not longer than 3 minutes ago!
t_last[p][N][i] = -300.;
t_last[p][N][i] = WRONG_T;
}else{
DBG("t_last[%d][%d][%d]=%.1f, measuredt=%zd", p, N, i, T, tmeasured[p][N][i]);
++Num; Tsum += T;
@ -357,16 +374,15 @@ static void process_T(){
if(Nmean[p][N][i]){
Tmean[p][N][i] /= Nmean[p][N][i];
Nmean[p][N][i] = 0;
}else Tmean[p][N][i] = -300.; // no data
}else Tmean[p][N][i] = WRONG_T; // no data
}
plot(Tmean, G->savepath);
DBG("memset start");
memset(Tmean, 0, sizeof(double)*2*(NCTRLR_MAX+1)*(NCHANNEL_MAX+1));
DBG("memset end");
Nmeanmax = 0;
}
}
meanT = Tsum / Num;
if(Num) meanT = Tsum / Num;
else meanT = WRONG_T; // no good measurements
DBG("got %d, mean: %g\n\n", Num, meanT);
}
@ -402,7 +418,8 @@ static void daemon_(int sock){
tgot = dtime();
process_T(); // get new temperatures & throw out bad results
for(i = 0; i <= NCTRLR_MAX; ++i){ // scan over controllers
for(int N = 0; N <= NCHANNEL_MAX; ++N) for(int p = 0; p < 2; ++p){
int N, p;
for(N = 0; N <= NCHANNEL_MAX; ++N) for(p = 0; p < 2; ++p){
double T = t_last[p][N][i];
char **buf;
size_t *len;

View File

@ -27,6 +27,11 @@
// timeout for socket closing
#define SOCKET_TIMEOUT (5.0)
// absolute zero: all T < ABS_ZERO_T are wrong
#define ABS_ZERO_T (-273.15)
// undoubtedly wrong T
#define WRONG_T (-300.)
void daemonize(char *port);
const char *gotstr(int N);
void TurnOFF();

View File

@ -1,4 +1,5 @@
#No dT (Treal = T - dT)
111 0.1
251 -0.7
320 0.12
330 0.15