|
|
View previous topic :: View next topic |
Author |
Message |
pgaastra
Joined: 05 Jan 2004 Posts: 17 Location: hamilton, NEW ZEALAND
|
A/D conversion spurious readings |
Posted: Sun Nov 04, 2007 7:58 pm |
|
|
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
|
|
Posted: Sun Nov 04, 2007 9:02 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 1:06 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 1:38 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 2:23 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 3:56 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 4:11 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 4:35 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 5:16 pm |
|
|
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
|
|
Posted: Mon Nov 05, 2007 6:08 pm |
|
|
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. |
|
|
|
|
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
|