mirror of
https://github.com/eddyem/tsys01.git
synced 2026-02-01 04:45:05 +03:00
fixed tmean=NaN, constrict valid T range to med(T)+=3RMS
This commit is contained in:
parent
9bfb542dfc
commit
3202beec31
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#No dT (Treal = T - dT)
|
||||
111 0.1
|
||||
251 -0.7
|
||||
320 0.12
|
||||
330 0.15
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user