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
#include <Arduino.h>
ADC_HandleTypeDef hadc1;
HardwareTimer *AdcTimer = new HardwareTimer(TIM1);
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);
}
void Timer_callback(void) { counter++; }
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
adc_setup(&hadc1, ADC1);
AdcTimer->pause();
AdcTimer->setOverflow(100000, HERTZ_FORMAT);
AdcTimer->attachInterrupt(Timer_callback);
AdcTimer->resume();
}
void loop() {
adc_loop();
digitalWrite(LED_BUILTIN, LOW);
delay(50);
digitalWrite(LED_BUILTIN, HIGH);
delay(950);
}