Since I am not at all familiar with esp32 and adruino.
I tried chatp gpt, gemini and cloud to get something working.
That was at least something that could be compiled but unfortunately it didn’t work.
/*--------------------------------------------------------------------------------------------------
Introduction
This program is intended to be used with the ESP32 Muse speaker, a portable and affordable bluetooth speaker that is fully programmable.
ESP32 Muse is a commercial product that can be purchase here: https://raspiaudio.com/espmuse
Features
ESP32 offers: line Input, RGB leds
This is a simplified version including only AUX in and LED functions.
--------------------------------------------------------------------------------------------------*/
#include "Audio.h"
// Standard ESP-IDF driver includes for I2C and GPIO
extern "C"
{
#include "driver/i2c.h"
#include "driver/gpio.h"
}
#include "Arduino.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <NeoPixelBus.h>
#define muse 1
////////////////////////////////
// Pin Definitions
///////////////////////////////
#define SDA 18
#define SCL 23
//Contacts
#define PA GPIO_NUM_21 // Amp power ON
#ifdef muse
#define AUXD GPIO_NUM_27 // AUX In detect 27
#else
#define AUXD GPIO_NUM_12
#endif
////////////////////////////////
// I2C Configuration for ES8388 Codec
//////////////////////////////
#define I2C_MASTER_NUM I2C_NUM_0
#define I2C_MASTER_FREQ_HZ 400000
#define I2C_MASTER_TIMEOUT_MS 1000
// Define I2C read/write bits for device address byte (used in hal_i2c_master_mem_write/read)
#define I2C_MASTER_WRITE_BIT I2C_MASTER_WRITE // for writing to slave
#define I2C_MASTER_READ_BIT I2C_MASTER_READ // for reading from slave
// Custom implementations of hal_i2c_master_* functions using ESP-IDF I2C driver API
esp_err_t hal_i2c_master_init(i2c_port_t i2c_num, int sda_io, int scl_io) {
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = sda_io;
conf.scl_io_num = scl_io;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
conf.clk_flags = 0; // default clk_flags is 0
esp_err_t ret = i2c_param_config(i2c_num, &conf);
if (ret != ESP_OK) return ret;
return i2c_driver_install(i2c_num, conf.mode, 0, 0, 0);
}
esp_err_t hal_i2c_master_mem_write(i2c_port_t i2c_num, uint8_t device_address,
uint8_t reg_addr, uint8_t *data, size_t data_len) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_address << 1) | I2C_MASTER_WRITE_BIT, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_write(cmd, data, data_len, true);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
esp_err_t hal_i2c_master_mem_read(i2c_port_t i2c_num, uint8_t device_address,
uint8_t reg_addr, uint8_t *data, size_t data_len) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_address << 1) | I2C_MASTER_WRITE_BIT, true);
i2c_master_write_byte(cmd, reg_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_address << 1) | I2C_MASTER_READ_BIT, true);
i2c_master_read(cmd, data, data_len, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
//////////////////////////////
// NeoPixel led control
/////////////////////////////
#define PixelCount 1
#define PixelPin 22
RgbColor RED(255, 0, 0);
RgbColor GREEN(0, 255, 0);
RgbColor BLUE(0, 0, 255);
RgbColor YELLOW(255, 128, 0);
RgbColor WHITE(255, 255, 255);
RgbColor BLACK(0, 0, 0);
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
//////////////////////////////////////////////////////////////
// init audio library
//////////////////////////////////////////////////////////////
Audio audio;
#define I2SN (i2s_port_t)0 // Still defined, but not directly used in this simplified I2S-less version
#define maxMode 3
#define btM 0
#define sdM 1
#define auxM 2
#define maxVol 50
uint8_t vauxd;
int vol, oldVol;
bool auxON = false;
bool beepON = false;
uint32_t sampleRate;
int mode = btM; // Declare mode globally and initialize
#define ES8388_ADDR 0x10
///////////////////////////////////////////////////////////////////////
// Write ES8388 register (using I2c)
///////////////////////////////////////////////////////////////////////
void ES8388_Write_Reg(uint8_t reg, uint8_t val)
{
uint8_t buf[2];
buf[0] = reg;
buf[1] = val;
hal_i2c_master_mem_write(I2C_MASTER_NUM, ES8388_ADDR, buf[0], buf + 1, 1);
}
////////////////////////////////////////////////////////////////////////
// Read ES8388 register (using I2c)
////////////////////////////////////////////////////////////////////////
uint8_t ES8388_Read_Reg( uint8_t reg_add)
{
uint8_t val;
hal_i2c_master_mem_read(I2C_MASTER_NUM, ES8388_ADDR, reg_add, &val, 1);
return val;
}
////////////////////////////////////////////////////////////////////////
//
// manages volume (via vol xOUT1, vol DAC, and vol xIN2)
//
////////////////////////////////////////////////////////////////////////
void ES8388vol_Set(uint8_t volx)
{
#define M maxVol - 33
printf("volume ==> %d\n", volx);
ES8388_Write_Reg(25, 0x00);
if (volx > maxVol) volx = maxVol;
if (volx == 0)
{
ES8388_Write_Reg(25, 0x04);
if (mode == auxM)
{
ES8388_Write_Reg(39, 0x80);
ES8388_Write_Reg(42, 0x80);
}
}
if (volx >= M)
{
ES8388_Write_Reg(46, volx - M);
ES8388_Write_Reg(47, volx - M);
ES8388_Write_Reg(26, 0x00);
ES8388_Write_Reg(27, 0x00);
if (mode == auxM)
{
uint8_t v = ((7 - (volx - M - 3) / 4) << 2) | 0xC0;
ES8388_Write_Reg(39, v);
ES8388_Write_Reg(42, v);
}
}
else
{
ES8388_Write_Reg(46, 0x00);
ES8388_Write_Reg(47, 0x00);
ES8388_Write_Reg(26, (M - volx) * 3);
ES8388_Write_Reg(27, (M - volx) * 3);
}
}
//////////////////////////////////////////////////////////////////
//
// init CCODEC chip ES8388 (via I2C)
////////////////////////////////////////////////////////////////////
void ES8388_Init(void)
{
// provides MCLK
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
WRITE_PERI_REG(PIN_CTRL, READ_PERI_REG(PIN_CTRL) & 0xFFFFFFF0);
// reset
ES8388_Write_Reg(0, 0x80);
ES8388_Write_Reg(0, 0x00);
// mute
ES8388_Write_Reg(25, 0x04);
ES8388_Write_Reg(1, 0x50); //powerup
ES8388_Write_Reg(2, 0x00);
// slave mode
ES8388_Write_Reg(8, 0x00);
// DAC powerdown
ES8388_Write_Reg(4, 0xC0);
// vmidsel/500k ADC/DAC idem
ES8388_Write_Reg(0, 0x12);
ES8388_Write_Reg(1, 0x00);
// i2s 16 bits
ES8388_Write_Reg(23, 0x18);
// sample freq 256
ES8388_Write_Reg(24, 0x02);
// LIN2/RIN2 for mixer
ES8388_Write_Reg(38, 0x09);
// left DAC to left mixer
ES8388_Write_Reg(39, 0x90);
// right DAC to right mixer
ES8388_Write_Reg(42, 0x90);
// DACLRC ADCLRC idem
ES8388_Write_Reg(43, 0x80);
ES8388_Write_Reg(45, 0x00);
// DAC volume max
ES8388_Write_Reg(27, 0x00);
ES8388_Write_Reg(26, 0x00);
ES8388_Write_Reg(2 , 0xF0);
ES8388_Write_Reg(2 , 0x00);
ES8388_Write_Reg(29, 0x1C); // DAC power-up LOUT1/ROUT1 enabled
ES8388_Write_Reg(4, 0x30);
// unmute
ES8388_Write_Reg(25, 0x00);
// amp validation
gpio_set_level(PA, 1);
}
////////////////////////////////////////////////////////////////////
// annonce tiny messages (2-3 sec) (mode name)
////////////////////////////////////////////////////////////////////
void modeCall(void)
{
#define volMode 50
char*n[] = {"/bluetooth.wav", "/player.wav", "/jack.wav"};
ES8388vol_Set(volMode);
printf("%d ====> %s\n", mode, n[mode]);
// Removed playWav calls as they require SPIFFS and WAV files which are not part of AUX/LED
beepON = false;
ES8388vol_Set(vol);
// i2s_set_clk is commented out or missing definition in simplified version
// If it's necessary for operation, consider how to include it or its equivalent
// i2s_set_clk(I2SN, sampleRate, (i2s_bits_per_sample_t)16, (i2s_channel_t)2);
}
///////////////////////////////////////////////////////////////////
//
// task managing analog input via AUXIn jack
//
///////////////////////////////////////////////////////////////////
static void aux (void* data)
{
delay(500);
ES8388_Write_Reg(39, 0xC0);
ES8388_Write_Reg(42, 0xC0);
ES8388vol_Set(45);
while (1) {
delay(100);
if (mode != auxM) {
ES8388_Write_Reg(39, 0x90);
ES8388_Write_Reg(42, 0x90);
auxON = 0;
vTaskDelete(NULL);
}
// Check for AUX cable connection (example, requires GPIO setup for AUXD)
vauxd = gpio_get_level(AUXD);
if ((vauxd == 0) && (auxON == false)) {
auxON = true;
mode = auxM;
modeCall();
}
if ((vauxd == 1) && (auxON == true)) {
auxON = false;
mode = btM; // Default to BT mode if AUX is disconnected
modeCall();
}
}
}
void setup() {
Serial.begin(115999);
Serial.println("ESP32 Muse Speaker - AUX and LED only version");
// Init LEDs
strip.Begin();
strip.Show(); // Initialize all pixels to 'off'
// Initialize I2C for ES8388 codec
hal_i2c_master_init(I2C_MASTER_NUM, SDA, SCL);
ES8388_Init(); // Initialize the audio codec
// Set initial volume
vol = 30; // Default volume
ES8388vol_Set(vol);
// Configure AUX detection pin
gpio_set_direction(AUXD, GPIO_MODE_INPUT);
// Start AUX task
xTaskCreatePinnedToCore(aux, "aux", 40000, NULL, 10, NULL, 1);
// Initial LED color
strip.SetPixelColor(0, BLUE);
strip.Show();
}
void loop() {
// Example: Change LED color based on mode
if (mode == auxM) {
strip.SetPixelColor(0, GREEN); // Green for AUX mode
} else {
strip.SetPixelColor(0, BLACK); // Off when not in AUX mode
}
strip.Show();
// Basic volume control (example, needs physical buttons to be implemented)
// For simplicity, this example doesn't include button handling
// You would read button states here and adjust 'vol' then call ES8388vol_Set(vol);
delay(500); // Small delay
}