ACS712elctr 30a Current Sensor Fluctuating Atmega8

Go To Last Post
95 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have been trying to use ACS712ELECTR 30A Module sold on ebay. I have used following formula

f = ((ADC * 0.0049) - 2.52)/0.066;

I have connected AREF to GND and AVCC to VCC (5V)

using 10 bit ADC resolution. But i am not getting stable output at zero current or nothing connected to circuit. I am getting 0.0934 or 0.1678 randomly both changing. I tried to put 100nf / 1uf cap on output and Gnd signal but no change. Values keep fluctuating. Same in the load condition i get one low value (False) and high value (True checked with multimeter).

What type of noise it could be ? how to get stable 0.00 reading while nothing connected to Current Sensor Module ?

I know there are many ACS712 threads in the forum but none of them have same issue like mine. so i have opened this thread.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IMO/IME first just work with ADC counts. (It isn't unusual for the units conversion to have a problem.)

What result do you get with the input terminals tied to ground? Or tied together?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would you tie AREF to ground?

AREF is your analog reference that you are measuring against, usually you tie a .1uF cap from AREF to gnd.

Show us your schematic, and code. Otherwise we are shooting in the dark.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Why would you tie AREF to ground?

;) I missed that! lol

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am.sorry its AREF to ground thru 0.1uf / 1 uf cap tried both
I was sleepy so bymistake..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
IMO/IME first just work with ADC counts. (It isn't unusual for the units conversion to have a problem.)

What result do you get with the input terminals tied to ground? Or tied together?

when i tied input ADC to ground i get -38.18 and open wire its 37.76 on my LCD.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not able to post code so please find link to code
http://pastebin.com/vXDC3uKm

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your diagram looks like spaghetti! The optos don't much value and D4 is backwards.

Determine if the problem is with the current sensor or the code - use a 10 turn trimpot instead of the current sensor - does the problem still exist?

Keep the current sensor away from the relay - otherwise the relay's magnetic field will be detected by the acs712. How do i know this????

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Your diagram looks like spaghetti! The optos don't much value and D4 is backwards.

Determine if the problem is with the current sensor or the code - use a 10 turn trimpot instead of the current sensor - does the problem still exist?

Keep the current sensor away from the relay - otherwise the relay's magnetic field will be detected by the acs712. How do i know this????

ADC Calculation might be wrong. I am still finding for better formula for calculation. As far as ADC is concerned, its fine no issue with ADC Part.the output keeps fluctuating due to normal magnetics around 0.09 to 0.16 randomely.

i am trying to verify this site's code and implement it
http://embedded-lab.com/blog/?p=4529

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You do realize that the ACS712 is a bidirectional current sensor which means at 0A the output will be Vcc/2.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rev wrote:
You do realize that the ACS712 is a bidirectional current sensor which means at 0A the output will be Vcc/2.

Yaa I do. Only problem is without connection it should be zero but keepd fluctuating. 0.09 - 0.16. Now question is how to avoid stray magnetic field to avoid noise to hall effect sensor

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just did some calcs - you do realise that what you're observing is a change in adc reading from 515 to 516! There is no problem as such. If you want to eliminate the visual jitter, then filter the result.

float k = 0.5; //coefficient between 0 and 1. 1 = no filtering, 0= output won't change
float oldval,newval; 

newval = ((ADC * 0.0049) - 2.50)/0.066;
oldval = (newval *k)+((1-k)* oldval);

This is a first order IIR filter - call this function, say, 10 times per second and adjust the value of k to suit

You have a resolution of around 75mA.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

when i tied input ADC to ground i get -38.18 and open wire its 37.76 on my LCD.

1) Please report ADC counts as I suggested. Along with that, the ADC settings, voltage levels including AREF, AVR model and clock speed. Complete small test program would be ideal.

1a) So, what is the voltage right on the ADC pin? What is the voltage when it is grounded? If it is jumping around with the pin grounded, then you must start over.

2) When I said

Quote:

What result do you get with the input terminals tied to ground? Or tied together?

I meant the current sensing wire running "through" the current sensor.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
I just did some calcs - you do realise that what you're observing is a change in adc reading from 515 to 516! There is no problem as such. If you want to eliminate the visual jitter, then filter the result.

float k = 0.5; //coefficient between 0 and 1. 1 = no filtering, 0= output won't change
float oldval,newval; 

newval = ((ADC * 0.0049) - 2.50)/0.066;
oldval = (newval *k)+((1-k)* oldval);

This is a first order IIR filter - call this function, say, 10 times per second and adjust the value of k to suit

You have a resolution of around 75mA.

That worked :) but i have kept value of k = 0.01 then its perfect and stable operation. Right now i have connected it with LiPro Battery Charger and comparing both values along with DM. Till now great :) no issues and i have noticed that this sensor are having magnetic field offsets of 15mA-40mA. Its ok with proper calculation we can avoid it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've got issue now measuring with AC line. What should be the code for measuring with AC Current ? with AC line ? the IIR Filter worked great for DC current. but my main concern is measuring the AC Motor Current. so what should i do ?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What I do is as many conversions as practical for a period of time that encompasses at least one cycle of the mains waveform.

Each conversion-complete, I see if the value is higher than the highest so far, and lower than the lowest so far.

At the end of the time period, I average the high and low, and subtract the "null" value, and compute the current from the difference.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, so you mean to say i have 50HZ AC Line. So every 0.02Seconds the value from sensor would be changed from +ve bias to -ve. But i have Question in mind. How the ADC Value would be -ve ? it would be simply 0? so whats my maximum and minimum for ADC Value ? according to me Vcc/2 means 5/2 = 2.5 for 1024 counts its 512. so maximum is 512 counts of ADC for highest 30A current in positive direction and 0 ADC counts for 30A -Ve direction. am i right ? or something please correct me if wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the reversal happens every 10ms!
Have you researched the wealth of information on Arduino? Since it is just an AVR on a pcb, the information is directly applicable.

Try gooogling 'avr ac current sensor'

Note that many of the hits use a current transformer which is a much safer method for measuring mains current. Still, you have an ac signal and there are various means of converting it to a value. For one, you might wish to do a RMS conversion.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Note that many of the hits use a current transformer which is a much safer method for measuring mains current.

Assuming a proper layout, I'd say the isolation of an Allegro ACS712 is sufficient. But indeed one would be handling connections vs. the insulated conductor.

Does that module really have an Allegro ACS712? "Allegro" is not mentioned anywhere in the listing or the silk-screened information.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One interesting thing i found with the acs is that i killed a couple of them by hitting them with a large overcurrent condition. The sense link didn't fuse but it was like the device was permanently biased. I didn't investigate it too deeply but it seems the overload capability maybe isn't too good.
Regarding the safety, i wasn't worried about the acs isolation but that it is much easier with the clamp style current transformers that can be purchased cheaply to clamp onto the feed wire and not having to cut wires etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not able to find the simple RMS Calculation. Can anyone help me with code ? a lil help will do i just want simple hint calculation with ADC count how it can be used with RMS ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
One interesting thing i found with the acs is that i killed a couple of them by hitting them with a large overcurrent condition. The sense link didn't fuse but it was like the device was permanently biased. I didn't investigate it too deeply but it seems the overload capability maybe isn't too good.

You could certainly be right but my experience was a bit different. In my case there wasn't any overloading of the acs but under certain circumstances there were very large currents flowing nearby in other circuits. To make things even more difficult to troubleshoot, by nature of the machine, the acs measurements were not needed nor monitored during the period where the high currents were active. The observed symptoms were that the machine would largely function well for a time and then, seemingly at random, the acs would develop an offset. Long story short. The other currents were magnetizing some iron in the vicinity of the acs causing the offset. Physical rearrangement of the parties involved solved the problem.

