1
\$\begingroup\$

I'm not sure the cause but I'm having troubles getting a consistent voltage reading from the ADC pin of my STM32F103(actual bluepill and not a knockoff). Here is the serial output from my board (each averaged over 200 sample points). When I measure using my multi-meter I have a value of 2.22V with almost no variability. How can I solve this variation in my ADC data? I've tried a draw down resistor, increasing the number of sample points, increasing the time span between each individual measurement, and nothing seems to work. Any ideas? (code included below)

2.206412
2.223868
2.499660
2.224902
2.493302
2.515666
2.415408
2.291376
//Includes//
//------------------------------------------------------------------------------
#include <Arduino.h>

//------------------------------------------------------------------------------

//Constants definitions//
//------------------------------------------------------------------------------

#define flow1_Sensor    PA6 
#define green_LED       PA11    // External LED-Green
#define LOG_INTERVAL    200     // mills between outputs

uint32_t  timeold;              //initial time
int reps=200;                     //number of adc values to be averaged
double flowrate1=0;             


void collect_flow_data(int flow_sens_pin, int reps, double* flowrate1) {
  double sum_flow=0;

  for(int i=1; i<=reps; i++){
    int val_flow = analogRead(flow_sens_pin);
    delay(20);
    sum_flow = sum_flow+val_flow;
  };

  double avg_flow=sum_flow/(double)reps;
  *flowrate1 = (avg_flow/4096) * 3.3; 
};


//------------------------------------------------------------------------------
//Main Setup
//------------------------------------------------------------------------------
void setup() {
  Serial.end();

  //Indicator LED
  pinMode(green_LED, OUTPUT);
  digitalWrite(green_LED,LOW);

  //start Flow Sensor Pin
  pinMode(flow1_Sensor, INPUT_ANALOG);

  timeold = millis();
  //setup serial connection
  Serial3.begin(9600); 
}
//------------------------------------------------------------------------------
void loop() 
{
  

  if ((millis() - timeold) >= LOG_INTERVAL) 
  {
    collect_flow_data(flow1_Sensor, reps, &flowrate1);
    Serial3.println(flowrate1,5);
    digitalWrite(green_LED, HIGH);
    delay(100);
    digitalWrite(green_LED, LOW);
    timeold = millis(); //update times
  }
  else{}
}


\$\endgroup\$
4
  • \$\begingroup\$ Getting quiet ADC readings is a multi-part challenge. The STM32F1 ADCs are well known to not be very quiet, they also have more resolution than those coming from say ATmegas are used to, and depending on setting they can have a low enough input impedance to distort the source by loading, too. Good analog design of the ADC supply and ADC input is key. There are also tricks people try of shutting down various other parts of the chip while reading, etc. And you can simply do more and better filtering... At present you don't have a specifically answerable question, just a variety to pursue. \$\endgroup\$ Oct 20, 2020 at 18:58
  • \$\begingroup\$ I'd check the VDDA pin first for any possible fluctuations/ripples/noise because the most crucial part of a stable ADC measurement is to have a clean supply. Also, make sure that a 1uF+100nF MLCC pair is present at the VDDA pin. \$\endgroup\$ Oct 20, 2020 at 19:30
  • 1
    \$\begingroup\$ @ChrisStratton Any suggestions for resources for ADC input design? \$\endgroup\$
    – Lifespark
    Oct 20, 2020 at 19:50
  • \$\begingroup\$ Check out Bonnie Baker's blog. She does a bunch about A2D and signal to noise. ti.com/analog-circuit/bonnie-baker-ebook.html \$\endgroup\$
    – Aaron
    Oct 20, 2020 at 20:09

1 Answer 1

0
\$\begingroup\$

Average anything long enough and the noise goes away! Also it is very important to have a clean power source. Check with oscilloscope if possible.

\$\endgroup\$
1
  • \$\begingroup\$ Hi, Is this actually the final answer? Either (a) You are writing it as an answer, because it really does answer your original question. In that case, please "accept" this answer (green "tick") to close the whole topic / question. Or (b) You still want replies / help. In that case, this is an update and not an answer, and must be "edited into" your original question instead i.e. click "edit" under the question, add this update in a sensible place in the question, then delete this "answer". Which applies here, (a) or (b)? Thanks. \$\endgroup\$
    – SamGibson
    Nov 9, 2020 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.