• AVR Freaks

Hot!PIC32MZ - ADC alternate pin

Starting Member
  • Total Posts : 52
  • Reward points : 0
  • Joined: 2014/09/19 03:41:47
  • Location: France
  • Status: offline
2020/10/30 07:37:52 (permalink)

PIC32MZ - ADC alternate pin


I am working on a PIC32MZ project, and getting a bit stuck on the ADC.
So far, I only worked with PIC32MX device, and my new design with PIC32MZ was mostly based on what I already knew. It's only when I started working on the software that I discovered that the ADC is far different between PIC32MX and MZ.
Anyway, I know have my hardware in front of me, and need to work with it.

I managed to properly setup the ADCs I need (Class1 ADC1 to ADC4, and Class 3 ADC7), and I get the expected ADC results.

I need to make measurement on AN0 and AN45, which are both connected to ADC1. Selection is made using the SH0ALT register.
   - AN0 is measuring an image of one of the DC inputs, providing ~2.5V
   - AN45 is reading another DC signal, that can be either 0V or 0.25V.

Most of the time, I am getting normal result. However, from time to time, the result on AN45 can vary quite a lot (+/- 25%), while the signal is not moving at all. I haven't check for any error error on AN0, since it's less sensitive in my application, but it's probably similar.

I first suspected an issue with the sampling duration : CHOLD might not have enough time to charge/discharge to the level of AN0/AN45 when changing the input. That's why I have a 1ms delay after setting SH0ALT. Also, the sampling time is ~100µs, which should be more than enough.
I know that the ADC is properly setup, because if I using a secondary DC input, I am never getting false results. In this case, ADC1 is still toggling between AN0 and AN45, but the voltage AN0 is 0V.

I did not find any info concerning the modification of SHxALT during runtime. This register is probably designed to be configured only once at the init ?

Here is a simplified version of my code.
Note that I don't think it's a code problem, as the wrong results only occur from time to time.

// Request conversions for the Class 1 ADC, by setting the trigger

// Wait for the results

// Wait for all the Class 1 ADC to be done
while(!ADCDSTAT1bits.ARDY0 && !ADCDSTAT1bits.ARDY1 && !ADCDSTAT1bits.ARDY2 && !ADCDSTAT1bits.ARDY3 &&! ADCDSTAT1bits.ARDY4) ;

// Results are ready !
localADCResults[0] = ADCDATA0 ; // Read the results
localADCResults[1] = ADCDATA1 ;
localADCResults[2] = ADCDATA2 ;
localADCResults[3] = ADCDATA3 ;
localADCResults[4] = ADCDATA4 ;

// Toggle ADC0 to sample AN45 instead of AN0,
// and allow a bit of time for the change to be effective
wait_us(1000) ;

// AN45 is now connected to ADC0 : force a conversion on ADC0
// Don't use GSWTRG : that would request a conversion on all the ADCs.
// Use the Single Conversion flag (RQCNVRT)

// Wait for completion and get the result
while(!ADCDSTAT1bits.ARDY0) ;

// Result is ready !
localADCResults[5] = ADCDATA0 ;

// Set ADC0 back to AN0, for the next call

Note that since I am measuring slow DC signal, I have no special needs for very fast or very accurate ADC, as long as I am getting some reliable results (10%).
Any help is welcome !

