CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ADC problem with output bridge diode
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sat Oct 14, 2017 1:45 pm     Reply with quote

No, it's a macro I included in what I posted.....

It is possible to do it without a capacitor. You'd not want 'random' samples, but to take fast repeated samples at a fixed interval for 1/2 a cycle time. Preferably using the CCP to trigger the sample so it is at a constant interval. If you take one half cycle of samples like this, then divide by the number of samples, you get the average voltage for a half cycle.
You need though to do this for exactly half a cycle(or a multiple of half a cycle) or the result will vary. This is why it is commonly done by adding a zero crossing detector and summing between triggers of this.
The other way is to repeatedly sample for more than half a cycle, and record the largest sample in this time. This gives the peak voltage.

It's a lot more complex than just adding a capacitor.....
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Oct 14, 2017 4:23 pm     Reply with quote

mereach wrote:
Do you think we can build any other solution without capacitor ?
For example , if we take random sample then calculate average of voltage...

I have not heard before and could not find any other example about vtocount(X) ... Is it a function ?
Ttelmah wrote:
It is flickering, because it is now tracking the real voltage.....

The output of the bridge, goes to zero every half cycle, and peaks at 1.4* the RMS voltage.

You need a capacitor either across R1, or at the top of R2 on the bridge voltage to smooth it to DC.

Now my conversion macro would allow you to put in another value like 2.5 or 3.5. Key is that you would only use this when the voltage changes, so it is not used in the actual comparison loop.

Look at figure3 here:
<http://www.bristolwatch.com/ele/basic_ac_rectification.htm>

This is what you have....

I have shown several times (on this forum) how to measure ac waveforms without either rectifiers or zero-crossing detectors.

Most recent
http://www.ccsinfo.com/forum/viewtopic.php?t=56115&highlight=rms

Mike

PS
On your schematic
Where is the other connection to the AC source?
Why is there a S/C across one of the diodes?
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 1:18 am     Reply with quote

Ouch....

With the circuit as posted, assuming the other AC line is also connected to the ground, he'll be only getting a half wave output. So for half a cycle, zero volts.
Circuit needs to change....
Also I'm worried about his divider. It is not clear whether the voltage figures he gives are RMS or peak?. However assuming it is something like a 10v AC source, the peak will be about 13.6v allowing for a diode drop. Fed into the divider shown, the peak voltage at the PIC would be about 5.06v.... Perhaps needs to rethink a little.

As a general comment, the easiest solution in his situation would be the peak detector. However there is a caveat here that if there are any spikes on the waveform (from mains there will be), these could easily give an erroneous high reading. A little capacitance is your friend in this regard.

Code:

#include <16F676.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset

#use delay(internal=4000000)

#define BUZZER   PIN_A4
#define SENSOR   PIN_C0
#define ROLE   PIN_C3
#define ALARMLED   PIN_C5

#define VTOCOUNT(x) (int16)(x*104)
//have modified this to give approximate counts per AC V rms (assumes
//a sin).

int16 read_peak(void)
{
   int16 temp=0, val;
   int16 ctr;
   //simple routine to return the peak voltage from a waveform
   //assuming waveform is 50 or 60Hz, so a 'full wave' is <0.02secs
   //ADC clock is 2.0uSec. Conversion/save then takes 27uSec. Tacq is
   //20uSec. Allow 25uSec for comparison, and loop. so sample interval
   //will be about 72uSec. 277 clocks for a full cycle. Allow 280 to be
   //sure.
   for (ctr=0; ctr<280;ctr++)
   {
       delay_us(20);
       val=read_adc();
       if (val>temp)   //update maximum if greater
           temp=val;
   }
   //temp will now be the highest voltage seen for just over a cycle.
   return temp;
}

void main()
{
   int16 digital, level;
   setup_adc_ports(sAN4 | VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_8);    //This is the best option at 4MHz
   set_adc_channel(4);

   level=VTOCOUNT(8.0); //integer count for 8v RMS

   while(TRUE)
   {
       digital=read_peak(); //get the peak voltage seen
       if (digital>level)
       {
           output_high(PIN_C3); //turn pins on if above 8v
           output_high(PIN_C4);
           output_high(PIN_A4);
       }
       else
       {
           output_low(PIN_C3); //off if equal or below
           output_low(PIN_C4);
           output_low(PIN_A4);
       }
    }
}


I've changed VTOCOUNT to be a guess for RMS AC to counts (assuming a sinusoidal waveform - so Vpeak = VRMS*1.414, and the voltage at the top of the divider will be this minus perhaps 0.6v.

With the rectifier fixed, so it does give full wave, the number of counts used in the read_peak code could be halved, using a half cycle instead of a full cycle.
mereach



