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);
}