AC Analog conversion for UNO

Can any one advise me regarding what to use to convert AC to DC to input the UNO for voltage and two current sensors. I have all the hardware and have  used some true rms to dc converters but they don't seem to interface properly with the UNO.

Thanks

Mark.

TrystanLea's picture

Re: AC Analog conversion for UNO

See here: http://openenergymonitor.org/emon/buildingblocks/ct-sensors-interface We have gone along the route of calculating true rms on the arduino itself.

markbeal2's picture

Re: AC Analog conversion for UNO

Thanks Trystan, I have build a voltage input circuit but the sketch is throwing up problems as errors below.

voltage_and_current_ex.cpp.o: In function `loop':
C:\DOCUME~1\MARK~1.BEA\LOCALS~1\Temp\build2352948031508961507.tmp/voltage_and_current_ex.cpp:17: undefined reference to `EnergyMonitor::calcVI(int, int)'
C:\DOCUME~1\MARK~1.BEA\LOCALS~1\Temp\build2352948031508961507.tmp/voltage_and_current_ex.cpp:18: undefined reference to `EnergyMonitor::serialprint()'
voltage_and_current_ex.cpp.o: In function `setup':
C:\DOCUME~1\MARK~1.BEA\LOCALS~1\Temp\build2352948031508961507.tmp/voltage_and_current_ex.cpp:11: undefined reference to `EnergyMonitor::voltage(int, double, double)'
C:\DOCUME~1\MARK~1.BEA\LOCALS~1\Temp\build2352948031508961507.tmp/voltage_and_current_ex.cpp:12: undefined reference to `EnergyMonitor::current(int, double)'

Any Ideas, I'm a little green with this.

markbeal2's picture

Re: AC Analog conversion for UNO

I can't seem to get the sketch to compile Trystan. Errors are as follows.

 

 

voltage_and_current_ex.cpp.o: In function `loop':
C:\Users\Mark\AppData\Local\Temp\build6210930148339193694.tmp/voltage_and_current_ex.cpp:17: undefined reference to `EnergyMonitor::calcVI(int, int)'
C:\Users\Mark\AppData\Local\Temp\build6210930148339193694.tmp/voltage_and_current_ex.cpp:18: undefined reference to `EnergyMonitor::serialprint()'
voltage_and_current_ex.cpp.o: In function `setup':
C:\Users\Mark\AppData\Local\Temp\build6210930148339193694.tmp/voltage_and_current_ex.cpp:11: undefined reference to `EnergyMonitor::voltage(int, double, double)'
C:\Users\Mark\AppData\Local\Temp\build6210930148339193694.tmp/voltage_and_current_ex.cpp:12: undefined reference to `EnergyMonitor::current(int, double)'
markbeal2's picture

Re: AC Analog conversion for UNO

Can anyone help with this? I am not seeing something here in the example script. I want to get my immersion heater device finish then I can post it on here.

markbeal2's picture

Re: AC Analog conversion for UNO

It seems that I am stuck out on a limb here, tried my hardest to workout what is wrong with the sample sketch here  http://openenergymonitor.org/emon/buildingblocks/ct-sensors-interface.

I have put the emon  lib in but still keeps coming up with error "undefined reference to `EnergyMonitor::current(int, double)' for voltage and current.    Please help someone.

prensel's picture

Re: AC Analog conversion for UNO

Maybe silly question but did you copy the EmonLib directory  into the libraries directory of Arduino ?

 

markbeal2's picture

Re: AC Analog conversion for UNO

Yes I have done that prensel; with all the post regarding the example others seem to get it working ok. I'm just learning about the Arduino and have carried out what is said but it throws the fore mentioned errors on compile.I've tried messaging Trystan but have no reply as yet. I'm not one for throwing the towel in but i'm getting very frustrated with the sketch. Thanks for your reply anyway.

Mark. 

Lloyd's picture

Re: AC Analog conversion for UNO

Another simple question - did you restart arduino after copying the libraries into place?

Lloyd

markbeal2's picture

Re: AC Analog conversion for UNO

Yes Lloyd I have done that.

markbeal2's picture

Re: AC Analog conversion for UNO

 

This is the sketch..............
 
#include "EmonLib.h"              // Include Emon Library
EnergyMonitor emon1;              // Create an instance
 
void setup()
{  
  Serial.begin(9600);
  
  emon1.voltage(2, 234.26, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(1, 111.1);        // Current: input pin, calibration.
}
 
void loop()
{
  emon1.calcVI(20,2000);          // Calculate all. No.of wavelengths, time-out
  emon1.serialprint();            // Print out all variables
}
 
These are the errors when I click on compile.....
 
voltage_and_current_ex.cpp.o: In function `loop':
C:\Users\Mark\AppData\Local\Temp\build1517359345261135376.tmp/voltage_and_current_ex.cpp:17: undefined reference to `EnergyMonitor::calcVI(int, int)'
C:\Users\Mark\AppData\Local\Temp\build1517359345261135376.tmp/voltage_and_current_ex.cpp:18: undefined reference to `EnergyMonitor::serialprint()'
voltage_and_current_ex.cpp.o: In function `setup':
C:\Users\Mark\AppData\Local\Temp\build1517359345261135376.tmp/voltage_and_current_ex.cpp:11: undefined reference to `EnergyMonitor::voltage(int, double, double)'
C:\Users\Mark\AppData\Local\Temp\build1517359345261135376.tmp/voltage_and_current_ex.cpp:12: undefined reference to `EnergyMonitor::current(int, double)'

 

markbeal2's picture

Re: AC Analog conversion for UNO

Have I got to set anything in the Emonlib would anyone know?

markbeal2's picture

Re: AC Analog conversion for UNO

In the Emonlib it says the following

  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;
 
Anyone know what I need to do here?
 

 

markbeal2's picture

Re: AC Analog conversion for UNO

Is this a test? well I have failed.. someone put me out of my misery pleeeeeeeeeeeeeezzzzz.

Pcunha's picture

Re: AC Analog conversion for UNO

Your sketch compiles fine.

  1. Open arduino
  2. Paste your code on the blank window;
  3. open windows explorer and browse to folder where the emonlib.c and emonlib.h are;
  4. drag emonlib.c and emonlib.h into the arduino screen, so it will have 3 open files ( your stetch, emonlib.c and emonlib.h)
  5. upload the code.

markbeal2's picture

Re: AC Analog conversion for UNO

Thanks Pcunha, It was the emonlib.c I didn't have in, when i put that in the lib folder it worked.

I'm just experimenting with a sketch that Paul Reed uses but that throws up errors, if you could try that as below.

Paul said it works ok but he used the older version of Arduino IDE.

 

 

/ 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, 4); // 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");  }
       lcd.setCursor(0, 2);
    lcd.print("Voltage "); lcd.print(ch1.Vrms, 0); lcd.print(" V");
    }
 
    //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);
        }
 }
Pcunha's picture

Re: AC Analog conversion for UNO

 

 /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
 
 
You shoud remove a slash in the first line above.
You shoud add one slash at the very first line of the code, as its a comment.
 
It looks to me that the code is not complete. it trows an compilation error. the emon_calc funcion does not have any code.
 
In my opinion you shoud start with a working example at openenergymonitor github and then modify for your needs.
markbeal2's picture

Re: AC Analog conversion for UNO

Thanks pcunha for the advice, I have a script that works now and have modified it to my needs. Thanks again.

Comment viewing options

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