Page 1 of 1

Continuous ADC reading with bare esp32-wroom-32 and sending the results to web. PROBLEM

Posted: Thu Sep 12, 2019 1:27 pm
by zekageri
Hello guys!

I want to measure a 4kHZ frequency with my bare ESP32 chip with it's internal ADC and then send the results to it's web server for chartJS.
Everything is working properly, except the continuous part.

My basic idea for the ADC was that:
- Create a task on the 0th core for the adc reading function.
- Measure the 4khz external signal ( from a signal generator for now ) at 8khz in a loop in that task with disabled interrupts on core 0.
- Create a fast function ( on core 1 ) for reading the measured data at some interval ( like 0.5 sec or it doesn't matter ) from the adc
buffer for further working.
- Create a normal function ( on core 1 ) to send the data to web ChartJS for visualization at modifiable intervals ( 1 to 10 sec, depends
on the user settings).

The idea in my code:

Code: Select all

#define CHANNEL 34
//uint16_t offset = 1757;                //middle DC level reading (unused)
uint16_t vReal[200];
double samplingFrequency = 80000;
unsigned long microseconds;
unsigned int sampling_period_us = round(1000000*(1.0/samplingFrequency));
uint16_t samples = 100;


long getfastdatamillis;
uint16_t vRealBuff[100]; 
boolean FastGetData = false;
int Frissit  = 10000;    // Refresh rate of the send data function


static const inline void ADC_Meres() {
  if (olvasunk_e == true) {                                                                          // User can turn on/off the read on the web
    microseconds = micros();                                                                      // Starting micros for the sampling period
    uint32_t volatile register ilevel = XTOS_DISABLE_ALL_INTERRUPTS;        // Disable everything that can interrupt the measurement
    for (int i = 0; i < samples; i++) {                                                            // Start Sampling
      vReal[i] = analogRead(CHANNEL);                                                       // Read analog to buffer
      while (micros() - microseconds < sampling_period_us) {}                     // Wait for sampling period us for 8Khz
      microseconds += sampling_period_us;
    XTOS_RESTORE_INTLEVEL(ilevel);                                                         // Restore Interrupts

/* Fast get data from the vReal buffer for data processing */

void IRAM_ATTR Fast_Get_Data(){
  FastGetData = false;
  int hanyadik = 0;
  int nulla = 0;
  portENTER_CRITICAL_ISR(&timerMux);                // Critical section for fast reading from buffer to buffer
  olvasunk_e = false;                                             // Turn off actual ADC measure function for read the current datas
  for(int i = 0;i < adatszelessegint;i++){                  // Start filling the process buffer (vRealBuff) while cheking it with user adjustable 
      u16_t Szuro = vReal[i];                                    // minimum data. ( default is 0 )
      if(Szuro >= MinErtek){
       for(hanyadik;hanyadik < 200;hanyadik++){
         vRealBuff[nulla] = vReal[hanyadik];
    olvasunk_e = true;
    FastGetData = true;

/* Sending the data to the web with webSocket for fast sending in "json" form. */

static inline void Send_Data(){
  if(FastGetData == true){
    for (int i = 0; i < adatszelessegint; i++) {
      String json = "";
      json += String(vRealBuff[i] / (float)40.95);
      json += "}";
      if(Nemkell == false){
      webSocket.broadcastTXT(json.c_str(), json.length());
    FastGetData = false;

void setup(){
/* Create a task on core0 for the adc read function. */
xTaskCreatePinnedToCore ( loop0, "v_getIMU0", 30000, NULL, 10, &TaskHandle_2, 0 );
/* Starting millis for the fast get data */
getfastdatamillis = millis();

/*  loop0 task on core0 for the ADC read function. */

static void loop0(void * pvParameters){
  for( ;; ){
    vTaskDelay(1);        // REQUIRED TO RESET THE WATCH DOG TIMER
    ADC_Meres();          // 8Khz ANALOG READ
    if(millis() - getfastdatamillis >= Frissit){
    getfastdatamillis = millis();

void loop(){
currentMillis = millis();
  if (currentMillis - getNullMag >= Frissit)
    getNullMag = currentMillis;
The problem:
Like this the measure function is measuring 100 datas at once and wait delay(1) and god knows how many milisec while it is turning back into the measure function again to measure that 100 data again. The problem is that is not async and not continous. The program can not do anything else during the measure and if it is done , it has to wait because of the watchdog timer and other task that runs on the core0 background. I attached a some pictures how the data looks on the web like this. It is fine, just not continous.

Re: Continuous ADC reading with bare esp32-wroom-32 and sending the results to web. PROBLEM

Posted: Fri Sep 13, 2019 6:36 am
by zekageri
I tried some async logic from the adc.h lib, but with that, i have to continously check the adc buffer if it is ended or not.
That is not async at all. Maybe if there was an interrupt if an adc is ended that would be good.
If i going like this:

Code: Select all

void setup(){

void loop(){
 uint16_t a0 = adcEnd(35);
That is way too slow for my purpose.
It is not async as Me_No_Dev says it is.
I have to check the adcend() for datas in my loop, and i have several tasks to do in here.
Is there any ADC register changed interrupt or something?