Closed fa1ke5 closed 5 years ago
In scan mode you are not allowed (at least is not recommended) to convert the same input as multiple channels simultaneously.
I dont using scan mode
`//calibrate ADC myADC.calibrate();
// Set up our analog pin(s) // for (unsigned int j = 0; j <8; j++) pinMode(pins[0], INPUT_ANALOG);
myADC.setSampleRate(ADC_SMPR_1_5);//set the Sample Rate // myADC.setScanMode(); //set the ADC in Scan mode. myADC.setPins(pins, 1); //set how many and which pins to convert. myADC.setContinuous(); //set the ADC in continuous mode.
//set the DMA transfer for the ADC. //in this case we want to increment the memory side and run it in circular mode //By doing this, we can read the last value sampled from the channels by reading the dataPoints array myADC.setDMA(dataPoints, 8, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
//start the conversion.
//because the ADC is set as continuous mode and in circular fashion, this can be done
//on setup().
myADC.startConversion();
`
any solutions???
Please post the complete example. Which is your target board? 20nF capacitor is too small, try higher values, ~1µF.
`/* This example shows how to use the ADC library to continuously sample several channels/pins. The acquisition of the channels is done using DMA in circular mode.
*/
STM32ADC myADC(ADC1);
//Channels to be acquired. uint8 pins[] = {PB0};
const int maxSamples = 8; // 8 channels
// Array for the ADC data uint16_t dataPoints[maxSamples];
void setup() { Serial.begin(19200); pinMode(BOARD_LED, OUTPUT); pinMode(D32, INPUT); //startup blink... good idea from Pig-O-Scope digitalWrite(BOARD_LED, HIGH); delay(1000); digitalWrite(BOARD_LED, LOW); delay(1000);
//calibrate ADC myADC.calibrate();
// Set up our analog pin(s) // for (unsigned int j = 0; j <8; j++) pinMode(pins[0], INPUT_ANALOG);
myADC.setSampleRate(ADC_SMPR_1_5);//set the Sample Rate // myADC.setScanMode(); //set the ADC in Scan mode. myADC.setPins(pins, 1); //set how many and which pins to convert. myADC.setContinuous(); //set the ADC in continuous mode.
//set the DMA transfer for the ADC. //in this case we want to increment the memory side and run it in circular mode //By doing this, we can read the last value sampled from the channels by reading the dataPoints array myADC.setDMA(dataPoints, 8, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
//start the conversion.
//because the ADC is set as continuous mode and in circular fashion, this can be done
//on setup().
myADC.startConversion();
}
void loop(){ //send the latest data acquired when the button is pushed.
Serial.println("begin");
// Take our samples
for(unsigned int i = 0; i < maxSamples; i ++) {
Serial.print("sample[");
Serial.print(i);
Serial.print("] = ");
Serial.println(dataPoints[i]);
}
}`
Capacitor dont change anything, im using voltage divider 12k x 160k (1/13) for measuring up to 48V input. if im use ADC_SMPR_1_5 i take nonzero level
begin sample[0] = 134 sample[1] = 137 sample[2] = 136 sample[3] = 136 sample[4] = 134 sample[5] = 136 sample[6] = 137 sample[7] = 136
if i use ADC_SMPR_239_5 i take about 5-6 nonzero values in shorten divider
begin sample[0] = 6 sample[1] = 6 sample[2] = 8 sample[3] = 6 sample[4] = 5 sample[5] = 5 sample[6] = 7 sample[7] = 5
But if i using direct reading ADC data by getData() funcrion, i take nice zerolevel, 0 in terminal and good linearty. And more....if i connect divider to negative voltage source " - 1 " V, i take good zero on terminal. I think in DMA mode ADC registers have a wrong setting. PS Im using blue pill board without modding.... PPS Sorry for my poor englesh, nice day!
Voltage divider is equal this https://www.stm32duino.com/viewtopic.php?t=3233#p41495 and this code nice working
//Shorten 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 //1.6V in 0.437 0.461 0.468 0.464 0.468 0.468 0.468 0.468 0.471 0.464 0.464 0.464 0.464 0.471 0.464 0.468 0.464 0.464
???
If you think that ADC registers have wrong settings, then you are welcome to correct them. I would suggest to use a higher capacitor and lower resistance, because ~10kOhm impedance is too high for high speed AD conversion.
10kOm work great, im testing it above in one sample mode and code work nice, but if im using DMA its data is corrupt. https://leoniv.livejournal.com/194681.html capacitor dont may be must greater then 10-100 nF and dont use it is good idea.....
i testing another resistors and capacitors, it does not solve the problem
may be possible solution is described here https://blog.kiltum.tech/2017/08/16/stm32-adc-multiple-channels-hal/ https://github.com/kiltum/stm32adc
Hi all! I successfully solved the ADC problem! as discribed here https://leoniv.livejournal.com/194681.html lage capasitor in filter is violates the correct operation of the ADC. In my case im down capacitive of input filter on 4 nF and take good ADC samples in ADC_SMPR_41_5 sample rate.
hi,
in my experience, your problem is about signal source output impedance.
if its low, you will not have problem, but with higer values you will start to see this kind of errors.
i suggest carefull reading of st appnotes, especially a "Workaround for extra high impedance sources" item starting on page 40
you must increase the sample time, and time between samples. there you can see how to calculate both
stm32 dont have a buffer amp hardware in every analog input, then your circuit will be connected directly to the internal sample capacitor, and this is why output impedance must be low
read this too. https://www.analog.com/media/en/analog-dialogue/volume-46/number-4/articles/front-end-amp-and-rc-filter-design.pdf
Hi all! im testing DMA mode of one channel ADC and take non zero samles on it. im using example code MultiChannelContinuousConversion. and i only correcting multichannel to one channel. i have 20nF and correct voltage divider, but take this in terminal
begin sample[0] = 134 sample[1] = 133 sample[2] = 134 sample[3] = 135 sample[4] = 133 sample[5] = 134 sample[6] = 136 sample[7] = 134
If im change myADC.setSampleRate(ADC_SMPR_1_5); to ADC_SMPR_7_5 level is lower and i take this output
begin sample[0] = 97 sample[1] = 97 sample[2] = 95 sample[3] = 97 sample[4] = 96 sample[5] = 95 sample[6] = 97
e.t.c In this case, i can read external voltage on ADC input, but measurement is non linear.
If im use direct reading by STM32ADC::getData() function all Ok, linear and zero level is perfect.