Adding extra analog inputs

I'm building a home energy controller, using CT's and arduino MEGA.  I need to control 3 extra CT inputs and not sure how to use the 74HC4051 (multiplexer) with the EmonLib library.  The problem I have is how to assign the same analog port to read the 3 extra CT inputs (voltage and current or just plain current).  I tried, but I have no good results.  

Does any one have a solution on how to do it?

Robert Wall's picture

Re: Adding extra analog inputs

Not knowing what you are doing with the multiplexer makes it hard to answer, but if my guess is correct, what you are looking for is 3 instances of EnergyMonitor that use the same physical I/O pin?

If so, all you must do is initialise each instance with the channel or pin, then before you call calcVI(...), you must switch as necessary with the multiplexer. It's probably more obvious for you to use EnergyMonitor::current(...) and EnergyMonitor::voltage(...) rather than EnergyMonitor::currentTX(...) and EnergyMonitor::voltageTX(...).

dBC's picture

Re: Adding extra analog inputs

Which Arduino Mega are you using?  Most of them have 16 analog input pins courtesy of the wider internal MUX in the bigger AVR processors (1280, 2560 etc.).

joseglez's picture

Re: Adding extra analog inputs

Mega 2560, 16 analog pins. Need extra 3 analog pins.

joseglez's picture

Re: Adding extra analog inputs

I'm trying to get 3 extra analog readings for 3 CTs to either read current or voltage.  The other analog pins of the arduino MEGA 2560 are used to read other CTs.

I was thinking on initialize the instance, but I do not know how.  How would you do it?  I know how to switch the miltiplexer, but I do not know how to isolate the answers.  

I do not know what you mean by    "It's probably more obvious for you to use EnergyMonitor::current(...) and EnergyMonitor::voltage(...) rather than EnergyMonitor::currentTX(...) and EnergyMonitor::voltageTX(...)."  Could you please explain?

I was using the code "Arduino sketch - voltage and current" modified to select the proper channel in the multiplexer. 

This is my code:

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

double A;

void setup()
{  
  Serial.begin(9600);  
  emon1.voltage(0, 217.06, 0.7);  // Voltage: input pin, calibration, phase_shift
  emon2.current(0, 6.06);         // Current: input pin, calibration.
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
}

void loop()
{
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  emon1.calcVI(20,2000);        
  Serial.println(emon1.Vrms);
  delay (1000);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  A= emon2.calcIrms(1480);
  Serial.println(A);
  Serial.println();
  delay(1000);

}

 

Robert Wall's picture

Re: Adding extra analog inputs

Your sketch is missing some statements. I think you need to look carefully at the emonlib source code to see how each instance of the class is initialised and how those values make it into the methods that run inside loop( ) to read the power. You need to set up voltage and current for each instance of EnergyMonitor, even though all will use the same voltage input pin of the Arduino, and for the multiplexer those channels will also use the same current input pin of the Arduino.

You are reading real power with calcVI(...), so for each CT you must at the same time read a current and the voltage. It makes sense to have the voltage input on one of the Arduino inputs, and currents on 14 of the remaining Arduino inputs, with 4 extra currents on the 16th Arduino input via your multiplexer.

Therefore, you need to create 18 class instances:

EnergyMonitor emon1, emon2, emon3,....emon18;

emon1.voltage(0, 217, 0.7);
emon2.voltage(0, 217, 0.7);
emon3.voltage(0, 217, 0.7);
...
emon18.voltage(0, 217, 0.7);

because all instances us the same voltage input - pin 0, then

emon1.current(1, 6.06); - for the current on pin 1
emon2.current(2, 6.06); - for the current on pin 2
emon3.current(3, 6.06); - for the current on pin 3
...
emon14.current(14, 6.06); - for the current on pin 14

and for the multiplexed currents all going in on pin 15

emon15.current(15, 6.06); - for the current on pin 15 mpx 1
emon16.current(15, 6.06); - for the current on pin 15 mpx 2
emon17.current(15, 6.06); - for the current on pin 15 mpx 3
emon18.current(15, 6.06); - for the current on pin 15 mpx 4

and inside loop( ):

emon1.calcVI(20,2000);
emon2.calcVI(20,2000);
emon3.calcVI(20,2000);
...
emon15.calcVI(20,2000);