Letting the smoke out since 1978

 

 

 

 

Last Edited: Sun. Aug 17, 2014 - 07:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally i've something lil success with following code

But i found strange behavior when checking with Hair Dryer. Dryer has 2 modes. Normal / Fast. When i keep dryer in Normal mode it gives me reading for 2.6 AMPs @ 250VAC. Thats true to 3AMP Measured by Multimeter. But when i move the switch to fast position... it shows only 0.4 AMPs. ? howz that possible ? Actually it should show 5.5AMPs (indicated by multimeter)... ? any idea what could be wrong ?


void ac_current_measurement()
{
	int32_t AVG=0;
	uint32_t SQAVG = 0;
	for(int i=0;i<50;i++)
	{
		int32_t k1 = padc; //PADC = ADC_read()
		AVG = AVG + k1;
		SQAVG = (k1*k1) + SQAVG;
	}
	SQAVG = SQAVG/50;
	AVG = AVG/50;
	rms = sqrt(SQAVG);
	//added for testing
	newval = (rms * 0.0049);
	newval = (newval - 2.50)/0.066;
	oldval = (newval *k)+((1-k)* oldval);     //IIR Infinite Impulse Response Filter
	fvalue = oldval-0.19; // 0.19 is offset error        persist even when no device connected
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you expect to do floating point calcs on integer variables?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, that was silly mistake.. :?

I've made some changes but issue is i am not able to detect lower current like 0.4AMP of my Glue Gun. I tried hair dryer now it goes to 2.0-2.1AMP and when i move to high speed its going upto 4.0 AMP. Still not upto to the mark..(it should touch 5.5AMP) around.

What could be the reason ? :idea:

void ac_current_measurement()
{
	float AVG=0;
	float SQAVG = 0;
	for(int i=0;i<50;i++)
	{
		int32_t k1 = padc;
		AVG = AVG + k1;
		SQAVG = (k1*k1) + SQAVG;
	}
	SQAVG = SQAVG/50;
	AVG = AVG/50;
	rms = sqrt(SQAVG);
	//added for testing
	newval = (rms * 0.0049);
	newval = (newval - 2.50)/0.066;
	newval = abs(newval);
	oldval = (newval *k)+((1-k)* oldval);     //IIR Infinite Impulse Response Filter
	fvalue = (oldval);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Ok, that was silly mistake..

What did I say earlier?
Quote:

IMO/IME first just work with ADC counts.

Tell what the ADC counts are under your conditions. Tell what you expect. Tell how you are measuring.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since we have no idea of how you're sampling the data, we can only guess. I'd suggest importing the raw data into excel and verify your calcs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes you guyz are right :)

ADC Counts matches my expectation. Finally i found some what nearest value by divinding fvalue/0.707 (Sine value).

Practically i test and will let you know the results.

After diving by 0.707 i am getting all the expected values as i see in my Digital Multimeter. So that is 99% correct lets see i need to check further.

i checked the Sine RMS Function on wikipedia and its a/Root(2). so i tried divided by 0.707 and it matches expectation.

I am using following code to sample

ISR(ADC_VECT)
{
 padc = ADC;
}


void ac_current_measurement() 
{ 
   float AVG=0; 
   float SQAVG = 0; 
   for(int i=0;i<50;i++) 
   { 
      int32_t k1 = padc; 
      AVG = AVG + k1; 
      SQAVG = (k1*k1) + SQAVG; 
   } 
   SQAVG = SQAVG/50; 
   AVG = AVG/50; 
   rms = sqrt(SQAVG); 
   //added for testing 
   newval = (rms * 0.0049); 
   newval = (newval - 2.50)/0.066; 
   newval = abs(newval); 
   oldval = (newval *k)+((1-k)* oldval);     //IIR Infinite Impulse Response Filter 
   fvalue = (oldval)/0.707; 
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

Ok, that was silly mistake..

What did I say earlier?
Quote:

IMO/IME first just work with ADC counts.

Tell what the ADC counts are under your conditions. Tell what you expect. Tell how you are measuring.

Yes, ADC count matches my expectation. Only problem was with RMS Calculation which i modified by studying little more over it.

I found newval variable moving towards negative side so what i did is i put abs(newval) and problem solved. Now only magnitude matters, nor its direction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you sample 50 equally spaced adc conversions over at least one cycle? The rms calculation effectively does the root of two correction for you so you shouldn't need to correct it. You need to stop and think carefully about what you're doing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
How do you sample 50 equally spaced adc conversions over at least one cycle? The rms calculation effectively does the root of two correction for you so you shouldn't need to correct it. You need to stop and think carefully about what you're doing.

You mean to say that i am sampling 50 times the same value of ADC?

Actually i tried to put all of this calculation in the ISR{} but doing that my complete processing becomes too laggy and LCD stops working at normal speed and display 1 character every second. So what i did is just take the value of Completed ADC Conversion and put the program in main loop processing.

What i can do is i can keep if(padc != ADC) condition to do sampling.i think that would work ?

Any better ideas ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are a number of solutions - one is to avoid using slow floating point, another is to put the samples into an array and do the rms calc. Some rectify the signal in the analog domain. Some might use a rms converter chip. I've even seen a lightbulb and a ldr used. You do realise that there has been a lot written about this very problem - just a Google away.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why do you sample 50 times? Sampling 32 -or 64 - times and doing all the intermedate calculations (needs 32 bits for SQAVG : a squared adc value is 20 bits -2*10-, cusumming would add 5-6 bits -> up to 26 bits; 16 bits would be enough for AVG -which is never used-) in integer, up to the division (and it is likely to be optimized out as shifs). Only one conversion would be needed, to scale and square root....

BTW : you should substract ADC bias (2.5 v, ie 512) before squaring....

BTW2 : does your IIR filter remain useful? -it was for continuous signals: you go wide away from wikipedia' s exact solution and you are likely to miss transients -value of "k" is small, leading to slow response- such as light bulb -tungstene ones- going on, amplifiers starting and loading filter capacitors....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
.

does your IIR filter remain useful? -it was for continuous signals: you go wide away from wikipedia' s exact solution and you are likely to miss transients -value of "k" is small, leading to slow response-

Its an RC circuit discretised, its actually really useful and interesting

This is something I have just 'discovered' and if anyone is interested I can show how to derive it in a few lines and it is then much easier to see what is going on, time constants, rise times etc

I worry that maybe its just me that never realised how easy it is to derive and develop a software filter?

Edit

does kartman who originally posted the code know the derivation and how it is in fact an RC filter?, I think he probably does and its just me who is behind the times!

Last Edited: Mon. Aug 18, 2014 - 11:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ooops

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Noob - i know you're dying to! Hit us with it and the reciprocal of pi to your good wife.

My math isn't that good but i do know it is an exponential function.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman, your comments here are the exact reason why I believe this site is sooooo good

No-one here pretends that they know everything and there is no shame in saying hey I don't know, engineering is a complicated affair and its impossible to know a fraction of it yet when I look around at other sites they are full of know it alls

There are plenty of people here whom I have the greatest respect for and you are one of them

So here it is, maybe I should of started a thread but lets do it, no heavy math at all but we go the long way to make it really clear

Drum roll......

An RC low pass filter circuit everyone knows, its a resistor and a capacitor in series, with the output taken across the capacitor, the current through the cap is the current through the resistor

The voltage across a capacitor is perhaps the hardest math here

S denotes integral

Vcap=(1/C)S i(t) dt (one over C times the integral of current with respect to time!!)

We can rearrange this so that

i(t) = C dVcap/dt

Vcap is output for us so let Vcap=Vo

The (voltage) equation for the RC circuit

Vin = Ri(t) + (1/C)S i(t)

Now replace i(t) with CdVo/dt

Vin = R(Cdvo)/dt + (1/C)S (Cdvo/dt)

The C's cancel and S cancels out d/dt to leave

Vin = RC dVo/dt + Vo

A differential is simply the slope of a line, distance up/distance along

distance up is simply the new_value-old_value and the distance along is the sampling interval

So

Vin(n) = RC (Vo(n)-Vo(n-1))/Ts + Vo(n)

Vin(n) = RCVo(n)/Ts - RCVo(n-1)/Ts +Vo(n)

Vin(n)+ RCVo(n-1)/Ts = Vo(n)(RC/Ts +1)

Vin(n)+ RCVo(n-1)/Ts = Vo(n)(RC+Ts)/Ts

V0(n) = Vin(n)*Ts/(RC+Ts) + Vo(n-1)*RC/(RC+Ts)

And there you have it, look at it and look at yours

How your k filtering factor is in fact Ts/(RC+Ts) and the fact that

Ts/(RC+Ts)+(RC+Ts)/RC = 1

It has an infinite impulse response because a single sample of 1 (followed by infinite 0's)will initially give an output and because that output is fed back into the input it creates another something at the output which will continue forever, an infinte response to an impulse

I find it really interesting but I suppose I am a bit off on a tangent to most other people

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I know (learned it 35 years ago : I doubt things changed that much) it is a digital low pass circuit and an RC is an anlog one: as a low pass, it eats transients and you cannot anymore see maximum "power" (rms(I) : power should be U*I, but let us assume you do not drive inductive loads); when tungstene bulbs get hot (positive temperature coefficients), current starts very high, then is divided by almost 10... Therefore, transients may be interesting...
Time to have a rising 'stair' reaching half its value is 6 or 7 "loops" (log(0.5)/log(1-k) ; k=0.1).

This -the infinite response low pass filter- has nothing to do with the computation of a r.m.s., and a schematic:
compute rms -> IIR -> display might be over complicated (one misses peaks, does not know when something happens -it has an infinite memory...-) ; maybe
compute rms -> display it would be more exact (times are known within an interval: the exact formula is applied) , and , if there are more samples, stable enough....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Well, I know (learned it 35 years ago

Employ this person!

Quote:

you cannot anymore see maximum "power"

Hmmm?, but that is going to depend on the measured systems time periods and filter time constants, as there will be negligible losses on a signal filter

Quote:

This -the infinite response low pass filter- has nothing to do with the computation of a r.m.s., and a schematic:

I feel guilty now for writing off the OP's thread, maybe I should of started my own thread but to be fair the OP's troubles are much less clear cut

Quote:
compute rms -> IIR -> display might be over complicated (one misses peaks, does not know when something happens -it has an infinite memory...-) ; maybe
compute rms -> display it would be more exact (times are known within an interval: the exact formula is applied) , and , if there are more samples, stable enough....

I just don't understand the issue with calculating RMS in the situation where you measuring current

Determine the peak value, the frequency is a known fixed value but most importantly its sinusoidal

Divide the peak value by the square root of two and job done!

I wouldn't put a lot of trust into a ''multimeter'' unless it had proved itself to me

With a hall current sensor, a microcontroller and a bit of knowledge a basic multimeter can be beaten

I have seen some dreadful multimeters in recent years

However you seem to be saying that the filter has a negative effect on the measurement? but you are completly neglecting the dynamics of the systems but it is making me think about it so let us explore

I wish I started a thread but in for a penny....

I simulated the filter in Simulink

Plot with Ts=1, and RC=10, a k of 0.091

Long time constant of ten seconds and sampling period of 1 second, the scope traces show the continuous time version in blue, the filter in purple and the error in yellow

Check out the digital filter in action!

We expect 63%(+) in one time constant and 99%(+) after 5 time constants

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just changing the sample time to 0.1 (ten times a second)

Really reduces the error

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If we change the values to more realistic value then we can see how our filter works on a sinusoid

We design our filter on a fag packet based on the fact we want to pass 50Hz signals

lets say a 1kHz cutoff

R=100, C=1.59uF

Isn't it great using a 1.59uF capacitor?, a 1.59uF cap that is in fact 1.59uF, it makes me feel warm inside thinking of the MTBF

The only showstopper for us is sampling time and how fast we can sample

We are considering 50Hz signals and our filter time constant is 0.159ms easily short enough to pass a 50Hz signal but look what happens in simulation even if our sampling time is 5ms

The error is enormous and this is in simulation with locked clocks, in the real world everything would drift making it much worse

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Last one for me, I changed the sampling time to 1ms

And the results are decent, as you can see the sampling time is the limiting factor, increase the sampling and dcrease the error,if we can sample fast enough then the software filter can be very useful and it can in fact measure the full range as long as our time constants are set accordingly

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, there are lot of wikipedia links to digital low pass filters, with intersting fonts....

At the beginning of the thread, OP was advised to use a low pass filter to hide spurious displays on a LCD (there are other ways of doing it: one may add "hysteresis", thus not refreshing display if abs(present value - displayed value) < threshold to keep LCd comfortable...)
I suppose it was for directional current;

Then he asked about computing the R.M.S (using wikipedia's explicit formula, which is the definition ). I am very sorry, but r.M.S is generally used for A.C (alternative current; for DC, it is trivial).

Is the context the same (that would mean AC==DC?)

Then , is it necessary to use an low pass filter after having computing an exact value (if this low pass filter has an infinite memory -what does IIR mean-), a huge value can lead to slowly decreasing "errors" and one does not know when then happens : using an explicit formula to have an unpleasant behavior is not a good idea IMO......
Maxima (minima, too) will be dampened out (and knowing a maximum current , even transient , is interesting IMO)...

Therefore, I asked **MR OP** whether he (i.e Mr OP) was interested in transients or not .

BTW as IIRFs simulate RC, and as RCs are recommanded at the entry of an ADC to avoid aliasing, maybe .... digital IIRFs are redundant... After a non linear treatment (sorry, R.M.S computing is not that linear), one does not know what will happen and first thing to be done, IMHO, would be
a) to make IIR filtering a distinct problem from the RMS one
b) to test if explicit RMS (may be for a second) is interesting enough for what he (translate : Mr OP) wants...

BTW : where can you buy 1.59 uF capacitors?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I am very sorry, but r.M.S is generally used for A.C (alternative current; for DC, it is trivial).

Is the context the same (that would mean AC==DC?)

Well yeah, RMS of an AC signal is just normalising it so that it has the same heating effect, the area beneath the curves is equal

We could work it out by setting the integrals equal but theres no need the DC value is the RMS value

Quote:
BTW as IIRFs simulate RC, and as RCs are recommanded at the entry of an ADC to avoid aliasing, maybe .... digital IIRFs are redundant... After a non linear treatment (sorry, R.M.S computing is not that linear), one does not know what will happen and first thing to be done, IMHO, would be
a) to make IIR filtering a distinct problem from the RMS one
b) to test if explicit RMS (may be for a second) is interesting enough for what he (translate : Mr OP) wants...

I haven't got a clue what you are talking about here but this comment

Quote:
BTW : where can you buy 1.59 uF capacitors?

made me laugh out loud, you don't know what I am talking about do you which is worrying, does anyone else?

The 1.59uF capacitor also has a tolerance of 0%, temperature and physical effects do not alter it, it has a MTBF of infinity and it doesn't age at all it is always 1.59uF to put the icing on the cake it is the cheapest capacitor in the world

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
you don't know what I am talking about

Well, I bet you ... try to reformulate wikipedia (which has nice fonts).
This is redundant with everything one can find with google (and OP already found it)
But I do not see why :

a) he multiplied by 0.7

