This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Sometimes my 12 bit ADC gives a 16 bit value

I am currently working with a custom board that captures an ECG using an AD8233 chip from analog devices. Attached to the board are gold plated pads that act as electrodes that a person will touch with their fingers, which is wired to the AD8233.

The analog output from the AD8233 goes to one of the analog in ports on the NRF52382, which is then read as a 12 bit value via the SAADC module.

Things work properly for the most part, but there will be periods where the ADC will return values ranging from about 65525 to 65535. There will sometimes be a few zeros returned by the ADC in between these 16 bit numbers.

From what I've been reading, it doesn't seem like the ADC should ever be returning 16 bit values if I've configured it to sample in 12 bit mode in sdk_config.h. I am storing the values in a uint16_6 type. Is this some kind of error code, or is this indicative of some sort of hardware issue due to the user making physical contact with the PCB?

EDIT: its also worth noting that this is seen with other ADC inputs, and will also occur without a person making physical contact with the PCB.

  • Hi,

     

    Not sure how you have setup your SAADC, but there are four erratums that you can potentially hit:

    Started events fires prematurely

    Triggering START task after offset calibration may write a sample to RAM

    EVENT_STARTED does not fire

    END event firing too early

     

    Does your handling of the SAADC resemble any of these scenarios?

    If not, could you elaborate on how often you see this, and how you sample your analog input from a fw-perspective?

     

    Best regards,

    Håkon

  • I've modified the SAADC SDK example to use four channels, sample every 6ms, and write to m_buffer_pool which is configured to have four elements (such that each channel samples once every 6ms). I don't think the situations you linked describe what I'm seeing.

    In my SAADC callback, I write the contents of two of the channels to their own dedicated array 2000 elements deep. There will be times (recently had this occur for about 1.1 seconds of samples in the middle of the sample array) There are a few bursts of less than 20 samples within this period in which there are some normal valued samples. Otherwise there is a range of values from 65523 to 65535 being returned from the callback.

    I think it is also worthwhile to mention that my ADC values will normally sit at around ~400 at the lowest. Prior to seeing this 16 bit values, the ADC values will start to get lower and lower. Since I am storing my values in an unsigned 16 bit integer, perhaps these are "negative" values that are just rolling over?

    This is a graph of the original signal during one of these 16 bit periods:

    Original Signal

    Here is that same set of values graphed, except I subtracted 65535 from every "16 bit" value such that a negative value was produced:

    Corrected Signal

    And just for clarity, here are the raw values captured from the ADC here:

    1677
    1653
    1618
    1588
    1602
    1570
    1601
    1578
    1565
    1544
    1485
    1450
    1458
    1416
    1352
    1338
    1285
    1256
    1237
    1177
    1164
    1158
    1099
    1071
    1040
    1017
    1032
    1013
    1017
    1047
    979
    924
    878
    775
    734
    716
    687
    731
    728
    702
    744
    749
    747
    785
    697
    639
    610
    569
    592
    558
    473
    433
    340
    266
    311
    382
    456
    463
    308
    144
    5
    65534
    65532
    65530
    65532
    65529
    65532
    65532
    65529
    65525
    65531
    65527
    65527
    65534
    0
    65529
    65532
    0
    65530
    65529
    65527
    65529
    65533
    65529
    65533
    65530
    65527
    65531
    65533
    65532
    65527
    65530
    65531
    65529
    65527
    65529
    65529
    65531
    65529
    65525
    65527
    65527
    65528
    65531
    97
    146
    92
    65527
    65523
    65529
    65527
    65533
    65526
    65534
    65527
    65532
    65530
    65527
    65534
    65527
    65523
    65530
    65529
    65530
    65529
    65530
    65533
    65531
    65525
    65527
    65527
    65525
    65534
    65526
    65530
    65527
    65527
    65526
    0
    65532
    65530
    65533
    65530
    65531
    65529
    65530
    65527
    65529
    65526
    65529
    65527
    65530
    65530
    65530
    65532
    65529
    65526
    65531
    65532
    65534
    65531
    65532
    65530
    65531
    65527
    65529
    65529
    65532
    0
    65533
    65526
    65533
    65527
    65527
    65527
    65530
    65528
    65526
    65527
    65532
    65527
    65533
    65529
    65530
    0
    65530
    65535
    65530
    65527
    65533
    65527
    65533
    65527
    65531
    65527
    65529
    65529
    65525
    65531
    65528
    65529
    65525
    65531
    65533
    65527
    65530
    65532
    65527
    65529
    65535
    65533
    65529
    65532
    65530
    65528
    65531
    65526
    65532
    65527
    65530
    65535
    65526
    65533
    65532
    65533
    65533
    65531
    65535
    65533
    65523
    65534
    65534
    1
    215
    371
    433
    392
    363
    435
    504
    564
    633
    517
    413
    324
    184
    119
    110
    32
    0
    65525
    65533
    65533
    65531
    65531
    65528
    65529
    65531
    65533
    65530
    65527
    16
    25
    104
    165
    272
    312
    273
    206
    214
    223
    229
    293
    323
    391
    480
    477
    513
    525
    551
    631
    658
    679
    693
    687
    740
    814
    857
    947
    999
    1020
    1073
    1103
    1154
    1251
    1284
    1275
    1304
    1291
    1352
    1414
    1402
    1469
    1518
    1512
    1588
    1624
    1632
    1675
    1699
    1747
    1809
    1811
    1843
    1874
    1848
    1908
    1951
    1955
    2039
    2105
    2128

  • Hi,

     

    Thanks for the detailed graphs and raw-data. The driver will interpret the ADC result as a int16_t type.

    ex: 65533 == -3. If you store and treat the data as signed, the graphs should look better.

     

    Cheers,

    Håkon

  • Ok, thank you, I can start doing that.

    Question for you though - why is the ADC yielding negative values? Doesn't that not necessarily make sense?

  • You have different types of noise that affects any ADC, like non-linearity, temperature, and offset errors.

    I suspect it's the offset error of the ADC that provides you with negative values. If you ground the ADC pin and check the result, it will yield a negative number.

     

    The different offset/linear errors for the SAADC can be found in the el-specs:

    http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/saadc.html?cp=2_1_0_36_11#unique_397560666

     

    Best regards,

    Håkon

Related