First sound
The first build is a scale of seven notes, Do to Si, on the kit's speaker. The sketch drives CTRL HIGH, starts I2S at 16 kHz on GPIO 15, 16 and 17, and works out every sample of every note with a sine, writing each one twice, left and right. Nothing to install: ESP_I2S comes with the ESP32 core.
What you need
- An ESP32-S3 dev board on a USB cable.
- The TK100 and the kit's speaker, plugged into the white socket.
- Six jumper wires.
Wire it
| TK100 | ESP32-S3 |
|---|---|
| GND | GND |
| 3V3 | 3V3 |
| LRCLK | GPIO 16 |
| BCLK | GPIO 15 |
| DIN | GPIO 17 |
| CTRL | GPIO 18 |
CTRL is the wire that gets left off. Without it the sketch runs, prints every note, and the speaker stays silent.
What the sketch sends
playNote() works out each sample as level * sinf(phase) and moves the phase
on by one step per sample, so a higher note takes bigger steps and completes a
cycle in fewer samples. At 440 Hz that is 16000 / 440, about 36 samples a cycle.
Each sample goes into both halves of the frame, frame[0] = frame[1], so the
chip plays it whichever channel its jumper picks. A 400 ms note is 6400 frames.
playNote(0, 100) is the gap: a sine of 0 Hz stays at 0, which is silence.
Three lines that matter
pinMode(PIN_AMP_ON, OUTPUT);
digitalWrite(PIN_AMP_ON, HIGH); // wake the amplifierCTRL, driven HIGH before anything is played. The name is PIN_AMP_ON, not
PIN_CTRL, because the ESP32-S3 core already uses PIN_CTRL for something of
its own, and a sketch that declares it does not compile.
i2s.begin(I2S_MODE_STD, RATE, I2S_DATA_BIT_WIDTH_16BIT,
I2S_SLOT_MODE_STEREO)Standard I2S, 16 kHz, 16-bit, stereo: a bit clock of 512 kHz, 32 ticks per frame, which the NS4168 accepts.
What it prints
Playing
261.63
293.66
329.63and so on to 493.88, a second's pause, and round again, one printed number per note you hear.
The code
Six wires and the speaker. The sketch plays Do, Re, Mi, Fa, Sol, La, Si, 400 ms each with a short gap, then waits a second and starts again, printing each frequency to the Serial Monitor.
// TK100 I2S Amplifier: first sound. A scale of seven notes on the speaker.
//
// Wiring, TK100 to ESP32-S3:
// GND -> GND
// 3V3 -> 3V3
// LRCLK -> GPIO 16
// BCLK -> GPIO 15
// DIN -> GPIO 17
// CTRL -> GPIO 18 (HIGH plays, LOW or unconnected is off)
// Speaker, 4 or 8 ohm, in the white two-pin socket.
//
// Arduino IDE: Tools > Board > "ESP32S3 Dev Module" (esp32 core 3.x),
// USB CDC On Boot: Enabled. Serial Monitor at 115200.
#include <ESP_I2S.h>
const int PIN_BCLK = 15;
const int PIN_LRCLK = 16;
const int PIN_DIN = 17;
const int PIN_AMP_ON = 18;
const int RATE = 16000; // samples per second
I2SClass i2s;
// One frame is a left sample then a right sample. The amplifier plays
// only one of them, so the same value goes in both.
void playNote(float hz, int ms) {
const int16_t level = 6000; // about a fifth of full scale
int16_t frame[2];
float phase = 0;
float step = 2 * PI * hz / RATE;
for (int i = 0; i < RATE * ms / 1000; i++) {
frame[0] = frame[1] = (int16_t)(level * sinf(phase));
i2s.write((uint8_t *)frame, sizeof(frame));
phase += step;
if (phase > 2 * PI) phase -= 2 * PI;
}
}
void setup() {
Serial.begin(115200);
pinMode(PIN_AMP_ON, OUTPUT);
digitalWrite(PIN_AMP_ON, HIGH); // wake the amplifier
i2s.setPins(PIN_BCLK, PIN_LRCLK, PIN_DIN);
if (!i2s.begin(I2S_MODE_STD, RATE, I2S_DATA_BIT_WIDTH_16BIT,
I2S_SLOT_MODE_STEREO)) {
Serial.println("I2S did not start");
while (true) delay(1000);
}
Serial.println("Playing");
}
void loop() {
const float notes[] = {261.63, 293.66, 329.63, 349.23,
392.00, 440.00, 493.88};
for (float hz : notes) {
Serial.println(hz);
playNote(hz, 400);
playNote(0, 100); // a short gap
}
delay(1000);
}Compiled, not run, for an ESP32S3 Dev Module on esp32 core 3.3.10; ESP_I2S is part of that core. The board itself was tested by its maker playing this same scale from his own code on other pins; this sketch puts the amplifier on 15 to 18 so it never meets the microphone's 5 and 6.
When it does not work
The sketch is running and I2S started, so look at CTRL: it must reach GPIO 18, and the sketch drives it HIGH in setup(). Then check DIN is on GPIO 17 and the speaker plug is fully in the white socket.
ESP_I2S refused the pins or the settings. Check the board is set to ESP32S3 Dev Module on esp32 core 3.x, which is the version with ESP_I2S.h, and that nothing else in the sketch uses GPIO 15, 16 or 17.
Tools > USB CDC On Boot must be Enabled for Serial to reach the USB port on most ESP32-S3 boards. Set it, upload again, and open the Serial Monitor at 115200.
Check the level: 6000 is about a fifth of full scale on purpose, and raised much higher a loud note asks more of the 3.3 V supply. Then check that neither speaker lead touches GND or the other lead's bare end.
The ESP32 core is older than 3.0. Open Tools > Board > Boards Manager, update esp32 by Espressif Systems to a 3.x version, and compile again.
Three seconds from the TK101 microphone, played back on the TK100.
Record and play back →Edit this page — content/books/i2s-amplifier/first-sound.mdx
Questions about this product
See what other owners have asked, and read their solutions.
I2S Amplifier
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.