b) he added a recursive filter, which dampens the extrema and makes datation impossible (they are seldom advised in signal processing) ... Exact, explicit formula do... (why should one add errors -they were advised in another context- to an exact formula? I suspect two errors...).

I fear he added an exact formula -the definition- and cascaded some stuff which should be separated.... This would make things even harder to trouble shout (and copying wikipedia about Ulysses travel .... or about irony (at least some, saying kindly, unsophisticated definition of irony) .... would add / adds confusion).

"Divide the peak value by the square root of two and job done! "

Under which magical assumption?

Well, current into some LED based lamps is like that:
a sinusoid + a pulse (the pulse lasts 1/20 of the time, and is 30 times higher....
: ; this is the case where R.M.S should be computed explicitly, by an exact formula...., else, approximated formula -integrating a sin**2 to "do the job" would lead to unemployemnt).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I was just experimenting.... i am not sure about anything...

Can you guyz give me exact calculation code? to calculate AC Current using ACS712 30A.

I tried my best possible.. but i am not experience with this things before... so forgive me for my mistakes.. i am just playing with code..to get correct value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Well, I bet you ... try to reformulate wikipedia (which has nice fonts).
This is redundant with everything one can find with google (and OP already found it)
But I do not see why :

i don't understand, are you saying I copied wikipedia? and it was a waste of time?

