Emon and SerLCD

Hi to all the Arduino Guru’s,

I think I have a simple question, but I am unable to solve it.

I am using the Emonlib from openenergymonitor.org to read out a CT and 9VAC powersupply to measure power consumption of my PC.
I have been able to get this working, but I would like to output some of the data to a SerLCD, All the calculations are being done inside Emonlib.h and I can’t find how to write this data to the SerLCD.

The first sketch outputs Vrms, Irms, Power Factor, Apparent and Real power to the Serial monitor.
But I need Vrms, Irms and Real Power to be outputted to the display.

Here are the 2 sketches I have made.

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance

void setup()
{  
  Serial.begin(9600);
  
  emon1.voltage(2, 212.670, 1.7);   // Voltage: input pin, calibration, phase_shift
  emon1.current(1, 10.7);           // Current: input pin, calibration.
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of wavelengths, time-out
  emon1.serialprint();           // Print out all variables
}
// SparkFun Serial LCD example 2
// Format and display fake RPM and temperature data

// This sketch is for Arduino versions 1.0 and later
// If you're using an Arduino version older than 1.0, use
// the other example code available on the tutorial page.

// Use the softwareserial library to create a new "soft" serial port
// for the display. This prevents display corruption when uploading code.
#include <SoftwareSerial.h>

// Attach the serial display's RX line to digital pin 2
SoftwareSerial mySerial(3,2); // pin 2 = TX, pin 3 = RX (unused)
void setup()
{ 
   mySerial.begin(9600); // set up serial port for 9600 baud
  
  delay(1000); // wait for display to boot up
  
  mySerial.write(254); // cursor to beginning of first line
  mySerial.write(128);

  mySerial.write("U=       V  AC Power"); // clear display + legends
  mySerial.write("I=       A         W");
  mySerial.write("U=       V  DC Power");
  mySerial.write("I=       A         W");
} 


void loop() 
{ 
  mySerial.write(254); // cursor to 4th position on first line
  mySerial.write(131);
 
  mySerial.print(Vrms); // write out the VAC value

  mySerial.write(254); // cursor to 4th position on second line
  mySerial.write(195);

  mySerial.write("bla"); // write out the AAC value

  mySerial.write(254); // cursor to 4th position on second line
  mySerial.write(204);

  mySerial.write("bla"); // write out the AAC value
    
  delay(1000); // short delay
}

All the calculations are being done inside Emonlib.h

Not likely. The header file likely does not do ANY calculations. The .cpp file is where the calculations are implemented.

Anyway, modify the library to output to your device, instead of the serial monitor.

How can I achieve this?

I tried adding myserial.write to the Emonlib.cpp but i get is "not defined in scope" error.

I tried adding myserial.write to the Emonlib.cpp but i get is "not defined in scope" error.

Lean over a little. It's hard to see past you, to see what changes you made, or what errors you are seeing.

A little farther. Still can't see. Hey, be careful. Don't fall out of the chair.

My apologies PaulS, I realise I'm being an ass.

I find it hard to gather information on the arduino that I can easily understand, it's all new to me.

What I have done is taken the code inside the loop of the 2nd sketch and placed it inside the Emonlib.cpp instead of the serial.print code inside Emonlib.cpp

When I verify this code I get the "undefined in scope" error. I understand why I get that, the instance myserial is not inside the Emonlib.cpp.

What I am unable to find is how to have the 5 values in Emonlib.cpp be available for use inside a sketch.

Hope this info is a little more usefull.

Regards, Pebbles

What I am unable to find is how to have the 5 values in Emonlib.cpp be available for use inside a sketch.

Modify the header file to add accessor method for the 5 values, and call those methods in the sketch.

Anyone that creates a library that can only output to the serial monitor deserves to have their ass kicked all over the place.

OK bear with me, I am at my office now so I can't test the code but I think I understand now.

Here is the code for Emonlib.h

class EnergyMonitor
{
  public:

    void voltage(int _inPinV, double _VCAL, double _PHASECAL);
    void current(int _inPinI, double _ICAL);

