You need to post your code You can blow a ADC input but if you limited it to 5 volts it would be hard to
I use this setup to test my ADC inputs ADC_tester.png
Hi All,
My first post here, although I have 'lurked' for a few weeks.
I am building an RF Amplifier and have an 18F4682 for use as a controller and display driver
(see circuit diagram / schematic)
I have eight ADC inputs to monitor varios voltages, all of which are between 0 - 5v (I will use a potential divider to scale higher voltages like that from the 48 volt supply).
To test the unit, I used a 2k2 trimmer across a 5v supply, and a series resistor of 2.7k (I just happen to have loads of these values! - I also used them as 'R' in the DAC).
The inputs do work, but seem to 'sink' the voltage on the input when approaching 5 volts. Also unconnected inputs seem to vary in sympathy with the voltage applied to connected input.
I then decided to use eight 2k2 trimmers and 2k7 series resistor , but still no luck, now the inputs stay stubbornly low - maybe i have damaged the inputs!
I have read that these type of effects can occur, someone mentioned using decoupling capacitors near the inputs, but I am not really sure what was meant (I understand what a decoupling cap is, but not what was meant in this context).
Do I have to use OP-AMP buffers or should I use higher values of pots , series resistors for this test Jig, and what about in the actual amp?
i may have damaged the PIC inputs, but before try (damage!) another new one, I would appreciate your advice!
Andy
I
You need to post your code You can blow a ADC input but if you limited it to 5 volts it would be hard to
I use this setup to test my ADC inputs ADC_tester.png
With analogue inputs that are not changing quickly, it is always a good idea to put a capacitor between each input and ground. That is because the ADC takes a pulse of current as it reads, and because if you are getting any noise, the input clamping diodes may be conducting and lowering the voltage.
Also you should make sure that none of the pins of the PIC are outside the 0 - 5 V range. I found you can get leakage from nearby pins if the input clamping diodes are conducting.
The following is a quote taken from a PIC 12F683 manual:
Note what is covered as to source impedance. Next is a quote from the manual for the PIC you are using:9.3 A/D Acquisition Requirements
For the ADC to meet its specified accuracy, the charge
holding capacitor (CHOLD) must be allowed to fully
charge to the input channel voltage level. The Analog
Input model is shown in Figure 9-4. The source
impedance (RS) and the internal sampling switch (RSS)
impedance directly affect the time required to charge the
capacitor CHOLD. The sampling switch (RSS) impedance
varies over the device voltage (VDD), see Figure 9-4.
The maximum recommended impedance for analog
sources is 10 kΩ. As the source impedance is
decreased, the acquisition time may be decreased.
After the analog input channel is selected (or changed),
an A/D acquisition must be done before the conversion
can be started. To calculate the minimum acquisition
time, Equation 9-1 may be used. This equation
assumes that 1/2 LSb error is used (1024 steps for the
ADC). The 1/2 LSb error is the maximum error allowed
for the ADC to meet its specified resolution.
While the source impedance has changed and your chip is 2.5 K Ohm you want to keep that in mind looking at your ladder logic in the drawing. This could be part of why you are seeing the effect you are seeing.19.1 A/D Acquisition Requirements
For the A/D converter to meet its specified accuracy,
the charge holding capacitor (CHOLD) must be allowed
to fully charge to the input channel voltage level. The
analog input model is shown in Figure 19-2. The
source impedance (RS) and the internal sampling
switch (RSS) impedance directly affect the time
required to charge the capacitor CHOLD. The sampling
switch (RSS) impedance varies over the device voltage
(VDD). The source impedance affects the offset voltage
at the analog input (due to pin leakage current). The
maximum recommended impedance for analog
sources is 2.5 kΩ. After the analog input channel is
selected (changed), the channel must be sampled for
at least the minimum acquisition time before starting a
conversion.
To calculate the minimum acquisition time,
Equation 19-1 may be used. This equation assumes
that 1/2 LSb error is used (1024 steps for the A/D). The
1/2 LSb error is the maximum error allowed for the A/D
to meet its specified resolution.
Example 19-3 shows the calculation of the minimum
required acquisition time TACQ. This calculation is
based on the following application system
assumptions:
CHOLD = 120 pF
Rs = 2.5 kΩ
Conversion Error ≤ 1/2 LSb
VDD = 5V → Rss = 7 kΩ
Temperature = 50°C (system max.)
VHOLD = 0V @ time = 0
Then too, I may be totally off base with this.
Ron
Please do not PM me with forum related questions. Let's keep things in the open forum. Thank you.
Small point: I don't see +5V and Ground connected to the PIC18F. I know you have power and ground or it could not work.
What your doing with 8 pins could be done with 1 pin and pwm controlling the attenuator
Burt
be80be
Like I said Be nice to see some code. I didn't really see any thing wrong with his circuit. And i don't see all 8 pins going bad at one time . And he said he was getting readings but low one and it was trying to sink power. Sounds like the port not set right to me. Sure be nice to see the Code then we would Know.
Burt
be80be
As others have mentioned, post your code - and also be aware that source impedance is crucial - if it's too high you need to leave longer for the sample and hold to settle every time you switch channels, otherwise channel voltages affect each other.
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Hi All,
Thanks for the replies.
It seems from the datasheet quoted above that the source impedance should be below 2k7, so I am close to this with my test Jig, depending on the setting of the pot(2k pots with 2k2 series resistor). However, other suggestions, such as Burt's above (10k pot and 470 R series) would have a higher source impedance. (but other PICs can cope with higher source impedance
The PIC is programmed in 'C' , and I have enlisted some help to do this, (basically I am an analoge guy struggling to get digital!) but here is the code relating to the inputs. there is some other codealso to do with the up/down buttons, BTW the pull up resistors on them are 27K, don't think it's on the drawing, also missing is the 5v and ground connections to the PIC itself, but as someone said above, it is working, in that the display is functioning and the up/down buttons working as required.
My main worry is how to test it properly and what value series resistor do I eventually need when measuring the like of PSU voltages - I don't think there will be a source impedance issue there!. On the other hand, for the forward and reflected power, I may need an Op-Amp there , as I am not sure what the source impedance will be for the directional coupler.
The caps from the inputs to ground I will try - any suggestionson values? as someone said, the reaction times to the inputs doesn't need to be in the microseconds, up to a second or so is fine, except perhaps for the reflected power which needs to b ea little bit faster, tens or hundreds of mS perhaps.
With regard to the DAC, I did consider using a PWM design , but decided against it after discussion and research suggested it may cause the attenuation level to 'cycle and not be precise enough if cap values change over time etc. I was considering using a DAC chip, but have the outputs available on the PIC, and it allows me to choose the bit resolution I need - I may revisit this one day though.
Andy
#pragma config WDT = OFF
//enables the PGM/PGC/PGD pins
#pragma config LVP = OFF
#pragma config PWRT = OFF
#pragma config BOREN = OFF
#pragma config PBADEN = OFF
void InterruptHandlerHigh (void);
long ticks = 0;
long debounce_tick = 0;
unsigned char enter_flag = 0;
unsigned char up_flag = 0;
unsigned char down_flag = 0;
unsigned char draw = 0;
unsigned char current_menu = 2;
unsigned char changing_menus = 0;
char DAC_byte = 0;
BYTE db_store = 10;
//0 - forward power
//1 - reflected power
//2 - MAIN PSU voltage
//3 - Aux PSU voltage
//4 - PA Heat Sink Temp
//5 - PA current
//6 - IPA current
#pragma udata udata5
float v_0;
#pragma udata udata5
float v_1;
#pragma udata udata6
float v_2;
#pragma udata udata6
float v_3;
#pragma udata udata7
float v_4;
#pragma udata udata7
float v_5;
#pragma udata udata8
float v_6;
#pragma udata udata8
float v_7;
#pragma udata udata9
float v_8;
#pragma udata udata9
float v_9;
menu top_menu;
menu power_adj_menu;
menu display_param_menu;
void output_byte_to_DAC(BYTE out)
{
DAC_b8 = (out&0x80)>>7;
DAC_b6 = (out&0x20)>>5;
DAC_b5 = (out&0x10)>>4;
DAC_b4 = (out&0x08)>>3;
DAC_b3 = (out&0x04)>>2;
DAC_b2 = (out&0x02)>>1;
DAC_b1 = (out&0x01);
DAC_b7 = (out&0x40)>>6;
}
void initMCU(void)
{
//set clock to 32 Mhz
OSCCON= 0b01110000;
OSCTUNE = 0b01000000;
INTCON = 0b10100000;
INTCON2 = 0b00000101;
TMR0H = 0; //clear timer
TMR0L = 0; //clear timer
T0CON = 0x80; //set up timer0 - prescaler 1:8
TRISA = 0x1F;
TRISE = 0x07; //direction output
TRISD = 0x00;
TRISC = 0x00;
TRISB = 0xF7;
}
void debounce(void)
{
static int up_button_cycles = 0;
static int down_button_cycles = 0;
static int enter_button_cycles = 0;
if(debounce_tick > 0)
{
//button up logic
if(button_up == 1)
{
up_button_cycles = 0;
}
else
up_button_cycles++;
if(up_button_cycles == 3)
{
up_flag = 1;
}
else if(up_button_cycles > 5)
up_button_cycles = 5;
//button down logic
if(button_down == 1)
{
down_button_cycles = 0;
}
else
down_button_cycles++;
if(down_button_cycles == 3)
{
down_flag = 1;
}
else if(down_button_cycles > 5)
down_button_cycles = 5;
//button enter logic
if(button_enter == 1)
{
enter_button_cycles = 0;
}
else
enter_button_cycles++;
if(enter_button_cycles == 3)
{
enter_flag = 1;
}
else if(enter_button_cycles > 5)
enter_button_cycles = 5;
debounce_tick = 0;
}
}
WORD ADCread(BYTE source)
{
WORD result = 0;
ADCON0 = source << 2;
ADCON0 = ADCON0 | 0x03; //enable A/D convert
while((ADCON0&0x02)!= 0x00);
result = ADRESH;
result = result<<8;
result = result | ADRESL;
ADCON0 = 0;
return result;
}
void ADCinit()
{
//enable all a/d pins and make the voltage reference based on the power pins to the PIC
ADCON1=0x00;
//right justified results
//use a sampling rate of oscilator/32
//us 2 T_ad
ADCON2=0b10001010;
}
void main (void)
{
int read_vals = 0;
int lit = 1;
WORD result;
initMCU();
initMCU_OLED();
oledinit();
ADCinit();
LED = 0;
draw = 1;
top_menu.num_items = 2;
top_menu.selected_item = 0;
top_menu.scrolled_item = 0;
display_param_menu.num_items=9;
display_param_menu.selected_item = 0;
display_param_menu.scrolled_item = 0;
power_adj_menu.num_items = 2;
power_adj_menu.selected_item = 0;
power_adj_menu.scrolled_item = 0;
for(;;)
{
if(ticks > 1)
{
//output_byte_to_DAC(0xAA);
if(read_vals > 10)
{
read_vals = 0;
result = ADCread(0);
v_0 = result/1024.0;
v_0 = (AD0UPPERVAL-AD0LOWERVAL) * (v_0*v_0*AD0QUADRATIC_A + v_0*AD0QUADRATIC_B + AD0QUADRATIC_C)+AD0LOWERVAL;
result = ADCread(1);
v_1 = result/1024.0;
v_1 = (AD1UPPERVAL-AD1LOWERVAL) * (v_1*v_1*AD1QUADRATIC_A + v_1*AD1QUADRATIC_B + AD1QUADRATIC_C)+AD1LOWERVAL;
result = ADCread(2);
v_2 = result/1024.0;
v_2 = (AD2UPPERVAL-AD2LOWERVAL) * (v_2*v_2*AD2QUADRATIC_A + v_2*AD2QUADRATIC_B + AD2QUADRATIC_C)+AD2LOWERVAL;
result = ADCread(3);
v_3 = result/1024.0;
v_3 = (AD3UPPERVAL-AD3LOWERVAL) * (v_3*v_3*AD3QUADRATIC_A + v_3*AD3QUADRATIC_B + AD3QUADRATIC_C)+AD3LOWERVAL;
result = ADCread(4);
v_4 = result/1024.0;
v_4 = (AD4UPPERVAL-AD4LOWERVAL) * (v_4*v_4*AD4QUADRATIC_A + v_4*AD4QUADRATIC_B + AD4QUADRATIC_C)+AD4LOWERVAL;
result = ADCread(5);
v_5 = result/1024.0;
v_5 = (attenuator_db_high-attenuator_db_low)*(v_5*v_5*AD5QUADRATIC_A + v_5*AD5QUADRATIC_B + AD5QUADRATIC_C)+attenuator_db_low;
result = ADCread(6);
v_6 = result/1024.0;
v_6 = (AD6UPPERVAL-AD6LOWERVAL) * (v_6*v_6*AD6QUADRATIC_A + v_6*AD6QUADRATIC_B + AD6QUADRATIC_C)+AD6LOWERVAL;
result = ADCread(7);
v_7 = result/1024.0;
v_7 = (AD7UPPERVAL-AD7LOWERVAL) * (v_7*v_7*AD7QUADRATIC_A + v_7*AD7QUADRATIC_B + AD7QUADRATIC_C)+AD7LOWERVAL;
//v_5 is going to be SWR, but it was forward voltage
v_9 = (v_6 + v_7)/(v_6 - v_7);
result = ADCread(8);
v_8 = result/1024.0;
v_8 = (AD8UPPERVAL-AD8LOWERVAL) * (v_8*v_8*AD8QUADRATIC_A + v_8*AD8QUADRATIC_B + AD8QUADRATIC_C)+AD8LOWERVAL;
// result = ADCread(9);
// v_9 = result/1024.0;
// v_9 = (AD9UPPERVAL-AD9LOWERVAL) * (v_9*v_9*AD9QUADRATIC_A + v_9*AD9QUADRATIC_B + AD9QUADRATIC_C)+AD9LOWERVAL;
}
controller_update();
menu_draw();
ticks = 0;
read_vals++;
}
debounce();
menu_update();
}
}
#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
//----------------------------------------------------------------------------
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void
InterruptHandlerHigh ()
{
unsigned char changes, portbd;
static unsigned char last_portb;
//probably don't need this
if(INTCONbits.RBIF != 0)
{
portbd = PORTB;
INTCONbits.RBIF = 0;
}
//need this
if (INTCONbits.TMR0IF)
{
//check for TMR0 overflow
INTCONbits.TMR0IF = 0; //clear interrupt flag
ticks++;
debounce_tick++;
}
}
| Tags |
| Similar Threads | ||||
| Thread | Starter | Forum | Replies | Last Post |
| Need a way to connect multiple UARTs to a single PIC | Kushan101 | Electronic Projects Design/Ideas/Reviews | 4 | 16th February 2010, 11:22 AM |
| Sampling multiple AD inputs Coding Help | Suraj143 | Microcontrollers | 22 | 6th February 2008, 09:40 AM |
| PIC A/D Sampling multiple inputs | NJ Roadmap | Microcontrollers | 10 | 21st February 2007, 01:54 AM |
| PIC and multiple serial devices | Oznog | Microcontrollers | 14 | 26th May 2005, 08:18 AM |
| FREE S/W to control multiple servos from cheap PIC | smpl9 | Microcontrollers | 0 | 11th October 2003, 04:36 PM |