[ESP32WROOM32] How to estimate the execution time of ADC reading when running the control?

Hi guys!!

I’m projecting a velocity control for a bldc motor using SimpleFOC. My setup is:

  • driver: MKS ESP32 FOC V1.0
    • The board has current sensor: INA1818A
    • I’m using the Simple FOC 2.3.5
  • motor: Gimbal Motor 4108H 120T (Iflight)
  • encoder: AS5600A (I’m using I2C)

While I was executing some experiments with Inline Current Sense, I noticed that the current readings from the INA1818A is very noisy. I was expecting to be noisy becausse of the 1% gain error as despicted in the techinical specifications of the driver and the INA1818A datasheet. But I wasn’t expecting to be so higher when I was reading the phase currents haha. From what I discover, besides the sensor’s error, the ESP32’s ADC is not very good too.

Because of that, I’m projecting a low pass filter to remove the unwanted noisy, taking some care to not cause aliasing (or to minimize the aliasing). I’m using the sample time of the filter as the sample time of the moment that happens the current ADC reading. But I am not sure how much is this sample time (ou how much is estimate to be).

I need to be very strict about some choices I’m making because I’ll need to justify it in my graduation’s final work. So I have a lit bit difficulties finding some information like

  • how can i estimate the execution time of ESP32 ADC reading?
    • I read in some topic in this forum that the SimpleFOC implement a driver that can make the execution time to be around 10us. How can I garantee that it is true when I running only the reading of the ADC port?
  • how can i estimate the execution time of ESP32 ADC reading when executing control modes?
    • I’m projecting the filter to reduce the noisy using the execution frequency of ESP32 ADC reading as my sample frequency. But this frequency can vary when I execute more tasks and can vary from control mode to control mode

I tried to measure this using Serial.println but this function adds delay to the execution time measurements, so I’m having a headache to estimate how much I use for the sample time in my filter project. I don’t have previous experience projecting digital filters so maybe I’m overthinking too much.

To add more context, I pretend to put this filter in my code, when the ADC readings are made to Inline Current Sense. To be more specific, I’ll customize the _readADCVoltageInline (link to the specif file in github here ) to include the filter.

I know very little about ESP32, but you should be able to call _micros() before and after the read to measure how long it takes (or 100 or 1000 reads for better precision).

You can also do like while((int32_t)_micros() - lastUpdateTime < timePerUpdate){} to limit the loop rate. It’s pointless to run faster than the PWM frequency since changes to the output won’t show up until the next cycle anyway. The default is usually 25KHz, so 40 micros per update. And for a low speed gimbal motor, slower update rate is fine too.

I tried using a capacitor (100nF and other values) to lowpass filter my ACS711 current sensors, but it was more problematic than helpful. The frequency of the noise was reduced, but the amplitude of it was not. It works much better to take multiple samples of the unfiltered output and average them.

See if you can set it up to read continuously into a circular buffer, and customize _readADCVoltageInline to average all the results in the buffer. Then try playing with the buffer size to use a “running average” of more than one frame’s worth of samples for even more accuracy. At some point the time delay of including older samples will become problematic, but that’s more of a concern for high speed motors.

Just to clarify — are you asking about the ADC conversion time of the ESP32 (the hardware time it takes to acquire and convert a sample), or about the sampling interval in your code (how often your loop or driver actually performs ADC reads)? What you need for running the filter is probably the latter, right?

Hi @nanaEuah , you‘re asking som good questions…

ADC reading consists of different parts:

  • The sample time that’s the time in which the signal is actually sampled
  • The conversion time that’s the time the hardware takes to acquire the sampled signal into its digital representation as a binary value
  • The code running to read the values from the ADC and process them

The sample and conversion times are usually very fast, but it may take your code longer to get and calculate with the value.

sampling within 10 µs will be no problem but writing a loop that works with that value at 100 kHz will be much more of a challenge.

One trick to measure your execution times without influencing them by printing can be to use a pin which you toggle instead of printing. Then you can use an external tool like an oscilloscope or logic analyzer to monitor the pin and get your timing information.