Quote:

This would make things even harder to trouble shout (and copying wikipedia about Ulysses travel .... or about irony (at least some, saying kindly, unsophisticated definition of irony)

This one really has me confused, I really do not know what you are talking about?

Ulysses trave?, irony?

What?

Quote:
Under which magical assumption?

Nothing magical, he is measuring mains powered equipment, the frequency is fixed and known the waveform is a sinusoidal

Whats magic about that?, no need to integrate anything

To work out the true RMS of a complicated waveform is more involved but its certainly doable, its not recommended for the OP though

Quote:
integrating a sin**2 to "do the job" would lead to unemployemnt)

Well yea of course it would

we need to times the integral by 1/T and take the square root to get RMS :D

Quote:

RMS=((1/T)*S(V(t)^2))^0.5

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

asking wrote:
Hi,

Can you guyz give me exact calculation code? to calculate AC Current

Its mains AC so its 50Hz (in UK) maybe 60Hz

Find the peak value and divide by sqrt(2)

Its honestly that easy if you know the frequency and you know its a sinusoid

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

"Divide the peak value by the square root of two and job done! "

Under which magical assumption?


Under the magical assumption that this is good enough for all of the production apps where I use ACSnnn sensors to measure AC current. I described my method. Indeed, I may not exactly find the peak and the valley every time with continuous ADC sampling. But close enough for real work IME. Remember that an AVR8 ADC is only 10 bits to start with. Mid-point offset brings us to 9 bits. the nature of this reading brings me to 8 or 7 bits--about two significant digits or a bit more. Close enough.

Now, if someone really wants to analyze mains waveforms--then get an Analog Devices ADEnnnn. More than enough stuff in there to satisfy even you purists, for a few bucks. Nearly all the mentioned topics are already in the little beasties.

NOTE: Take care when reading the mains voltage waveforms--simple dropping resistors don't isolate you.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you guyz give me exact calculation code? to calculate AC Current using ACS712 30A.

If you want to compute R.M.S (and it is nivce experimenting) you should:

a) remove the 0.707 multiplication...

b) remove the digital filter (cascading complexity will make things uneasy to debug).

c) substract the ADC bias before squaring (-512); be sure you do not substract it twice)

Then, as you already coded it, it might work (but slowly : you were hinted how to use integers instead of floats... )

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you guyz give me exact calculation code? to calculate AC Current using ACS712 30A.

If you want to compute R.M.S (and it is nivce experimenting) you should:

a) remove the 0.707 multiplication...

b) remove the digital filter (cascading complexity will make things uneasy to debug).

c) substract the ADC bias before squaring (-512); be sure you do not substract it twice)

Then, as you already coded it, it might work (but slowly : you were hinted how to use integers instead of floats... )

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When i compile and run this program on Atmega8 Running with Int osc @ 8MHZ. i get 38.50 on LCD ? :(

volatile float oldval,newval,fvalue,padc,rms;

ISR(ADC_vect)
{
   padc = ADC;	
}


void ac_current_measurement()
{
	float SQAVG = 0;
	for(int i=0;i<32;i++)
	{
		padc = padc - 512;  //padc = read_adc();
		int32_t k1 = padc;
		SQAVG = (k1*k1) + SQAVG;
	}
	SQAVG = SQAVG/32;
	rms = sqrt(SQAVG);
	newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
	newval = newval/0.066; // sensor output 66mv/A
	fvalue = newval; // final output on lcd
}
Last Edited: Mon. Aug 18, 2014 - 04:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
If you want to compute R.M.S[/i] (and it is nivce experimenting) you should

No sorry but please explain what is so hard to grasp here?

Maybe its me?, why on earth would the OP want to start squaring things when all he needs to know is the peak value

he doesn't even need to know the frequency thats just to be observed when it comes to sample times

Please explain to mean why you think that multiplying a sinusoidal waveform by 0.707 (1/sqrt(2)) doesn't give RMS?

I can guarantee you it does

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bignoob wrote:

If you want to compute R.M.S[/i] (and it is nivce experimenting) you should

No sorry but please explain what is so hard to grasp here?

Maybe its me?, why on earth would the OP want to start squaring things when all he needs to know is the peak value

he doesn't even need to know the frequency thats just to be observed when it comes to sample times

Please explain to mean why you think that multiplying a sinusoidal waveform by 0.707 (1/sqrt(2)) doesn't give RMS?

I can guarantee you it does

can you give me some code to calculate peak value ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Nothing magical, he is measuring mains powered equipment, the frequency is fixed and known the waveform is a sinusoidal

Whats magic about that?, no need to integrate anything


Well, light bulbs may have a very non linear response
Some waveform (the foltage) is sinusoidal... may be (does your main provider warrant "the waveform"
a sinusoidal one) ?

The intensity waveform (oh, it was Mr OPs topic) is not sinusoidal at all....
See
http://forum.elektor.com/downloa...
figure 4 (and the job will be poorly done with a 0.7 multiplication; users will hope the programmer will be fired, if they want RMS)...
R.M.S. should be attempted with an exact , explicit formulation in such cases (and fluorescent or LED light bulbs are part of the real, not that sinusoidal life...). Unless there is a best solution.(it is slow..)

BTW : how can industry quality (with simplifications, which can be justified in a given domain) be verified for their R.M.S displaying?

a) They are not verified: the man who programmed was a friend...

b) a nice Crystal ball?

c) Exact integration on selected cases?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
can you give me some code to calculate peak value ?

Do not jump from an idea (IMO, explicit RMS was/is a good idea) to another; it is the best way to mess a lot of things ...

FYI : peak value -say, maximum) is computed like that:

outside the loop, at initt:
maxi=MININT // MININT is the minimum value -32***, say, depends on your data representation

in the loop
if (value > maxi) maxi = value...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
Quote:
can you give me some code to calculate peak value ?

Do not jump from an idea (IMO, explicit RMS was/is a good idea) to another; it is the best way to mess a lot of things ...

FYI : peak value -say, maximum) is computed like that:

outside the loop, at initt:
maxi=MININT // MININT is the minimum value -32***, say, depends on your data representation

in the loop
if (value > maxi) maxi = value...

Nah, i am not jumping..from ideas.. i was wondering..how can one calculate peak value :D

BTW i made below program but it gives 38.something on lcd instead of RMS current value. ? what could be wrong ?


volatile float oldval,newval,fvalue,padc,rms; 

ISR(ADC_vect) 
{ 
   padc = ADC;    
} 


