///////////////////////////////////////////////////////////////////////////////////// /// 電力モニター  /// V01-L01: 2015.03.13 電力計測&保存 基本バージョン Ns=3077 /// PC連携は次期バージョン迄保留 /// //////////////////////////////////////////////////////////////////////////////////// #define DEB 0 // 1:デバッグモード #define AC100 1 // AC200 を AC100 で代用 #define HEMS 0 // HEMS運用 適用電圧を指定 #define Lip 112 // web local ip 111:通常 112:TEST #define MasInit 0 // Mas 強制初期化(当日分) #include #include #include #include #include #include #include #include #define SDchipSelect 4 typedef struct { volatile uint8_t SS; volatile uint8_t Ms; volatile uint8_t HH; volatile uint8_t We; volatile uint8_t DD; volatile uint8_t MM; volatile unsigned int YY; } tim_def; tim_def Tday; tim_def Hday; // Hx 時刻 load save IPAddress ip(192,168,0, Lip); // 固定IP byte mac[] = { 0x00, 0x50, 0xc2, 0x97, 0x22, 0xc4 }; // MACアドレス unsigned int localPort = 8888; // UDPローカルポート番号 IPAddress timeServer(133, 243, 238, 164); // NTPタイムサーバIPアドレス(ntp.nict.jp NTP server) const int NTP_PACKET_SIZE= 48; // NTPパケットバッファサイズ byte packetBuffer[NTP_PACKET_SIZE]; // NTP送受信用パケットバッファ EthernetUDP Udp; // Udpクラス unsigned long lastSendPacketTime = 0; // 最後にパケットを送信した時間(ミリ秒) EthernetServer server(80); // (port 80 is default for HTTP): #define CT 6 // CT数(パワコン実装数) #define CTm CT+1 // CTテーブル数 #define Txm CT+6 // ADCテーブル個数max #define Txn Txm-1 // ADCテーブルmax #define KPp 1.0 // 電力量調整係数(発電) #define KPu 1.0 // 電力量調整係数(売買) #define AREF 2.5 // アナログ基準電圧 5v/2 const float KVT = float(AREF/512.0/(180.0/540.0)/5.1036*100.0); // 電圧センサ係数 100.0v-->5.1036v *(180/540) / 2.5 * 511 AC100 const float KCT0 = float(AREF/512.0*3000.0/ 32.0); // 電流センサ係数 幹線 (公称変流比:3000:1) const float KCT1 = float(AREF/512.0*3000.0/190.0); // 電流センサ係数 PWC (公称変流比:3000:1) const float KCTu = (1.0); // 電流センサ係数 売買 float KVTx[3] = { KVT,KVT,KVT}; // KVT float KCux[2] = { KCTu,KCTu}; // KCTu float KCTx[CTm] = { KCT0*1.0, //0 電流センサ係数 = KCT0*1.0 KCT1*1.0, //1 = KCT1*1.0 KCT1*1.0, //2 KCT1*1.0, //3 KCT1*1.0, //4 KCT1*1.0, //5 KCT1*1.0}; //6 #if HEMS const byte KCTv[CTm] = { 0,0,1,2,0,1,2}; // 適用電圧 0..CT #endif const byte Tpx[Txm]={ 2, //00 Z ゼロV基準電圧 3, //01 V1 系統電圧1 4, //02 V2 系統電圧2 0, //03 CTa 電力売買1 0, //04 CTb 電力売買2 5, //05 CT0 幹線電力 8,9,10,11,12,13}; //06 CT1..6,7..9 CT パワコンetc個別電力 const byte Tox[]={0x48,0x49,0x4a,0x4b}; // I2C 温度センサーアドレス const byte Ton = 1; // 温度センサー数 const byte Tonn = 4; // 温度センサー数(テーブル) const byte THs = 5; // 開始時刻 const byte THe = 19; // 終了時刻 const byte TH = THe-THs+1; // 時刻テーブル数 const char DayTimFmt[]="%4d.%02d.%02d %02d:%02d.%02d"; const char DayFmt[] ="%4d.%02d.%02d"; const char TimFmt[] ="%02d:%02d.%02d"; const char DirF[] ="%04d/%02d"; // yyyy\mm const char fnaF[] ="%s/%04d%02d%02d"; // yyyymmdd const float F10 = 10.0; const float F200 = 200.0; const float F1000 = 1000.0; const float F128 = 128.0; const byte N255 = 255; const byte N60 = 60; const byte N32 = 32; const byte N10 = 10; uint8_t px,pz; // pin ix int Z; // ADC 0電位 int ADCX[Txm]; // ADC ////////////////////////////////////// ADC時に集計 unsigned int Nc,Ncs; // 集計数 1set/sec unsigned long Vs0; // sum(X*X) sqrt (-> 実効) unsigned long Vs1; // sum(X*X) sqrt (-> 実効) unsigned long Vs2; // sum(X*X) sqrt (-> 実効) unsigned long Isu1; // sum(X*X) sqrt (-> 実効) unsigned long Isu2; // sum(X*X) sqrt (-> 実効) unsigned long Is[CTm]; // sum(X*X) sqrt (-> 実効) long Psu; // U:売買電力 W /(sec)=sum(瞬時電圧 x 瞬時電流) long Psp[CTm]; // P:有効電力 W /(sec)=sum(瞬時電圧 x 瞬時電流) int Ns; // 1秒間の集計数 ////////////////////////////////////// 1sec毎に算出 float Vr0; // 実効 rms(sec) float Vr1; // 実効 rms(sec) float Vr2; // 実効 rms(sec) float Iu1; // 実効 rms(sec) float Iu2; // 実効 rms(sec) float Ir[CTm]; // 実効 rms(sec) ////////////////////////////////////// 1sec間保持 float Pu; // U:売買電力 <-- Psu W /(sec)=sum(瞬時電圧 x 瞬時電流) float Pp[CTm]; // P:有効電力 <-- Psp W /(sec)=sum(瞬時電圧 x 瞬時電流) ////////////////////////////////////// 平均算出用(1分毎) float Pf; // 発電 w (平均) float Vf0; // 系統電圧 200v (平均) float Vf1; // 系統電圧 100v (平均) float Vf2; // 系統電圧 100v (平均) int Nss; // 1秒間の集計数 (=Ns) int Onr[Tonn]; // 温度 1/128度 ////////////////////////////////////// 1分毎の情報 typedef struct { // float Pa; // 発電 w (平均) float Va0; // 系統電圧 200v (平均) float Va1; // 系統電圧 100v (平均) float Va2; // 系統電圧 100v (平均) int Om; // 1/128 度 abs(max) } Mx_def; ////////////////////////////////////// 1時間毎の情報 typedef struct { // float Pm; // 発電 w (最大) float Vm0; // 系統電圧 200v (最大) float Vm1; // 系統電圧 100v (最大) float Vm2; // 系統電圧 100v (最大) int Om[Tonn]; // 1/128 度 abs(max) (最大) float Pu; // 売買量 wh (時刻単位) float Ph[CTm]; // 発電量 wh (時刻単位) } Hx_def; Mx_def Mxx; // sec Hx_def Hx0; // 0:day 集計 Hx_def Hxx; // 5[1]..19[16] 集計 Mx_def Mxw; // work Hx_def Hxw; // work byte F_AutoT=0; // 自動調整 char F_samp; // サンプリングフラグ 1:記録中 char F_sec; // 1sec 集計フラグ -1:集計しない 0:集計中 1:1秒経過 char CalcMode=0; // 集計制御 char F_24H=0; // 日付合わせ char F_DayBegin=0; // 集計処理開始 char F_DayEnd=0; // 集計後処理 char F_SD; // 1:ok -1:NG char F_TBLSave=0; // データ保存T char F_NTP=0; // NTP call char F_ondo=0; // 温度call char F_Dsp=0; // 表示 // set up variables using the SD utility library functions: File Mst; // SD EthernetClient client; typedef struct { unsigned int YY; uint8_t MM; uint8_t DD; } day_def; day_def Sday,Eday; // 開始日,終了日(保存日) //---------------------------------------------------------------------------------- #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) void analogReadH() { uint8_t pin; pz=px; pin=Tpx[pz]; // 集中分散型V1,CT1..6を順番 if ((F_AutoT>0)&&(pz>0)) pin=Tpx[1]; // ADCSRA = 0x8E; // ADEN=1, ADIE = 1, ADPS[2-0] = 64 1000 1110 927 // ADCSRA = 0x8D; // ADEN=1, ADIE = 1, ADPS[2-0] = 32 1000 1101 1220 ADCSRA = 0x8C; // ADEN=1, ADIE = 1, ADPS[2-0] = 16 1000 1100 3287 #if defined(__AVR_ATmega32U4__) // pin = analogPinToChannel(pin); ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); #elif defined(ADCSRB) && defined(MUX5) // the MUX5 bit of ADCSRB selects whether we're reading from channels // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); #endif // set the analog reference (high two bits of ADMUX) and select the // channel (low 4 bits). this also sets ADLAR (left-adjust result) // to 0 (the default). #if defined(ADMUX) // ADMUX = (analog_reference << 6) | (pin & 0x07); ADMUX = (1 << 6) | (pin & 0x07); // 0100 0xxx #endif sbi(ADCSRA, ADSC); // start the conversion } ////////////////////////////////////////////////// ADC 完了 //////////////// ISR(ADC_vect) { uint8_t low, high, p; int ans; int k; long Vc0,Vc1,Vc2,Ic0,Ic1,Ic2; p=pz; // read px low =ADCL; high=ADCH; ans= (high << 8) | low; if (F_sec!=0) { Nc=0; Vs0=Vs1=Vs2=0; Isu1=Isu2=0; memset(Is,0,sizeof(Is)); Psu=0; memset(Psp,0,sizeof(Psp)); F_samp=1; px=pz=0; } else { while(1) // next pin { px++; if (px>=Txm) { px=0; break; } if (Tpx[px]>0) break; } } if (F_samp>=0) analogReadH(); // using px 読込指示 if (F_sec==0) { if (p==0) Z=ans; else ADCX[p]=ans-Z; #if AC100 if (p==2) ADCX[p]=-ADCX[p]; // テスト環境 #endif if (p>=Txn) { Z=ADCX[0]; if (Tpx[1]>0) { Vc1=ADCX[1]; Vs1+=Vc1*Vc1; Vc2=ADCX[2]; Vs2+=Vc2*Vc2; Vc0=Vc1+Vc2; Vs0+=Vc0*Vc0; } if (Tpx[3]>0) { Ic1=ADCX[3]; Isu1+=Ic1*Ic1; Ic2=ADCX[4]; Isu2+=Ic2*Ic2; if (Tpx[1]>0) Psu+=(Vc1*Ic1+Vc2*KVT*Ic2); } for(k=0;k<=CT;k++) { if (Tpx[5+k]>0) { Ic0=ADCX[5+k]; Is[k]+=Ic0*Ic0; #if HEMS switch (KCTv[k]) { case 0 : Psp[k]+=(Vc0*Ic0); break; case 1 : Psp[k]+=(Vc1*Ic0); break; case 2 : Psp[k]+=(Vc2*Ic0); break; } #endif #if (HEMS==0) Psp[k]+=(Vc0*Ic0); #endif } } Nc++; } } else { if (F_sec>0) F_sec=0; } } ////////////////////////////////////////////// TimeUp /////////// void TimeUp() { int i; Hday=Tday; // backup if (++Tday.SS>=N60) { Tday.SS=0; if (++Tday.Ms>=N60) { Tday.Ms=0; if (++Tday.HH>=24) { Tday.HH=0; if (++Tday.We>6) { Tday.We=0; } ++Tday.DD; NextDay(); } if (Tday.HH== 0) F_24H =1; if (Tday.HH== THs) F_DayBegin=1; if (Tday.HH==(THe+1)) F_DayEnd =1; } } if (CalcMode>0) { if (Nc>0) SecCalc(); F_sec=1; F_ondo=1; // 集計1秒経過フラグ if (Tday.SS==59) F_TBLSave =1; // 1分毎に保存 } } //////////////////////////////////////////// setup //////////////////////////// void setup() { Serial.begin(115200); Serial.println("setup begin"); delay(100); memset(&Tday,0,sizeof(Tday)); Net_init(); pinMode(53, OUTPUT); if (SD.begin(SDchipSelect)) F_SD=1; else F_SD=-1; SdFile::dateTimeCallback( &dateTime ); Serial.print("NTP..."); while(Tday.YY==0) { if (NTP_Call()==0) break; delay(3*1000); } // 30sec後にトライ Serial.println("XX"); Hday=Tday; Wire.begin(); // I2c初期化 for(int i=0;i=THs)&&(Tday.HH<=THe)) F_DayBegin=1; // F_DayBegin=1; // デバッグ TdayDsp(); } ////////////////////////////////////////////////////// Loop /////////// void loop() { int k; if (F_24H >0) { Ns=0; TBLinit(Tday.YY,Tday.MM,Tday.DD); // 当日データーファイル作成 F_24H=0; } if (F_DayBegin>0) { TBLLoadHx(Tday.YY,Tday.MM,Tday.DD, 0 ,(char*)&Hx0); // 集計領域読込み(日計) TBLLoadHx(Tday.YY,Tday.MM,Tday.DD,Tday.HH ,(char*)&Hxx); // 集計領域読込み(時刻) TBLLoadMx(Tday.YY,Tday.MM,Tday.DD,Tday.HH,Tday.HH,(char*)&Mxx); // 集計領域読込み(分) px=pz=0; F_samp=0; // ADC ON F_sec=-1; // ADC INIT analogReadH(); CalcMode=1; // 集計開始 F_DayBegin=0; } if (F_DayEnd >0) { F_samp=-1; // ADC OFF CalcMode=0; // 集計中止 // DayUpdate(); // 1日分を月・年へ加算更新 F_DayEnd=0; } if (F_NTP>0) { F_NTP=0; } if (F_ondo>0) { OndoSet(); // 温度計測 F_ondo=0; } if (F_TBLSave>0) // データ保存(1分ごと) { if (F_AutoT==0) TBLSave(Tday.YY,Tday.MM,Tday.DD,Tday.HH,Tday.Ms); // 集計領域書込み F_TBLSave=0; } if (F_Dsp>0) // リアル表示(1秒以内で完結が望ましい) { Serial.print("Nc="); Serial.print(Ncs); Serial.print(" V0="); Serial.print(Vr0,2); Serial.print(" V1="); Serial.print(Vr1,2); Serial.print(" V2="); Serial.print(Vr2,2); Serial.print(" I0="); Serial.print(Ir[0],1); Serial.print(" P="); for(k=0;k<=CT;k++) { Serial.print(Pp[k]/1000,3); Serial.print(" "); } Serial.println(); F_Dsp=0; } if (Tday.SS<50) web_server(); // WEBサーバー処理 } /////////////////////////////////////////////////////////////// SecCalc //////////////////////// int SecCalc() // 集計 { int i,k; float Pw; if (Tday.HH>Hday.HH) memset(&Hxx,0,sizeof(Hxx)); // 時刻集計初期化 Ncs=Nc; if (Tpx[1]>0) { Vr0=(float)sqrt(Vs0/Nc)*KVTx[0]; //if (Vr0<10) Vr0=0; Vr1=(float)sqrt(Vs1/Nc)*KVTx[1]; //if (Vr1<10) Vr1=0; Vr2=(float)sqrt(Vs2/Nc)*KVTx[2]; //if (Vr2<10) Vr2=0; } else { Vr1=100; Vr2=100; Vr0=Vr1+Vr2; } if (Tpx[3]>0) { Iu1=(float)sqrt(Isu1/Nc)*KCux[0]; Iu2=(float)sqrt(Isu2/Nc)*KCux[0]; Pu=Psu/Nc*KVTx[0]*KCux[0]; } if (Tpx[5]>0) { Ir[0]=(float)sqrt(Is[0]/Nc)*KCTx[0]; if (Tpx[1]>0) Pp[0]=Psp[0]/Nc*KCTx[0]*KVTx[0]*KPp; else Pp[0]=Vr0*Ir[0]; } else { Ir[0]=0; Pp[0]=0; } if (CT>0) { for(k=1;k<=CT;k++) { Ir[k]=(float)sqrt(Is[k]/Nc)*KCTx[k]; if (Tpx[1]>0) Pp[k]=Psp[k]/Nc*KCTx[k]*KVTx[0]*KPp; else Pp[k]=Vr0*Ir[k]; if (Tpx[5]==0) { Ir[0]+=Ir[k]; Pp[0]+=Pp[k]; } } } for(k=0;k<=CT;k++) { Pw=Pp[k]/3600; Hxx.Ph[k]+=Pw; Hx0.Ph[k]+=Pw; } // 有効電力 積算 if (Tpx[3]>0) { Pw=Pu/3600; Hxx.Pu+=Pw; Hx0.Pu+=Pw; } // 売買電力 積算 if (Ns==0) { Vf0=Vr0; Vf1=Vr1; Vf2=Vr2; Pf=Pp[0]; Ns=1; // 平均用集計 Hxx.Pm =Hx0.Pm =Pp[0]; Hxx.Vm0=Hx0.Vm0=Vr0; Hxx.Vm1=Hx0.Vm1=Vr1; Hxx.Vm2=Hx0.Vm2=Vr2; } else { Vf0+=Vr0; Vf1+=Vr1; Vf2+=Vr2; Pf+=Pp[0]; Ns++; // 平均用集計 if (Hxx.Pm0) { Mxx.Pa =Pf /Ns; Mxx.Va0=Vf0/Ns; Mxx.Va1=Vf1/Ns; Mxx.Va2=Vf2/Ns; } else { memset(&Mxx,0,sizeof(Mxx)); } Pf=Vf0=Vf1=Vf2=Ns=0; Hxw=Hxx; } F_Dsp=1; } void DayUpdate() // 1日分を累計 { } void OndoSet() { uint16_t val; long int ival; int i,j; for(i=0;i")); } void put_TDr() { client_print_P(PSTR("")); } void put_TDc() { client_print_P(PSTR("")); } void put_TDl() { client_print_P(PSTR("")); } void put_TDe() { client_print_P(PSTR("")); } void put_TRs() { client_print_P(PSTR("")); } void put_TRc() { client_print_P(PSTR("")); } void put_TRr() { client_print_P(PSTR("")); } void put_TRe() { client_print_P(PSTR("")); } void put_TABLEs() { client_print_P(PSTR("")); } void put_TABLEe() { client_print_P(PSTR("
")); } void put_Err() { client_print_P(PSTR("Err")); } void put_PD() { client_print_P(PSTR(",")); } void put_0() { client_print_P(PSTR("0")); } void web_server() { client = server.available(); int i,j,k,g; char c; day_def Xday; char Get[10]; char str[21]; char Dir[8]; char fna[22]; unsigned long pos; File Mst; // SD memset(Get,0,sizeof(Get)); g=-1; if (client) { #if DEB Serial.println("new client"); #endif // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { c = client.read(); if (g<0) { if (c=='/') g=0; } else { if (c==' ') g=99; if (g")); client_println_P(PSTR("")); if (Get[0]=='*') client_println_P(PSTR("")); else client_println_P(PSTR("")); client_print_P(PSTR("")); client_print_P(PSTR("")); put_sawayaka(); client_print_P(PSTR("")); client_print_P(PSTR("")); client_println_P(PSTR("")); if (Get[0]!='C') { put_TABLEs(); put_TRs(); put_TDs(); put_sawayaka(); put_TDe(); if (Xday.YY==0) { Xday.YY=Tday.YY; Xday.MM=Tday.MM; Xday.DD=Tday.DD; } switch (Get[0]) { case 'J': snprintf(str,sizeof(str),DayFmt,Xday.YY,Xday.MM,Xday.DD); break; case 'D': snprintf(str,sizeof(str),"%04d.%02d",Xday.YY,Xday.MM); break; default: snprintf(str,sizeof(str),DayTimFmt,Tday.YY,Tday.MM,Tday.DD,Tday.HH,Tday.Ms,Tday.SS); } if (Get[0]!='Y') { put_TDs(); client.print(str); put_TDe(); } put_TRe(); put_TABLEe(); } if ((Get[0]=='*')&&(CalcMode>0)) { put_TABLEs(); put_TRc(); put_TDl(); client_print_P(PSTR("系統電圧(V)"));put_TDe(); put_TDr(); client.print(Vr0,1); put_TDe(); put_TDs(); client.print(Vr1,1); put_TDe(); put_TDs(); client.print(Vr2,1); put_TDe(); put_TDs(); client_print_P(PSTR("温度(℃)")); put_TDe(); for(i=0;i0)) { put_TABLEs(); put_TRc(); put_TDs(); put_TDe(); put_TDs(); client_print_P(PSTR("有効電力(W)")); put_TDe(); put_TDs(); client_print_P(PSTR("電流(A)")); put_TDe();put_TRe(); for(i=0;i<=CT;i++) { put_TRr(); put_TDc(); client.print(i); put_TDe(); put_TDs(); client.print(Pp[i],0); put_TDe(); put_TDs(); client.print(Ir[i],1); put_TDe(); put_TRe(); } put_TABLEe(); } if ((Get[0]=='*')&&(CalcMode>0)) // 時刻別 { put_TABLEs(); put_TRc(); put_TDs(); client_print_P(PSTR("時刻"));put_TDe(); for(i=0;i<=CT;i++) { put_TDs(); client.print(i); put_TDe(); } put_TDs(); client_print_P(PSTR("max(KW)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); for(i=0;i0) client.print(Hxw.Ph[i],0); put_TDe(); } put_TDs(); if (Hxw.Pm >0) client.print(Hxw.Pm/F1000,2); put_TDe(); put_TDs(); if (Hxw.Vm0>0) client.print(Hxw.Vm0,1); put_TDe(); put_TDs(); if (Hxw.Vm1>0) client.print(Hxw.Vm1,1); put_TDe(); put_TDs(); if (Hxw.Vm2>0) client.print(Hxw.Vm2,1); put_TDe(); for(i=0;i0) client.print(Hxw.Om[i]/F128,1); put_TDe(); } put_TRe(); } put_TABLEe(); } if (Get[0]=='J') // 時刻別 { snprintf(Dir,sizeof(Dir),DirF ,Xday.YY,Xday.MM); snprintf(fna,sizeof(fna),fnaF,Dir,Xday.YY,Xday.MM,Xday.DD); Mst=SD.open(fna); if (!(Mst)) break; put_TABLEs(); put_TRc(); put_TDs(); client_print_P(PSTR("時刻")); put_TDe(); for(i=0;i<=CT;i++) { put_TDs(); client.print(i); put_TDe(); } put_TDs(); client_print_P(PSTR("max(KW)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); put_TDs(); client_print_P(PSTR("max(V)")); put_TDe(); for(i=0;i0) client.print(j); else client_print_P(PSTR("wh")); put_TDe(); for(i=0;i<=CT;i++) { put_TDs(); if (Hxw.Ph[i]>0) client.print(Hxw.Ph[i],0); put_TDe(); } put_TDs(); if (Hxw.Pm >0) client.print(Hxw.Pm/F1000,2); put_TDe(); put_TDs(); if (Hxw.Vm0>0) client.print(Hxw.Vm0,1); put_TDe(); put_TDs(); if (Hxw.Vm1>0) client.print(Hxw.Vm1,1); put_TDe(); put_TDs(); if (Hxw.Vm2>0) client.print(Hxw.Vm2,1); put_TDe(); for(i=0;i0) client.print(Hxw.Vm0 ,1); put_PD(); if (Hxw.Vm1 >0) client.print(Hxw.Vm1 ,1); put_PD(); if (Hxw.Vm2 >0) client.print(Hxw.Vm2 ,1); put_PD(); for(i=0;i< 4;i++) { if (Hxw.Om[i] >0) client.print(Hxw.Om[i]/F128,1); put_PD(); } if (k>0) { for(i=0;i 0) client.print(Mxw.Pa/F1000,2); put_PD(); // 平均 if (Mxw.Va0>0) client.print(Mxw.Va0,1); put_PD(); if (Mxw.Va1>0) client.print(Mxw.Va1,1); put_PD(); if (Mxw.Va2>0) client.print(Mxw.Va2,1); put_PD(); if (Mxw.Om >0) client.print(Mxw.Om/F128,1); put_PD(); } } client.println("*"); } Mst.close(); } else { put_PD(); client.println("*"); snprintf(str,sizeof(str),TimFmt,Tday.HH,Tday.Ms,Tday.SS); client.print(str); put_PD(); client.println("*"); for(i=0;i<=CT;i++) { client.print(i); put_PD(); client.print(Pp[i]); put_PD(); client.print(Ir[i],1); put_PD(); client.print(Hxx.Ph[i],0); put_PD(); client.print(Hx0.Ph[i],0); put_PD(); client.println("*"); } client_print_P(PSTR("v,")); client.print(Vr0 ,1); put_PD(); put_PD(); put_PD(); client.print(Hxx.Vm0,1); put_PD(); client.print(Hx0.Vm0,1); put_PD(); client.println("*"); client_print_P(PSTR("v,")); client.print(Vr1,1); put_PD(); put_PD(); put_PD(); client.print(Hxx.Vm1,1); put_PD(); client.print(Hx0.Vm1,1); put_PD(); client.println("*"); for(i=0;i")); client_println_P(PSTR(" ")); client.flush(); // myGLCD.print(" ",16,cy_mgs); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); #if DEB Serial.println("client disonnected"); Serial.flush(); #endif } }