Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

What would cause this:

CURRENT_MONITOR.cpp.o: In function `loop':
CURRENT_MONITOR.cpp:87: undefined reference to `Channel::emon_calc(int, double)'
CURRENT_MONITOR.cpp:88: undefined reference to `Channel::emon_calc(int, double)'
 

Anonwelder's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Hi swilus.

Did you ever get to the bottom of this error at all? I am getting a very similar message when attempting to verify Pauldreed's Solar Power Manager sketch. In my case I get:

sketch_Solar_Power_Meter.cpp.o: In function `loop':
sketch_Solar_Power_Meter.cpp:124: undefined reference to `Channel::emon_calc(int, double) 'sketch_Solar_Power_Meter.cpp:125: undefined reference to `Channel::emon_calc(int, double)'

Any assistance would be great.

 

AW

 

 

 

 

 

 

glyn.hudson's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

 Have a look at the emonTx examples: https://github.com/openenergymonitor/emonTxFirmware they are more up to date and work well with Arduino 1.0.

Anonwelder's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Hi Glyn.

All verifying and compiling now. It was my error as I did not include the pde correctly. I can confirm that all is well in both Arduino v023 and Arduino 1.0.

Sorry for delay in replying as I am unable to access this site without going through a proxy server and my previous application had expired.

Thanks for your continued help.

AW

aam's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Hi all,

I am having exactly this problem compiling the energy monitor sketch for my Arduino, however I do not know what the pde mentioned above is.

Can anyone please help

Thankyou

Alan

TrystanLea's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Aam: have you downloaded and unziped EmonLib: https://github.com/openenergymonitor/EmonLib into the arduino libraries folder?

aam's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Hi Trystan,

Yes I have downloaded EmonLib and put it in the library folder but still get:-

124: Undefined Reference to Channel::emon_calc (int, double)

125: Undefined Reference to Channel::emon_calc (int, double)

when compiling. I have pasted the code in below, any help will be much appreciated.

 

 

//--------------------------------------------------------------------------------------
// Mains AC Non-Invasive Energy Monitor (2 channel)
// Last revision 27th Oct 2010
// Licence: GNU GPL
// By Trystan Lea (updated to support two channel energy monitoring by Glyn Hudson)
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// VARIABLE DECLERATION
//--------------------------------------------------------------------------------------
  //--ENERGY MEASURMENT VARIABLES------------------------------
 
  //Power measurement/time variables
  unsigned long t_now, t_diff, t_last, t_culm;
  
  //kwhTotal is cumulative kwh today.
  double Solarkwh =0.0;
  double Mainskwh =0.0;
//--------------------------------------------------------------------------------------
// EMON
//--------------------------------------------------------------------------------------

// include the library code:
#include <LiquidCrystal.h>  // initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int menuState = 0;
int menu = 0;

int wavelengths = 3000;   //number of wavelengths to sample
int inPinV = 1;           //Analog input pin number that voltage signal is connected to
int inPinI_1 = 3;         //Analog input pin number that current signal is connected to. Channel 1
int inPinI_2 = 2;         //Analog input pin number that current signal is connected to. Channel 2
int menupin = 1;          //Arduino pin 1 goes to pushbutton for menu
int RelayOn = 4;          //Arduino pin 4 goes to the opto isolator (full power)
int HRelayOn = 3;         //Arduino pin 3 goes to opto isolator (half power)
int led_on = 6;           //Arduino pin 6 goes to panel LED

//channel 1
double VCAL = 1.28348;              //Voltage calibration scaler
double ICAL_1 = 0.05815;            //Current calibration scaler
double ICAL_2 = 0.05806;

double PHASECAL = 2.3;                        //Shifts voltage relative to current,
                                              //subtracting any phase shifting caused by components
   
int emon_timeout = 2000;                       //how long to wait ms if something goes wrong.

class Channel
{
  public:
    void emon_calc(int,double);                //create pulse function
    double realPower,                          //Output variables
       apparentPower,
       powerFactor,
       Vrms,
       Irms,
       whInc,
       wh;

