ESP32S3 Oscilloscope code....anything out there that's not old?

I'm trying to find a recent project with code for a simple ESP32S3 oscilloscope. Every example I find has code that will not run using Arduino IDE 2.3.4. Even code from 2022 won't compile right. Like this project's code:

https://circuitdigest.com/microcontroller-projects/diy-esp32-oscilloscope#comment-36373

Compilation error: 'i2s_adc_enable' was not declared in this scope

This is highly frustrating for this noob. Anyone?

Post your code and error code here using code tags.

1 Like

That’s not a code error.
That’s a project configuration error.
You need to understand the error codes, it’s not Lego blocks.

1 Like
#include <Arduino.h>
#include <driver/i2s.h>
#include <driver/adc.h>
#include <soc/syscon_reg.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include "esp_adc_cal.h"
#include "filters.h"

//#define DEBUG_SERIAL
//#define DEBUG_BUFF
#define DELAY 1000

// Width and height of sprite
#define WIDTH  240
#define HEIGHT 280

#define ADC_CHANNEL   ADC1_CHANNEL_5  // GPIO33
#define NUM_SAMPLES   1000            // number of samples
#define I2S_NUM         (0)
#define BUFF_SIZE 50000
#define B_MULT BUFF_SIZE/NUM_SAMPLES
#define BUTTON_Ok        32
#define BUTTON_Plus        15
#define BUTTON_Minus        35
#define BUTTON_Back        34

TFT_eSPI    tft = TFT_eSPI();         // Declare object "tft"

TFT_eSprite spr = TFT_eSprite(&tft);  // Declare Sprite object "spr" with pointer to "tft" object



esp_adc_cal_characteristics_t adc_chars;

TaskHandle_t task_menu;
TaskHandle_t task_adc;

float v_div = 825;
float s_div = 10;
float offset = 0;
float toffset = 0;
uint8_t current_filter = 1;

//options handler
enum Option {
  None,
  Autoscale,
  Vdiv,
  Sdiv,
  Offset,
  TOffset,
  Filter,
  Stop,
  Mode,
  Single,
  Clear,
  Reset,
  Probe,
  UpdateF,
  Cursor1,
  Cursor2
};

int8_t volts_index = 0;

int8_t tscale_index = 0;

uint8_t opt = None;

bool menu = false;
bool info = true;
bool set_value  = false;

float RATE = 1000; //in ksps --> 1000 = 1Msps

bool auto_scale = false;

bool full_pix = true;

bool stop = false;

bool stop_change = false;

uint16_t i2s_buff[BUFF_SIZE];

bool single_trigger = false;
bool data_trigger = false;

bool updating_screen = false;
bool new_data = false;
bool menu_action = false;
uint8_t digital_wave_option = 0; //0-auto | 1-analog | 2-digital data (SERIAL/SPI/I2C/etc)
int btnok,btnpl,btnmn,btnbk;
void IRAM_ATTR btok()
{
  btnok = 1;
}
void IRAM_ATTR btplus()
{
  btnpl = 1;
}
void IRAM_ATTR btminus()
{
  btnmn = 1;
}
void IRAM_ATTR btback()
{
  btnbk = 1;
}
void setup() {
  Serial.begin(115200);

  configure_i2s(1000000);

  setup_screen();

  pinMode(BUTTON_Ok , INPUT);
  pinMode(BUTTON_Plus , INPUT);
  pinMode(BUTTON_Minus , INPUT);
  pinMode(BUTTON_Back , INPUT);
  attachInterrupt(BUTTON_Ok, btok, RISING);
  attachInterrupt(BUTTON_Plus, btplus, RISING);
  attachInterrupt(BUTTON_Minus, btminus, RISING);
  attachInterrupt(BUTTON_Back, btback, RISING);

  characterize_adc();
#ifdef DEBUG_BUF
  debug_buffer();
#endif

  xTaskCreatePinnedToCore(
    core0_task,
    "menu_handle",
    10000,  /* Stack size in words */
    NULL,  /* Task input parameter */
    0,  /* Priority of the task */
    &task_menu,  /* Task handle. */
    0); /* Core where the task should run */

  xTaskCreatePinnedToCore(
    core1_task,
    "adc_handle",
    10000,  /* Stack size in words */
    NULL,  /* Task input parameter */
    3,  /* Priority of the task */
    &task_adc,  /* Task handle. */
    1); /* Core where the task should run */
}


void core0_task( void * pvParameters ) {

  (void) pvParameters;

  for (;;) {
    menu_handler();

    if (new_data || menu_action) {
      new_data = false;
      menu_action = false;

      updating_screen = true;
      update_screen(i2s_buff, RATE);
      updating_screen = false;
      vTaskDelay(pdMS_TO_TICKS(10));
      Serial.println("CORE0");
    }

    vTaskDelay(pdMS_TO_TICKS(10));
  }

}