void ac_current_measurement() 
{ 
   float SQAVG = 0; 
   for(int i=0;i<32;i++) 
   { 
      padc = padc - 512;  //padc = read_adc(); 
      int32_t k1 = padc; 
      SQAVG = (k1*k1) + SQAVG; 
   } 
   SQAVG = SQAVG/32; 
   rms = sqrt(SQAVG); 
   newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC 
   newval = newval/0.066; // sensor output 66mv/A 
   fvalue = newval; // final output on lcd 
}

:shock:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Please explain to mean why you think that multiplying a sinusoidal waveform by 0.707 (1/sqrt(2)) doesn't give RMS?

I can guarantee you it does
"

Well, what is your garantiee
(when one assumes every current is sinusoidal? Well, one can assume, too , every voltage and intensites are known : measuring is a big waste of time....)

Quote:
Its honestly that easy if you know the frequency and you know its a sinusoid

Well, it becomes even easier if voltage and intensities are known, too... (measuring instruments are expensive: people trying to improve them are redundant crooks, are not they?)

Try a mixture of pulses and rectified sinuses (like current through a LED / fluorescent light bulb , when feed with a sinusoidal voltage. And you will see the ugly job done....
Oh, I was nice enough to give the link...

Last Edited: Mon. Aug 18, 2014 - 05:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

asking wrote:
Bignoob wrote:
[code]If you want to

can you give me some code to calculate peak value ?

Mate I am the last person you want to give you code

But I can help certainly

Look at the datasheet

Output voltage versus sensed current

with 5V

2.5V@0A

0.5V@-30A

4.5V@+30A

Its a straight line

y=mx+c

The ADC gives us a reading of

1023@5V

0@0V

With the sensor

0.5V is a reading of about 102

2.5V is a reading of about 512

4.5V is a reading of about 920

Plot as straight line relating amps to ADC counts

A =m*ADC +C

We know it goes up 60A in 818 counts

so m= 60/818

we know ADC = 512 when A = 0

0 = (60/818)*512 + C

C=37.55 (ish)

Amps=0.07335*ADC - 37.55

If you are not sampling at a rate higher than 1kHz, then drop the filter, if you ca sample higher than 1kHz then the filter is usable

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"
If you are not sampling at a rate higher than 1kHz, then drop the filter, if you ca sample higher than 1kHz then the filter is usable"
But is it of any use?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
(oh, it was Mr OPs topic)

Its a public forum

Quote:
Well, what is your garantiee

the guarantee that its a sinusoid supply, and that sinusoids only contain one frequency by their definition the rest of your post is not relevant at all, you seem to think I am saying that divide by root 2 is to work out the RMS of any waveform but I am not, just a mains sinusoidal current will be a known frequency

The OP isn't building a space shuttle, he is using a multimeter to check results and multimeters unless very expensive only measure fundamental frequencies so the multi meter will not measure none linear currents anyway

you haven't understood a word I have said from the start, I think maybe you are just trolling this thread now if I am honest

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
"

But is it of any use?

Of course its of use, to filter why don't you check the plots? its so clear how useful it is

You clearly don't get any of it, its entirely possible to get that 1.59uF capacitor

I don't think wiki is very good at getting a good understanding for anything

If the OP can sample faster than 1kHz let me know and we can work out the filter constants to give a good response with realistic cutoff frequency

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
float oldval,newval,fvalue,rms; // do not need to be volatile (needs to be fast, why criplling optimiser?)

volatile int16_t padc;
volatile uint8_t semadc;

ISR(ADC_vect) // should be triggered at fixed rates...
{
   if (semadc== 0) {
     padc = ADC;
     semadc =1;   
    }
}


void ac_current_measurement()
{
   float SQAVG = 0;
   uint32_t sumsqrs = 0;
   for(int i=0;i<32;i++)
   {
      padc = padc - 512;  //padc = read_adc();
      while (semadc == 0) {} // active loop to synchronize (clumsy programming)
      int32_t k1 = padc;
      sumsqrs = sumsqrs + padc*padc;
      semadc = 0; // allows next value
      // SQAVG = (k1*k1) + SQAVG;
   }
   sumsqrs = sumsqrs/32;
   rms = sqrt((float)(sumsqrs));
   newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
   newval = newval/0.066; // sensor output 66mv/A
   fvalue = newval; // final output on lcd
} 

Ths code might be faster (and you can hope walues will be read only once, one of Kartmanns hints)

You might test it (I did not look at the different contants, which is boring) by replacing the ISR with:

ISR(ADC_vect) // should be triggered at fixed rates...
{
   if (semadc== 0) {
/* test wit a constant */
     padc = 1012; // will return a constant : you can figure out the solution
     semadc =1;   
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

" why don't you check the plots? "
Which plots:
Bignoops one , redundant with wikipedia and with was I have been knowing since centuries.. , and , if they are of any use, too early (will cascade wit unuseful complexity) ...
(and sprinkle with insults and ... unsophisticated .. "irony")
or Maxims one? (interesting for modern light bulbs; well written) http://www.maximintegrated.com/e... -see figure 4, an non linear component-

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
" why don't you check the plots? "
Which plots:
Bignoops one , redundant with wikipedia

Quote:
and sprinkle with insults and ... unsophisticated .. "irony"

The last plot shows a 1kHz cut off with 50Hz response

It shows how it performs with 1ms sampling and it shows that it is indeed a useful filter

I didn't copy the simulation off wiki, I explained as best as I could the dynamics and how we cant just write off the filter like you did so now please provide a link (not just on wiki) that illustrates this problem as clarly, otherwise your comments just sound child like

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
he is using a multimeter to check results and multimeters unless very expensive only measure fundamental frequencies so the multi meter will not measure none linear currents anyway

Therefore, it is bright idea to measure non linear current (and a non redundant one!).

It is a very ugly "job" to add a lot of redundant drawings (wikipedia ) and to belittle exact solutions...

And, for

Quote:
checking results
:
a) one can check pieces of code (with known, trivial solutions)
b) one can then check with real hardware, once pieces of code have been checked, by choosing linear components... and bet checks were elaborated enough to be of some use in complicated cases (where a dual trace scope /datalogger would be useful)...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Therefore, it is bright idea to measure non linear current

No its not necessary, its a really bad idea, the multimeter doesn't do it and the OP is measuring linear currents

Quote:
It is a very ugly "job" to add a lot of redundant drawings (wikipedia ) and to belittle exact solutions...

Who has done that?, and where?

What solutions have been belittled?

Quote:

a) one can check pieces of code (with known, trivial solutions)
b) one can then check with real hardware, once pieces of code have been checked, by choosing linear components... and bet checks were elaborated enough to be of some use in complicated cases (where a dual trace scope /datalogger would be useful)...

And one can use theory and computers to help out before ever writing any code or building any hardware

please provide a link to an example that illustrates the filter response when filtering a waveform like the OP's

I don't expect the exact system just something like it that makes it all redundant

You make it sound so easy like there is wealths of it around but I am struggling here

Edit

I was thinking of posting up the 2nd order RLC filter derivation, thats not on wiki lol but got to think of the OP!

Last Edited: Mon. Aug 18, 2014 - 06:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The last plot shows a 1kHz cut off with 50Hz response

It shows how it performs with 1ms sampling and it shows that it is indeed a useful filter

Well, ADC needs an analog filter to avoid aliasing; digital, first order, infinite response filters are simply redundant... At the best, they cascade some complexity (are never used in image processing)...

"I didn't copy the simulation off wiki, I explained as best as I could"

Well, I already noticed wikipedia, even in languages other than mine, and my lectures (a century ago) were better... much better... Perhaps you should have copied.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
my lectures (a century ago) were better... much better... Perhaps you should have copied.

Your lectures were better than wiki?, I would expect so

