SAADC results unclear.

Using the NRF5 SDK V17.0.2

Once again finding myself struggling to understand the structure of the SDK as a result of lacking documentation, there seem to be so many layers of abstraction used accross the example code. functions using nrf/nrfx/nrf_drv prefixes & endless redirect header files. I'm trying to review one of the SAADC example projects. There are less than 10 annotations accross the main.c file & it's not made clear why functions are called at given times.

In my own code, I am inputting to a single ended channel of the SAADC peripheral, a sinusoid that is centred about -30mv (or sometimes 0V). The signal has been AC coupled, but in future this coupling will be removed. For now i must try to conduct some testing regardless, the negative voltage doesn't go anywhere near the -0.3V absolute maximum & features plenty of positive components.

I am using a single ended ADC channel, with a gain of 1 & resolution of 14 bits. Reference voltage 0.6V internal. The SAADC samples are coming out around 8000 (~0.3V).

When i try adjusting the resolution to 12 bits, i get samples around 2000 (again, ~0.3V).

Why is it my samples are centered around the 0.3V region. When i know they are in fact centred around 0V...

It's worth noting that the waveforms i'm seeing, while centred around the wrong value, are roughly correct & in keeping with what i would expect).

I have also noticed that if i invert my signal (signal is an ECG type signal, that i can invert by swapping chest electrodes), the ADC results, do NOT invert to match.

Am i converting the sample values to voltages correctly? (I'm following the standard equations shown on the infocentre).

  • SeanHowsonTB said:
    so it's now a sinusoid centered around 1V, with 0.5V pk-pk ish. No more negative voltages.

    For an unconnected pin? Is it possible you are picking up some noise from the power grid or USB? What is the frequency?

    Kenneth

  • This this is a mis-communication here.

    The only time the pin has been unconnected was while i was trialing the effects of the internal pullup's & pull downs.

    I've removed the AC coupling, from the board & replaced it with a 0603 sized peice of copper, IE the filter no longer exists. The output of the ECG circuit now runs through a single mains-noise filter as it always had & straight into the SAADC pin.

    There are no usb related components on the board.

    This 1V offset, 0.5V pk-pk is my desired signal, this is the ECG signal i'm trying to measure. The difference is that it is no longer centered around 0V, instread it has a positive offset voltage to keep it within the input range of the SAADC.

  • SeanHowsonTB said:
    This 1V offset, 0.5V pk-pk is my desired signal, this is the ECG signal i'm trying to measure. The difference is that it is no longer centered around 0V, instread it has a positive offset voltage to keep it within the input range of the SAADC.

    Ah, thanks for clarifying.

    Kenneth

  • Keep in mind the SAADC only measures positive voltages above GND. ECG signals of (say) 1mV really require a differential input otherwise most of the resolution is lost handling the DC offset even when AC coupled. This can be handled by using a true differential input, which requires two pins. Both input pins have both bias pull-up and bias pull-down enabled, ie 160k pull-up and 160k pull-down, which biases the signal to mid-rail (VDD/2) on both SAADC input pins. Leaving both pins disconnected now allows high gain measurement of random noise. AC couple the positive signal to the 1mV ECG waveform (which may sit at any DC level) now allows high amplification of the small ECG signal. Reversing the ECG leads (not the SAADC inputs) will invert the ECG waveform as one would expect.

    Optionally the normally-unconnected -ve input pin can be connected via an identical CR network to the ECG signal -ve output (quite possibly the ECG GND). Doing so balances both input impedance and noise pickup, which in SAADC differential mode will cancel out.

    // Differential SAADC Mode
    //                                                     |    VDD
    //                                                     |   --#--
    //                                                     |     |
    //                                                     |     +-|   (160k)
    //                                                     |       |<- CFG.RESP
    //   ECG Sensor                                        |     +-|
    //   +--------+                                        |     |
    //   |        |     ECG Signal         | |             |     |
    //   |        0------------------------| |-------------O-----#-----------------#--> P0.nn ADC +ve input
    //   |        |                        | |             |     |                 |          Ref = 0.6
    //   |        0--+  ECG Gnd                            |     +-|  (160k)       |
    //   |        |  |  negative reference                 |       |<-CFG.RESN   -----
    //   +--------+  |  optional                           |     +-|             -----
    //               |                                     |     |                 |
    //               |                                     |     |                 |
    //               |                                     |   =====             =====
    //               |                                     |    ===               ===
    //               |                                     |     =                 =
    //               |                                     |
    //               |                                     |
    //               |                                     |    VDD
    //               |                                     |   --#--
    //               |                                     |     |
    //        +====  | =============================+      |     +-|  (160k)
    //        !      |                              !      |       |<-CFG.RESP
    //        !      |                              !      |     +-|
    //        !      |                              !      |     |
    //        !      |                  | |         !      |     |
    //        !      +------------------| |----------------O-----#-----------------#--> P0.nn ADC -ve input
    //        !                         | |         !      |     |                 |          Ref = 0.6
    //        !                                     !      |     +-|  (160k)       |
    //        ! Optional, can leave pin unconnected !      |       |<-CFG.RESN   -----
    //        +=====================================+      |     +-|             -----
    //                                                     |     |                 |
    //                                                     |     |                 |
    //                                                     |   =====             =====
    //                                                     |    ===               ===
    //                                                     |     =                 =
    //                                                     | nRF52832
    //                                                     +----------------------------------

  • Kenneth,

    Problem solved. So the signal described above. Seeingly just wan't having any affect on the input pin. (tapping & touching the ECG electrodes had no effect, normally this should induce huge spike).

    As mentioned, in the past i was pretty confident that the pin i had defined was not the issue. As i'd definitely seen ECG on the screen, & been able to influence the ADC readings by tapping the input to the sensor circuit etc.

    However, prompted by your earlier post, i swapped the definition for the EEG pin from  NRF_GPIO_PIN_MAP(0,04)

    to

    NRF_SAADC_INPUT_AIN2

    ...Which to my understanding would map to the same pin.... apparently not. it now works.

    Thanks for the prompt in the right direction.

Related