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

A/D conversion spurious readings

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

A/D conversion spurious readings
PostPosted: Sun Nov 04, 2007 7:58 pm     Reply with quote

Hi, I have a simple A/D conversion program written in pcm V2.731 (an oldie but a goodie)

I am just reading channel 1 and printing the result out the serial port.
With vref+ = VDD and Vref- = Vss

With the AN0 connected to 0V with a good test lead I get strings of numbers like this:

0,0,0,0,0,0,0,18,0,0,18,5,6,0,0,0,0,1,5,6,0,0,0, etc.

I have a lab powersupply with decoupling cap close to the micro.

Any ideas what's wrong?


My program is:

/*atod.c
by Paul Gaastra
Program for PIC16F876

L:\ELEC\Pollen\Sprayer\PICSoft\atod.bat
*/

#include "16F876.h"
#include "atod.h"

#include <stdlib.h>
#include <string.h>

#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP // NOPUT gives YESPUT on Warp 13.


#use delay(clock=3686400)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BITS=8, PARITY=N)

//-----------------------------------------------------------------

#bit ADFM_BIT = 0x9F.7
//-----------------------------------------------------------------

void main(void){

unsigned long AtoDReading;

initialise();
printf("hello world");

while(1)
{

AtoDReading = read_adc();
printf("%ld\n\r",AtoDReading);
delay_ms(500);
};
}

//-----------------------------------------------------------------

void Initialise(void){

//Port A assignments

// RA0 Analog in: Photodiode amplifier
// RA1 Not used
// RA2 Ref-
// RA3 Ref+
// RA4 Not used .
// RA5 Not connected
//
Set_Tris_A(0b111111); // 1 sets it as input 0 sets it as output
//Port B assignments:
// RB0 Start pulse input interrupt pin.
// RB1 DEBUGOUT
// RB2 DEBUGOUT2
// RB3
// RB4
// RB5
// RB6
// RB7

Set_Tris_B(0b00000001); //setting Spares as outputs as well

// PORTB = 0;

//Port C Assignments
// RC0
// RC1
// RC2
// RC3
// RC4
// RC5
// RC6 is RS232 Transmit
// RC7 is RS232 receive
Set_Tris_C (0b10011000);
//#use fixed_io(c_outputs=TESTPINC3,RX_ENABLE,RS232_SHUTDOWN)
#use standard_io(C)

// PORTC=0;

Output_Bit(PIN_C6,1); //Start off in idle (Mark)

// enable_interrupts(INT_EXT);


setup_adc(ADC_CLOCK_DIV_8);
setup_ADC_ports(ALL_ANALOG); //This erroneously sets bit 8 to 0 i.e. makes it left justified
ADFM_BIT = 1;
set_adc_channel(0);

enable_interrupts(GLOBAL);

}
//-----------------------------------------------------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 04, 2007 9:02 pm     Reply with quote

Quote:
enable_interrupts(GLOBAL);

Get rid of this line. You have no interrupt service routine.
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 05, 2007 1:06 pm     Reply with quote

Thanks PCM Programmer, you wrote:
Quote:


Quote:
enable_interrupts(GLOBAL);

Get rid of this line. You have no interrupt service routine.



Sorry, the program was a simplification of another program I was trying to debug. I got rid of the enable_interrupts(GLOBAL) and I still get the same spurious readings.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 05, 2007 1:38 pm     Reply with quote

I compiled the program shown below with vs. 2.731 and ran it on a
16F876 in a PicDem2-Plus board. It displayed the following output as
I turned the trimpot down to 0. It works OK.
Quote:

233 232 233 232 233 232 232 232 165 119 0 0 0 0 0 0 0 0 0 0 0 0


Code:

#include <16F876.H>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#bit ADFM_BIT = 0x9F.7
//============================
void main()
{
long adc_value;

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
ADFM_BIT = 1;
 

while(1)
  {
   adc_value = read_adc();
   printf("%lu ", adc_value);
   delay_ms(500);
  }
}
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 05, 2007 2:23 pm     Reply with quote

Thanks PCM Programmer.

I tried your program (not that there was anything really different) and I get the same spurious readings.

That points to bad PCB design or faulty chip. I find it very hard to believe that the PCB can introduce an error of 18 counts.

We have some other boards with PIC16F876's on them, I'll try them.

Thanks again.
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 05, 2007 3:56 pm     Reply with quote

I tried it on an identical PCB (except for a different regulator chip) and the readings range from 0 to 8 so thats a lot better than 0 to 18.

Nevertheless I was under the impression that 10 bits was pretty easy to achieve without special layout considerations.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 05, 2007 4:11 pm     Reply with quote

Quote:
With the AN0 connected to 0V with a good test lead

Remove the test lead. Make a connection between the AN0 pin
and the Vss pin on the PIC with a very short wire. Don't have any
other wires or cables connected to the AN0 pin.
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 05, 2007 4:35 pm     Reply with quote

I have joined AN0 to Vss with just about the shortest piece of wire possible and cut the track that was going to that pin and the readings still have more jitter than I would like eg 0,0,0,2,0,0,0,0,0,6,0,0,3,0,0,1 etc.

Most A/D's I'm familiar with would have readings with more of a normal distribution. (I know it can't be normal being at zero but...)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 05, 2007 5:16 pm     Reply with quote

Quote:
I have a lab power supply with decoupling cap close to the micro.

Try putting a linear voltage regulator on the board. Use that to supply
the PIC and other components instead of the lab power supply. Put a
10 uF Tantalum cap on the input and output of the voltage regulator.
pgaastra



Joined: 05 Jan 2004
Posts: 17
Location: hamilton, NEW ZEALAND

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 05, 2007 6:08 pm     Reply with quote

Amazing!

I already had the linear regulator on the PCB (being supplied by the lab supply).

My circuit diagram said I had a 10uF cap after the regulator but looking at the PCB I think it was 1uF (I had already put a 47pF and 1uF across the supply pins of the micro).

Putting the 10uF in parallel with 1uF at the output of the regulator has made a fantastic improvement. Now I get 0,0,...20 or so 0's and the odd 1, 2,4 or 6. The regulator I am using is one of those old 78L05's so maybe if I had a beefier regulator those freak readings would disappear too.

1000 apologies for wasting your time. Thanks very much.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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