set multiplexer for sub-channel 1
emon15.calcVI(20,2000);
set multiplexer for sub-channel 2
emon16.calcVI(20,2000);
set multiplexer for sub-channel 3
emon17.calcVI(20,2000);
set multiplexer for sub-channel 4
emon18.calcVI(20,2000);

And the results for CT1 are in emon1.realPower / emon1.apparentPower etc,
for CT2 they are in emon2....
for CT3 they are in emon3....
...
and for the CT on channel 4 of your multiplexer, they are in emon18.... etc.

[All this isn't real code - it is only giving you the basic outline of how to do it.]

joseglez's picture

Re: Adding extra analog inputs

I have only put the code for the extra CTs I need to read by the multiplexer, which I wrote to test the code.  All of the other instances are working fine in the main program I wrote.

In my test program I can read clearly voltage and when I load the CT for current reading the values I get do not correspond to anything. 

I may try to see using voltage in one arduino pins and use current for the mux pins. Do not clearly understand your method.

dBC's picture

Re: Adding extra analog inputs

Have you confirmed with a scope, or even a multimeter, that the signal at the Arduino pin is as expected after you've selected a CT input with the mux.... presumably it should be identical to the signal on the other side of the mux.

Robert Wall's picture

Re: Adding extra analog inputs

Joseglez,

What you have here:

EnergyMonitor emon1; // Create an instance
EnergyMonitor emon2;

emon1.voltage(0, 217.06, 0.7); // Voltage: input pin, calibration, phase_shift
emon2.current(0, 6.06); // Current: input pin, calibration.

is two separate instances of EnergyMonitor.

emon1 is set up with the voltage pin and the constants for the voltage but you have not set the current pin nor the current constant, and

emon2 is set up with the constants for the current pin and the current constant, but you have not set the voltage pin and the constants for the voltage.

The voltage for emon1 should be correct but the current and power should be zero (or very small) and the current for emon2 should be correct but likewise the voltage and power will be wrong. Each instance needs to read the voltage and the current in order to compute power.

For your multiplexer, you have 4 current channels - is that correct? If yes, then those 4 channels appear on the same Arduino input pin, therefore the 4 corresponding instances of EnergyMonitor must all use the same current input pin. The EnergyMonitor class has no knowledge of your multiplexer - as far as it is concerned, the multiplexer does not exist. But by having separate instances, and running calcVI after you set the multiplexer channel, you are selecting the output that the readings go to.

joseglez's picture

Re: Adding extra analog inputs

Sorry. I do not follow you at all. 

How can I check the voltage reading?  I believe I only can do it with calcVI.  Right?

To check the amps I can use calcIrms independently the calcVI did it. Right?

In relation to your statement  "emon1 is set up with the voltage pin and the constants for the voltage but you have not set the current pin nor the current constant"  I only need to get the voltage.  

In relation to your next statement, I only need to get the amps, not the power, so I do not need the voltage.. I also have to use de same pin as voltage, and that is the whole problem.  Very difficult to understand, al least for me.

I have done only the mux for all current readings and got no good answers.  I guess the EmonLib library does not like to use the same pin number to get results.

Robert Wall's picture

Re: Adding extra analog inputs

Now I am beginning to understand what you are doing. Most people want to know real power, because that relates directly to the energy they pay for. You have chosen to not do that, which is what confused me.

"How can I check the voltage reading? I believe I only can do it with calcVI?"
Correct - unless you write your own method to calculate it. That would be very easy to do because you would take calcVI( ) and remove the current reading and power calculations.

"To check the amps I can use calcIrms independently the calcVI did it. Right?"
It is not necessary that you use calcVI( ) to calculate current, but when you do, you will get a more accurate reading - because the voltage is available which means you can count cycles, which you cannot do with calcIrms( ). And you can know the values that calcVI calculated, they are all available:
emon1.realPower, emon1.apparentPower, emon1.Irms, emon1.Vrms and emon1.powerFactor.
But to use calcVI( ), you must have a voltage signal available to the Arduino at the same time as the current signal is available. That is why I put the voltage input on pin 0 (not through the multiplexer) and the current inputs on the other input pins.

Why do you want to measure current and voltage separately? Is real power not more important to you?

"I guess the EmonLib library does not like to use the same pin number to get results."
While you are using different instances of EnergyMonitor, each instance should be completely separate. For the emonTx, we normally use 4 instances and all 4 share the same voltage pin. So I think that is not the problem.

I suggest the multiplexer might not have settled before you start measuring, can you add a delay between switching the channel and starting the reading? You might also get better results if you use the "op.amp bias" circuit http://openenergymonitor.org/emon/node/673 using the same op.amp to provide the bias for all 18 inputs, which will ensure that all the inputs 'sit' at the same d.c. voltage.

joseglez's picture

Re: Adding extra analog inputs

As I said, I'm building a House Energy Controller.  My house in Spain is all electric. I have a 3-phase supply 380-50Hz (4 wire) and the electric company will install a digital meter in no later than 10 months.  This will put limit on the contacted power.  I won't like to use more than the contact so I will lke to control which loads go in or out especially at night and during the winter (when heating is on).  My normal use is 10kW daily in summer and 70-80kW in winter.  I have a contract with time discrimination rates.

Electricity costs have gone up skyrocket in last few years and I will like to stay in this 60-80kW range contract.

The Open Energy Project sounded great for this.  Do not need a very accurate reading of my power, just I want to stay within my contract.

My electronic knowledge is limited, although I have done several projects, asking when in doubt.

This "op.amp bias" circuit is a very good solution.  In relation with testing the voltage is because I have noticed a not too steady supply at times (lived in an area country like).  I'll do the testing randomly.

Not sure how the emonTX works, but with the mux I haven't been lucky (so far).

I'll keep on trying to see how I can use the mux, although I may have to schedule the use of the existing pins for different CT measurements.  Because I have not being successful on reading using the same pin number.

Robert Wall's picture

Re: Adding extra analog inputs

Thank you for the explanation. It is now much clearer.

Firstly, you cannot accurately measure power by reading current alone. Secondly, because you have a 3-phase supply, you cannot assume the three voltages of the three phases will be the same. However, you understand those limitations, and though you will only calculate apparent power, you should have a good (probably within 10%) estimate of the real power.

I think you need to learn how the emonTx and emonLib works. The quick guide is:

CalcVI( ): The emonTx takes pairs of samples voltage and current 50 times (approximately) per cycle. Voltage and current are multiplied together, the total is added up. At the same time, the voltage is squared, the total added up. The same thing happens to the current. At the end of the 10 cycles, the average values are calculated and the average of V × I is real power. The average V2 is calculated, and the square root of that is the rms voltage, similarly the current.

CalcIrms( ): The emonTx takes readings of current, at about 5000 samples per second (twice the speed of calcVI because it is not reading the voltage). It cannot know when a mains cycle starts, so all you can do is guess how many samples it will read in (say) 10 cycles, and tell it to read that many samples. Each sample is squared, the total is averaged and the square root is Irms.

Your "emon1" is an instance of the class EnergyMonitor. All those measurements and calculations happen quite separately for each class instance, even though they might use the same voltage pin.

Part of reading the voltage (or current) is to select the input pin, and that is done with a multiplexer inside the processor component. Trystan Lea has used an external multiplexer here
http://openenergymonitor.org/emon/buildingblocks/rtd-temperature-sensing
, and you can download the code and see how he did it. There is no fundamental reason why the multiplexer does not work.
One thing I do notice: Trystan put a 10 ms delay (delay(10);) between setting the multiplexer and reading the analogue value. You might need to do the same. If you start reading before the multiplexer has finished switching, you might get a large voltage step at the analogue input pin because the voltage and current inputs sit at slightly different d.c. voltages. If you read the edge of that step, you will certainly get wrong readings. The op.amp bias supply should remove that step, but it would still be a good idea to have a small delay.

[You might like to look at this http://openenergymonitor.org/emon/node/11143 - calcIrms(1228) seems to be a good value to choose. If you are reading a random part-cycle of current at the end, your Irms readings will vary because the maths assumes an exact number of whole cycles.]

joseglez's picture

Re: Adding extra analog inputs

I finally made it to work.  The problem was a faulty mux.  I started fresh, replaced all the components one by one and once I replaced the mux everything worked as it should.  Now, I can continue with the project.

I appreciate the help I received and for sure now I have a more intense knowledge of the system.  I hope I will have the same attention in case I need it.  Thanks again.

Comment viewing options

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