Better way with ESP32 of Analog-Read on core0.

zekageri
Posts: 43
Joined: Mon Sep 03, 2018 11:04 am

Better way with ESP32 of Analog-Read on core0.

Postby zekageri » Fri Aug 16, 2019 8:55 am

Hello guys!
I have a complicated question.
The thing:

Right now i measure on ADC1 on core0 with the stanrad analogRead() func.
The esp capable running my adc read with 8Khz to read and measure a 4 - 4,4Khz signal from a signal generator.
The way i do it is pretty easy. Iam running a task on the core 0.


The issue:

Sometimes i get completelly different signal width on every single wave, sometimes strange gaps in the signals.Maybe because of the delay between measurements.(The signals are even on an oscilloscope).

The question:

Does anybody know a better way to measure at 8Khz?

I'am visualizing it on a webserver with async web and websockets to a canvas by Chart.js.
Sorry if i forget something.

This is a minimal working sketch in PlatformIO.

Code: Select all

#include <Arduino.h>

TaskHandle_t TaskHandle_2; // CREATE TASK TANDLE

/* ADC SETTINGS AND THE MEASURE FUNCTION */
#define CHANNEL 34                         // ADC1 BECAUSE OF THE WIFI
uint16_t offset = 1757;                     //middle DC level reading
uint16_t vReal[200];                         // BUFFER TO READ
double samplingFrequency = 80000;  // IN HZ
unsigned long microseconds;
unsigned int sampling_period_us = round(1000000*(1.0/samplingFrequency));
uint16_t samples = 200;                     //READ SAMPLES

static const inline void ADC_Meres() {
  if (olvasunk_e == true) {                 // ADC MEASURE TURN ON FLAG
    microseconds = micros();              // LET'S SEE WHERE ARE WE
    uint32_t volatile register ilevel = XTOS_DISABLE_ALL_INTERRUPTS; // SAVE THE INTERRUPTS TO A VOLATILE AND TURN ALL OF IT OFF
    for (int i = 0; i < samples; i++) {   // BEGIN THE SAMPLING WITH 8KHZ
      vReal[i] = analogRead(CHANNEL); // READ THE SIGNAL ON I/O-34
      while (micros() - microseconds < sampling_period_us) {} // WAIT THE DESIRED MICROS
      microseconds += sampling_period_us;
    }
    XTOS_RESTORE_INTLEVEL(ilevel); // RETURN INTERRUPT LEVEL
  }
}

void setup(){
Serial.begin(115200);
xTaskCreatePinnedToCore ( loop0, "v_getIMU0", 30000, NULL, 10, &TaskHandle_2, 0 );
}

static void loop0(void * pvParameters){
  for( ;; ){
    vTaskDelay(1);	  // REQUIRED TO RESET THE WATCH DOG TIMER
    ADC_Meres();          // 8Khz ANALOG READ
  }
}

void loop(){
}
Attachments
Képernyőfelvétel (8).png
Képernyőfelvétel (8).png (89.28 KiB) Viewed 8685 times
Képernyőfelvétel (7).png
Képernyőfelvétel (7).png (91.52 KiB) Viewed 8685 times
Képernyőfelvétel (6).png
Képernyőfelvétel (6).png (91.72 KiB) Viewed 8685 times

mikemoy
Posts: 626
Joined: Fri Jan 12, 2018 9:10 pm

Re: Better way with ESP32 of Analog-Read on core0.

Postby mikemoy » Fri Aug 16, 2019 1:14 pm

My first thought is to first use core1. Core0 is called the PRO_CPU, and core 1 is called the APP_CPU.
All the internal running of things Wi-Fi and so on is done on the PRO_CPU.
So i would first use a freed up core to heavy lifting of things.

My second thought was (if I am correct) using XTOS_DISABLE_ALL_INTERRUPTS, disables all IRQ's, So the PRO_CPU core housekeeping IRQ's are also stopped. When re-enabled it will service them and it might cause you to have inconsistent measuring times.

In ESP-IDF, through menuconfig you can disable the watchdog timer on either core so you can do intensive tasks like this.
You could disable the watchdog on core1, so get rid of disabling IRQ's. To my knowledge (which is limited on Arduino, you do not have access to menuconfig, so I do not know how your would do this).

My 3'rd thought would be to set up a timer, that would fire at a specified rate. because right now your at the mercy of the OS servicing your task when it can, which will not be consistent.

Since your using arduino-esp32, whereas I only use ESP-IDF. So I will let others more knowledgeable in this realm to comment.

Brain Scientist
Posts: 4
Joined: Thu Aug 15, 2019 10:15 pm

Re: Better way with ESP32 of Analog-Read on core0.

Postby Brain Scientist » Fri Aug 16, 2019 1:39 pm

Don't forget an outboard low pass filter at about 4 KHz for antialiasing. You are actually working below the Nyquist sample frequency, so a sharp filter would be appropriate.

zekageri
Posts: 43
Joined: Mon Sep 03, 2018 11:04 am

Re: Better way with ESP32 of Analog-Read on core0.

Postby zekageri » Fri Aug 16, 2019 3:13 pm

My core 1 is also use so many things, i wanted to separate the ADC read from all of my codes and that is the reason i created the task on core 0. I can also disable the WDT on core 0, and it is disabled. On core 1 i can not disable it, it trohws me an error of some sort.

The second is that if i have the interrupts enabled during the measure, i get even stranger samples because the wifi, and ofc of my code. I got so many interrupts, i can't let it enabled during the measure. :( And if i running the measure on core1 along with all of my other codes the measured datas are all the same. ( At least the data that i can see because the maximum plotting speed to the web is like one sec)
I wanted to ping-pong two task in the core0 for measure. My idea was that i create a task at the boot, and when that task is ended it is created an other task and destroyed itself and on the second task there was the same measure and then that task is created the first task again etc..etc..etc.. But that was not worked out very well.

oh and about the timer interrupts. These things can not work in such speeds. I tried the adc measure function with a timer interrupt. But the fastest timer interrupt i can get is like what? 80hz? that is very very very low for my 8kHz needs.

mikemoy
Posts: 626
Joined: Fri Jan 12, 2018 9:10 pm

Re: Better way with ESP32 of Analog-Read on core0.

Postby mikemoy » Fri Aug 16, 2019 3:37 pm

Gotcha, didn't know there was way more code you were doing.
These things can not work in such speeds. I tried the adc measure function with a timer interrupt. But the fastest timer interrupt i can get is like what? 80hz? that is very very very low for my 8kHz needs.
That is strange. Must be an arduino thing. using ESP-IDF I have a timer running at every 1us.

Who is online

Users browsing this forum: No registered users and 92 guests