Hi,
I would like to use the AtomS3U to behave as a wireless real-time audio broadcaster. I have seen that the ESP-32S3 is capable of doing this with an IMP441 using a node server (see here), but haven't had success using the AtomS3U's onboard PDM.
I've attached my code, which is mostly a modified version of the program written by ThatProject in the linked YouTube video. I've also incorporated some code from the PDM unit Arduino example by M5Stack (see here).
So far, I am able to run the server and establish connection to the AtomS3U, however, when I try and stream the audio, I either get static noise, or nothing at all.
#include <driver/i2s.h>
#include <WiFi.h>
#include <ArduinoWebsockets.h>
#define I2S_SD 38
#define I2S_SCK 39
#define I2S_PORT I2S_NUM_0
#define bufferCnt 2
#define bufferLen 128
int16_t sBuffer[bufferLen];
const char* ssid = "spider_gateway";
const char* password = "TMTspider1";
const char* websocket_server_host = "192.168.24.246";
const uint16_t websocket_server_port = 8888; // <WEBSOCKET_SERVER_PORT>
using namespace websockets;
WebsocketsClient client;
bool isWebSocketConnected;
void onEventsCallback(WebsocketsEvent event, String data) {
if (event == WebsocketsEvent::ConnectionOpened) {
Serial.println("Connnection Opened");
isWebSocketConnected = true;
} else if (event == WebsocketsEvent::ConnectionClosed) {
Serial.println("Connnection Closed");
isWebSocketConnected = false;
} else if (event == WebsocketsEvent::GotPing) {
Serial.println("Got a Ping!");
} else if (event == WebsocketsEvent::GotPong) {
Serial.println("Got a Pong!");
}
}
void i2s_install() {
// Set up I2S Processor configuration
const i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // is fixed at 12bit, stereo, MSB
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = bufferCnt,
.dma_buf_len = bufferLen,
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
}
void i2s_setpin() {
// Set I2S pin configuration
const i2s_pin_config_t pin_config = {
.bck_io_num = I2S_PIN_NO_CHANGE,
.ws_io_num = I2S_SCK,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_SD,
};
i2s_set_pin(I2S_PORT, &pin_config);
//Serial.println("Init i2s_set_clk");
i2s_set_clk(I2S_PORT, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
}
void setup() {
Serial.begin(115200);
connectWiFi();
connectWSServer();
xTaskCreatePinnedToCore(micTask, "micTask", 10000, NULL, 1, NULL, 1);
}
void loop() {
}
void connectWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
void connectWSServer() {
client.onEvent(onEventsCallback);
while (!client.connect(websocket_server_host, websocket_server_port, "/")) {
delay(500);
Serial.print(".");
}
Serial.println("Websocket Connected!");
}
void micTask(void* parameter) {
i2s_install();
i2s_setpin();
i2s_start(I2S_PORT);
size_t bytesIn = 0;
while (1) {
esp_err_t result = i2s_read(I2S_PORT, &sBuffer, bufferLen, &bytesIn, portMAX_DELAY);
if (result == ESP_OK && isWebSocketConnected) {
client.sendBinary((const char*)sBuffer, bytesIn);
}
}
}
Thanks in advance for any tips.