I trying to read Power Factor that compare the signal input from voltage and current by using Bitwise XOR (^),
The result of program, I compare that to XOR component in ISIS Proteus
my Code
/*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
unsigned long a = 0;
unsigned long b = 0;
unsigned long c = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
lcd.begin(16, 4);
unsigned long a = 0;
unsigned long b = 0;
unsigned long c = 0;
pinMode(8,OUTPUT);
// Print a message to the LCD.
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorVol = analogRead(A2);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorVol ;
if (195<voltage)
{
a = 1;
}
else {
a = 0;
}
// print out the value you read:
int sensorAmp = analogRead(A3);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float current = sensorAmp ;
if (515<current)
{
b = 1;
}
else {
b = 0;
}
// print out the value you read:
c = a ^ b;
if (c==1)
{
digitalWrite(8,HIGH);
}
else {
digitalWrite(8,LOW);
}
Serial.println("current");
Serial.println(current);
Serial.println("voltage");
Serial.println(voltage);
lcd.setCursor(0,0);
lcd.print("voltage =");
lcd.print(voltage);
lcd.setCursor(0,2);
lcd.print("current =");
lcd.print(current);
}
the problem is…
why the result is so different?
Did I miss something in calibration ? or somethings else?
XOR component show how it go
*blue = voltage
yellow = current
pink = XOR component output
green = Bitwise XOR output
the different between Bitwise (^) XOR with XOR component
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
lcd.begin(16, 4);
unsigned long a = 0;
unsigned long b = 0;
unsigned long c = 0;
pinMode(8,OUTPUT);
// Print a message to the LCD.
}
Since a, b, and c are already defined global variables and you don't use them in the setup() function, you shouldn't "re-declare" them in setup().
As for your problem, I think your code's logic is to blame. Although I'm familiar with AC circuit analysis (just finished the class this past semester ), I don't know too much on how to actually measure power factor. Here is a link to a forum discussion where they answer your question. [PIC] - Power factor measurement using PIC18f4520 | Forum for Electronics
Based on this quote, I think you are missing some logic in your code:
Ninonic:
measure voltage with one ADC input
measure current with a second ADC input.
XOR (use a logic gate such as 74LS86 or equivalent) the two waveforms, feed it through a low pass filter and measure the resulting voltage through a third ADC input.
As long as you 'square up' the voltage and current waveforms using an op-amp or comparator before feeding them to the XOR gate, it's output will be a pulse with width equal to the phase difference in the signals. If you filter it to find the average, you get an analog voltage proportional to the phase shift.
It isn't using the zero crossing method at all but it will allow you to measure V, I, apparent power and phase displacement using simple math.
I know the common way is using comparator to before feeding to XOR gate.
then using for my arduino input. I did that.
but, the result from component XOR gate as I expected (in simulation),
its HIGH(sometime negative HIGH) when a!=b, and LOW when a=b.
I just need fix or erase the negative one.
for reading power factor,
I can do that with calculation based the XOR input
but I looking for another method.
I making code that can work as comparator and XOR gate at once,
maybe I miss something in calibration or input? I still don't know yet
Why not just use a couple comparators and an XOR gate? It would be a lot cheaper and simpler. Might even have a better frequency response than an Arduino.
I did. I 've been there. That not work for me. The voltage and current phase in come in same time, theres no different phase. even my mentor dunno how.
I already test, from raw voltage and current, its show the lagging.
but after trough comparator, the phase become one. dunno how, I follow the circuit design as many journal do.
I dunno why different.
So please...
maybe its time for code?
why cheaper and simpler ? the fact you buy component, make design, and so on...
why not just create the code?
So I need to convert it to Boolean? but I think its hard. Dunno much
can we do XOR in numeric mode?
I change the variable like this
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int digVol = 0;
int digAmp = 0;
int pie = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
lcd.begin(16, 4);
pinMode(8,OUTPUT);
// Print a message to the LCD.
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 2:
int sensorVol = analogRead(A2);
float voltage = sensorVol ;
if (voltage>0.01)
{
digVol = 1;
}
else {
digVol = 0;
}
int sensorAmp = analogRead(A3);
float current = sensorAmp ;
if (current>515)
{
digAmp = 1;
}
else {
digAmp = 0;
}
pie = digVol ^ digAmp;
if (pie==1)
{
digitalWrite(8,HIGH);
}
else {
digitalWrite(8,LOW);
}
Serial.println("current");
Serial.println(current);
Serial.println("voltage");
Serial.println(voltage);
lcd.setCursor(0,0);
lcd.print("voltage =");
lcd.print(voltage);
lcd.setCursor(0,2);
lcd.print("current =");
lcd.print(current);
}
Sir,
Bitwise XOR for Boolean ?
but my data in single number
0 and 1
thats XOR function should be work on that
(voltage>=195) != (current>=515));
because the voltage sensor start from 0,
I had it back to zero
and current sensor start from 2.5V which is around 510-515,
so thats why I need to cut half data from sensor current.
Your "circuit" has a fundamental problem. The current sensor would have an output signal connected to A3 that's centered at 2.5V. This is the zero crossing voltage level for the amps signal.
Your voltage signal connected to A2 shows a 1/2 wave rectified signal that's referenced to GND (0V) ... there is no zero crossing.
The voltage signal needs to be full wave centered at 2.5V, or you'll never be able to detect the phase interval between the 2 signals. Make sure the peaks are within the power rail voltages.
thanks for advice...
I tried, still not work properly...
I think still there something wrong with calibration... :C
I even use comparator, because the acs712 voltage too low, below 2.7V.
Beside, the peak to peak acs output 185mV/A. And my project more less 1A (so it around 2.315 - 2.685, with bold noise.
I think thats why...
I think comparator hard to sense the current value
Ninonic:
thanks for advice...
I tried, still not work properly...
I think still there something wrong with calibration... :C
Did the voltage signal get centered at 2.5V?
Do you mean calibration of the ACS712?
Ninonic:
I even use comparator, because the acs712 voltage too low, below 2.7V.
Beside, the peak to peak acs output 185mV/A. And my project more less 1A (so it around 2.315 - 2.685, with bold noise.
I think thats why...
I think comparator hard to sense the current value
+1
The comparator's reference voltage would need to be set above the noise level of the signal or the noise will appear full swing at the output. The datasheet shows 21mV noise peak-peak.
Several more options you could try:
Amplify the signal:
In the datasheet, Application #3 (page 12), if you replace the 3.3K with 12K, you'll get ± 2.22V/A. Now you could use a comparator or just connect directly to the analog input of the Arduino.
Use a Current Transformer
With this, if you wrap 10 turns through the hole and use a 250Ω load resistor, you'll get a ± 1.25V AC signal on the output when there's 1A going through the wire that's wrapped through the hole (primary).
Note: The speed of reading an Analog input is about 100µs (10kHz). You have 2 of them, so now 5kHz for both readings. Your AC signal is 50Hz, so you'll only be able to take 100 readings per cycle and your phase resolution would only be ± 3.6 degrees. This is not allowing for additional code slowing down the loop.
Research using the Arduino's analog comparator and input capture to get high precision time interval readings for phase calculation.
dlloyd:
Did the voltage signal get centered at 2.5V?
Do you mean calibration of the ACS712?
when I did. Its all 2.5V. raw voltage sensor 3V half wave. So I connected like your design,its seems like it just fill the empty one.
yap. ACS712.
I use ACS module this one
so I can't modify the resistor
But, I was looking someone calibrating ACS sensor to read RMS value, @elik745i. page 4. #48
the sensor runs correctly and smoothly.
[/url=http://forum.arduino.cc/index.php?topic=179541.15]this way[/url]
I wonder it can work with code method in previous code.
I think, we better use ACS than CT, because arduino operational Volt and Current small scale.
Beside using CT need to do reactifier before connected to arduino board.
Do you know how to
How to count in ms when voltage signal come, the count start
then when current signal come, the count stop
when I did. Its all 2.5V. raw voltage sensor 3V half wave. So I connected like your design,its seems like it just fill the empty one.
I guess you didn't remove the diode. The circuit I posted doesn't show any diode. Removing it should give you ±3V AC. Use a 10K series resistor (as shown in the diagram to protect the Arduino). The Arduino readings will be clipped at ± 2.5V ... this is OK because we're interested in the 2.5V crossing of the waveform, not the voltage measurement itself.
so I can't modify the resistor
Nothing to modify. Application 3 shows an external op amp circuit to amplify the output signal.
But, I was looking someone calibrating ACS sensor to read RMS value, @elik745i. page 4. #48
the sensor runs correctly and smoothly.
I wonder it can work with code method in previous code.
Not sure where this is. I wouldn't bother with code until you get proper signals to work with.
I think, we better use ACS than CT, because arduino operational Volt and Current small scale.
Beside using CT need to do reactifier before connected to arduino board.
No rectifier diode needed. Use the same circuit as posted for the voltage, except additionally connect a 250Ω load resistor across the secondary.
Do you know how to
How to count in ms when voltage signal come, the count start
then when current signal come, the count stop
Yes, but why bother now if the signals aren't ready yet.
P.S. I think you mean µs because ms will give a lousy ±18 degrees phase resolution.
I forgot to mention, if you prefer to use 1/2 wave rectified signals referenced to 0V, then your original voltage circuit is OK, except I would connect the signal to a comparator to create a digital signal. The reference voltage could be adjusted for calibration. Note that you might be able to eliminate the diode and still get a pulse representing 1/2 cycle (this would be more accurate but depends on the comparator specifications).
The current signal could be fed into a second comparator with reference at 2.5V + 21mV noise offset + xxmV calibration. This would create your second digital signal.
Now you could use 2 digital inputs (i.e. interrupts INT0 and INT1) to record the timing between the signals.