10 Replies Related Threads

    Super Member
    • Total Posts : 3947
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: online
    Re: PIC32MZ - ADC alternate pin 2020/10/30 11:52:21 (permalink)
    MZ is a big chip with Analog and Digital signals routed all around the chip,
    some traces may be longer, both inside the chip and outside on your board.
    I will usually assume that ADC pins that are closer to AVdd, AVss, Vref+ and Vref- pins,
    may be less likely to pick up digital noise.
    Also your wiring outside the chip may pick up noise.
    Do you have extra filtering for AVdd?
    Those developers that deal with high frequency, high resolution ADC measurements,
    use a lot of attention on wiring design and board layout, to avoid picking up noise.
    Impedance of the ADC signal source. If the DC signal is from a high impedance voltage divider,
    then a small capacitor (~ 10 nF) connected between ADC pin and analog groundplane near the pin.
    This may also help against picking up noise from your wiring.
    You may make several measurements (8, or a higher power of 2), and calculate average in software,
    or use hardware in the ADC to do oversampling.
    A trick more often used on small PIC microcontrollers,
    is to let the chip go into Sleep mode while ADC is working.
    According to datasheet this is possible also in MZ__EF... also.
    post edited by Mysil - 2020/10/30 11:57:19
    Starting Member
    • Total Posts : 52
    • Reward points : 0
    • Joined: 2014/09/19 03:41:47
    • Location: France
    • Status: offline
    Re: PIC32MZ - ADC alternate pin 2020/11/02 02:13:47 (permalink)
    Thanks for the replies.
    We already took most of these considerations when designing the hardware.
      - PIC32MZ has 8 decoupling 100nF (X5R or X7R) around it's VCC pins.
      - The 3.3V is separated from other IC by a small ferite.
      - The AVDD/AVSS is decoupled with a 100nF.
      - PCB traces have been keps as small as possible. Also, there are no big sources of noise on the board.
      - All signals to measure are DC voltage, reduced by voltage divider and filtered by a 10nF capacitor.
    I checked on the scope : the signal is very stable.
    All the other signals I measure are good. I used a breakpoint to spot whenever an input is changing by +/-10% with the previous result: never occurs !
    he same type of signal is measured on another input (AN4 / ADC4, Class 1), and works fine.
    I feels really odd to me that the problem only occurs on the pin which is used wich is toggling between normal and alternate input, where the voltage level is very different (~2.5V on normal, ~0.25V on alternate).
    I couldn't find any info wether toggling between normal and alternate input was good/bad/need specific operations...
    This only happen from time to time, not on every sample.
    With all that being said, I don't think it's an issue with my hardware design.
    I will add some software averaging, to get better results. But I think it's just sugar coating, rather than fixing : averaging is always a good idea to cancel noise, but why do I need to have it on a just a single pin ? There be something else.
    Starting Member
    • Total Posts : 52
    • Reward points : 0
    • Joined: 2014/09/19 03:41:47
    • Location: France
    • Status: offline
    Re: PIC32MZ - ADC alternate pin 2020/11/02 03:00:38 (permalink)
    Are you using the multiplexor for the measurements in your code, if so then you need to wait the settling time before you take a reading.

    No sure if "multiplexor" is the term used in the datasheet for Class 1 ADC, but yes, ADC1 is switching between 2 inputs : AN0 (normal) an AN45 (alternate), using the SH0ALT register.
    If you look at the code above, before making the second measurement, I add a delay after switching the input.
    After some tests, I can definitely confirm that a short delay (1µs) seem to provide more wrong results. However, using a 100µs or a 1ms delay seem to provide similar results.
    Again, I could not find any info on this in the datasheet. But considering ADC timings, 100µs seems already pretty large.
    All the examples using SHxALT only select the pin during the init of the ADC, and don't change it afterwards.
    Starting Member
    • Total Posts : 52
    • Reward points : 0
    • Joined: 2014/09/19 03:41:47
    • Location: France
    • Status: offline
    Re: PIC32MZ - ADC alternate pin 2020/11/02 04:44:02 (permalink)
    Have you looked at the specific ADC doc, I've found the main datasheets for the pic32 are only good as a guide, and for a lot of the detailed stuff on the ADC you need to go to the section22 separate datasheet

    Yes, I did look at this document http://ww1.microchip.com/downloads/en/DeviceDoc/60001344B.pdf
    Section only states "For dedicated ADC modules, four alternate selection is provided for each positive input. This alternate input can be chosen using the SHxALT<1:0> bits in the ADC Triggering Mode Register(ADCTRGMODE)"
    No detail on wether this can be anytime or not, or if we need to wait for XX duration or YY register flag.
    Also checked the errata (http://ww1.microchip.com/downloads/en/DeviceDoc/PIC32MZ-EF-FAMILY-DS80000663H.pdf ), but no luck.
    For now, I've just added some averaging on my samples and it's working fine. But since this is not the source of the problem, I am still open to any suggestion.
    Starting Member
    • Total Posts : 52
    • Reward points : 0
    • Joined: 2014/09/19 03:41:47
    • Location: France
    • Status: offline
    Re: PIC32MZ - ADC alternate pin 2020/11/03 00:31:19 (permalink)
    4 (1)
    Attached is a simplified view of the schematic, with both outside and inside the PIC32MZ.
    Here is my understanding.
    Since the signals (+5V and +24V) are stable DC, we can consider taht the 10nF are charged, and the voltage at the pins AN45 and AN0 are stable.
    Thus, charging the 5pF should take:
      - AN0 : 5*(82k+200+44)*5pF = 2µs
      - AN45 : 5*((20k+22k)200+44)*5pF = 1µs
    I double check my sampling time, and I can confirm that it's set to 100µs.
    Again, I have the same circuit than AN45 on AN4, and it's working fine. In this one though, I don't use the multiplexor : the ADC4 is always sampling AN4.

    Attached Image(s)

    Jump to:
    © 2020 APG vNext Commercial Version 4.5