The AtomS3R and Atomic Audio Base will work using the RecordPlay example in https://github.com/m5stack/M5Atomic-EchoBase/tree/main/example . Whenever I try to include both M5Unified.h and M5EchoBase in the same sketch I get the i2s conflict between new and legacy i2s drivers . I cant get any sound however when using just the M5Unified.h library. Below is my latest code. Still no sound?
#include "M5Unified.h"
#include <Wire.h>
// Define buffer size (200KB for ESP32-S3)
#define RECORD_SIZE (1024 * 200)
static uint8_t *buffer = nullptr;
void initES8311() {
// AtomS3R I2C pins for the Audio Base are SDA=38, SCL=39
Wire.begin(38, 39);
// Helper to write to ES8311 registers
auto writeReg = [](uint8_t reg, uint8_t val) {
Wire.beginTransmission(0x18); // Default ES8311 I2C address
Wire.write(reg);
Wire.write(val);
Wire.endTransmission();
};
// --- ES8311 Initialization Sequence ---
writeReg(0x00, 0x00); // Reset
writeReg(0x01, 0x3F); // Power down all
writeReg(0x0D, 0x01); // Clock on
writeReg(0x01, 0x03); // Power up
writeReg(0x02, 0x00); // Master clock
writeReg(0x05, 0x00); // DAC power
writeReg(0x04, 0x00); // ADC power
writeReg(0x14, 0x24); // Set MIC gain
writeReg(0x46, 0xFF); // Set Speaker Volume to Max
writeReg(0x06, 0x00); // ADC Mute Off
writeReg(0x09, 0x00); // Set ADC to I2S format
Serial.println("ES8311 Codec Initialized!");
}
void setup() {
Serial.begin(115200);
auto cfg = M5.config();
// Enable external I2C for ES8311 codec on the audio base
cfg.external_imu = false;
M5.begin(cfg);
initES8311();
M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
// --------------------------
// Speaker Configuration (I2S Output)
// AtomS3R I2S pins: BCK=8, WS=6, DOUT=5
// --------------------------
auto spk_cfg = M5.Speaker.config();
spk_cfg.pin_data_out = 5;
spk_cfg.pin_bck = 8;
spk_cfg.pin_ws = 6;
spk_cfg.sample_rate = 44100;
// spk_cfg.i2s_port = I2S_NUM_0;
spk_cfg.stereo = false; // Use mono for the base speaker
M5.Speaker.config(spk_cfg);
M5.Speaker.begin();
// --------------------------
// Microphone Configuration (I2S Input)
// AtomS3R I2S pins: BCK=8, WS=6, DIN=7
// --------------------------
auto mic_cfg = M5.Mic.config();
mic_cfg.pin_data_in = 7;
mic_cfg.pin_bck = 8;
mic_cfg.pin_ws = 6;
mic_cfg.sample_rate = 44100;
// mic_cfg.i2s_port = I2S_NUM_0; // Use separate I2S port for input
mic_cfg.magnification = 2;
M5.Mic.config(mic_cfg);
M5.Mic.begin();
// Set volume/gain
M5.Speaker.setVolume(100);
// For v0.2.14, set mic gain via config if needed (default works for most cases)
mic_cfg.magnification = 2;
// Allocate recording buffer
buffer = (uint8_t *)malloc(RECORD_SIZE);
if (buffer == nullptr) {
Serial.println("Memory allocation failed!");
while (true) delay(1000);
}
Serial.println("Device ready! Press button to record/play");
M5.Display.println("Click to\nRecord & Play");
}
void loop() {
M5.update();
if (M5.BtnA.wasClicked()) {
M5.Display.fillScreen(BLACK);
M5.Display.setCursor(0, 0);
// --------------------------
// Recording
// --------------------------
M5.Display.println("Recording...");
Serial.println("Start recording");
M5.Mic.record(buffer, RECORD_SIZE, 44100);
delay(500);
Serial.println(M5.Mic.isRecording());
delay(3000);
// while (M5.Mic.isRecording()==1) delay(10);
// --------------------------
// Playback
// --------------------------
M5.Display.println("Playing...");
Serial.println("Start playing");
M5.Speaker.playRaw(buffer, RECORD_SIZE, 44100, false, 1);
Serial.println(M5.Speaker.isRunning());
while (M5.Speaker.isPlaying()) delay(10);
M5.Display.println("Done");
Serial.println("Done");
}
}