void core1_task( void * pvParameters ) {

  (void) pvParameters;

  for (;;) {
    if (!single_trigger) {
      while (updating_screen) {
        vTaskDelay(pdMS_TO_TICKS(1));
      }
      if (!stop) {
        if (stop_change) {
          i2s_adc_enable(I2S_NUM_0);
          stop_change = false;
        }
        ADC_Sampling(i2s_buff);
        new_data = true;
      }
      else {
        if (!stop_change) {
          i2s_adc_disable(I2S_NUM_0);
          i2s_zero_dma_buffer(I2S_NUM_0);
          stop_change = true;
        }
      }
      Serial.println("CORE1");
      vTaskDelay(pdMS_TO_TICKS(300));
    }
    else {
      float old_mean = 0;
      while (single_trigger) {
        stop = true;
        ADC_Sampling(i2s_buff);
        float mean = 0;
        float max_v, min_v;
        peak_mean(i2s_buff, BUFF_SIZE, &max_v, &min_v, &mean);

        //signal captured (pp > 0.4V || changing mean > 0.2V) -> DATA ANALYSIS
        if ((old_mean != 0 && fabs(mean - old_mean) > 0.2) || to_voltage(max_v) - to_voltage(min_v) > 0.05) {
          float freq = 0;
          float period = 0;
          uint32_t trigger0 = 0;
          uint32_t trigger1 = 0;

          //if analog mode OR auto mode and wave recognized as analog
          bool digital_data = !false;
          if (digital_wave_option == 1) {
            trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);
          }
          else if (digital_wave_option == 0) {
            digital_data = digital_analog(i2s_buff, max_v, min_v);
            if (!digital_data) {
              trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);
            }
            else {
              trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0);
            }
          }
          else {
            trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0);
          }

          single_trigger = false;
          new_data = true;
          Serial.println("Single GOT");
          //return to normal execution in stop mode
        }

        vTaskDelay(pdMS_TO_TICKS(1));   //time for the other task to start (low priorit)

      }
      vTaskDelay(pdMS_TO_TICKS(300));
    }
  }
}

void loop() {}

…and ?

Is it possible this has something to do with the ESP32 boards manager v3 not working with code written for an earlier version?

https://www.youtube.com/watch?v=JdIHAY7UDOk

bluejets asked that I post the code. I did that.

Surely you have ESP32 core 3.x installed, downgrade to 2.x

https://docs.espressif.com/projects/arduino-esp32/en/latest/migration_guides/2.x_to_3.0.html

General advice: it's often helpful to dive into the header files in the espressif code (or any open source code) to get answers to your questions more quickly.

One thing I notice about the legacy driver: i2s_adc_enable is only defined if SOC_I2S_SUPPORTS_ADC. I see that defined in the capabilities for the ESP32 here. However, no such define is in the capabilities for the esp32s3. Not positive it's related but this is certainly waggling its eyebrows suggestively. What is the value of this define in your module?

Now that is a Video worth a watch, very good.

Suggests that great care is needed with ESP32 these days, the newer version 3 core has changed a great deal.

Lots of comparisons mentioned in the video about functions\features that might have worked just fine under version 2 core but may need 'adjustment' to work under version 3. Clearly great care needed if publishing code for ESP32.

I was trying the TFT_eFEX library, works fine under version 2, but it seems that version 3 core has turned lots of compiler warnings, where the code worked, into errors, so compile fails.

I have tried downgrading the ESP32 core to multiple different earlier versions and that doesn't solve the issue. I continue to get the same error when compiling.

I do appreciate everyone's help.

I'd like to recommend you to look at my comment. The issue I mentioned is core-version independent, since the issue is whether the chip you have supports the feature you're trying to use.

Thanks all. I've reached my limit with regard to finding a solution and I appreciate your input.

Should anyone in the Arduino community decide to build a oscilloscope like the one listed below using current versions of IDE and hardware, please do let me know.

https://circuitdigest.com/microcontroller-projects/diy-esp32-oscilloscope

The code is 3 years old. Have you considered testing it with a ESP32 core from the same era, such as version 2.0.4 or 2.0.5?
The same applies to libraries.

I will give that a try. Thanks.

It's not going to work, because your MCU does not have the required feature.

https://tanakamasayuki.github.io/ESP-IDF-SoC-Check/soc.html#:~:text=SOC_I2S_SUPPORTS_ADC

Don't try it because @jaguilar84 is right, the code doesn't work on S3 regardless of the core version.

@jaguilar84 - whew! Just how loud and often do you have to yell to get people looking for help to listen? I will say "thank you" since the op quit before trying.

Highly unlikely.

I was beginning to wonder if OP had blocked me for some reason. I feel like I provided the answer pretty early on and there was no acknowledgement of it. That's fine, no worries, just an odd interaction.

No blocking of anyone and appreciative of all the suggestions.
I DID try your early on suggestion and it did not solve my issues.

I took a C++ semester long course in 1990.

It’s the hardware core changes that seem to bugger me. I just wanted a simple Arduino-based oscilloscope, found several examples from 2022, and none will compile properly.

So, I’ve moved on.

Thanks again everyone.