|
|
View previous topic :: View next topic |
Author |
Message |
POPE19
Joined: 27 Jun 2017 Posts: 71
|
pic ADC gives erratic readings |
Posted: Fri Apr 27, 2018 9:48 am |
|
|
I am using PIC16F914 with 20.0000 MHz crystal for reading the voltage input for a voltmeter application. I am using a custom LCD with that to display the raw ADC values of voltage input. I am using PCWH Version 5.074 compiler. The voltage input to pic is on pin-3 (AN-1). I am using a 40 pin PDIP package.
I could not figure out why microcontroller gives different ADC readings even for same input. Here is what i have done so far:
1) I tried to blink the LED to check weather the PIC is functioning or not but it blinks at 1s interval.
2) I used a trim-pot and a 5V dc input to vary the output voltage and fed that to AN1 input to PIC. I am setting the trimpot to get 1V output which is fed to PIC (check the voltage using multimeter). So I should get 205 value on my display, instead i am getting 1023.....897......0000 !! These readings keep bouncing.
Any suggestion to what should i do next ?
Here is my code:
Code: |
#include <16F914.h>
#device ADC=10
#fuses HS, NOWDT, PUT, BROWNOUT, MCLR, NOFCMEN, NOIESO
#use delay(clock=20000000)
int count1 = 11; // 1st digit
int count2 = 11; // 2nd digit
int count3 = 11; // 3rd digit
int count4 = 11; // 4th digit
int seconds = 0;
long AC_volt_samp1;
long reading;
//========================================================================================//
// LCD Configuration //
//========================================================================================//
// Digit segments A B C D E F G DP
// b7 b6 b5 b4 b3 b2 b1 b0
#define DIGIT1 COM0+11, COM1+11, COM2+11, COM3+11, COM2+10, COM0+10, COM1+10, COM3+10
#define DIGIT2 COM0+6, COM1+6, COM2+6, COM3+6, COM2+16, COM0+16, COM1+16, COM3+16
#define DIGIT3 COM0+17, COM1+17, COM2+17, COM3+17, COM2+18, COM0+18, COM1+18, COM3+18
#define DIGIT4 COM0+19, COM1+19, COM2+19, COM3+19, COM2+20, COM0+20, COM1+20, COM3+20
//#define DIGIT5 COM0+2, COM1+2, COM2+2, COM3+2, COM2+3, COM0+3, COM1+3, COM3+3
// COM0+0, COM1+0, COM2+0, COM3+0, COM2+1, COM0+1, COM1+1, COM3+1
// ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//========================================================================================//
// character 0 1 2 3 4 5 6 7 8 9 0 Null
//Decimal
byte const Digit_Map[12] = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0xFD,0x01};
//No Decimal
byte const Digit_Map_1[12] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xFC,0x00};
//========================================================================================//
// Segments Initilization //
// Seg23 Seg22 ... Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
// 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 //
// if bit_SegX is 1, SegX is set as Segment Output. Otherwise //
//=======================================================================================//
#define Segments 0x1F0C4F // Initilize LCD SegmentX
//=======================================================================================//
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
int int_count=INTS_PER_SECOND;
//============================================================================//
#int_rtcc //This function is called
void clock_isr()
{ //every time the RTCC (timer0)
//overflows (255->0)
//For this program this is apx
//31 times per second.
if(--int_count==0)
{
seconds ++;
int_count=INTS_PER_SECOND;
}
}
//============================================================================//
//============================================================================//
void Display()
{
lcd_symbol (Digit_Map_1[count1], DIGIT1); // from left to right
lcd_symbol (Digit_Map_1[count2], DIGIT2); // from left to right
lcd_symbol (Digit_Map_1[count3], DIGIT3); // from left to right
lcd_symbol (Digit_Map_1[count4], DIGIT4); // from left to right
}
//============================================================================//
Void Display_AC_Volt_Cal ()
{
set_adc_channel(1);
if( seconds >=1) //sample after 1 second
{
AC_volt_samp1 = read_adc();
delay_ms(500);
reading = AC_volt_samp1;
seconds = 0; // reset sampling time
}
// to display readings on LCD --------
count1 = reading%10000/1000;
count2 = reading%1000/100;
count3 = reading%100/10;
count4 = reading%10;
//--------------------------
}
//============================================================================//
Void Reset_Count ()
{
count1 = 10;
count2 = 10;
count3 = 10;
count4 = 10;
}
// Main Program //
//============================================================================//
void main()
{
set_tris_a (0xC2); // 1= input & 0 = output
set_tris_b (0x00);
set_tris_c (0x07);
set_tris_d (0x00);
set_tris_e (0x08);
set_rtcc(0);
setup_counters (RTCC_INTERNAL, RTCC_DIV_256);
setup_adc_ports(sAN1|VSS_VDD);
setup_adc (ADC_CLOCK_DIV_32);
enable_interrupts (INT_RTCC);
enable_interrupts (GLOBAL);
setup_comparator (NC_NC_NC_NC); // disable comp
setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,2, Segments); // set segments
delay_ms (500);
count1 = 8;
count2 = 8;
count3 = 8;
count4 = 8;
Display ();
Reset_Count ();
Display ();
delay_ms (500);
while(TRUE)
{
Display_AC_Volt_Cal ();
Display ();
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Apr 27, 2018 12:19 pm |
|
|
First thing that will be making the reading worse, is ADC_CLOCK_INTERNAL. This is not a legal setting for any clock rate above 1MHz, unless you put the PIC to sleep while you do the conversion.
Then your ADC is using your chip's supply for the reference. Any ripple on this will show as changing readings. You need to look carefully at your hardware and just how stable this is going to be....
Also select the ADC channel once at the start of the code. Currently you re-select it immediately before you read it. The ADC needs to be connected to the pin it is reading for a minimum of Tacq before you read it. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Fri Apr 27, 2018 1:20 pm |
|
|
Ttelmah,
Thanks for the reply. I realized my mistake, I have already corrected the code. My output is constant 1.001v dc.
You are right again. When I try to power PIC using 5v DC power source i get the constant ADC reading of 205.
I have to check my converter circuit. BTW i am using a 0.6 uF capacitor & a bridge rectifier after that to convert AC to DC and later I am using a 12V Zener & a 330 uF capacitor along with 7805 regulator. PIC is powered from 7805. Any suggestion what might be the culprit or how can I determine why are the ripples in output causing ADC to malfunction. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Apr 27, 2018 2:15 pm |
|
|
this line..
Quote: | AC_volt_samp1 = read_adc(); |
is scaring me !
Have to ask, are you actually tryng to read an AC voltage ? If so that's a BIG error ! PIC ADC can ONLY read a positive DC voltage, NOT AC, NOT negative DC. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Fri Apr 27, 2018 3:31 pm |
|
|
Yes I am. But I am using an OPAMP as differential amplifier and it’s output to determine ADC using PIC.
Am I going wrong way ? Please suggest. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Apr 27, 2018 4:04 pm |
|
|
Without seeing a schematic it's difficult to say BUT the PIC ADC can only have 0 to +5V DC as an input.
A diff amp can easily be outputting -ve voltage, or AC.
You can post a link to a 3rd party website to get a schematic into your post.
Also try Google, something like 'measuring AC voltage with a microcomputer'. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Apr 30, 2018 11:06 am |
|
|
Thanks Temtronic
This is my initial arrangement. I am strictly focusing on power PIC using Transformerless AC To DC Converter. And then I am using another 5v DC Source, 1 K ohm POT (To vary from 0-5 v DC) and measure ADC readings on LCD.
I am still noticing erratic readings . I understand that this is because of ripples after AC to DC conversion but any suggestion how to proceed further ? I am kind of stuck.
Thanks in advance.
here is link to my schematic Diagram.
https://www.pdf-archive.com/2018/04/30/ac-voltmeter-using-pic/ |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Apr 30, 2018 11:27 am |
|
|
You should put a small cap on the ADC input line, say 1mfd. That should help.
One problem is that your PIC is 'live' and unisolated from the mains power. Be extremely careful !!
If the power for the PIC and the ADC test supply are not tied together, you can get 'ground loops' and BIG variations in voltage levels.
The guys on 'the other side of the pond' can help. Personally I will not power projects the way you show. A simple $2 'wallwart' supply is far safer.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 30, 2018 11:53 am |
|
|
Your schematic is missing 100 nF ceramic bypass caps on both Vdd pins of
the PIC. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Apr 30, 2018 12:08 pm |
|
|
There is also the question of whether the DC voltage on the input side of the regulator is reliably above 5v?.
It is not clear from the circuit what the actual capacitor value used on the AC is?. It says '2*0.33uF', but doesn't say whether this is series or parallel?. You'd have to test the DC current being drawn and calculate the reactance to see what the actual AC voltage will be at the regulator. There may be massive ripple.... |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Apr 30, 2018 12:39 pm |
|
|
Thanks for suggestions guys .
Quote: |
If the power for the PIC and the ADC test supply are not tied together, you can get 'ground loops' and BIG variations in voltage levels.
|
Temtronic, The DC power supply & the AC / DC converter ( Build as per Circuit Shown) are powered from same 110V Receptacle. This is just for test.
Quote: |
Your schematic is missing 100 nF ceramic bypass caps on both Vdd pins of
the PIC.
|
PCM Programmer, I tried Inserting 0.1uF Capacitor to both VDD input but still no improvement.
Quote: |
There is also the question of whether the DC voltage on the input side of the regulator is reliably above 5v?.
It is not clear from the circuit what the actual capacitor value used on the AC is?. It says '2*0.33uF', but doesn't say whether this is series or parallel?. You'd have to test the DC current being drawn and calculate the reactance to see what the actual AC voltage will be at the regulator. There may be massive ripple....
|
The DC voltage on input of regulator is >5 volt. I have checked voltage using multimeter. It is around 20 v DC .
I am using 2 0.33UF capacitor in parallel (Total capacitance is 0.66 uF). The DC current at rectifier output is 30 milliamps DC. I did not understand what you mean by saying "Calculate the reactance to see what the actual AC voltage will be at the regulator". |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Apr 30, 2018 12:42 pm |
|
|
You calculate the reactance of the capacitor so you then know what the total equivalent resistance in the AC line is. Then with the load current you can calculate the AC voltage that will be present on the rectifier. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Apr 30, 2018 4:29 pm |
|
|
I found your schematic difficult to read properly.
You really need to be looking at your circuit with a 'scope.
I used to work as a switch mode power supply designer.
Most of the action happens on the live side of the isolating transformer.
To make safe 'scope measurements safe we ran everything from a 1:1 isolating transformer.
That way you can see how much ripple you've got at your regulator input.
You're quoting 20V as the input voltage to the regulator. That does not make sense.
You've got a 20-some volt zener, straight across the rectifier output. (Its difficult to tell what the actual zener voltage is.)
That's followed by a 15V (maybe 18V) zener and transistor regulator which feeds the 5V regulator IC.
Your multimeter measurements don't help you know what the ripple is.
Mike |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Tue May 01, 2018 5:11 am |
|
|
Quote: |
You calculate the reactance of the capacitor so you then know what the total equivalent resistance in the AC line is. Then with the load current you can calculate the AC voltage that will be present on the rectifier.
|
Thanks Ttelmah . I got Capacitor reactance of about 4019 ohms. and the load current is 0.03 Amps . so the voltage present at rectifier would be around 120.57 volts. but my multi meter reads 50 v at rectifier input . i don't understand am i missing something here !! |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Tue May 01, 2018 5:17 am |
|
|
Thanks mike for the suggestion . I will use the oscilloscope to figure out ripples in my circuit.
However i have used the zener (D1) as 25 volts to reduce the input voltage across the capacitor as it is rated for 25 volts and i don't have higher rating capacitor . I don't know exactly weather i can do it or not . I have ordered 100 v 330 uF capacitor but just to get going i used zener to limit the voltage to 25 volt so that I stay within the capacitor voltage rating.
without it i am getting 50 volt at output of the bridge rectifier ! |
|
|
|
|
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
|