espressif / arduino-esp32

Arduino core for the ESP32

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

analoRead very slow - what is the fastest way to read analog value?

laurentopia opened this issue · comments

A task runs this code and it cannot sample very fast, I think it's limited by the RTOS @ 1000 tick/s
What's the very fastest to read analog values, that doesn't block (something with interrupts?)
Thank you.

void Capture()
{
	//capturee
	for (int i = 0; i < SAMPLES; i++)
	{
		newTime = micros() - oldTime;
		oldTime = newTime;
		vSample[i] = analogRead(35); // A conversion takes about 1uS on an ESP32
		//vSample[i] = adc1_get_raw(ADC1_CHANNEL_7);
		vTaskDelay(sampling_period_ms / portTICK_PERIOD_MS);
	}
}

analogRead does multiple samples and uses a default sample width. Look at https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-adc.h to see how to set the configuration for analogRead. You can also use the esp-idf functions to save a couple ticks per read. http://esp-idf.readthedocs.io/en/latest/api-reference/peripherals/adc.html

Thanks, I didn't know arduino lib was doing supersampling by default. I did use the esp adc commands but they were slower.

Quite the difference between 8 and 128 samples, is supersampling the equivalent to smoothing out high frequencies?

2144ba9a-5d6d-45ee-9b09-db5c20f7af89

477d9c00-384b-4e71-85d5-10d0b77393d8

Well, there is no guarantee when it will take the samples, so it will generally give you an average, but it is not by any means going to be exact on a wave. ADC is not intended for precision wavelength work. You may be looking for pcnt or i2s?

The wave on the image is a test square wave but the signal I'm looking at is sine composit such as sound EMF and such so i2s and pcnt which measure rise and drops (I think) are not suitable.
That said, an off shoot project that requires multiple microphones could use mems with digital out, i2s would work, I don't know where to start, tbh.

That is going beyond the scope of a bug report. Please close the issue and take discussion to gitter.

For anyone else who is looking and doesn't want to suffer with the performance issues, check out rtc_module.c. You can do stuff instead of just spin-waiting for it to do its thing.

        while (SENS.sar_slave_addr1.meas_status != 0);

and

        while (SENS.sar_meas_start1.meas1_done_sar == 0);

@laurentopia As complete side note, I would think that detecting consecutive rising edges/falling edges on interrupts would be a more accurate way of counting the frequency. However it means that we need two signals from the original signal.

One to calculate frequency and one which talks about the amplitude.The hard part is getting those signals. That way we with frequency information we may be able to dynamically reconfigure the sampling delay to satisfy Nyquist Criteria. This is just a thought however and needs extensive practical testing.