Joined: 14 Oct 2017
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 3:27 am     Reply with quote

Thank you, most logical solution seems to be detect peak level. Please ignore schematic, as i said before i am new user here and it was Proteus and i did not know about PIC101.

Now i measure 2.4V with voltmeter on AN4. I just would like to be lit LED(C5), change over relay(C3) and Buzzer(A4) sound when voltage level exceed 3V on AN4.

I put your code my compiler and load my pic, LED, Buzzer and relay is always on.

How you calculate 104 in "VTOCOUNT(x) (int16)(x*104)" ? What does it mean ?

I think if i can understand your logic, i would solve this problem.
_________________
mereach
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 5:41 am     Reply with quote

The analog pin needs to have protection ! A 5 volt zener diode should work. A small cap would also 'quench' or reduce the excess voltage from a spike or two. MOVs are designed for this. The problem is 'mains' can go a lot higher than you think. even without 'EMI'.
Here, in Canada, mains is '120'. Mine is consistantly '126' all day/night long. This I assume is because there are only 2 households on the transformer rated for 6 homes.
mereach



Joined: 14 Oct 2017
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 5:47 am     Reply with quote

Last status is LED, relay, buzzer always flickering but when i apply +5V to AN4 all is working constantly. Code is below.
Code:

#include <16F676.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset

#use delay(internal=4000000)

//#define BUZZER   PIN_A4
//#define SENSOR   PIN_C0
//#define ROLE   PIN_C3
//#define ALARMLED   PIN_C5

#define VTOCOUNT(x) (int16)(x*204)
//have modified this to give approximate counts per AC V rms (assumes
//a sin).

int16 read_peak(void)
{
   int16 temp=0, val;
   int16 ctr;
   //simple routine to return the peak voltage from a waveform
   //assuming waveform is 50 or 60Hz, so a 'full wave' is <0.02secs
   //ADC clock is 2.0uSec. Conversion/save then takes 27uSec. Tacq is
   //20uSec. Allow 25uSec for comparison, and loop. so sample interval
   //will be about 72uSec. 277 clocks for a full cycle. Allow 280 to be
   //sure.
   for (ctr=0; ctr<138;ctr++)
   {
       delay_us(20);
       val=read_adc();
       if (val>temp)   //update maximum if greater
           temp=val;
   }
   //temp will now be the highest voltage seen for just over a cycle.
   return temp;
}

void main()
{
   int16 digital, level;
   setup_adc_ports(sAN4 | VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_8);    //This is the best option at 4MHz
   set_adc_channel(4);

   level=VTOCOUNT(5); //integer count for 8v RMS

   while(1)
   {
       digital=read_peak(); //get the peak voltage seen
       if (digital>level)
       {
           output_high(PIN_C3); //turn pins on if above 8v
           output_high(PIN_C5);
           // output_high(PIN_A4);
       }
     else
     {
     output_low(PIN_C3); //off if equal or below
     output_low(PIN_C5);
     output_low(PIN_A4);
     }
    }
}

_________________
mereach
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 7:34 am     Reply with quote

Of course it will 'flicker'...

Without some filtering of the AC ,the input voltage will flicker...

Also you need some amount of hysterisis on the setpoint.

IE:
consider the setpoint to be 3 volts

turn on if greater than 3 volts and turn off if less than 2.5.

The 1/2 volt of 'hysterisis' in this example would minimize the flicker.
It is also how a 'window comparator' can be used to compensate for line loss or variation in sensor output from unit to unit.

Jay
mereach



Joined: 14 Oct 2017
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 8:19 am     Reply with quote

Due to the codes are belong to Ttelmah, i will be waiting Ttelmah's comment.
_________________
mereach
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 8:40 am     Reply with quote

Also worth understanding that a DVM, _integrates_. Unless you are paying for very expensive high frequency response DVM's, they work by having a capacitor inside, with a FET to connect it to the input. They connect the capacitor for a fixed time to the incoming voltage to charge, then disconnect it, and start discharging it using a reference voltage, till it gets to zero. The total time taken for it to charge and get back to the zero, gives a measure of the voltage that was on the input. Most cheaper DVM's only take perhaps around 4 samples per second. Big advantage is that the accuracy is not affected by drift in the capacitors or resistors in the circuit (they cancel from the charging and discharging terms in the equation). Downside is the sloth, so they will miss quick changes in the signals.
'Dual slope integrating ADC'.