wiki is not good for much, I have access to all the learning I could ever need and theres lots new since the last century, believe me

Please the links, they dont exist do they? it was simply childish comments designed to troll the thread, sorry but I don't do internet arguments they detract from the learning

Would you like to see the second order derivation? I dont think its on wiki?

:roll:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"
No its not necessary, its a really bad idea, the multimeter doesn't do it and the OP is measuring linear currents
"
Well, either :
a) he should keep his multimeter (better ergonomy, likely to be cheaper than some LCDs)
or
b) make something original as he intended to.

Modern equipment can have a very non linear response to sinusoidal voltages (what you improperly call "linear current"). Therefore, explicit computations of R.M.S are interesting (IIRFs : there are hundreds of them) and manufacturers, who make RMS converters, seem to be aware of it...

Quote:

Who has done that?, and where?

What solutions have been belittled?

Befiore asking to look at some pictures you did, did you reread what you posted?
But maybe
"you haven't understood a word" you "wrote from the start"...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your just a troll desperate for something to get me for but sorry I am here to learn, you will not get me into an argument I just won't do it

You made a statement that theres all these links on wiki but none are forthcoming so I have lost all respect for anything else you say, unless you can prove me wrong I am sure now you were just trolling

Quote:

"you haven't understood a word" you "wrote from the start"...

please don't take offence here as I know english isn't your native language but its very very difficult to understand your posts given this and the fact that you ask where you could buy a capacitor that only exists in software leads me to question are my posts as hard for you to understand as yours are for me?

It was a very stupid question that highlighted to me very strongly that you didn't get it, I mean how could you of understood with such a stupid question

In the words of David

I give up

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guyz, i think we are moving out of topic :) guyz you all did great and i am noob to learn all this... please do not get engage in arguments... i appreciate each of your work to get me understand what are the basics of RMS.

BTW i use Mastech MS8260E Multimeter which follows IEC61010-1 standards (40 USD). It has both AC Current Measurement and DC current Measurement. I use AC Current Measurement to compare and i don't know its true or not. But practically calculated the Wattage (P=VI) its coming to nearby.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

asking wrote:
Guyz, i think we are moving out of topic :) guyz you all did great and i am noob to learn all this... please do not get engage in arguments... i appreciate each of your work to get me understand what are the basics of RMS.

BTW i use Mastech MS8260E Multimeter which follows IEC61010-1 standards (40 USD). It has both AC Current Measurement and DC current Measurement. I use AC Current Measurement to compare and i don't know its true or not. But practically calculated the Wattage (P=VI) its coming to nearby.

i feel really bad for responding as much as I did, i really have wrote off your thread and I am sorry

read my post and use this equation

Quote:
Amps=0.07335*ADC - 37.55

Do you see how we got this equation?

you do know that you always have to calibrate systems like this as theres always little errors to offset its the nature of the beast

use that equation to convert your ADC reading ito amps, find the peak value of the measured waveform and as long as its sinusoidal then the RMS is 0.707*peak

if you want to measure none linear currents i.e currents that contain harmonics then you need to do more but from the loads you describe they are all sinusoidal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hope you understand my poor trolling English;
anyway, I made a little mistake in the code I "gave" you :

 int32_t k1 = padc;
      sumsqrs = sumsqrs + padc*padc;
      semadc = 0; // allows next value 

should be replaced by

 Disable interrupts (I do not remember the exact instruction
      int32_t k1 k1 = padc;
      sumsqrs = sumsqrs + padc*padc;
      semadc = 0; // allows next value 
enable interrupts // there is an exact instruction

(the section where interrupts should not exist is very short, however, but will it remain short and fast -by removing FP calculations- ?)...

I do not think your multimeter computes explicitely RMS ; that is not that bad with sinusoids, leading to an exact value;
* for square wave (say, -1, +1), maximum - minimum RMS will be 1.4 and exact value will be 1... maybe one can live with that, ,maybe not (and it seeems an easy way to test a multimeter);
* for short pulses mixed with sinusoid waves (some LED bulbs), it gets even worse....

And, sorry, square waves and LED bulbs exist in real life... Having another equipment , explicitely programmed, might be an interesting solution (and you can verify it on classical cases with your multimeter). I am aware a dual trace scope or a fast data logger (transmitting its data to a PC) would be even better...

"Some stupid behaviors deserve stupid questions"

Last Edited: Mon. Aug 18, 2014 - 07:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've modified the code as per your coding. But on LCD i am getting 1.80 some random value. So what i did i tested the condition by giving padc = 512. It shows 0.00 AMPs. when i change the Padc constant value to 513 it shows 2.34 AMPs on lcd. 2.34 GAP ? i think something wrong in our calculation ? it should be 0.058A Steps for every ADC count. 512 Counts and we have 30A.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If offset is removed, 0 is a good value for ADC constant == 512;
If your LCD can display int32_t values, you should display the value of sumsqrs befor dividing (then, after dividing, but things should be debugged slowly). I hope there is no overflow (a wrong integer type?). That is why I want to have very short code to begin with (and a first order filter can be replaced by a RC filter: anyways, this is necessary, for real hardware, to avoid aliasing... and I doubt aliasing will be cured by 3333rd order derivation....).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am just going off the data sheet

https://www.openimpulse.com/blog...

Its a straight line

If I put 4.5V into a mega with 5V reference it reads 920 ish

Looking at the data sheet 4.5V is 30A

If my sensor was giving out 4.5V and I read it with my ADC then use the result (should be 920)

Bang it into

Quote:
Amps=0.07335*ADC - 37.55

Then

Amps=29.982

if its 2.5V from my sensor the ADC result is 512

quote]Amps=0.07335*ADC - 37.55

Amps = 0.0052 rounding errors but close you always need to calibrate these things

If your ADC doesn't read the voltage as you expect then there could be a million reasons

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"if you want to measure none linear currents"
Well, I suppose OP wants to measure some currents (else, he would have none instruments, as I can say in my poor, trolling English -but it is not my native language and I do not need lectures- ). As some very usual gear is non linear, there are harmonics (and light bulbs, from Fourier transforms I saw, have more harmonics in their supply current, voltage being sinusoidal, than fundamental frequency....). Thus, a reference multimeter can be used with classical gear to verify a true rms works in trivial cases, but a true RMS would be useful.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
for(int i=0;i<32;i++)
   {
      while (semadc == 0) {} // active loop to synchronize (clumsy programming)
      padc = padc - 512;  //padc = read_adc();
      int32_t k1 = padc;
      sumsqrs = sumsqrs + padc*padc;
      semadc = 0; // allows next value
      // SQAVG = (k1*k1) + SQAVG;
   }

should be replaced by

for(int i=0;i<32;i++)
   {
      while (semadc == 0) {} // active loop to synchronize (clumsy programming)
/* here, an interrupt just occured and was notified */
      DISABLE_INTERRUPTS
      padc = padc - 512;  // offset correction
      int32_t k1 = padc;
      sumsqrs = sumsqrs + k1*k1;
      semadc = 0; // allows next value
       ENABLE_INTERRUPTS
      
   }

Of course, one can, in 30 passionating lines, fit a line through 2 points.... I bet it is redundant with OPs skills (overflows can be unpleasant to find).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bignoob- i know where your coming from. Dbrion - i think a bit gets lost in the translation.

Asking - i think the root cause of your problem is the way you sample your data.

You have two choices - either find the peak and scale (0.707) or compute the rms. using the peak and scaling is simpler but assumes a sinewave signal and will have an error if you measure DC. If you feed dc or any other waveform into the rms calculation, you'll get the correct answer (assuming you want the rms value). Why would you want rms? Because it makes it easier to compare ac values.

If you want to find the peak, take 30 samples and look for the highest value (assuming you sample 1000 times per second). We want more than one cycle of samples as we don't know where in the cycle we start.

