ADC values weird

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
DashieV3
Posts: 5
Joined: Thu Jun 26, 2014 1:37 pm

ADC values weird

Post by DashieV3 »

Hi,

I'm trying to got ADC values from single-scan and not continuous.
I'm using ping PF4 of ADC3_IN14. I've activated ADC and ADC3 in mcuconf.
My main is as following (Based on code found at https://github.com/Mathias-L/STM32F4-Di ... ample-code) :

Code: Select all

// Create buffer to store ADC results. This is
// one-dimensional interleaved array
#define ADC_GRP1_BUF_DEPTH 2014*2*4 // depth of buffer
#define ADC_GRP1_NUM_CHANNELS 1    // number of used ADC channels
static adcsample_t samples_singlescan[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; // results array

/*
 * Internal Reference Voltage, according to ST this is 1.21V typical
 * with -40°C<T<+105°C its Min: 1.18V, Typ 1.21V, Max: 1.24V
 */
#define VREFINT 121
/*
 * The measured Value is initialized to 2^16/3V*2.21V
 */
uint32_t VREFMeasured = 26433;

/* error callback, does nothing */
static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) {
  (void)adcp;
  (void)err;
}

/*
 * ADC conversion group
 * Mode : Linear buffer, 8 samples of 1 channel, SW triggered.
 * Channels : ADC3_IN14 / PF4
 */
static const ADCConversionGroup adcgrpcfg1 = {
  FALSE, // circular buffer mode
  ADC_GRP1_NUM_CHANNELS, // number of analog channels
  NULL, // callback function (not nedded here)
  adcerrorcallback, //error callback
  0, // CR1
  ADC_CR2_SWSTART, // CR2
  ADC_SMPR1_SMP_AN14(ADC_SAMPLE_3), // sample times ch10-18
  0, // sample times ch0-9,
  ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS), // SQR1: conversion group sequence 13...16 + sequence length
  0, // SQR2: conversion group sequence 7..12
  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN14) // SQR3: Conversion group sequence 1...6
};

/*
 * Red LED blinker thread, times are in milliseconds.
 */
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker1");
  while (TRUE) {
    palClearPad(GPIOC, GPIOC_LED);
    chThdSleepMilliseconds(500);
    palSetPad(GPIOC, GPIOC_LED);
    chThdSleepMilliseconds(500);
  }
}

/*===========================================================================*/
/* Command line related.                                                     */
/*===========================================================================*/

/* Virtual serial port over USB.*/
SerialUSBDriver SDU1;

#define SHELL_WA_SIZE   THD_WA_SIZE(2048)
#define TEST_WA_SIZE    THD_WA_SIZE(256)

static void cmd_adc(BaseSequentialStream *chp, int argc, char *argv[]) {
  (void)argv;
  uint32_t sum=0;
  unsigned int i;
  if (argc > 0) {
    chprintf(chp, "Usage: adc\r\n");
    return;
  }

  adcConvert(&ADCD3, &adcgrpcfg1, samples_singlescan, ADC_GRP1_BUF_DEPTH);
  // print the first measured value
  chprintf(chp, "Measured: %d ", samples_singlescan[0]*16);
  sum = 0;
  for (i=0;i<ADC_GRP1_BUF_DEPTH;i++) {
    // chprintf(chp, "%d ", samples_singlescan[i]);
    sum += samples_singlescan[i];
  }
  // print the averaged value wih two digits precision
  chprintf(chp, "%U\r\n", sum/(ADC_GRP1_BUF_DEPTH/16));
}

static const ShellCommand commands[] = {
  {"adc", cmd_adc},
  {NULL, NULL}
};

static const ShellConfig shell_cfg1 = {
  (BaseSequentialStream *)&SDU1,
  commands
};

/*===========================================================================*/
/* Initialization and main thread.                                           */
/*===========================================================================*/

/*
 * Application entry point.
 */
int main(void) {
  Thread *shelltp = NULL;

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Shell manager initialization.
   */
  shellInit();

  /* Init ADC */
  palSetPadMode(GPIOF, 4, PAL_MODE_INPUT_ANALOG);
  //palSetGroupMode(GPIOF, PAL_PORT_BIT(1), 0, PAL_MODE_INPUT_ANALOG);
  adcStart(&ADCD3, NULL);
  adcSTM32EnableTSVREFE();

  /*
   * Initializes a serial-over-USB CDC driver.
   */
  sduObjectInit(&SDU1);
  sduStart(&SDU1, &serusbcfg);

  /*
   * Activates the USB driver and then the USB bus pull-up on D+.
   * Note, a delay is inserted in order to not have to disconnect the cable
   * after a reset.
   */
  usbDisconnectBus(serusbcfg.usbp);
  chThdSleepMilliseconds(1000);
  usbStart(serusbcfg.usbp, &usbcfg);
  usbConnectBus(serusbcfg.usbp);

  /*
   * Creating the blinker threads.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1),
                    NORMALPRIO + 10, Thread1, NULL);

  /*
   * Normal main() thread activity, in this demo it just performs
   * a shell respawn upon its termination.
   */
  while (TRUE) {
    if (!shelltp) {
      if (SDU1.config->usbp->state == USB_ACTIVE) {
        /* Spawns a new shell.*/
        shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
      }
    }
    else {
      /* If the previous shell exited.*/
      if (chThdTerminated(shelltp)) {
        /* Recovers memory of the previous shell.*/
        chThdRelease(shelltp);
        shelltp = NULL;
      }
    }
    chThdSleepMilliseconds(500);
  }
}


When trying « adc » i got changing values, oscillating a bit :
Open Pin, Measured: 4816 16602
Pin to GND , oscillating between 0/174/240, Measured: 240 80
Pin to 3.3V : Measured: 65152 65326

It seems that the delta between open and 3.3 tell me that it seems to works, but i don't understand thoses weird values.

Any things ?
Last edited by DashieV3 on Wed Jul 02, 2014 1:53 pm, edited 1 time in total.
steved
Posts: 834
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 138 times

Re: ADC values weird

Post by steved »

When trying « adc » i got changing values, oscillating a bit :
Open Pin, Measured: 4816 16602
Pin to GND , oscillating between 0/174/240, Measured: 240 80
Pin to 3.3V : Measured: 65152 65326

It seems that the delta between open and 3.3 tell me that it seems to works, but i don't understand thoses weird values.


Those seem perfectly reasonable, unless you've taken steps to minimise analog noise in your hardware.

With the open pin, it will act as an antenna, picking up all the RF rubbish that floats around. Also, it's high impedance (unless you've enabled a pullup/pulldown). So you'd expect widely varying values.

For pins connected to one of the supplies, some variation is quite normal, due to noise in the system.

Getting rid of that noise can be quite a challenge!


And are your samples 12-bit values, left-justified? If so, your readings will vary in steps of 16 'counts', which starts to make things look much better.
Post Reply