    void voltageTX(double _VCAL, double _PHASECAL);
    void currentTX(int _channel, double _ICAL);

    void calcVI(int wavelengths, int timeout);
    double calcIrms(int NUMBER_OF_SAMPLES);
    void serialprint();

    long readVcc();
    //Useful value variables
    double realPower,
       apparentPower,
       powerFactor,
       Vrms,
       Irms;

  private:

    //Set Voltage and current input pins
    int inPinV;
    int inPinI;
    //Calibration coeficients
    //These need to be set in order to obtain accurate results
    double VCAL;
    double ICAL;
    double PHASECAL;

    //--------------------------------------------------------------------------------------
    // 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;                                   // ''


};

In the original sketch there is a piece of code: emon1.calcVI(20,2000);

It looks to me this is a reference to the code below:

void calcVI(int wavelengths, int timeout);

I guess this part means I should be able to call it in a sketch right? double realPower, ** apparentPower,** ** powerFactor,** ** Vrms,** ** Irms;**

using: emon1.realPower emon1.apparentPower emon1.powerFactor emon1.Vrms emon1.Irms

Is this correct or not?

In the original sketch there is a piece of code: emon1.calcVI(20,2000);

It looks to me this is a reference to the code below:

void calcVI(int wavelengths, int timeout);

That is the declaration of the method that gets called, yes.

I guess this part means I should be able to call it in a sketch right? double realPower, apparentPower, powerFactor, Vrms, Irms;

using: emon1.realPower emon1.apparentPower emon1.powerFactor emon1.Vrms emon1.Irms

Is this correct or not?

Sorry, no. See that keyword private:? It means that only methods of the class can access that data.

You can add, in the public section, some methods:

double getRealPower();
double getApparentPower();

etc.

Then, in the source code, you implement those methods:

double EnergyMonitor::getRealPower()
{
   return realPower;
}

etc.

Or, you can combine the declaration and implementation, in the header file:

double getApparentPower() { return apparentPower; }

etc.

OK I will try what you said when I get home.

Do I use you code like the following example?

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of wavelengths, time-out

  mySerial.write(254); // cursor to 4th position on first line
  mySerial.write(131);

  mySerial.print(emon1.getVrms()); // write out the VAC value

  mySerial.write(254); // cursor to 4th position on second line
  mySerial.write(195);

  mySerial.write(emon1.getIrms()); // write out the AAC value

  mySerial.write(254); // cursor to 4th position on second line
  mySerial.write(204);

  mySerial.write(emon1.getApparentPower()); // write out the AAC value
    
  delay(1000); // short delay
}

You said that the 5 values are private but these are located above the keyword private: aren't they public then?

This part is public:

public:

    void voltage(int _inPinV, double _VCAL, double _PHASECAL);
    void current(int _inPinI, double _ICAL);

    void voltageTX(double _VCAL, double _PHASECAL);
    void currentTX(int _channel, double _ICAL);

    void calcVI(int wavelengths, int timeout);
    double calcIrms(int NUMBER_OF_SAMPLES);
    void serialprint();

    long readVcc();
    //Useful value variables
    double realPower,
       apparentPower,
       powerFactor,
       Vrms,
       Irms;

And this part is private:

  private:

    //Set Voltage and current input pins
    int inPinV;
    int inPinI;
    //Calibration coeficients
    //These need to be set in order to obtain accurate results
    double VCAL;
    double ICAL;
    double PHASECAL;

    //--------------------------------------------------------------------------------------
    // 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;                                   // ''

Do I use you code like the following example?

Yes, that should work.

You said that the 5 values are private but these are located above the keyword private: aren't they public then?

Must have been looking at that cross-eyed. Yes, they are public, so the accessors are not needed. Just use the variable:

  mySerial.print(emon1.Vrms); // write out the VAC value

Thank you a lot PaulS

I am new to Arduino and Electronics in general, so being as vague as I am must not be very helpful.

I am gonna try and get this working when I get home and will post the final code for this as the solution.