Asynchronous ADC start/read on bluepill STM32F103C8?

Post here first, or if you can't find a relevant section!
Post Reply
zapta
Posts: 10
Joined: Sun Aug 02, 2020 7:41 pm

Asynchronous ADC start/read on bluepill STM32F103C8?

Post by zapta »

Hi all,

[using bluepill, STM32F103C8, using vscode/platform.io with Arduino framework and stlink v2 uploading/debugging]

My questions to you are:
1. Does the bluepill has a single or double ADCs? (I mean real two ADCs that can convert in parallel).
2. Is there an asynchronous API for the ADCs?

Background: I am migrating a program from teensy to bluepill to redcue cost and have a question about the usage of the ADC(s). The program sets a timer to generate 100Khz interrupts and on each interrupt handler call it does the following:

Code: Select all

interrupt routine {
  I1 = read_adc1 result;
  I2 = read_adc2 result;
  start adc1;  // for reading in next interrupt
  start adc2;  
  process results I1, I2;  // processing is significant, decoding position/speed of a stepper motor. 
}
I managed to setup a timer that invokes the interrupt routine but am not sure how to setup the ADC(s) or do asynchronous start/read. All I see is the arduino blocking analog read.

Thanks.
User avatar
fpiSTM
Posts: 1745
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by fpiSTM »

You will have to implement yourself the ADC read using the HAL/LL layer.

I've provide an example of a converted STM32Cube project here:
viewtopic.php?f=41&t=110&p=669

For question 1:
https://www.st.com/en/microcontrollers- ... 103c8.html
2 x 12-bit, 1 μs A/D converters (up to 16 channels)

Conversion range: 0 to 3.6 V
Dual-sample and hold capability
Temperature sensor
zapta
Posts: 10
Joined: Sun Aug 02, 2020 7:41 pm

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by zapta »

> I've provide an example of a converted STM32Cube project here: viewtopic.php?f=41&t=110&p=669

Thanks fpiSTM. I will go through the example and try to understand.

Will this involve just adding .h and .c file to my stm32duino project directory or will it also require to modify/add/replace lower level library files that come with the stm32duino environment?

Also, if anybody has an example of asynchronous ADC in a stm32duino project, please let me know.
User avatar
fpiSTM
Posts: 1745
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by fpiSTM »

Just add to tour sketch file or new file. No need to modify the core.
zapta
Posts: 10
Joined: Sun Aug 02, 2020 7:41 pm

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by zapta »

Thanks fpiSTM that's very useful. I collected commands and came with the program below which seems to measure A0 using ADC1 inside the main loop (no sampling from interrupts yet), so that's a progress.

A few question for you if you don't mind:
1. Does this program look reasonable so far?
2. How do I select a different input (other than A0)?
3. Are all the selectable analog inputs the same or are some more preferred than others?
4. The conversion takes about 10usec. Any way to speed it up? (e.g. sub 5usec)
5. I want to add a second channel ADC2 with same time sampling. Should I just treat it as a separate channel with its own Start/Read or does the chip has a simultaneous two channel operation? (how?).

EDIT: it seems that HAL_ADC_Start(&hadc1) alone takes ~8usec and looking at its code it seems to be logic heaver. I guess I need to trigger the conversion in a different way, mayby directly from the timer and run my signal processing at the ADC completion interrupt?

Thanks,
Z.

Code: Select all

// stm32duino core API here https://github.com/stm32duino/wiki/wiki/API

#include <Arduino.h>

ADC_HandleTypeDef hadc1;

HardwareTimer *AdcTimer = new HardwareTimer(TIM1);

//  Updated by an interrupt routine. Protect as needed.
static int counter = 0;

void adc_setup(ADC_HandleTypeDef* adc_handle, ADC_TypeDef *adc) {
  adc_handle->Instance = adc;
  adc_handle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
  adc_handle->Init.ScanConvMode = ADC_SCAN_DISABLE;
  adc_handle->Init.ContinuousConvMode = DISABLE;
  adc_handle->Init.NbrOfConversion = 1;
  adc_handle->Init.DiscontinuousConvMode = DISABLE;
  adc_handle->Init.NbrOfDiscConversion = 1;
  adc_handle->Init.ExternalTrigConv = ADC_SOFTWARE_START;
  HAL_StatusTypeDef status = HAL_ADC_Init(adc_handle);
  if (status != HAL_OK ) {
    for(;;) {
      Serial.printf("ADC setup error: %d", status);
      delay(1000);
    }
  }
}

void adc_loop() {
  auto start = micros();
  HAL_ADC_Start(&hadc1);
  HAL_StatusTypeDef status = HAL_ADC_PollForConversion(&hadc1, 100);
  if (status != HAL_OK ) {
    for(;;) {
      Serial.printf("ADC read error: %d", status);
      delay(1000);
    }
  }
  int value = HAL_ADC_GetValue(&hadc1);
  auto end = micros();
  Serial.printf("Adc: %d (%d usec)\n", value, end - start);
}

// Timer interrupt routing. 
void Timer_callback(void) { counter++; }

// Arduino's one time setup.
void setup() {
  // Should be done first, to print setup errors.
  Serial.begin(9600);

  pinMode(LED_BUILTIN, OUTPUT);
  adc_setup(&hadc1, ADC1);

  AdcTimer->pause();
  AdcTimer->setOverflow(100000, HERTZ_FORMAT);  // 10 Hz
  AdcTimer->attachInterrupt(Timer_callback);
  AdcTimer->resume();
}

// Arduino's main loop handler.
void loop() {
  adc_loop();
  digitalWrite(LED_BUILTIN, LOW); // LED on
  delay(50); 
  digitalWrite(LED_BUILTIN, HIGH);  // LED off.
  delay(950); 
}
zapta
Posts: 10
Joined: Sun Aug 02, 2020 7:41 pm

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by zapta »

A quick update, everything is working now. I am using Timer1 to generate output pulses for reference and internal triggers to ADC1 that acts as a master to ADC2 and IRQ handling on ADC1 completion. I first had it working with the CUBE IDE and then ported to the arduino framework.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: Asynchronous ADC start/read on bluepill STM32F103C8?

Post by stevestrong »

Can you share a working example?
Post Reply

Return to “General discussion”