/* 簡易交流電圧ロガー AC電源波形をADCして実効値を求め、指定間隔でEEPROMに記録する。 入力端子:A0 (負側は無視) 測定周期:120秒(recIntervalで指定) 測定方法:160us間隔で1250回サンプリングを行い、実効値を計算  (160us×1250回=0.2秒なので、50Hzなら10サイクル、60Hzなら   12サイクルに相当) 記録容量:1023バイト(2分間隔なら34時間) 動作モード切り替え:Pin8  リセット時High:読み出し動作  リセット時Low :Highにすると書き込み(旧データーは上書き) 2014/3/27ラジオペンチ http://radiopench.blog96.fc2.com/ */ #include #include #include #include volatile boolean ppsFlag, mesFlag; boolean recFlag; unsigned long v, vSum,v2Sum; float vAVE, vRMS; byte vRMSbyte; int n, recN, count; int recInterval=120; // 記録周期(120秒) LiquidCrystal lcd(12,11,5,4,3,2); // 標準のピンアサイン(液晶シールド) void setup(){ pinMode(8, INPUT); // モード切り替えピン digitalWrite(8, HIGH); pinMode(13, OUTPUT); analogReference(INTERNAL); // Aref=1.1V Serial.begin(9600); lcd.begin(2,16); if(digitalRead(8) == HIGH){ // Pin8がHighなら recFlag=false; // 記録しない for(n=0; n <= 1023; n++){ // EEPROMをダンプ Serial.print(n); Serial.print(", "); Serial.println(EEPROM.read(n)); } } else { // Pin8はLowなら lcd.print("Pin8 Hi to Start"); // 開始メッセージ表示して while(digitalRead(8)== LOW){ // Pin8がHIGHになるまで待って } lcd.clear(); recFlag=true; // 記録フラグON count = recInterval - 1; // すぐに記録開始されるようにしておく } MsTimer2::set(1000, T1); // 1秒毎の割り込みでLOOPを回す MsTimer2::start(); } void loop(){ while(ppsFlag == false){ // 1秒割り込み待ち } ppsFlag=false; Timer1.initialize(160); // 測定インターバルセット(160us) Timer1.attachInterrupt( T2 ); // Timer1起動 vSum=0; v2Sum=0; for(int n =1; n <=1250; n++){ // 160us×1250回=0.2秒 while(mesFlag == false){ // Timer1割り込み待ち(測定インターバル待ち) } mesFlag = false; digitalWrite(13,HIGH); v = analogRead(0); // 電圧読み取り vSum = vSum + v; // Σx 計算 v2Sum = v2Sum + (v * v); // Σx^2 計算 digitalWrite(13,LOW); } Timer1.stop(); vAVE = vSum / 625; // 負側のデータは無いので625で割る vRMS = sqrt(float(v2Sum / 625)); // 同上 vRMSbyte = vRMS; // EEPROM保存用にbyteに変換(最大は255mV=255W) Serial.print(vSum); Serial.print(", "); Serial.print(v2Sum); Serial.print(", "); Serial.println(vRMS); lcd.clear(); lcd.print(vAVE,2); lcd.print(", "); lcd.print(vRMS,2); if(recFlag==true){ count++; if(count == recInterval){ // 120秒周期で記録 if(recN <= 1022){ EEPROM.write(recN,vRMSbyte); EEPROM.write(recN+1, 0xFF); recN++; lcd.setCursor(0,1); lcd.print("Rec! "); lcd.print(recN); lcd.print(", "); lcd.print(vRMSbyte); } count=0; } } } void T1() { // MsTimer2の割り込み処理 ppsFlag = true; // ppsフラグをアサート } void T2() { // Timer1の割り込み処理 mesFlag = true; }