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 support@ccsinfo.com

pic ADC gives erratic readings
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

pic ADC gives erratic readings
PostPosted: Fri Apr 27, 2018 9:48 am     Reply with quote

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: 19215

View user's profile Send private message

PostPosted: Fri Apr 27, 2018 12:19 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Apr 27, 2018 1:20 pm     Reply with quote

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: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Apr 27, 2018 2:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Apr 27, 2018 3:31 pm     Reply with quote

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: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Apr 27, 2018 4:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 11:06 am     Reply with quote

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: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 11:27 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 11:53 am     Reply with quote

Your schematic is missing 100 nF ceramic bypass caps on both Vdd pins of
the PIC.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 12:08 pm     Reply with 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....
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 12:39 pm     Reply with quote

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: 19215

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 12:42 pm     Reply with 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.
Mike Walne



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

View user's profile Send private message

PostPosted: Mon Apr 30, 2018 4:29 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 01, 2018 5:11 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 01, 2018 5:17 am     Reply with quote

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 !
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 1, 2  Next
Page 1 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