//-------------------------------------------------------------------------------------- double EnergyMonitor::calcIrms(int NUMBER_OF_SAMPLES) { int SUPPLYVOLTAGE = readVcc(); for (int n = 0; n < NUMBER_OF_SAMPLES; n++) { lastSampleI = sampleI; sampleI = analogRead(inPinI); lastFilteredI = filteredI; filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI); // Root-mean-square method current // 1) square current values sqI = filteredI * filteredI; // 2) sum sumI += sqI; } double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / 1023.0); Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES); //Reset accumulators sumI = 0; //-------------------------------------------------------------------------------------- return Irms; }
void VoltMeter::loop() { #ifdef PRECISE_VOLTAGE long vcc=readVcc(); myActualReadValue= (analogRead(myPin) *vcc) / 1023; //as we do precise reading there is no need to average myAveragedReadValue=myActualReadValue; #else myActualReadValue= analogRead(myPin); //As we do not read precisely we average the result myAveragedReadValue=(myAveragedReadValue*8+(2*myActualReadValue))/10; #endif myCentiVolt=(uint16_t)(((uint32_t)myAveragedReadValue*(uint32_t)myMultiplyerValue)/1000UL); }
double readCalcIrms(int pin, int Number_of_Samples) { int sampleI; double filteredI, offsetI, Irms; double sqI,sumI=0; //sq = squared, sum = Sum, inst = instantaneous double ICAL = gParam.rede.calibragemFase1; #if USE_REAL_VCC == 1 int SupplyVoltage = readVcc(); #else int SupplyVoltage = gParam.rede.vcc_supply; #endif offsetI = ADC_COUNTS>>1; for (unsigned int n = 0; n < Number_of_Samples; n++) { sampleI = analogRead(pin); // Digital low pass filter extracts the 2.5 V or 1.65 V dc offset, // then subtract this - signal is now centered on 0 counts. offsetI = (offsetI + (sampleI-offsetI)/1024); filteredI = sampleI - offsetI; // Root-mean-square method current // 1) square current values sqI = filteredI * filteredI; // 2) sum sumI += sqI; } double I_RATIO = ICAL *((SupplyVoltage/1000.0) / (ADC_COUNTS)); Irms = I_RATIO * sqrt(sumI / Number_of_Samples); //Reset accumulators //sumI = 0; //-------------------------------------------------------------------------------------- return Irms; }
double readCalcIrms(int pin, int NUMBER_OF_SAMPLES) { int lastSampleI,sampleI; double lastFilteredI, filteredI, Irms; double sqI,sumI=0; //sq = squared, sum = Sum, inst = instantaneous double ICAL = gParam.rede.calibragemFase1; #if USE_REAL_VCC == 1 int SUPPLYVOLTAGE = readVcc(); #else int SUPPLYVOLTAGE = gParam.rede.vcc_supply; #endif filteredI = 0; //ADC_COUNTS>>1; sampleI = analogRead(pin); for (int n = 0; n < NUMBER_OF_SAMPLES; n++) { lastSampleI = sampleI; sampleI = analogRead(pin); lastFilteredI = filteredI; filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI); // Root-mean-square method current // 1) square current values sqI = filteredI * filteredI; // 2) sum sumI += sqI; } double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / (ADC_COUNTS)); Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES); //Reset accumulators sumI = 0; //-------------------------------------------------------------------------------------- return Irms; }
//-------------------------------------------------------------------------------------- // emon_calc procedure // Calculates realPower,apparentPower,powerFactor,Vrms,Irms,kwh increment // From a sample window of the mains AC voltage and current. // The Sample window length is defined by the number of half wavelengths or crossings we choose to measure. //-------------------------------------------------------------------------------------- void EnergyMonitor::calcVI(int crossings, int timeout) { int SUPPLYVOLTAGE = readVcc(); int crossCount = 0; //Used to measure number of times threshold is crossed. int numberOfSamples = 0; //This is now incremented //------------------------------------------------------------------------------------------------------------------------- // 1) Waits for the waveform to be close to 'zero' (500 adc) part in sin curve. //------------------------------------------------------------------------------------------------------------------------- boolean st=false; //an indicator to exit the while loop unsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error. while(st==false) //the while loop... { startV = analogRead(inPinV); //using the voltage waveform if ((startV < 550) && (startV > 440)) st=true; //check its within range if ((millis()-start)>timeout) st = true; } //------------------------------------------------------------------------------------------------------------------------- // 2) Main measurment loop //------------------------------------------------------------------------------------------------------------------------- start = millis(); while ((crossCount < crossings) && ((millis()-start)<timeout)) { numberOfSamples++; //Count number of times looped. lastSampleV=sampleV; //Used for digital high pass filter lastSampleI=sampleI; //Used for digital high pass filter lastFilteredV = filteredV; //Used for offset removal lastFilteredI = filteredI; //Used for offset removal //----------------------------------------------------------------------------- // A) Read in raw voltage and current samples //----------------------------------------------------------------------------- sampleV = analogRead(inPinV); //Read in raw voltage signal sampleI = analogRead(inPinI); //Read in raw current signal //----------------------------------------------------------------------------- // B) Apply digital high pass filters to remove 2.5V DC offset (centered on 0V). //----------------------------------------------------------------------------- filteredV = 0.996*(lastFilteredV+(sampleV-lastSampleV)); filteredI = 0.996*(lastFilteredI+(sampleI-lastSampleI)); //----------------------------------------------------------------------------- // C) Root-mean-square method voltage //----------------------------------------------------------------------------- sqV= filteredV * filteredV; //1) square voltage values sumV += sqV; //2) sum //----------------------------------------------------------------------------- // D) Root-mean-square method current //----------------------------------------------------------------------------- sqI = filteredI * filteredI; //1) square current values sumI += sqI; //2) sum //----------------------------------------------------------------------------- // E) Phase calibration //----------------------------------------------------------------------------- phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV); //----------------------------------------------------------------------------- // F) Instantaneous power calc //----------------------------------------------------------------------------- instP = phaseShiftedV * filteredI; //Instantaneous Power sumP +=instP; //Sum //----------------------------------------------------------------------------- // G) Find the number of times the voltage has crossed the initial voltage // - every 2 crosses we will have sampled 1 wavelength // - so this method allows us to sample an integer number of half wavelengths which increases accuracy //----------------------------------------------------------------------------- lastVCross = checkVCross; if (sampleV > startV) checkVCross = true; else checkVCross = false; if (numberOfSamples==1) lastVCross = checkVCross; if (lastVCross != checkVCross) crossCount++; } //------------------------------------------------------------------------------------------------------------------------- // 3) Post loop calculations //------------------------------------------------------------------------------------------------------------------------- //Calculation of the root of the mean of the voltage and current squared (rms) //Calibration coeficients applied. double V_RATIO = VCAL *((SUPPLYVOLTAGE/1000.0) / 1023.0); Vrms = V_RATIO * sqrt(sumV / numberOfSamples); double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / 1023.0); Irms = I_RATIO * sqrt(sumI / numberOfSamples); //Calculation power values realPower = V_RATIO * I_RATIO * sumP / numberOfSamples; apparentPower = Vrms * Irms; powerFactor=realPower / apparentPower; //Reset accumulators sumV = 0; sumI = 0; sumP = 0; //-------------------------------------------------------------------------------------- }
void Controller25::device_loop(Command command){ if (time.elapsed (100)) { // subtract the last reading: total= total - readings[index]; // read from the sensor: readings[index] = readBrdCurrent(A0); // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1; // if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0; // calculate the average: average = total / numReadings; } if (onesecondtimer.elapsed (1000)){ readTemp(); Serial.print(F("BRDT:")); Serial.print(celsiusTempRead); Serial.print(';'); Serial.print(F("SC1I:")); Serial.print(readCurrent(A3)); Serial.print(';'); Serial.print(F("SC2I:")); Serial.print(readCurrent(A2)); Serial.print(';'); Serial.print(F("SC3I:")); Serial.print(readCurrent(A1)); Serial.print(';'); Serial.print(F("BRDI:")); Serial.print(readBrdCurrent(A0)); Serial.print(';'); Serial.print(F("BT1I:")); Serial.print(readCurrent(A6)); Serial.print(';'); Serial.print(F("BT2I:")); Serial.print(readCurrent(A5)); Serial.print(';'); Serial.print(F("BRDV:")); Serial.print(read20Volts(A4)); Serial.print(';'); Serial.print(F("AVCC:")); Serial.print(readVcc()); Serial.println(';'); } // send voltage and current if (statustime2.elapsed(100)) { capedata::VOUT = read20Volts(A4); capedata::IOUT = readBrdCurrent(A0); capedata::FMEM = freeMemory(); // capedata::ATMP = GetTemp(); capedata::UTIM = millis(); } }
void CControllerBoard::Update( CCommand& commandIn ) { if( time.HasElapsed( 100 ) ) { // subtract the last reading: total = total - readings[index]; // read from the sensor: readings[index] = readBrdCurrent( A0 ); // add the reading to the total: total = total + readings[index]; // advance to the next position in the array: index = index + 1; // if we're at the end of the array... if( index >= numReadings ) // ...wrap around to the beginning: { index = 0; } // calculate the average: average = total / numReadings; } if( onesecondtimer.HasElapsed( 1000 ) ) { readTemp(); Serial.print( F( "BRDT:" ) ); Serial.print( celsiusTempRead ); Serial.print( ';' ); Serial.print( F( "SC1I:" ) ); Serial.print( readCurrent( A3 ) ); Serial.print( ';' ); Serial.print( F( "SC2I:" ) ); Serial.print( readCurrent( A2 ) ); Serial.print( ';' ); Serial.print( F( "SC3I:" ) ); Serial.print( readCurrent( A1 ) ); Serial.print( ';' ); Serial.print( F( "BRDI:" ) ); Serial.print( readBrdCurrent( A0 ) ); Serial.print( ';' ); Serial.print( F( "BT1I:" ) ); Serial.print( readCurrent( A6 ) ); Serial.print( ';' ); Serial.print( F( "BT2I:" ) ); Serial.print( readCurrent( A5 ) ); Serial.print( ';' ); Serial.print( F( "BRDV:" ) ); Serial.print( read20Volts( A4 ) ); Serial.print( ';' ); Serial.print( F( "AVCC:" ) ); Serial.print( readVcc() ); Serial.println( ';' ); } // Update Cape Data voltages and currents if( statustime2.HasElapsed( 100 ) ) { NDataManager::m_capeData.VOUT = read20Volts( A4 ); // #315: deprecated: this is the same thing as BRDI: NDataManager::m_capeData.IOUT = readBrdCurrent( A0 ); // Total current draw from batteries: NDataManager::m_capeData.BTTI = readCurrent( A5 ) + readCurrent( A6 ); NDataManager::m_capeData.FMEM = util::FreeMemory(); NDataManager::m_capeData.UTIM = millis(); } }
void loop() { unsigned long tick = millis(); long diff = tick - lastTick; avgTickDelay = expAvg(avgTickDelay, diff); lastTick = tick; if (printTicks > printTicksI) { Serial.print("tick delay: "); Serial.print(diff); Serial.println("ms"); } // Radio tick. radio->tick(); // Send helo. diff = tick - lastSent; if ((lastAck < lastSent && diff > MAX_SEND_WAIT) || diff > MIN_SEND_WAIT ) { avgSendDelay = expAvg(avgSendDelay, diff); lastSent = tick; if (printTicks > printTicksI) { printTicksI++; Serial.print("send delay: "); Serial.print(diff); Serial.println("ms"); } if (sendInfx) { Message msg("he"); radio->send(&msg); } else { Message msg("lo"); radio->send(&msg); } sendInfx = !sendInfx; } // Update metrics. tick = millis(); if (tick - lastUpdate > UPDATE_WAIT) { memcpy(&mLast, &m, sizeof(metrics)); lastUpdate = tick; lastVcc = readVcc(); sinceLastAck = (int) ((lastUpdate - lastAck) / 1000L); if (sinceLastAck < 0) { #ifdef DEBUG Serial.println("sinceLastAck less than 0"); Serial.print("round(("); Serial.print(lastUpdate); Serial.print(" - "); Serial.print(lastAck); Serial.print(") / 1000.0) = "); Serial.println(sinceLastAck); #endif sinceLastAck = 0; } if (lastAck + TIMEOUT_WAIT < lastSent) { lastRoundtrip = NO_READING_INT; lastRssi = NO_READING_INT; } writeLog(); } // Pipeline tick. pipe->tick(); // Serial commands. if (Serial.available()) { String cmd = Serial.readStringUntil('\n'); if (cmd[0] == 'D') { dataFile.close(); if (!dataFile.open(root, logFilename, O_READ)) { Serial.println(); Serial.println("Could not open file for reading"); return; } uint32_t offset; long cmdOffset = cmd.substring(1).toInt(); if (cmdOffset < 0) { offset = dataFile.fileSize() + cmdOffset; } else { offset = cmdOffset; } dataFile.seekSet(offset); char buf[128]; int16_t read; bool firstRead = true; do { read = dataFile.read(buf, 127); buf[read] = 0; if (firstRead && read > 0) { firstRead = false; char *firstNewline = strchr(buf, '\n'); Serial.print(++firstNewline); } else { Serial.print(buf); } } while (read > 0); Serial.println(); dataFile.close(); } else if (cmd[0] == 'L') { printCardInfo(); } else if (cmd[0] == 'I') { Serial.print(F("Average tick delay: ")); Serial.print(avgTickDelay); Serial.println(F("ms")); Serial.print(F("Average send delay: ")); Serial.print(avgSendDelay); Serial.println(F("ms")); Serial.print(F("RAM free: ")); Serial.print(freeRam()); Serial.println(F(" bytes")); printTicks = (int) cmd.substring(1).toInt(); printTicksI = 0; } else if (cmd[0] == 'G') { Serial.print(F("Location: ")); Serial.print(m.latitude, 6); Serial.print(F(",")); Serial.println(m.longitude, 6); } else if (cmd[0] == 'U') { Message msg("up"); radio->send(&msg); } else if (cmd[0] == 'F') { if (m.logging != MODULE_ENABLED) { Serial.println(F("Requesting to enable logging")); } else { Serial.println(F("Requesting to disable logging")); } Message msg("tl"); radio->send(&msg); } else if (cmd[0] == 'T') { Serial.print(F("Remote data logging is ")); Serial.println(m.logging == MODULE_ENABLED ? "enabled" : "disabled"); } } }