Electronic Circuits and Projects Forum



Multiple AD inputs on a PIC 18F4682

123 Last »
  1. #1
    EI3HG EI3HG is offline

    Multiple AD inputs on a PIC 18F4682

    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
    Attached Images

  2. #2
    be80be be80be is offline
    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
    0
    Last edited by be80be; 8th February 2012 at 11:02 PM.
    Burt
    be80be

  3. #3
    Diver300 Diver300 is offline
    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.

  4. #4
    Reloadron Reloadron is online now
    The following is a quote taken from a PIC 12F683 manual:

    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.
    Note what is covered as to source impedance. Next is a quote from the manual for the PIC you are using:

    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
    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.

    Then too, I may be totally off base with this.

    Ron
    0
    Please do not PM me with forum related questions. Let's keep things in the open forum. Thank you.

  5. #5
    ronsimpson ronsimpson is offline
    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.
    0

  6. #6
    be80be be80be is offline
    What your doing with 8 pins could be done with 1 pin and pwm controlling the attenuator
    0
    Burt
    be80be

  7. #7
    Pommie Pommie is online now
    Quote Originally Posted by EI3HG View Post
    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.
    The only time I have seen this is when the pins have been set to output and low. The ADC will still work but the readings are biased towards zero.

    Have you tried reading the pin voltages with a multimeter?

    Mike.
    0

  8. #8
    be80be be80be is offline
    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.
    0
    Burt
    be80be

  9. #9
    Nigel Goodwin Nigel Goodwin is online now
    Super Moderator
    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.
    0
    PIC programmer software, and PIC Tutorials at:
    http://www.winpicprog.co.uk

  10. #10
    EI3HG EI3HG is offline
    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++;
    }
    }
    0

123 Last »
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
Electronic Circuits  |  Learning Electronics

Join our community with over 100,000 Members! It's free, easy and when you're logged in you have many more features! Click to register.
Page Time: 0.05373 seconds      Memory: 7,462 KB      Queries: 17      Templates: 0