From 478ad21c7a591d9df0d5b38d83c3ec8fcb4695b6 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 4 Jul 2022 18:05:08 +0300 Subject: [PATCH] some fixes with meteo --- BTA_modbusmeteo/bta_meteo_modbus.c | 31 +- BTA_modbusmeteo/bta_meteo_modbus.h | 5 +- BTA_modbusmeteo/main.c | 2 +- BTA_modbusmeteo/olddaemon/bta_meteo_can.c | 371 ++++++++++------------ 4 files changed, 197 insertions(+), 212 deletions(-) diff --git a/BTA_modbusmeteo/bta_meteo_modbus.c b/BTA_modbusmeteo/bta_meteo_modbus.c index fb8a32c..8544c41 100644 --- a/BTA_modbusmeteo/bta_meteo_modbus.c +++ b/BTA_modbusmeteo/bta_meteo_modbus.c @@ -82,18 +82,20 @@ static int crc_check(uint8_t *buffer, int length){ uint8_t byte; uint16_t crc = 0xFFFF; int valid_crc; + /* #ifdef EBUG printf("buffer: "); for(int i = 0; i < length; ++i) printf("%02x ", buffer[i]); printf("\n"); #endif + */ while (length-- > 2) { byte = *buffer++ ^ crc; crc >>= 8; crc ^= crc16_table[byte]; } valid_crc = (crc >> 8) == buffer[1] && (crc & 0xFF) == buffer[0]; - DBG("CRC %s", valid_crc ? "OK" : "bad"); + if(!valid_crc) DBG("CRC BAD"); return valid_crc; } @@ -150,12 +152,12 @@ params_ans check_meteo_params(){ if(portfd < 0) return ANS_LOSTCONN; int n_bytes = -1, res, size = 0; uint8_t meteoflags = 0; - uint16_t lastpar = 0; + static uint16_t lastpar = 0; unsigned char buffer[MODBUS_MAX_PACKET_SIZE]; struct timeval timeout; fd_set set; - time_t tstart = time(NULL); - int ctr = 50; // max 50 tries + //time_t tstart = time(NULL); + int ctr = 30; // max 30 tries while(ctr--){ FD_ZERO(&set); FD_SET(portfd, &set); @@ -173,13 +175,21 @@ params_ans check_meteo_params(){ } size += n_bytes; if(n_bytes) continue; + }else if(size == 0){ + //DBG("no data"); + return ANS_NODATA; } + DBG("Ctr=%d, size=%d, res=%d", ctr, size, res); // read all or end of packet if(size > 0 && res == 0 && (size == REQ_LEN || size == ANS_LEN)){ if(crc_check(buffer, size)){ if(size == REQ_LEN){ + DBG("request"); + ctr = 30; lastpar = buffer[2] << 8 | buffer[3]; }else if(size == ANS_LEN){ + ctr = 30; + DBG("answer"); uint16_t val = buffer[3] << 8 | buffer[4]; int prval = 1; float f = (float)val / 10.f; @@ -231,19 +241,26 @@ params_ans check_meteo_params(){ default: prval = 0; } - if(prval) DBG("=%.1f\n", f); lastpar = 0; + if(prval){ + DBG("=%.1f\n", f); + return ANS_OK; + } } } size = 0; } + /* if(meteoflags == ALLFLAGS){ DBG("Got all data"); return ANS_OK; } - if(time(NULL) - tstart >= METEO_TIMEOUT) return ANS_NOTFULL; + if(time(NULL) - tstart >= METEO_TIMEOUT){ + DBG("Timeout, not all data meteoflags=0x%02X instead of 0x%02X", meteoflags, ALLFLAGS); + return ANS_NODATA; + }*/ } - return ANS_NOTFULL; + return ANS_NODATA; } diff --git a/BTA_modbusmeteo/bta_meteo_modbus.h b/BTA_modbusmeteo/bta_meteo_modbus.h index beac43f..919b570 100644 --- a/BTA_modbusmeteo/bta_meteo_modbus.h +++ b/BTA_modbusmeteo/bta_meteo_modbus.h @@ -20,12 +20,13 @@ #define BTA_METEO_MODBUS_H__ // data reading timeout (in seconds) -#define METEO_TIMEOUT 5 +#define METEO_TIMEOUT 15 typedef enum{ ANS_OK, // all OK ANS_LOSTCONN, // lost connection - ANS_NOTFULL // got not full dataset (or nothing at all) + ANS_NODATA, // no data yet +// ANS_NOTFULL // got not full dataset (or nothing at all) } params_ans; int connect2tty(); diff --git a/BTA_modbusmeteo/main.c b/BTA_modbusmeteo/main.c index a53788d..84e9dde 100644 --- a/BTA_modbusmeteo/main.c +++ b/BTA_modbusmeteo/main.c @@ -114,7 +114,7 @@ int main(int argc, char *argv[]){ return 1; } params_ans a = check_meteo_params(); - DBG("chk_meteo: %d", a); + if(a != ANS_NODATA) DBG("chk_meteo: %d", a); if(a == ANS_LOSTCONN){ LOG("Lost connection with device, reconnect!"); clear_flags(); diff --git a/BTA_modbusmeteo/olddaemon/bta_meteo_can.c b/BTA_modbusmeteo/olddaemon/bta_meteo_can.c index 44f4c38..0277718 100644 --- a/BTA_modbusmeteo/olddaemon/bta_meteo_can.c +++ b/BTA_modbusmeteo/olddaemon/bta_meteo_can.c @@ -67,19 +67,18 @@ static void myabort(int sig) { char ss[10], tmp[80]; signal(sig,SIG_IGN); switch (sig) { - case SIGHUP : strcpy(ss,"SIGHUP"); break; - case SIGINT : strcpy(ss,"SIGINT"); break; - case SIGQUIT: strcpy(ss,"SIGQUIT"); break; - case SIGFPE : strcpy(ss,"SIGFPE"); break; - case SIGPIPE: strcpy(ss,"SIGPIPE"); break; - case SIGSEGV: strcpy(ss,"SIGSEGV"); break; - case SIGTERM: strcpy(ss,"SIGTERM"); break; - default: sprintf(ss,"SIG_%d",sig); break; + case SIGHUP : strcpy(ss,"SIGHUP"); break; + case SIGINT : strcpy(ss,"SIGINT"); break; + case SIGQUIT: strcpy(ss,"SIGQUIT"); break; + case SIGFPE : strcpy(ss,"SIGFPE"); break; + case SIGPIPE: strcpy(ss,"SIGPIPE"); break; + case SIGSEGV: strcpy(ss,"SIGSEGV"); break; + case SIGTERM: strcpy(ss,"SIGTERM"); break; + default: sprintf(ss,"SIG_%d",sig); break; } print_date(stderr); switch (sig) { default: - case SIGHUP : case SIGINT : fprintf(stderr,"%s: %s - Ignore .....\n",myname,ss); @@ -102,8 +101,7 @@ static void myabort(int sig) { static int rxpnt; static double rxtime; -int main (int argc, char *argv[]) -{ +int main (int argc, char *argv[]){ double tcurr, tlast, tok, twndok; char msg[60]; double t0=0., t; @@ -139,200 +137,169 @@ int main (int argc, char *argv[]) t0 = tcurr = tlast = tok = twndok = dtime(); tok -= 600.; - while (1) { - char *pep = "RK"; - int nch = 0; - dsleep(0.2); - tcurr = dtime(); - if(PEP_A_On && PEP_R_On) { - if(!stop_prog && !start && tcurr-tok>15.) { - idt = 0x447; - dlen=6; - tdata[0] = 7; - tdata[2] = 50; /* 0.5s */ - tdata[3] = 1; - tdata[4] = 0; tdata[5] = 50; /* 0.5s */ - for(i=0; i<8; i++) { - if(i==2||i==3||i==5||i==6) /* T-зеркала, ветер, влажность, T на метео-мачте */ - continue; /* пока не используются (заменены) */ - if(i==4) { /*временно: пока АЦП4 идет с PEP-A (давление)*/ - pep = "A"; - idt = 0x40f; /* PEP-A */ - tdata[1] = nch = 4; /* АЦП/4 */ - } else { - pep = "RK"; - idt = 0x447; /* PEP-RK */ - tdata[1] = nch = i; /* АЦП/i */ + while (1){ + char *pep = "RK"; + int nch = 0; + dsleep(0.2); + tcurr = dtime(); + if(PEP_A_On && PEP_R_On){ + if(!stop_prog && !start && tcurr-tok>15.) { + idt = 0x447; + dlen=6; + tdata[0] = 7; + tdata[2] = 50; /* 0.5s */ + tdata[3] = 1; + tdata[4] = 0; tdata[5] = 50; /* 0.5s */ + for(i=0; i<8; i++) { + if(i==2||i==4|i==3||i==5||i==6) /* T-зеркала, ветер, давление, влажность, T на метео-мачте */ + continue; /* пока не используются (заменены) */ + pep = "RK"; + idt = 0x447; /* PEP-RK */ + tdata[1] = nch = i; /* АЦП/i */ + print_date(stderr); + if(can_send_frame(idt, dlen, tdata)<=0) { + fprintf(stderr, "Can't send command \"Start ADC%d\" to PEP-%s!\n", nch,pep); + } else if(tcurr-tlast<70.) + fprintf(stderr, "Send command \"Start ADC%d\" to PEP-%s.\n", nch,pep); + fflush(stderr); + } + start=1; + tok = tcurr; } - print_date(stderr); - if(can_send_frame(idt, dlen, tdata)<=0) { - fprintf(stderr,"Can't send command \"Start ADC%d\" to PEP-%s!\n",nch,pep); - } else if(tcurr-tlast<70.) - fprintf(stderr,"Send command \"Start ADC%d\" to PEP-%s.\n",nch,pep); - fflush(stderr); - } - start=1; - tok = tcurr; - } - if(stop_prog || (start && tcurr-tok>5.)) { - if(!stop_prog) { - print_date(stderr); - fprintf(stderr,"PEP-RK: ADC(0,1,7) (or PEP-A ADC4) timeout!\n"); - } -#if 0 - MeteoMode &= ~SENSOR_T2; - idt = 0x447; - dlen=6; - tdata[0] = 7; - tdata[2] = tdata[3] = tdata[4] = tdata[5] = 0; - for(i=0; i<8; i++) { - if(i==2||i==3||i==5||i==6) /* T-зеркала, ветер, влажность, T на метео-мачте */ - continue; /* пока не используются (заменены) */ - if(i==4) { /*временно: пока АЦП4 идет с PEP-A (давление)*/ - pep = "A"; - idt = 0x40f; /* PEP-A */ - tdata[1] = nch = 4; /* АЦП/4 */ - } else { - pep = "RK"; - idt = 0x447; /* PEP-RK */ - tdata[1] = nch = i; /* АЦП/i */ + if(stop_prog || (start && tcurr-tok>5.)) { + if(!stop_prog) { + print_date(stderr); + fprintf(stderr,"PEP-RK: ADC(0,1,7) (or PEP-A ADC4) timeout!\n"); + } + MeteoMode &= ~SENSOR_T2; + idt = 0x447; + dlen=6; + tdata[0] = 7; + tdata[2] = tdata[3] = tdata[4] = tdata[5] = 0; + for(i=0; i<8; i++) { + if(i==2||i==3||i==5||i==6) /* T-зеркала, ветер, влажность, T на метео-мачте */ + continue; /* пока не используются (заменены) */ + if(i==4) { /*временно: пока АЦП4 идет с PEP-A (давление)*/ + pep = "A"; + idt = 0x40f; /* PEP-A */ + tdata[1] = nch = 4; /* АЦП/4 */ + } else { + pep = "RK"; + idt = 0x447; /* PEP-RK */ + tdata[1] = nch = i; /* АЦП/i */ + } + print_date(stderr); + if(can_send_frame(idt, dlen, tdata)<=0) { + fprintf(stderr,"Can't send command \"Stop ADC%d\" to PEP-%s!\n",nch,pep); + } else if(tcurr-tlast<70.) + fprintf(stderr,"Send command \"Stop ADC%d\" to PEP-%s.\n",nch,pep); + fflush(stderr); + } + if(stop_prog) can_exit(0); + start=0; + tok = tcurr; } - print_date(stderr); - if(can_send_frame(idt, dlen, tdata)<=0) { - fprintf(stderr,"Can't send command \"Stop ADC%d\" to PEP-%s!\n",nch,pep); - } else if(tcurr-tlast<70.) - fprintf(stderr,"Send command \"Stop ADC%d\" to PEP-%s.\n",nch,pep); - fflush(stderr); - } -#endif - if(stop_prog) can_exit(0); - start=0; - tok = tcurr; - } - } else { - if(stop_prog) can_exit(0); - else { - static int tpr = 0; - if(tcurr-tpr>600.) { - if(PEP_R_Off) { - print_date(stderr); - fprintf(stderr,"PEP-RK (ADC0/1/7) turned off!\n"); + } else { + if(stop_prog) can_exit(0); + else { + static int tpr = 0; + if(tcurr-tpr>600.) { + if(PEP_R_Off) { + print_date(stderr); + fprintf(stderr,"PEP-RK (ADC0/1/7) turned off!\n"); + } + if(PEP_A_Off) { + print_date(stderr); + fprintf(stderr,"PEP-A (ADC4) turned off!\n"); + } + tpr=tcurr; + } + if(PEP_R_Off) { + if((MeteoMode & NET_T2)==0) + MeteoMode &= ~SENSOR_T2; + } } - if(PEP_A_Off) { - print_date(stderr); - fprintf(stderr,"PEP-A (ADC4) turned off!\n"); + } + while(can_recv_frame(&rxpnt, &rxtime, &idr, &dlen, rdata)) { + int rcode = 0; + t = rxtime; + if((idr&0xff8)==0x220) { /* код от АЦП PEP-RK */ + static double T2 = 0.; + static int terr=0; + int chan, code; + double volt,T,b,w,h; +adc_pep_rk: + if(dlen!=3) { + static double last_print = 0.; +wrong_frame: + if(tcurr-last_print > 60.) { + print_date(stderr); + fprintf(stderr,"Wrong CAN-frame id=0x%x len=%d < ",idr,dlen); + for(i=0; i\n"); + fflush(stderr); + last_print = tcurr; + } + continue; + } + chan = idr&7; + code = (unsigned int)rdata[0]<<8|rdata[1]; + volt = (double)code/4096.*5.; /* ADC 12bit 0-5V */ + if(chan == 1){ /* АЦП1 - T-подкупольного */ + T = zeroT2 + (volt-zeroV)*scaleT; + /*t2=T;*/ + if(T >= -20. && T <= 30.) { + if((MeteoMode & SENSOR_T2) && fabs(T2-T)<5.) { + if(fabs(T2-T)>0.1) + T2 += (T2>T)? -0.005 : 0.005; + else + T2 = 0.9*T2 + 0.1*T; + } else { + T2=T; + MeteoMode |= SENSOR_T2; + } + } else { + terr |= 2; + if(T<-20.) T2=-20.; + else if(T>30.) T2=30.; + MeteoMode &= ~SENSOR_T2; + } + if((MeteoMode & INPUT_T2)== 0 && (MeteoMode & SENSOR_T2)) + val_T2 = T2; + //printf("Get T=%.1f\n", T2); + tok = t; + } + tok = tlast = t; + }else if(idr==0x21){ /* принят код RK от PEP-контроллера */ + static double off_time = 0.; + static double last_msg_time = 0.; + static char msg[30] = " Туман или осадки."; + static int o_rcode = 0; + rcode = ((unsigned int)rdata[0]<<16)|((unsigned int)rdata[1]<<8)|rdata[2]; + if(rcode & RK_Precipitations){ + if(o_rcode & RK_Precipitations){ // датчик осадков имени Данилова на метео-мачте + if(fabs(M_time-Precip_time>60.)){ // датчик осадков включен 2 считывания подряд + if(Tel_State!=Stopping && Dome_State!=D_Off && fabs(M_time-last_msg_time>30.)){ // реагировать на него не чаще раза в минуту + *msg = MesgFault; // выдать сообщение если идут реальные наблюдения + SendMessage(msg); + last_msg_time = M_time; + } + if(fabs(M_time-off_time)>3.){ // постоянно включен минимум 3сек + Precip_time = M_time; /* информировать другие программы */ + } + } + }else{ // датчик осадков только что включился + if(fabs(M_time-last_msg_time>600.)){ // выдавать сообщение раз в 10 мин + *msg = MesgWarn; + SendMessage(msg); + last_msg_time = M_time; + } + } + }else off_time = M_time; + o_rcode = rcode; } - tpr=tcurr; - } - if(PEP_R_Off) { - if((MeteoMode & NET_T2)==0) - MeteoMode &= ~SENSOR_T2; - } - } - } - while(can_recv_frame(&rxpnt, &rxtime, &idr, &dlen, rdata)) { - int rcode = 0; - t = rxtime; - if(idr==0x447||idr==0x40f) { - pep = (idr==0x40f)? "A" : "RK"; - if(rdata[0]==7) { - if(rdata[2] == 0 && rdata[3] == 0) - fprintf(stderr,"%s PEP-%s: Echo command \"Stop ADC%d\"\n", time2asc(rxtime-timezone),pep,rdata[1]); - else - fprintf(stderr,"%s PEP-%s: Echo command \"Start ADC%d\"\n", time2asc(rxtime-timezone),pep,rdata[1]); - } else if(rdata[0]==8) { - fprintf(stderr,"%s PEP-%s: Echo command \"Stop all ADC\"\n", time2asc(rxtime-timezone),pep); - start=0; - } - fflush(stderr); - } else if(idr==0x20c) { /* временно: код АЦП4 PEP-A - давление */ - if(dlen!=3) - goto wrong_frame; - idr = 0x224; /* временно: имитация АЦП4 PEP-RK */ - goto adc_pep_rk; - } else if((idr&0xff8)==0x220) { /* код от АЦП PEP-RK */ - static double T2 = 0.; - static int ctm=0; - static int terr=0; - int chan, code; - double volt,T,b,w,h; - adc_pep_rk: - if(dlen!=3) { - static double last_print = 0.; - wrong_frame: - if(tcurr-last_print > 60.) { - print_date(stderr); - fprintf(stderr,"Wrong CAN-frame id=0x%x len=%d < ",idr,dlen); - for(i=0; i\n"); - fflush(stderr); - last_print = tcurr; - } - continue; - } - chan = idr&7; - code = (unsigned int)rdata[0]<<8|rdata[1]; - volt = (double)code/4096.*5.; /* ADC 12bit 0-5V */ - if(chan == 1){ /* АЦП1 - T-подкупольного */ - ctm |= 2; /* АЦП1 - T-подкупольного */ - T = zeroT2 + (volt-zeroV)*scaleT; - /*t2=T;*/ - if(T >= -20. && T <= 30.) { - if((MeteoMode & SENSOR_T2) && fabs(T2-T)<5.) { - if(fabs(T2-T)>0.1) - T2 += (T2>T)? -0.005 : 0.005; - else - T2 = 0.9*T2 + 0.1*T; - } else { - T2=T; - MeteoMode |= SENSOR_T2; - } - } else { - terr |= 2; - if(T<-20.) T2=-20.; - else if(T>30.) T2=30.; - MeteoMode &= ~SENSOR_T2; - } - if((MeteoMode & INPUT_T2)== 0 && (MeteoMode & SENSOR_T2)) - val_T2 = T2; -//printf("Get T=%.1f\n", T2); - tok = t; - } - if(chan<3 && (ctm&0x93) == 0x93) { /* АЦП-0,1,4,7 - Ok */ - tok = t; - ctm=0; - } - tlast=t; - }else if(idr==0x21){ /* принят код RK от PEP-контроллера */ - static double off_time = 0.; - static double last_msg_time = 0.; - static char msg[30] = " Туман или осадки."; - static int o_rcode = 0; - rcode = ((unsigned int)rdata[0]<<16)|((unsigned int)rdata[1]<<8)|rdata[2]; - if(rcode & RK_Precipitations){ - if(o_rcode & RK_Precipitations){ // датчик осадков имени Данилова на метео-мачте - if(fabs(M_time-Precip_time>60.)){ // датчик осадков включен 2 считывания подряд - if(Tel_State!=Stopping && Dome_State!=D_Off && fabs(M_time-last_msg_time>30.)){ // реагировать на него не чаще раза в минуту - *msg = MesgFault; // выдать сообщение если идут реальные наблюдения - SendMessage(msg); - last_msg_time = M_time; - } - if(fabs(M_time-off_time)>3.){ // постоянно включен минимум 3сек - Precip_time = M_time; /* информировать другие программы */ - } - } - }else{ // датчик осадков только что включился - if(fabs(M_time-last_msg_time>600.)){ // выдавать сообщение раз в 10 мин - *msg = MesgWarn; - SendMessage(msg); - last_msg_time = M_time; - } - } - }else off_time = M_time; - o_rcode = rcode; - } - fflush(stdout); - } - if(stop_prog) can_exit(0); + fflush(stdout); + } + if(stop_prog) can_exit(0); } }