Fast ADC readings

Thats normal, because i measured 10 us for one analogRead() and millis() allso takes some time.
There are also interrupts from the system...

I found now a solution myself. I was using the wrong commands from the STM32_StdPeriph_Driver lib because i tried to use some from STM32F1xx-generation. Photon is based on STM32F2xx!

My working Code with 1.2 µs reading time!

/*
* returns the counts of a given ADC (ADC1 and AD2, ADC3 wans't working)
* takes approx. 1.2 µs
*/
uint16_t readADCx(ADC_TypeDef* ADCx){
  ADC_SoftwareStartConv(ADC2); // ca. 150 ns
  // Wait until conversion completion
  while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET); // ca. 800 ns
  pinResetFast(D0);
  //ADC_ClearFlag(ADC1, ADC_FLAG_EOC); // is not necessarry
  return ADC_GetConversionValue(ADC2); //ca. 100ns
}
source complete
#include "Particle.h"
SYSTEM_THREAD(ENABLED); //multitasking with system thread
SYSTEM_MODE(MANUAL); //connection to wifi must be activated from code, the code itself is activated before connection

/*
* retruns the counts of a given ADC (ADC1 and AD2, ADC3 wans't working)
* takes approx. 1.2 µs
*/
uint16_t readADCx(ADC_TypeDef* ADCx){
  ADC_SoftwareStartConv(ADC2); // ca. 150 ns
  // Wait until conversion completion
  while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET); // ca. 800 ns
  pinSetFast(D0);
  //ADC_ClearFlag(ADC1, ADC_FLAG_EOC); // is not necessarry
  return ADC_GetConversionValue(ADC2); //ca. 100ns
}

/*
* Configurate the given Pin to the given ADC
* takes approx. 4.4 µs but if i measured the parts inside single it was much longer????
*/
void configure_ADC_channel(ADC_TypeDef* ADCx, uint16_t pin){

  STM32_Pin_Info* PIN_MAP = HAL_Pin_Map(); // approx. 780 ns

  HAL_Pin_Mode(pin, AN_INPUT); // approx 3.8 µs
  ADC_RegularChannelConfig(ADCx, PIN_MAP[pin].adc_channel, 1, ADC_SampleTime_3Cycles); //4.4 µs ???

}

void ADCx_Configuration(ADC_TypeDef* ADCx)
{
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_InitTypeDef ADC_InitStructure;

  /* Enable ADC's APB interface clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //if(ADCx==ADC1)
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //if(ADCx==ADC2)
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //if(ADCx==ADC3)
  /* Common configuration (applicable for the three ADCs) *********************/
  /* Single ADC mode */
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  /* ADCCLK = PCLK2/2 */
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  /* Available only for multi ADC mode */
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  /* Delay between 2 sampling phases */
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);
  /* Configure ADCx to convert continously channel14 **************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//old: ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADCx, &ADC_InitStructure);
  /* ADCx regular channel14 configuration */
  ADC_RegularChannelConfig(ADCx, ADC_Channel_14, 1, ADC_SampleTime_3Cycles);
  /* Enable ADCx */
  ADC_Cmd(ADCx, ENABLE);
  /* Start ADCx Software Conversion */
  //ADC_SoftwareStartConv(ADCx); //not here!, otherwise it was blocking sometimes...
}

void setup(){
  WiFi.off();
  Serial1.begin(115200); //Serial Comunication at  RX-TX pins
  analogRead(A0); //Dummi analogRead to configure pins in HAL well
  pinMode(D0, OUTPUT); //dummi pin-definition otherwise wrong ADC-Value (I don't know why)

  //DONT USE analogRead()!!!!!!!! IT WILL CHANGE PIN AND HARDWARE

  ADCx_Configuration(ADC2); // inilize the ADC in HAL
  configure_ADC_channel(ADC2,A3); //Connect PIN A3 to ADC2, takes 4.4 µs
}

uint32_t var=0;
void loop(){
  pinSetFast(D0);
  var=readADCx(ADC2); //ca. 1.2 µs
  pinReSetFast(D0);
  Serial1.println(var);
}


The red curve showes the voltage on pin 0. (the functions PinSetFast() and PinResetFast() take approx. 50 ns)

2 Likes