  private: // Variable declaration for emon_calc procedure
   int lastSampleV,sampleV;                          //sample_ holds the raw analog read value, lastSample_ holds the last sample_
    int lastSampleI,sampleI;                     

    double lastFilteredV,filteredV;                   //Filtered_ is the raw analog value minus the DC offset
    double lastFilteredI, filteredI;                 
   
    double phaseShiftedV;                             //Holds the calibrated phase shifted voltage.
   
    double sqV,sumV,sqI,sumI,instP,sumP;              //sq = squared, sum = Sum, inst = instantaneous
   
    int startV;                                       //Instantaneous voltage at start of sample window.
   
    boolean lastVCross, checkVCross;                  //Used to measure number of times threshold is crossed.
    int crossCount;                                   // ''
   
    unsigned long lwhtime, whtime;                    //used to calculate energy used.

};

Channel ch1,ch2;    //create two incidence of class channel for the two channels

//--------------------------------------------------------------------------------------
// SETUP
//--------------------------------------------------------------------------------------
void setup()
{
   lcd.begin(16, 2); // set up the LCD's number of columns and rows:
 
   Serial.begin(9600);
   pinMode(RelayOn,OUTPUT); // this sets the pin named RelayOn to be an output
   pinMode(HRelayOn,OUTPUT); // this sets the pin named RelayOn to be an output
   pinMode(menupin, INPUT); // this sets the pin named menupin to be an input
   pinMode (led_on, OUTPUT); //this sets the pin named led_on to be an output

   t_culm = (3600000 * 12);       //On first run, advances the 24hr timer by 12hrs (so can restart at midday!) 
   //t_culm = (3600000 * 23.75);  //FOR TESTING ONLY
  
   digitalWrite(RelayOn,HIGH);   //Switches relay off
   digitalWrite(HRelayOn,HIGH);  //Switches relay off
  
   //Introduces 15 second delay to allow caps to charge up
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Please Wait  ");
    lcd.setCursor(0, 1);
    lcd.print("Initialising....");
    delay (15000);
}

unsigned long wtime;