I'm sure all of this has been covered before along with sample code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok finally i got it working AC Current by RMS method. But if i keep 32 Sample and divide by 32 to get average RMS. It swings from 3-4-5-8-9 AMPS i mean just like sine wave response. going slowly up n slowly down. I have not tested this in real hardware i am checking right now in proteus (away from home). But when i increase the Sample like 200-500-1000 i get stable value, but that value is diverted around 2-3 amps. I get value 7.5 AMPS on proteus with 1000 samples.

So now what to do to get stable value with low sample like 32 or 64? can we average the maximum peak value from RMS Average ? or can we use any type of filter ?

This code works for measurement of AC Current Using RMS Method (Output Current Swings like sine wave with low sample rates).

ISR(ADC_vect)
{
	 if (semadc == 0) {
		 padc = ADC;
		 semadc = 1;
	 }
}


void ac_current_measurement()
{
	float SQAVG = 0;
	uint32_t sumsqrs = 0;
	for(int i=0;i<32;i++)
	{
		
		while (semadc == 0) {} // active loop to synchronize (clumsy programming)
		/* here, an interrupt just occured and was notified */
	//	cli(); //disable global interrupt
		padc = padc - 512;  // offset correction
		int32_t k1 = padc;
		sumsqrs = sumsqrs + k1*k1;
		semadc = 0; // allows next value
	//	sei(); //	ENABLE_INTERRUPTS
	}
	SQAVG = sumsqrs/32;
	rms = sqrt(SQAVG);
	newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
	newval = newval/0.066; // sensor output 66mv/A
	fvalue = newval; // final output on lcd
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

Quote:
Asking - i think the root cause of your problem is the way you sample your data.

Well, before trying to answer this hint (and you seem to have answered it by sampling for a great number of samples -is it optimal? anyway, you can cusum up to 2**(31-20) samples without overflows with int32_t integers), are you sure it leads to known solution whith cheating the ADC interrupt to yield a constant (verifies there are no underflows)?
a) for the sum of squares
b) for the average of squares (after /32) ?
c) for the square root
d) after multiplying by constants...
(IMO/IME first just work with ADC counts. (It isn't unusual for the units conversion to have a problem. from theush : )

What happens if you sample on more (or less) than a period, before computing RMS?
say, instead of
0, 0.7,0,1,0.7,0,-0.7,-1,-0,7,0
0, 0.7,0,1,0.7,0,-0.7,-1,-0,7 (leads to somwhat higher RMS, as a zero is "missing") I suppose if it lasts a long time, things remain stable.

Just another question : how long does it take for an eye / an optical nerve to read a LCD? (IMO a second would be comfortable, without unpleasant updates, but I do not know what is pleasant)

IMO, I would sample at fixed times (1024 times a second for 50 Hz,

Edited :
I saw something inconsistent wetween code and comment in

  newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC  (should be 4.9 mv/count or 0.049)
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,

Its 4.9mv / count :) Thanks for info.

Finally i got why i was getting difference. 32 is not enough to calculate sample for 50HZ i did with 1024 or more i am getting stable Irms value. I learned that Irms = Imax * 0.707. Hence to get Imax = Irms/0.707 i am getting accurate readings.

Please correct me if i am wrong in that.

RMS value = Equivalent of Same amount DC Voltage ? right ?

Then what we say about the power available in our Home/Offices it says 110VAC(america) or 230VAC (india).
Its Vmax or Vrms ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

R.M.S value?
Voltages are given in R.M.S (ie, in US, you get 154 v maxi, in India and continental Europe -except maybe railways and airplanes (are not on earth) -, you get 308v max) to comfortably calculate power in heaters -knowing their resistance-.
Same thing applies to intensities.
If your waveform is sinusoidal, the relationship I=(Imax -Imin)*0.707 is right, and leads to less calculations (or (Irms = (45*Imax - Imin))/ 64/2 do compute only with integers...
If the waveform is not sinusoidal , which happens with fluorescent bulbs or les bulbs (when fed with sinusoidal voltages, they are very nonlinear is intensity waveform is pulses), the relationship can lead to absurd values and you should compute it explicitely, as you began.... And soes your main power supplier warrant it is sinusoidal (it warrants voltage, within a given percentage and number of changes per day for clocks to remain stable...
but not the sinusoidal waveform)

BTW to revove offsets, I substraced the min value (else, with a 512 offset, results migt be weird) and divided another time by 2..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
R.M.S value?
Voltages are given in R.M.S (ie, in US, you get 154 v maxi, in India and continental Europe -except maybe railways and airplanes (are not on earth) -, you get 308v max) to comfortably calculate power in heaters -knowing their resistance-.
Same thing applies to intensities.
If your waveform is sinusoidal, the relationship I=(Imax -Imin)*0.707 is right, and leads to less calculations (or (Irms = (45*Imax - Imin))/ 64/2 do compute only with integers...
If the waveform is not sinusoidal , which happens with fluorescent bulbs or les bulbs (when fed with sinusoidal voltages, they are very nonlinear is intensity waveform is pulses), the relationship can lead to absurd values and you should compute it explicitely, as you began.... And soes your main power supplier warrant it is sinusoidal (it warrants voltage, within a given percentage and number of changes per day for clocks to remain stable...
but not the sinusoidal waveform)

BTW to revove offsets, I substraced the min value (else, with a 512 offset, results migt be weird) and divided another time by 2..

Oh that's wonderful information.

People talk lots about Finding Peak Voltage (imax / imin peak low). How can i do with my current program ?

Do you have any coding ? in which first we store the samples in Array and then find the max or lowest ? While finding imax or imin w.r.t what we compare them ?

i am not able to find any good code to find the peak value and lowest value ? can you show me the code ? i found few on the internet but didn't understand it.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Asking - finding the max and min is dead simple. Set max and min to 0. In a loop test to see if the sample is greater than max, if so, max = sample. If sample is less than min, min= sample. Repeat for your 30 samples. You have your result.

You method of passing the adc result from the isr to the other code is a waste of time - you don't need interrupts. It also means your code has to complete before the next sample.

If i was to use interrupts, i'd be putting the samples in an array in the isr, then set a flag to say i have 30 samples, now go and compute a value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void ac_current_measurement()
{
   float SQAVG = 0;
   uint32_t sumsqrs = 0;
/* added : imin, imax initialisation (supposed to be int16_t */
   imin = 32700;
   imax = -32700;
   for(int i=0;i<32;i++)
   {
      
      while (semadc == 0) {} // active loop to synchronize (clumsy programming)
      /* here, an interrupt just occured and was notified */
   //   cli(); //disable global interrupt
      padc = padc - 512;  // offset correction
/* computes Imin and Imax on the fly */
      if (padc < imin) {
           imin = padc;
      } 
      if (padc > imax)
      {
           imax = padc;
      }
      int32_t k1 = padc;
      sumsqrs = sumsqrs + k1*k1;
      semadc = 0; // allows next value
   //   sei(); //   ENABLE_INTERRUPTS
   }
   SQAVG = sumsqrs/32;
   rms = sqrt(SQAVG);
   newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
   newval = newval/0.066; // sensor output 66mv/A
   fvalue = newval; // final output on lcd
/* scales Imin and Imax */
   realImin = (float)imin * (5.0/1023.0) /0.066;
   realImax = (float)imax * (5.0/1023.0) /0.066;
} 

BTW : you should have a unique value for constants (copying and pasting is bug prone)
say
#define COEFF ((5.0/1023.0) /0.066)

Quote:
If i was to use interrupts, i'd be putting the samples in an array in the isr, then set a flag to say i have 30 samples, now go and compute a value.

Another solution is to put some calculations inside the ISR(min, max, cumulated squares of samples on the fly -they are not that slow-), and, once a counter goes beyond , say, 32, copy the values to other places for main to further process and display at his pace...
The (only) advantage I see is that it continuously evolves from OP's initial code... (old softwares computed min, max, variance on the fly; modern ones use arrays, unless files are huge..)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok we're done :) I have finally a Great RMS Ammeter which can measure accurate DC or AC Signal.

But i need to ask, i heard that we can use Imax / Imin to average and remove offset from our final output ? do i need to do anything with Imax/imin once i have successfully get the RMS value ? Any further optimization ? becoz we have not use imax/imin anywhere...useful.

Btw..I found a way to check multimeter is RMS or not. Just put the multimeter in AC Current Measurement and take DC Current Reading. IF it doesn't show means its not True RMS Meter. My this code works accurate for DC and AC Measurements :) ofcourse

void ac_current_measurement()
{
	float SQAVG = 0;
	uint32_t sumsqrs = 0;
	int16_t imin = 32700;
	int16_t imax = -32700;
	uint16_t samples = 2048;
	
	
	for(int i=0;i imax)
		{
			imax = padc;
		}
		
		int32_t k1 = padc;
		sumsqrs = sumsqrs + k1*k1;
		semadc = 0; // allows next value
		//	sei(); //	ENABLE_INTERRUPTS
	}
	SQAVG = sumsqrs/samples;
	rms = sqrt(SQAVG);
	newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
	newval = newval/0.066; // sensor output 66mv/A
	realImin = (float)imin * 0.0739;
	realImax = (float)imax * 0.0739;
	fvalue = (newval); // final output on lcd

:D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you had the samples in an array, you could figure out min and max, take the middle value and use this as the offset value (rather than 512) then calc rms.

Still, with your code, the interrupt does very little apart from waste time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
If you had the samples in an array, you could figure out min and max, take the middle value and use this as the offset value (rather than 512) then calc rms.

Still, with your code, the interrupt does very little apart from waste time.

Taking mean value from array you mean to say that again i have to square those samples and do RMS on that too ? Bcoz those are Equally negative Quantity so summing and averaging directly would be zero. We need to square to get rid of the -ve direction.

You're right. I will change it. Actually when i started coding i had just kept interrupt to get Data when ADC is ready. Else it's of no use.

i will use this ADC function in loop intead of interrupt

uint16_t adc_read(uint8_t ch)
{
    // select the corresponding channel 0~7
    // ANDing with '7' will always keep the value
    // of 'ch' between 0 and 7
    ch &= 0b00000111;  // AND operation with 7
    ADMUX = (ADMUX & 0xF8)|ch;     // clears the bottom 3 bits before ORing
  
    // start single conversion
    // write '1' to ADSC
    ADCSRA |= (1<<ADSC);
  
    // wait for conversion to complete
    // ADSC becomes '0' again
    // till then, run loop continuously
    while(ADCSRA & (1<<ADSC));
  
    return (ADC);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman,

Do you have better code to READ ADC ? without using interrupt ? Please share.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, the code in your function adc_read wastes cycles here:
while(ADCSRA & (1<<ADSC)); ( this does not matter, as you can only do one t
hing at the time without interrupts)
Code in ac_current_measurement wastes some time in :
while (semadc == 0) {} // active loop to synchronize (clumsy programming)
Here, it matters : time waiting to synchronize could be best used to refresh dis
play (stupid reason :display is already refreshed) or to look at buttons(more likely), if one returned with an error code instead of waiting.

A better way would be to put some computations inside the ISR -I looked at generated assembly, and, under the assumption that each assembly line eats 3 cycles -a very pessimistic one- and that multiplying call eats 100 cycles, it leads to a 300 cycles greadiness in the new ISR -ca 20 us- ; only Imin, Imax, squares and count are shared...
If you use arrays, instead of on the fly computing, you must be sure arrays are in a consistent state (ex: ISR fills one half of the array; main processes the other part). This makes programming more difficult (but it is likely to be optimal, as

a) you can do more sophisticated processing whith the full story than with on the fly computing.... if there is CPU time enough...

b) DMA just fills arrays -I know avrs do not have; but xmegas and arms have- and eats very few cycles -fires an interrupt when .. the array is half full and when it is fully full, IIRC-

if you want to port to other processors , it is a brilliant solution
)
but I prefer sticking to the old solution and make it evolve...

Computing average with the min and the max can lead -with rectified supplies, say, or pulse ones- to weird errors.
Only solution I see (it makes the assumption offsets do not change quickly) would be to ... add a button to measure zero current offset, when users thinks it is necessay ( a Dual switch: one to disconect physically the current, unless one trusts the user, the other for the processor to know it must compute offset and store it)
One can compute average on the fly (instead of squaring and adding, one just adds...). Deriving computin with an array fromcomputing in the fly is very trivial -just increase a counter and read the ith element instead of having it physically read...

#define COUNTER 32
uint16_t imax, imin;
float realImax, realImin;
volatile int16_t padc, imin, imax, counter = 0;
volatile uint8_t semadc;


ISR(ADC_vect) // should be triggered at fixed rates...
{
	static uint16_t lmax, lmin;
	static uint32_t lsumsqrs;
        if (counter == 0) {
        	lmin=32700;
		lmax=-32700;
   		lsumsqrs = 0;

	}	
        padc = padc - 512;
	if (padc > lmax) {lmax = padc;}
	if (padc < lmin) {lmin = padc;}
	lsumsqrs += padc*padc;
   	counter++;
	if (counter >= 32 ) // 32 should be a defined constant
	        {counter=0;
	        if (semadc == 0) { // main is not busy with shared variables	        
        sumsqrs = lsumsqrs; 
        imax = lmax;
        imin = lmin;
	semadc = 1; // enables sharing (imin is always < imax, say, as they are consistent copies of consistent values
		
	} // end of sharing (copies of) variables
}// end of resetting counter
}// end of ISR

	uint8_t ac_current_measurement() {
		if (semadc == 0) {return 1; // no new rms value occured
		}
		sumsqrs = sumsqrs/32;
		realImin = (float) imin;
		realImax = (float) imax;
 		semadc = 0; // shared variables have been processed (at least, copied) 

                rms = sqrt((float)(sumsqrs));
                newval = (rms * 0.0049);   //resoultion 49mv/count for 10 bit ADC
                newval = newval/0.066; // sensor output 66mv/A
                fvalue = newval; // final output on lcd
		return 0; // new value should be displayed , which eats time
	}

}

Edited: closed brackets in ISR(untested)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

-- (meaning?)

I wanted to delete my post, no option for that.

It all starts with a mental vision.

Last Edited: Wed. Oct 15, 2014 - 02:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well. 

I use a lot of ACS712 ( 5 & 20A) stabilt of course some bit floating but what do you measure 0.09 0,16? Ampere? 

in your calcul what is the LSB value? 

Thierry

 

PS: make better schema, a lot of possibility to make mistake, not add more

 

Thierry Pottier

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

About a dozen messages ago, Lee askd you if the a/d reading was Nice and Smooth 0x000 to 0x7ff with a pot or something besides the current sensor. If it is, this means the ripple could be in the sensor. I'd try taking 16 or 32 or 64 or 128 readings and right shifting the sum by 4,5,6 or 7 (see how I'm doing that integer divide using a binary trick?). Now we can convert the a/d count to floating volts  v=adreading*ad2volts; I usually precompute ad2volts=5.0/1023.0; because I'm a SpeedFreak. Now you can cvt volts to current according to the formula in the datasheet.

 

I thought there were 3 pages, so I typed a comment. Yikes! There were 10 more pages.

 

 

Imagecraft compiler user

Last Edited: Wed. Oct 15, 2014 - 04:57 PM