The PIC ADC is comparatively a much faster design. Even the one you have (which is slow by the standards of most modern PIC's), can actually sample in excess of 20000 times per second (Successive approximation ADC).

On calculating a value for VTOCOUNT, this is totally down to what you want it to actually measure 'in'. The figure I calculated was for RMS volts in.

If you feed in 10V RMS, then this gives 14.14v out of the full bridge rectifier. Less about 0.6v for the diode drop, gives about 13.54v to the top of the resistive divider. The PIC sees 4/10.8 of this, so 5.014v. The PIC ADC is reading 4.8mV/step, so would see 1027 counts (though won't because it is over-voltage at this point). So you are effectively getting about 103 or 104 counts/AC volt. So if you want to measure 5VAC, the count to use is about 512 (5*103). It won't obviously be quite linear because of the error from the diode, but will be as close as is practical (remember your ADC is only going to have very low accuracy, because you are using the supply as a reference). The key thing is though that the conversion from volts to counts becomes a simple multiplication.

To add hysteresis, do it as counts. Perhaps 30 for about 1/3rd volt AC:
Code:

//existing code before this
   while(TRUE)
   {
       digital=read_peak(); //get the peak voltage seen
       if (digital>level)
       {
           output_high(PIN_C3); //turn pins on if above 8v
           output_high(PIN_C4);
           output_high(PIN_A4);
       }
       else if (digital<(level-30))
       {
           output_low(PIN_C3); //off if equal or below
           output_low(PIN_C4);
           output_low(PIN_A4);
       }
    }
mereach



Joined: 14 Oct 2017
Posts: 13

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 12:08 pm     Reply with quote

Ok, I understand I have to change circuit. I failed first trying after button Application in ccs c.

Thank you
_________________
mereach
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Oct 15, 2017 5:17 pm     Reply with quote

this....
Quote:
Less about 0.6v for the diode drop,

... is a 'textbook' value.

While it's 'close' or 'approximate', you really need to measure the actual value of the diode drop. Vd can be changed by the load after the diode. A 'light' load, say ua, and you won't see the .6 volt drop whereas a 'heavy' load, say ma, then you will see the .6 volt drop. While load current is a major factor, diode type (Si, Ge,Sh) have a big influence. Schottky diodes typically have a Vdrop of .2, making them THE choice for simple diode battery backup schemes.

It's always best to read the diode's datasheet and do some bench testing R&D especially when you want or need precise values.

Also, whenever you make a voltage divider, be sure to measure both resistors. It's always 'fun' to find out the top one is a little low and the bottom one a little high, thus changing the ratio just enough to give bad numbers. As well, use 1% (or better) resistors that will handle the power going through them. The more accurate they are, the better your results will be.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Mon Oct 16, 2017 12:42 am     Reply with quote

A big question arises as to what 'accuracy' he really wants?.

First of all we run back into the old 'chestnut' of using the supply rail as the reference. Even a '1%' regulator, won't give you a 1% 'accuracy' when used as a reference. The reason is that the '1%', is a figure for the voltage in static conditions at the regulator itself, while the voltage on the PIC will be being changed by the other things drawing power on the rail, and the PIC itself. So you have 'transient' effects even at the regulator, and (of course) the voltages being developed on the tracks between the regulator and the PIC.

Then you have as Temtronic points out the accuracies of the other components.

Then there is another factor. The '0.6', is a typical drop into light loads, but to use this as a figure, I was assuming the circuit was actually the incorrectly wired bridge posted. In this the circuit is actually giving half wave rectification only, so only one diode drop. If he does actually have a full wave rectifier, there will be _two_ diode drops present not one.

If any form of reasonable accuracy is required, then the whole circuit needs re-thinking, with a precision rectifier, and an external reference to the PIC. If he is happy to accept perhaps no better than three or four percent 'accuracy', and no ability to cope at small signal levels, then the posted circuit can be made to work, however if reasonable linearity is wanted over the operating range, then really the diode drop should be measured, and included as it's own term in the calculation.
mereach



Joined: 14 Oct 2017
Posts: 13

View user's profile Send private message

PostPosted: Thu Oct 19, 2017 3:57 am     Reply with quote

A solution came to my mind... Output of the bridge frequency is 100 Hz. I will be trying to count. If we suppose there will be 2 times 3V level, we should measure 200 times 3V. I will count 3V and detect if the counter is bigger than >200 and with a proper delay.
_________________
mereach
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Oct 19, 2017 5:47 am     Reply with quote

Your idea, while it 'sounds OK', has several flaws and is way more complicated than required. It's also a very,very bad design to try to use 'fancy software' to compensate for flawed hardware.

The basic one is that you 'think' you'll get proper ADC readings say 200+ times.

Currently you're not reading the signal properly so reading it 200+ times is still 'wrong'.

The easy solution, already presented is to put a small filter cap on the rectified AC signal source,along with a small 'bleed' resistor. Use an 'Olympic' average function and you've got a 'good' reading.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group