• AVR Freaks

Hot!New to interrupts. Continious ADC reading

Page: 12 > Showing page 1 of 2
Author
Killerpiraat
Starting Member
  • Total Posts : 68
  • Reward points : 0
  • Joined: 2020/03/09 07:40:17
  • Location: 0
  • Status: offline
2020/06/25 00:04:33 (permalink)
0

New to interrupts. Continious ADC reading

Hello,
 
straight to the question:  If i want to read the ADC value during an event, i have to use interrupts right?
My problem is, i want to see the curve of the voltage of a battery when i place a load resistor on it. The ADC will measure the voltage. 
Right now i am doing it like this. Only 2 values are measured with the ADC, the voltage of the battery right before the resistor is connected, and the voltage when the resistor is connected for 1ms. So i only get 2 points on my graph. But now i want to measure all the voltages between the 2 points, so you can see the exponential curve when i place this in an Excel sheet.
 
 
This requires interrupts right? I am not very familier with them, so perhaps someone can help me out? What are the steps that i need to take? And i probably have to get rid of the delay's?
?
 
post edited by Killerpiraat - 2020/06/25 00:06:19

Attached Image(s)

#1

21 Replies Related Threads

    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: New to interrupts. Continious ADC reading 2020/06/25 00:54:03 (permalink)
    0
    Do you need to be doing something else at the same time? If not, no you don't need interrupts at all. It would be a good idea to use a timer to help take the measurements at regular intervals.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    acharnley
    Super Member
    • Total Posts : 540
    • Reward points : 0
    • Joined: 2016/05/01 06:51:28
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:20:25 (permalink)
    0
    As Ric says use a timer to autotrigger the adc. Note that on many PIC's the autotrigger is unavailable in sleep mode (idle mode works).
    #3
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:33:35 (permalink)
    0
    ric
    Do you need to be doing something else at the same time? If not, no you don't need interrupts at all. It would be a good idea to use a timer to help take the measurements at regular intervals.



    Thanks Ric, you are right, probably no need for interrupts. I know that the __delay_ms function isnt too accurate, although 1 ms is really close to 1 ms (close enough for my project). But it takes the uC around 0.6ms to get the ADC value from the ADC pin, so lets say that i remove the __delay_ms(1) and replace it with a loop that gets the ADC value 15 times in a row. This would take 15*0.6 ms = 9ms. Can i make this faster? Perhaps by increasing the clock? Right now the clock is at 4 MHz with a clock divider of 8. (only in this case the __delay_ms(1) is close to 1ms. Offcourse with a 8MHz clock and clock divider of 16 it would be the same, but whats the benefit from that?
     
     
     
    #4
    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:40:31 (permalink)
    +1 (1)
    Killerpiraat
    ...
    I know that the __delay_ms function isnt too accurate, although 1 ms is really close to 1 ms (close enough for my project).

    Actualy, if you don't have interrupts running, the delay_ms macro is very accurate.
    But as you go on to say, the other code you run in between delays won't be so accurate in time.

    But it takes the uC around 0.6ms to get the ADC value from the ADC pin,

    That seems very slow. Do you have some delays built in to your ADC read code?
    What Tad setting are you using on the ADC?
    You have not mentioned what PIC you are using (you really should), so I don't know if it has hardware acquisition time support either.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    PStechPaul
    Super Member
    • Total Posts : 2727
    • Reward points : 0
    • Joined: 2006/06/27 16:11:32
    • Location: Cockeysville, MD, USA
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:41:31 (permalink)
    +1 (1)
    Does the battery actually lose so much voltage in just one millisecond? That must be quite a high current drain. If you want to see intermediate points, you would need to take samples at perhaps 50 or 100 uSec, which would give you 10-20 samples from which you could plot the discharge curve. You would do well to set up a timer interrupt at the rate you want to sample to initiate the conversion sample at precise intervals. Then you could use another interrupt from the ADC to put the results of each conversion into an array. Your main routine could just monitor a sample count so that the first sample will apply the load resistor, and then wait until all samples have been taken to print out the values in the array.

     
    #6
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:45:36 (permalink)
    0
    Btw: 
     
    Right here it says that 1 conversion takes 46uS. This gets smaller when i increase the clock. But if i use the ADCGetConversion function, the 1ms delay turns into a 1.6 ms delay. Why is it taking so long to get the ADC value?
     
    EDIT: PIC16F15356 is the one im using
    post edited by Killerpiraat - 2020/06/25 01:47:57

    Attached Image(s)

    #7
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:53:35 (permalink)
    0
    PStechPaul
    Does the battery actually lose so much voltage in just one millisecond? That must be quite a high current drain. 




    Indeed, the voltage drop (and rise) is FAST.
    I have 3 load resistors. #1 = 68 Ohm, #2 = 120 Ohm and #3 = 680 Ohm. I attached some of my measurement result. In that particular case the load time was 1ms per measurement. In that measurement the battery was loaded 5 times with each resistor, so 5x 1 ms per load resistor. The voltage after 1 ms is already way down. Notice that the waveform in the image is not real, just a example to show where in the time the adcConversion is taking place.
    post edited by Killerpiraat - 2020/06/25 01:56:07

    Attached Image(s)

    #8
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 01:59:29 (permalink)
    0
    ric
    Killerpiraat
    ...
    I know that the __delay_ms function isnt too accurate, although 1 ms is really close to 1 ms (close enough for my project).

    Actualy, if you don't have interrupts running, the delay_ms macro is very accurate.
    But as you go on to say, the other code you run in between delays won't be so accurate in time.

    But it takes the uC around 0.6ms to get the ADC value from the ADC pin,

    That seems very slow. Do you have some delays built in to your ADC read code?
    What Tad setting are you using on the ADC?
    You have not mentioned what PIC you are using (you really should), so I don't know if it has hardware acquisition time support either.
     





    The ADC code is MCC generated. Didnt change anything there.
     
     
     
    #include <xc.h>
    #include "adc.h"
    #include "device_config.h"
    /**
    Section: Macro Declarations
    */
    #define ACQ_US_DELAY 5
    void (*ADC_InterruptHandler)(void);
    /**
    Section: ADC Module APIs
    */
    void ADC_Initialize(void)
    {
    // set the ADC to the options selected in the User Interface

    // GO stop; ADON enabled; CHS ANA0;
    ADCON0 = 0x01;

    // ADFM left; ADPREF FVR; ADCS FOSC/2;
    ADCON1 = 0x03;

    // ADRESL 0;
    ADRESL = 0x00;

    // ADRESH 0;
    ADRESH = 0x00;

    }
    void ADC_SelectChannel(adc_channel_t channel)
    {
    // select the A/D channel
    ADCON0bits.CHS = channel;
    // Turn on the ADC module
    ADCON0bits.ADON = 1;
    }
    void ADC_StartConversion(void)
    {
    // Start the conversion
    ADCON0bits.GO = 1;
    }

    bool ADC_IsConversionDone(void)
    {
    // Start the conversion
    return ((bool)(!ADCON0bits.GO));
    }
    adc_result_t ADC_GetConversionResult(void)
    {
    // Conversion finished, return the result
    return ((adc_result_t)((ADRESH << 8) + ADRESL));
    }
    adc_result_t ADC_GetConversion(adc_channel_t channel)
    {
    // select the A/D channel
    ADCON0bits.CHS = channel;

    // Turn on the ADC module
    ADCON0bits.ADON = 1;
    // Acquisition time delay
    __delay_us(ACQ_US_DELAY);
    // Start the conversion
    ADCON0bits.GO = 1;
    // Wait for the conversion to finish
    while (ADCON0bits.GO)
    {
    }
    // Conversion finished, return the result
    return ((adc_result_t)((ADRESH << 8) + ADRESL))/64;
    }
    void ADC_TemperatureAcquisitionDelay(void)
    {
    __delay_us(200);
    }
    /**
    End of File
    */
     

    #9
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 02:04:45 (permalink)
    0
    Here is a photo of my scope with a 1ms delay after i set a pin high and get the ADC conversion. If i remove the ADCGetConversion it will only be a pulse of 1ms (like it should)
    post edited by Killerpiraat - 2020/06/25 02:05:52

    Attached Image(s)

    #10
    mbrowning
    USNA79
    • Total Posts : 1773
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 03:09:24 (permalink)
    +3 (3)
    Running the PIC at 500KHz is part of the problem, especially using the horribly inefficient MCC code. It should be 32MHz. That probably accounts for 2-300us.

    Running the ADC with 4us Tad is 32us wasted. Use the minimum 1us.

    Using left justified mode and then dividing by 64 is wasteful. Use right justified.

    Turning the ADC on for every conversion wastes 8us at 500KHz. Don’t turn it off after initialization.

    Using 200us acq time for the temp sensor wastes 175us over the datasheet 25us spec, but it doesn’t appear you are calling this delay.

    You should be able to do a sample in 25us or so.
    #11
    1and0
    Access is Denied
    • Total Posts : 10906
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 03:17:33 (permalink)
    +1 (1)
    mbrowning
    Using left justified mode and then dividing by 64 is wasteful. Use right justified.

    That MCC is really something huh?! LOL!
     
    #12
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 03:58:43 (permalink)
    0
    mbrowning
    Running the PIC at 500KHz is part of the problem, especially using the horribly inefficient MCC code. It should be 32MHz. That probably accounts for 2-300us.

    Running the ADC with 4us Tad is 32us wasted. Use the minimum 1us.


    Is this achieved by changing the FOSC/2 to FOSC/64 (for example)? Or do i have to change something else?



     
    mbrowning

    Turning the ADC on for every conversion wastes 8us at 500KHz. Don’t turn it off after initialization.


    Where am i turning it off?
     
    mbrowning

    Using 200us acq time for the temp sensor wastes 175us over the datasheet 25us spec, but it doesn’t appear you are calling this delay.

    You should be able to do a sample in 25us or so.



    Temp sensor? Is that internal in the PIC?
     
    Look, i changed the frequency to 32MHz, with a clockdivider of 1. These are the result of a pulse without ADC conversion, and WITH ADC conversion.
    Also, the delay_ms function is not accurate anymore because of the high clock. Is there a setting for this? Or do i have to multiply my delay value by 64? So in order to get a 1 second delay, normally i would use __delay_ms(1000), but do i have to use __delay_ms(64000) right now or something?
    post edited by Killerpiraat - 2020/06/25 04:00:15

    Attached Image(s)

    #13
    mbrowning
    USNA79
    • Total Posts : 1773
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/25 04:35:43 (permalink)
    +2 (2)
    The delay macros are very accurate if you remember to change _XTAL_FREQ to match the actual clock you are using.

    It seems you aren’t reading the code that MCC generates. Most of my comments were based on the code you posted.

    As an aside, your experience here illustrates perfectly one of the issues that many of us have with MCC. You click some buttons and generate some code and it sort of works. But the code is convoluted and inefficient and is not very suitable for learning how things work.

    It seems to encourage people to ignore the datasheet, which should be the first tool you turn to (with the errata #2), not the last tool. Digging into the datasheet takes time up front but saves so much down the line.
    #14
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/29 00:26:07 (permalink)
    0
    mbrowning
    Running the PIC at 500KHz is part of the problem, especially using the horribly inefficient MCC code. It should be 32MHz. That probably accounts for 2-300us.




    BTW, right now i am using 4MHz (well, 32MHz, with clockdivider of 8) because if i go above a 4 MHz clock, the adc value goes inaccurate.
    #15
    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: New to interrupts. Continious ADC reading 2020/06/29 01:24:16 (permalink)
    +1 (1)
    It sounds like you're speeding up the clock without recalculating the ADC parameters.
    If you change the clock, the ADC needs to be reconfigured to maintain the same sampling speed.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #16
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/29 02:20:31 (permalink)
    0
    ric
    It sounds like you're speeding up the clock without recalculating the ADC parameters.
    If you change the clock, the ADC needs to be reconfigured to maintain the same sampling speed.




    Perhaps you are right Ric, could you tell me how thats done? Is it achieved by changing the clock source in the ADC peripheral?? Right now it is FOSC/2.
     
     
    #17
    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: New to interrupts. Continious ADC reading 2020/06/29 02:26:00 (permalink)
    +1 (1)
    There's a comprehensive table (20-1) in the datasheet showing the correct values
    https://ww1.microchip.com...40001866B.pdf#page=272
    post edited by ric - 2020/06/29 02:27:31

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #18
    Killerpiraat
    Starting Member
    • Total Posts : 68
    • Reward points : 0
    • Joined: 2020/03/09 07:40:17
    • Location: 0
    • Status: offline
    Re: New to interrupts. Continious ADC reading 2020/06/29 02:43:54 (permalink)
    0
    ric
    There's a comprehensive table (20-1) in the datasheet showing the correct values
    https://ww1.microchip.com...40001866B.pdf#page=272




    Thanks, i noticed that table too. But it doesnt explain why the conversion is taking 100 uS(!) extra, instead of the 5 uS. 

    Attached Image(s)

    #19
    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: New to interrupts. Continious ADC reading 2020/06/29 02:51:34 (permalink)
    0
    Have you looked into what the MCC routine to read the ADC is doing?
    Quite possibly it is adding an "acquisition delay" before each reading.
    Where are you getting 5us from? With the minimum legal Tad setting (1us), a conversion is going to take at least 11us.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5