This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADC issues with TM4C1231H6PZ

Hi,

I am using ADC0 with sequence number 3 (single sample) and an external 3V reference.  I am sampling on over a dozen channels, most of which return reasonable values.  However, there are some that consistently return incorrect values (as compared to the actual voltage going into that channels, as verified with a volt meter).  Some of the values are low and some are high.  What could cause some channels to give inaccuracies?  

Thanks!  Cindy

  • Cindy, concentrate on a single channel, probably the one with the worst problem.

    Can you sketch the signal chain for it?

    Still looking for information on the reference you are using.

    Robert
  • Hello Robert,

    Don't you think it is time the schematic for the input channel be brought up as well.

    Regards
    Amit
  • I thought that was what I just asked for

    Robert
  • Hey Robert-

    Can I have an offline email so I can send you the schematic?

    Thanks,

    Cindy

  • I have sent contact information.

    Keep in mind that while Amit is a TI employee, neither cb1 or I are.

    Also, It would probably provide a better overview if you can extract the particular circuit for us all to review. There is a lot to be gained from the interaction of various views in a circuit review.

    Robert
  • In addition to the suggestion by poster f.m. (test @ 0V & 3V3) may I state (again) that use of a reference w/in "mid-range" of the ADC may prove more telling.   (as deviations - both above & below that "test" voltage level - are then recognized!)

    I'd check also that such tests of the ADC are NOT run when potential "offenders" such as motors, actuators or high-speed digital transfers are "in play."   Indeed this is not, "real world" - yet it is critical to divorce "ADC issues" from "foreign events - potentially confounding the sensitive ADC."

    And - of course - the ADC's reference voltage & MCU's 3V3 must be rock solid - especially under "potentially challenging conditions - listed above.   (It remains unclear if such "serious" (yet basic) voltage monitoring has been implemented...)

  • I think this has ended up in the wrong thread

    Robert
  • Sorry - I don't believe we've been told if (other) influencers have been adequately surveyed - and blocked or greatly reduced.
  • Hello Robert,

    It's all up to you to find the issue in the schematics.

    Regards
    Amit
  • I was keying in on the reference to f.m. who was contributing to a different thread.

    Robert
  • Hi Robert- my bad. I thought you were a TI employee. I appreciate you bringing up the fact that you aren't. I can't share my schematics with anyone or any company that we don't have a NDA with, so I think I'm stuck. I'll see if Amit is will to do the review. Bummer. Cindy
  • Amit-
    I can't share my schematic with Robert because of NDA issues. We have a blanket NDA with TI, however. Would you be willing to review the schematic? Can I get offline contact information? Thanks, Cindy
  • Then hopefully I will prove of value.

    Robert
  • You've been very helpful all along! I wish I could give you the schematic. I do appreciate all the time you've put into my problem. It's critical that I get this sorted out. I'll post anything I discover. Hopefully Amit will be willing to look over the schematics.

    Cindy
  • Not a problem Cindy, the sensitivity works both ways. I want to avoid the possibility of a conflict of interest on my part as well.

    I will note that it is unlikely that you have anything sensitive in a sensor signal chain so snipping an image of a chain for all to see may be a possibility. I also recognize that many see more uniqueness in such interface circuits than I see as reasonable and it makes no sense for you to buck company convention.

    Robert

    I also remember items like X/Y chart recorders, oscilloscopes and bench top power supplies coming with full schematics.
  • Hi Robert, Amit, and cb1-

    So, I solved my problem and it was a programming error on my part. It turns out that at times I was using the channel number when reading the ADC instead of the channel control value (for example: 20 instead of ADC_CTL_CH20). This doesn't cause a problem on channels of less than 16, but for the larger channels, the control values no longer equal the channel numbers. So I was specifying invalid channel numbers and who know what the ADC was reading. This is why I was only having trouble reading the larger channel numbers, and why my results for those channels were so erratic.

    Thank you to all of you for your help, especially Amit who has been helping with this issue for a VERY LONG TIME. :)

    Cindy
  • Hi Cindy - good for you - although the likelihood of that explanation is exceeded only by "OJ's" search for the real killer...   (the measurement deviations were so slight as to - in my book - confound your stated diagnosis...)

  • It often turns out that what we are convinced is a hardware problem ends up being a software problem or vice versa.

    I will point out that this particular class of problem could have been prevented by proper software engineering (some of which is missing from the TIVA library) and the use of supporting tools.

    Robert
  • Hello Robert

    "Supporting tools" could you exemplify. My main motive to ask this specific question is forum richness and hopefully guidance for someone in similar situation.

    Regards
    Amt
  • I was specifically thinking of PC-Lint (with strong typing turned on) but that does require proper software engineering of the TIVA library (Note that this could be done w/o affecting the binary).  Specifically the following changes

    Currently adc.h has

    #define ADC_CTL_TS              0x00000080  // Temperature sensor select

    #define ADC_CTL_IE              0x00000040  // Interrupt enable

    #define ADC_CTL_END             0x00000020  // Sequence end select

    #define ADC_CTL_D               0x00000010  // Differential select

    #define ADC_CTL_CH0             0x00000000  // Input channel 0

    #define ADC_CTL_CH1             0x00000001  // Input channel 1

    #define ADC_CTL_CH2             0x00000002  // Input channel 2

    #define ADC_CTL_CH3             0x00000003  // Input channel 3

    #define ADC_CTL_CH4             0x00000004  // Input channel 4

    #define ADC_CTL_CH5             0x00000005  // Input channel 5

    #define ADC_CTL_CH6             0x00000006  // Input channel 6

    #define ADC_CTL_CH7             0x00000007  // Input channel 7

    #define ADC_CTL_CH8             0x00000008  // Input channel 8

    #define ADC_CTL_CH9             0x00000009  // Input channel 9

    #define ADC_CTL_CH10            0x0000000A  // Input channel 10

    #define ADC_CTL_CH11            0x0000000B  // Input channel 11

    #define ADC_CTL_CH12            0x0000000C  // Input channel 12

    #define ADC_CTL_CH13            0x0000000D  // Input channel 13

    #define ADC_CTL_CH14            0x0000000E  // Input channel 14

    #define ADC_CTL_CH15            0x0000000F  // Input channel 15

    #define ADC_CTL_CH16            0x00000100  // Input channel 16

    #define ADC_CTL_CH17            0x00000101  // Input channel 17

    #define ADC_CTL_CH18            0x00000102  // Input channel 18

    #define ADC_CTL_CH19            0x00000103  // Input channel 19

    #define ADC_CTL_CH20            0x00000104  // Input channel 20

    #define ADC_CTL_CH21            0x00000105  // Input channel 21

    #define ADC_CTL_CH22            0x00000106  // Input channel 22

    #define ADC_CTL_CH23            0x00000107  // Input channel 23

    #define ADC_CTL_CMP0            0x00080000  // Select Comparator 0

    #define ADC_CTL_CMP1            0x00090000  // Select Comparator 1

    #define ADC_CTL_CMP2            0x000A0000  // Select Comparator 2

    #define ADC_CTL_CMP3            0x000B0000  // Select Comparator 3

    #define ADC_CTL_CMP4            0x000C0000  // Select Comparator 4

    #define ADC_CTL_CMP5            0x000D0000  // Select Comparator 5

    #define ADC_CTL_CMP6            0x000E0000  // Select Comparator 6

    #define ADC_CTL_CMP7            0x000F0000  // Select Comparator 7

    extern void ADCSequenceStepConfigure(uint32_t ui32Base,

                                        uint32_t ui32SequenceNum,

                                        uint32_t ui32Step, uint32_t ui32Config);

    There are at least two ways to do this in a way that the arguments get checked at (really before) compile. Concentrating on the last argument here.

    Method 1

    typedef  uint32_t ADC_CONFIG;

    #define ADC_CTL_TS              ((ADC_CONFIG)0x00000080u)  // Temperature sensor select

    #define ADC_CTL_IE              ((ADC_CONFIG)0x00000040u)  // Interrupt enable

    #define ADC_CTL_END             ((ADC_CONFIG)0x00000020u)  // Sequence end select

    #define ADC_CTL_D               ((ADC_CONFIG)0x00000010u)  // Differential select

    #define ADC_CTL_CH0             ((ADC_CONFIG)0x00000000u)  // Input channel 0

    #define ADC_CTL_CH1            ((ADC_CONFIG) 0x00000001u)  // Input channel 1

    etc....

    extern void ADCSequenceStepConfigure(uint32_t ui32Base,

                                        uint32_t ui32SequenceNum,

                                        uint32_t ui32Step, ADC_CONFIG Config);

    Now PC-Lint, which should be run automatically before the compiler, will detect if anything other than a value with the ADC_CONFIG type is assigned and, if your build process is properly configured, you will be prevented from building the code. Note, that I also corrected the sign error in the TIVA header.

    I.E.

    ADCSequenceStepConfigure( ui32Base, ui32SequenceNum,  ui32Step, ADC_CTL_CH1);

    Will compile w/o error and

    ADCSequenceStepConfigure( ui32Base, ui32SequenceNum,  ui32Step, 20u);

    The second method (my preferred), differs in how the type is defined

    Method 2

    typedef  enum { 

       ADC_CTL_TS=0x00000080,  // Temperature sensor select

       ADC_CTL_IE=0x00000040,  // Interrupt enable

       ADC_CTL_END=0x00000020,  // Sequence end select

       ADC_CTL_D=0x00000010,  // Differential select

       ADC_CTL_CH0=0x00000000,  // Input channel 0

       ADC_CTL_CH1= 0x00000001,  // Input channel 1

    etc....

    } ADC_CONFIG;

    extern void ADCSequenceStepConfigure(uint32_t ui32Base,

                                        uint32_t ui32SequenceNum,

                                        uint32_t ui32Step, ADC_CONFIG Config);

    There is a downside to the second method, some compilers provide a non-standard extension that adjusts the size of the enum based on the range of values in the enum. This would obviously present possible compatibility issues, it is otherwise a cleaner solution and I would prefer this with standard enum sizes.

    This should obviously be extended to the other arguments (and to return values for functions that have them) as well.

    All of this is bog standard C and C++.

    In addition PC-Lint provides the capability of adding sematic checking that would allow checking the range of values to all the arguments (ui32SequenceNum comes to mind). That is quite a step further for the TIVA library though.

    The other tool that comes to mind as possibly helping here is Test Driven Development (TDD). Also applicable pre-compile but more work to set up.

    Robert

  • Robert,

    Quite good - and unusual in its great detail - thank you.

    My small firm has the book, "Test-Driven Development for Embedded C" by James Grenning (w/forward by Jack Ganssle). Might you comment upon this book (if known) and/or on others you'd recommend - and upon "best practice" of implementing such, "TDD?" Thank you.
  • Hello Robert, cb1,

    Thank you for the post and the book read. Very insightful.

    Regards
    Amit
  • That's the book I've got on my shelf as well. It clued me in on the difference between TDD and all the earlier PC based testing methods.

    Simple straightforward and easy to understand. I'd recommend it and I think I have elsewhere in the forum.

    Robert
  • A good rule of thumb, if Jack Ganssle recommends a book, it's worth taking a chance on.

    Robert
  • Thank you for the suggestion.  I just ordered it. :)

  • For others who may be interested in - or even seeking "Test-Driven Development" for Embedded use - here is my (not quite ready for prime time) scan of this book's rear cover.   (scanned several times - this was best effort :(...)

    [edit]  Mocked incessantly for early scans - mere 4 more "tries" produced the following:    (skill is such I now include the front cover - too!)

     And even the book's front cover is inventive - if not too original...   (been bitten by mosquitoes with thicker wings on the "Jersey shore")

    Note: Firm/I receive no benefit nor gain from this endorsement...

     

  • Hello cb1

    Thanks for the cover... Got to be a useful book.

    Regards
    Amit
  • Maybe we should set up a recommended reading list.

    Robert
  • Let the record show that (many) have responded (already) to Robert's mention of "TDD" (and this reporter's hasty front/rear scan of a "well-liked" volume.   (and to those who asked - "Yes - indeed I made those 1st few scans w/one hand "tied" behind my back...")

    Note that "scan technique" now (almost) rises to, "Good for Gov't Work" (high) standards...   And front cover has been added to earlier post (4-5 "up")
     
    One suspects that such books and reading list would follow (quickly) on the heels of those "missing" PF0/PD7 and the 0Ω "plague-istors" - caringly placed on LPads.