Пример #1
0
//--------------------------------------------------------------------------------------
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
//--------------------------------------------------------------------------------------
// 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;
//--------------------------------------------------------------------------------------       
}
Пример #6
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();
    }
}
Пример #8
0
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");
        }
    }
}