//--------------------------------------------------------------------------------------
// MAIN LOOP
//--------------------------------------------------------------------------------------
void loop()
{
  //-------------------------------------------------------------------------------------------
  // 1) Calculate energy monitor values
  //-------------------------------------------------------------------------------------------
  ch1.emon_calc(inPinI_1,ICAL_1);  //Energy Monitor calc function for channel 1, pass Arduino analog in pin nummber and calibration coefficient
  ch2.emon_calc(inPinI_2,ICAL_2);  //Energy Monitor calc function, for channel 2, pass Arduino analog in pin nummber and calibration coefficient

  //--ENERGY MEASURMENT CALCULATION----------------  
 
 //Power measurement
  t_now = millis();
    if ( t_now > t_last ) {   //check to see if millis has overflowed back to zero (after approx 49 days)
      t_diff = t_now - t_last; } //if not, the time each emon cycle takes
        else {  //if millis has reset...
          t_diff = 4127; }   //t_diff = (the amount of time each average emon cycle takes), again dealing with the millis reset.
  t_culm += t_diff;
  t_last = t_now;
 
  if ( t_culm > (3600000 * 24)){ //check to see if 24hrs has elapsed
  Solarkwh = 0; // RESET
  Mainskwh = 0; // RESET
  t_culm = 0;   // RESET
  }

  //ch1.realPower = 2534;  //FOR TESTING ONLY
  //ch2.realPower = 1522;  //FOR TESTING ONLY
 
  //Calculate number of kwh generated.
  Solarkwh = Solarkwh + ((ch1.realPower/1000.0) * 1.0/3600.0 * (t_diff/1000.0));
  Mainskwh = Mainskwh + ((ch2.realPower/1000.0) * 1.0/3600.0 * (t_diff/1000.0)); 

    //------------Data Output-------------
    
    //Read menupin to see what menu to display
    menuState = digitalRead(menupin);
    if ( menuState == LOW) {
    menu = menu+1; }
    if (menu > 4){
    menu = 0;
    } 
   
    //MENU 0  
    if (menu == 0) {
    // clear the lcd screen
    lcd.clear();
    //if-else statement to alter LCD print format depending upon power reading
    lcd.setCursor(0, 0);
        if (ch1.realPower >= 1000)  {
      lcd.print("Solar "); lcd.print(ch1.realPower / 1000.0, 3); lcd.print(" kW");  }
    else  {
      lcd.print("Solar "); lcd.print(ch1.realPower, 0); lcd.print(" Watts");  }
   
    lcd.setCursor(0, 1);
        if (ch2.realPower >= 5000)  {
      lcd.print("M/Power over 5kW"); }
    else
      if (ch2.realPower >= 1000)  {
      lcd.print("Mains "); lcd.print(ch2.realPower / 1000.0, 3); lcd.print(" kW");  }
    else  {
      lcd.print("Mains "); lcd.print(ch2.realPower, 0); lcd.print(" Watts");  }
    }

    //MENU 1 - to enable detailed readings for calibration
    if (menu == 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Solar "); lcd.print(Solarkwh); lcd.print(" kWh");
    lcd.setCursor(0, 1);
    lcd.print("Mains "); lcd.print(Mainskwh); lcd.print(" kWh");  }

    //MENU 2 - to enable detailed readings for calibration
    if (menu == 2) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("PowerF "); lcd.print(ch1.powerFactor, 2);
    lcd.setCursor(0, 1);
    lcd.print("Voltage "); lcd.print(ch1.Vrms, 0); lcd.print(" V");  }
   
    //MENU 3 - to enable detailed readings for calibration
    if (menu == 3) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Solar "); lcd.print(ch1.realPower, 0); lcd.print(" W");
    lcd.setCursor(0, 1);
    lcd.print("Mains "); lcd.print(ch2.realPower, 0); lcd.print(" W");  }
   
    //MENU 4 - DEMO MODE
    if (menu == 4) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print ("Press button for");
    lcd.setCursor(0, 1);
    lcd.print("3 secs for demo");
    delay (3000);
    if (digitalRead(menupin)== LOW) {  //check to see if button is still pressed
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print ("DEMO MODE");
    delay (2000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Solar 1.326 kW");
    lcd.setCursor(0, 1);
    lcd.print("Mains 298 Watts");
    digitalWrite (led_on,HIGH);
    delay (10000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Solar 18.36 kWh");
    lcd.setCursor(0, 1);
    lcd.print("Mains 4.29 kWh");
    digitalWrite (led_on,HIGH);
    delay (10000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("PowerF 0.98");
    lcd.setCursor(0, 1);
    lcd.print("Voltage 247 V");
    digitalWrite (led_on,HIGH);
    delay (10000);
    menu = 0; }
    else {
      menu = 0; }
    }
      
 //checks to see if can run at full power
  if (ch1.realPower > (ch2.realPower +1090)) {
      digitalWrite(HRelayOn,HIGH); //turn the half power output off
      digitalWrite(RelayOn,LOW); //turn the full output on
       }
  else{
      digitalWrite(RelayOn,HIGH); //turn the output off
       //checks to see if can run at half power
       if (ch1.realPower > (ch2.realPower +545)) {
        digitalWrite(HRelayOn,LOW); }//turn the output on
          else  {
           digitalWrite(HRelayOn,HIGH); //turn the output off
     }
   }
 //LED control
   if (digitalRead(RelayOn) == LOW) {
     analogWrite(led_on, 200);  }
   else if (digitalRead(HRelayOn) == LOW) {
     analogWrite(led_on, 30);   } //quarter brightness
   else {
         digitalWrite (led_on,HIGH);
         delay (100);
         digitalWrite (led_on,LOW);
        }
 }

fabiusmontana's picture

Re: Error compiling "Mains AC Non-Invasive Energy Monitor (2 channel)

Hello everyone.
I'm having the same problem. I installed all the libraries, but the error remains:

122: undefined reference to `Channel::emon_calc(int, double)

123: undefined reference to `Channel::emon_calc(int, double)'

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.