Page 1 of 1

Calculating the Temperature Indicator

Posted: Tue Mar 11, 2014 5:27 pm
by Tabulous

Code: Select all

/* Total number of channels to be sampled by a single ADC operation.*/
#define ADC_GRP1_NUM_CHANNELS   5

/* Depth of the conversion buffer, channels are sampled five times each.*/
#define ADC_GRP1_BUF_DEPTH      2

/* This is the scaling factor to convert to voltages.*/
#define ADC_SCALING_V44         (0.000732 * 2)
#define ADC_SCALING_V30         (0.000732 * 2)
#define ADC_SCALING_VBAT        (0.000732 * 2)
#define ADC_SCALING_VIN         (0.000732 * 10)

/*
 * ADC samples buffer.
 */
static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];

/*
 * ADC conversion group.
 * Mode:        Linear buffer, 4 samples of 2 channels, SW triggered.
 * Channels:    IN11   (48 cycles sample time)
 *              Sensor (192 cycles sample time)
 */
static const ADCConversionGroup adcgrpcfg = {
  FALSE,
  ADC_GRP1_NUM_CHANNELS,
  adccb,
  NULL,
  /* HW dependent part.*/
  0,
  ADC_CR2_SWSTART,
  ADC_SMPR2_SMP_AN1(ADC_SAMPLE_480) |
  ADC_SMPR2_SMP_AN2(ADC_SAMPLE_480) |
  ADC_SMPR2_SMP_AN3(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_VBAT(ADC_SAMPLE_480) |
  ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_480),
  0,
  ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
  0,
  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN1) |
  ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2) |
  ADC_SQR3_SQ3_N(ADC_CHANNEL_IN3) |
  ADC_SQR3_SQ4_N(ADC_CHANNEL_VBAT) |
  ADC_SQR3_SQ5_N(ADC_CHANNEL_SENSOR)
};

/*
 * ADC end conversion callback.
 */
void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {

    (void) n;
    (void)buffer;
    /* Note, only in the ADC_COMPLETE state because the ADC driver fires an
       intermediate callback when the buffer is half full.*/

    if (adcp->state == ADC_COMPLETE)
    {
        float ch1, ch2, ch3, ch4, ch5;
        palTogglePad(GPIOG, GPIOG_LED_STATUS_GRN);

        /* Calculates the average values from the ADC samples.*/
        ch1 = ((samples[0] + samples[5]) / ADC_GRP1_BUF_DEPTH) * ADC_SCALING_VIN;
        ch2 = ((samples[1] + samples[6]) / ADC_GRP1_BUF_DEPTH) * ADC_SCALING_V30;
        ch3 = ((samples[2] + samples[7]) / ADC_GRP1_BUF_DEPTH) * ADC_SCALING_V44;
        ch4 = ((samples[3] + samples[8]) / ADC_GRP1_BUF_DEPTH) * ADC_SCALING_VBAT;
        ch5 = ((samples[4] + samples[9]) / ADC_GRP1_BUF_DEPTH);
        ch5 = ((ch5 - 760) / 2.5) + 25;

        chSysLockFromIsr();
        adcStartConversionI(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
        chSysUnlockFromIsr();
    }
}

void psuInit(void)
{

    /*
     * Initializes the ADC driver 1 and enable the thermal sensor.
     * The pin PC1 on the port GPIOC is programmed as analog input.
     */
    adcSTM32EnableVBATE();
    adcSTM32EnableTSVREFE();
    adcStart(&ADCD1, NULL);

    adcStartConversion(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
}


Is this correct as the temp is coming out all wrong, temp is on ch5 ?

Re: Calculating the Temperature Indicator

Posted: Tue Mar 11, 2014 8:48 pm
by Giovanni
Hi,

It should go in position 5.

The F4Discovery ADC demo reads the sensor, apparently it works.

Try calling adcSTM32EnableVBATE() and adcSTM32EnableTSVREFE() after starting the ADC driver. Before adcStart() the ADC clock is not yet activated.

Giovanni