Board-dat/SMO/SMO1070-dat/SMO1070-dat.md
... ...
@@ -2,6 +2,8 @@
2 2
# SMO1070-dat
3 3
4 4
5
+- [[line-follower-dat]] - [[TCRT5000-dat]] - [[SMO1070-dat]]
6
+
5 7
6 8
7 9
Chip-cn-dat/ICroute-dat/2026-07-23-16-18-58.png
... ...
Binary files /dev/null and b/Chip-cn-dat/ICroute-dat/2026-07-23-16-18-58.png differ
Chip-cn-dat/ICroute-dat/LD3320-dat.md
... ...
@@ -41,6 +41,12 @@ Supported MP3 formats: MPEG-1 (ISO/IEC 11172-3), MPEG-2 (ISO/IEC 13818-3), and M
41 41
42 42
![](2026-02-27-02-38-07.png)
43 43
44
+SCH 2
45
+
46
+![](2026-07-23-16-18-58.png)
47
+
48
+
49
+
44 50
## Documentation
45 51
46 52
- Datasheet: https://w.electrodragon.com/w/LD3320_Datasheet
... ...
@@ -49,6 +55,12 @@ Supported MP3 formats: MPEG-1 (ISO/IEC 11172-3), MPEG-2 (ISO/IEC 13818-3), and M
49 55
50 56
- Example driver and sample code: https://github.com/libdriver/ld3320
51 57
58
+
59
+## control
60
+
61
+- [[relay-dat]]
62
+
63
+
52 64
## ref
53 65
54 66
- [[ICroute-dat]]
... ...
\ No newline at end of file
Chip-cn-dat/avia-dat/HX711-dat/2026-07-23-16-42-49.png
... ...
Binary files /dev/null and b/Chip-cn-dat/avia-dat/HX711-dat/2026-07-23-16-42-49.png differ
Chip-cn-dat/avia-dat/HX711-dat/HX711-dat.md
... ...
@@ -1,6 +1,9 @@
1 1
2 2
# HX711-dat
3 3
4
+
5
+- [[sensor-weight-dat]] - [[HX711-dat]] - [[sensor-dat]] - [[ADC-dat]]
6
+
4 7
- [[ADC-dat]]
5 8
6 9
- datasheet = [[hx711_english.pdf]]
... ...
@@ -29,6 +32,10 @@ FEATURES
29 32
- [[weight-dat]]
30 33
31 34
35
+![](2026-07-23-16-42-49.png)
36
+
37
+
38
+
32 39
## ref
33 40
34 41
Chip-cn-dat/everest-semi-dat/ES8311-dat/2026-07-23-16-10-50.png
... ...
Binary files /dev/null and b/Chip-cn-dat/everest-semi-dat/ES8311-dat/2026-07-23-16-10-50.png differ
Chip-cn-dat/everest-semi-dat/ES8311-dat/2026-07-23-16-11-27.png
... ...
Binary files /dev/null and b/Chip-cn-dat/everest-semi-dat/ES8311-dat/2026-07-23-16-11-27.png differ
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/ES8311-SDK-dat.md
... ...
@@ -4,7 +4,7 @@
4 4
5 5
- [[NS4150-dat]]
6 6
7
-
7
+https://github.com/espressif/esp-idf/blob/master/examples/peripherals/i2s/i2s_codec/i2s_es8311/main/i2s_es8311_example.c
8 8
9 9
I2C device found at address 0x18 !
10 10
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk1/ES8311-code-spk1.ino
... ...
@@ -2,13 +2,14 @@
2 2
#include "AudioBoard.h"
3 3
4 4
// 1. Define your pins clearly
5
-#define I2S_BCLK 5
6
-#define I2S_LRCK 4
7
-#define I2S_DOUT 6
8
-#define I2S_MCLK 2
5
+#define I2S_BCLK 14
6
+#define I2S_LRCK 12
7
+#define I2S_DOUT 13
9 8
10
-#define I2C_SDA 18
11
-#define I2C_SCL 17
9
+#define I2S_MCLK 6
10
+
11
+#define I2C_SDA 5
12
+#define I2C_SCL 4
12 13
13 14
using namespace audio_driver;
14 15
using namespace audio_tools;
... ...
@@ -20,16 +21,18 @@ DriverPins my_pins;
20 21
AudioBoard board(AudioDriverES8311, my_pins);
21 22
22 23
// 4. Define Audio Tools objects
23
-AudioInfo info(44100, 1, 16); // Mono, 44.1kHz, 16-bit
24
-SineWaveGenerator<int16_t> sineWave;
24
+AudioInfo info(16000, 2, 16); // STEREO 16kHz (proven working rate)
25
+SineWaveGenerator<int16_t> sineWave(2); // 2 channels
25 26
GeneratedSoundStream<int16_t> sound(sineWave);
26 27
I2SStream i2s;
27
-VolumeStream volume(i2s); // Added VolumeStream for software gain
28
+VolumeStream volume(i2s);
28 29
StreamCopy copier(volume, sound);
29 30
30 31
void setup()
31 32
{
32 33
Serial.begin(115200);
34
+ delay(1000);
35
+ Serial.println("=== ESP32-S3 + ES8311 + NS4150 ===");
33 36
34 37
// Define I2S Pins for the driver
35 38
my_pins.addI2S(PinFunction::CODEC, I2S_MCLK, I2S_BCLK, I2S_LRCK, I2S_DOUT);
... ...
@@ -38,14 +41,32 @@ void setup()
38 41
Wire.begin(I2C_SDA, I2C_SCL);
39 42
my_pins.addI2C(PinFunction::CODEC, Wire);
40 43
41
- // Start the board (I2C configuration of ES8311)
42
- if (!board.begin())
44
+ // Verify I2C
45
+ Wire.beginTransmission(0x18);
46
+ if (Wire.endTransmission() == 0)
47
+ Serial.println("✅ ES8311 found at 0x18");
48
+ else {
49
+ Serial.println("❌ ES8311 NOT found at 0x18!");
50
+ while (true);
51
+ }
52
+
53
+ // Configure codec explicitly for DAC playback
54
+ CodecConfig cfg;
55
+ cfg.output_device = DAC_OUTPUT_ALL;
56
+ cfg.i2s.bits = BIT_LENGTH_16BITS;
57
+ cfg.i2s.rate = RATE_16K;
58
+ cfg.i2s.fmt = I2S_NORMAL;
59
+ cfg.i2s.mode = MODE_SLAVE; // ESP32 is I2S master
60
+
61
+ // Start the board with explicit config
62
+ Serial.print("Initializing ES8311... ");
63
+ if (!board.begin(cfg))
43 64
{
44
- Serial.println("Failed to initialize ES8311 Board!");
45
- while (true)
46
- ;
65
+ Serial.println("FAILED!");
66
+ while (true);
47 67
}
48
- board.setVolume(1.0); // Set Hardware Volume to Maximum (1.0)
68
+ Serial.println("OK");
69
+ board.setVolume(1.0);
49 70
Serial.println("ES8311 Driver Initialized.");
50 71
51 72
// Configure I2S for Audio Tools
... ...
@@ -54,19 +75,24 @@ void setup()
54 75
config.pin_ws = I2S_LRCK;
55 76
config.pin_data = I2S_DOUT;
56 77
config.pin_mck = I2S_MCLK;
57
- config.use_apll = true; // Use APLL for better clock accuracy or internal MCLK generation
78
+ // Do NOT use APLL at 16kHz — let the driver use default clock division
58 79
config.copyFrom(info);
59
- i2s.begin(config);
80
+ Serial.print("Starting I2S... ");
81
+ if (!i2s.begin(config)) {
82
+ Serial.println("FAILED!");
83
+ while (true);
84
+ }
85
+ Serial.println("OK");
60 86
61 87
// Initialize VolumeStream
62 88
volume.begin(config);
63
- volume.setVolume(1.0); // Set Software Volume to Maximum (1.0)
89
+ volume.setVolume(1.0);
64 90
65 91
// Start generator
66 92
sineWave.begin(info, 440); // 440Hz Sine Wave
67 93
sound.begin();
68 94
69
- Serial.println("Streaming Sine Wave to ES8311...");
95
+ Serial.println("▶ Streaming 440Hz to ES8311...");
70 96
}
71 97
72 98
void loop()
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk2/ES8311-code-spk2.ino
... ...
@@ -11,6 +11,8 @@
11 11
#define I2S_DIN 7
12 12
#define I2S_MCLK 2
13 13
14
+// NS4150 CTRL pin: hardware-pulled HIGH (no GPIO needed)
15
+
14 16
#define ES8311_ADDR 0x18 // Default I2C Address for ES8311
15 17
16 18
I2SClass i2s;
... ...
@@ -23,46 +25,153 @@ void writeReg(uint8_t reg, uint8_t value) {
23 25
Wire.endTransmission();
24 26
}
25 27
28
+uint8_t readReg(uint8_t reg) {
29
+ Wire.beginTransmission(ES8311_ADDR);
30
+ Wire.write(reg);
31
+ Wire.endTransmission(false);
32
+ Wire.requestFrom((uint16_t)ES8311_ADDR, (uint8_t)1);
33
+ if (Wire.available()) return Wire.read();
34
+ return 0;
35
+}
36
+
26 37
void init_ES8311() {
27
- // Resets and wakes up the chip sequence
28
- writeReg(0x00, 0x80); // Reset system
29
- delay(10);
30
- writeReg(0x00, 0x00); // Clear reset
31
-
32
- // Clock configurations
33
- writeReg(0x01, 0x30); // Enable master clock (MCLK)
34
- writeReg(0x02, 0x00); // Digital calibration clock
35
-
36
- // ADC/DAC powering setup
37
- writeReg(0x03, 0x10); // Power up analog core
38
- writeReg(0x04, 0x10); // Power up DAC
39
- writeReg(0x0D, 0x02); // Configure DAC standard resolution (e.g., 16-bit I2S)
40
-
41
- // Volume Controls
42
- // 0x32: DAC Digital Volume (0x00 to 0xFF, 0xBF is 0dB, 0xFF is maximum gain)
43
- writeReg(0x32, 0xFF);
44
-
45
- // 0x14: System Control (PGA and Analog Gain)
46
- // Bits [3:0] are analog gain. 0x0B sets high analog gain.
47
- writeReg(0x14, 0x1B);
48
-
49
- Serial.println("ES8311 Registers Configured for Maximum Volume.");
38
+ // === ES8311 Register Map (from arduino-audio-driver ES8311.h) ===
39
+ // 0x00=RESET, 0x01=CLK_MGR1, 0x02=CLK_MGR2, 0x03=CLK_MGR3(ADC OSR),
40
+ // 0x04=CLK_MGR4(DAC OSR), 0x05=CLK_MGR5(ADC/DAC div),
41
+ // 0x06=CLK_MGR6(BCLK div), 0x07=CLK_MGR7(LRCK H), 0x08=CLK_MGR8(LRCK L),
42
+ // 0x09=SDP_IN(DAC I2S), 0x0A=SDP_OUT(ADC I2S),
43
+ // 0x0B-0x0C=SYSTEM, 0x0D=ANALOG_PWR, 0x0E=SYSTEM,
44
+ // 0x10-0x11=SYSTEM, 0x12-0x13=SYSTEM,
45
+ // 0x14=SYSTEM(PGA/analog), 0x15-0x1C=ADC,
46
+ // 0x31-0x35=DAC, 0x37=DAC_CTRL, 0x32=DAC_VOL,
47
+ // 0xFD=CHIP_ID1, 0xFE=CHIP_ID2
48
+
49
+ // === 1. Initial register setup (before reset) ===
50
+ writeReg(0x01, 0x30); // CLK_MGR1: enable main clocks
51
+ writeReg(0x02, 0x00); // CLK_MGR2: clear pre-divider
52
+ writeReg(0x03, 0x10); // CLK_MGR3: ADC OSR=16x (default)
53
+ writeReg(0x16, 0x24); // ADC_REG16: MIC gain initial
54
+ writeReg(0x04, 0x10); // CLK_MGR4: DAC OSR=16x
55
+ writeReg(0x05, 0x00); // CLK_MGR5: clear ADC/DAC dividers
56
+ writeReg(0x0B, 0x00); // SYSTEM_REG0B
57
+ writeReg(0x0C, 0x00); // SYSTEM_REG0C
58
+ writeReg(0x10, 0x1F); // SYSTEM_REG10
59
+ writeReg(0x11, 0x7F); // SYSTEM_REG11
60
+
61
+ // === 2. Reset chip ===
62
+ writeReg(0x00, 0x80); // RESET: trigger reset
63
+ delay(20);
64
+
65
+ // === 3. Set Slave Mode (ESP32 is I2S Master) ===
66
+ uint8_t regv = readReg(0x00);
67
+ regv &= 0xBF; // Clear bit 6 → Slave mode
68
+ writeReg(0x00, regv);
69
+
70
+ // === 4. Enable all internal clocks, use BCLK as clock source ===
71
+ // Using BCLK (SCLK) instead of MCLK pin avoids MCLK frequency mismatch
72
+ writeReg(0x01, 0x3F); // CLK_MGR1: all clocks ON
73
+ regv = readReg(0x01);
74
+ regv |= 0x80; // Set bit 7 → clock source = BCLK (SCLK pin)
75
+ writeReg(0x01, regv);
76
+
77
+ // === 5. Clock dividers for 16kHz @ 4.096MHz MCLK (256*Fs) ===
78
+ // From coefficient table: {4096000, 16000, pre=1, mult=1, adc=1, dac=1,
79
+ // fs=0, lrch=0, lrcl=0xFF, bck=4, osr=0x10}
80
+ writeReg(0x02, 0x00); // CLK_MGR2: pre_div=1, multi=1
81
+ writeReg(0x03, 0x10); // CLK_MGR3: fs_mode=0, adc_osr=0x10
82
+ writeReg(0x04, 0x10); // CLK_MGR4: dac_osr=0x10
83
+ writeReg(0x05, 0x00); // CLK_MGR5: adc_div=1, dac_div=1
84
+ writeReg(0x06, 0x03); // CLK_MGR6: bclk_div=4
85
+ writeReg(0x07, 0x00); // CLK_MGR7: lrck_h=0
86
+ writeReg(0x08, 0xFF); // CLK_MGR8: lrck_l=0xFF
87
+
88
+ // === 6. I2S Format: 16-bit Phillips (standard I2S) ===
89
+ writeReg(0x09, 0x0C); // SDP_IN: 16-bit I2S for DAC
90
+ writeReg(0x0A, 0x0C); // SDP_OUT: 16-bit I2S for ADC
91
+
92
+ // === 7. System init (from official driver) ===
93
+ writeReg(0x13, 0x10); // SYSTEM_REG13
94
+ writeReg(0x1B, 0x0A); // ADC_REG1B
95
+ writeReg(0x1C, 0x6A); // ADC_REG1C
96
+
97
+ Serial.println("ES8311 Init done (clock + I2S format).");
98
+
99
+ // === Verify chip ID ===
100
+ uint8_t chip_id1 = readReg(0xFD);
101
+ uint8_t chip_id2 = readReg(0xFE);
102
+ Serial.printf("ES8311 Chip ID: 0x%02X%02X (expect 0x8311)\n", chip_id1, chip_id2);
103
+}
104
+
105
+void start_ES8311_DAC() {
106
+ // === START sequence for DAC playback (from official driver) ===
107
+ // Powers up DAC, unmutes, routes audio to output
108
+
109
+ // 1. Set PGA / analog control (max analog gain)
110
+ writeReg(0x14, 0x3B); // SYSTEM_REG14: max PGA gain, no mic bias
111
+
112
+ // 2. Unmute DAC on I2S interface (clear bit 6 in SDP_IN)
113
+ uint8_t dac_iface = readReg(0x09) & 0xBF;
114
+ writeReg(0x09, dac_iface);
115
+
116
+ // 3. Unmute ADC on I2S interface (not needed, but harmless)
117
+ uint8_t adc_iface = readReg(0x0A) & 0xBF;
118
+ writeReg(0x0A, adc_iface);
119
+
120
+ // 4. ADC digital volume = max
121
+ writeReg(0x17, 0xBF); // ADC_REG17
122
+
123
+ // 5. System analog enable
124
+ writeReg(0x0E, 0x02); // SYSTEM_REG0E
125
+
126
+ // 6. System control
127
+ writeReg(0x12, 0x00); // SYSTEM_REG12
128
+
129
+ // 7. Power up analog (DAC + ADC + full analog blocks)
130
+ writeReg(0x0D, 0x03); // SYSTEM_REG0D: power up DAC + ADC analog
131
+
132
+ // 8. ADC control
133
+ writeReg(0x15, 0x40); // ADC_REG15
134
+
135
+ // 9. DAC control - max output drive
136
+ writeReg(0x37, 0x78); // DAC_REG37: max DAC output drive (was 0x68)
137
+
138
+ // 10. GPIO / digital
139
+ writeReg(0x45, 0x00); // GP_REG45
140
+
141
+ // 11. DAC digital volume (0x00=mute, 0xBF=0dB, 0xFF=+6dB max)
142
+ writeReg(0x32, 0xFF); // DAC_REG32: MAXIMUM volume
143
+
144
+ Serial.println("ES8311 DAC STARTED (powered, unmuted, routed).");
50 145
}
51 146
52 147
void setup() {
53 148
Serial.begin(115200);
149
+ delay(1000); // Wait for Serial monitor
54 150
55
- // 1. Fire up I2C Bus
151
+ // === 1. Fire up I2C Bus ===
56 152
Wire.begin(I2C_SDA, I2C_SCL);
153
+ Wire.setClock(100000); // 100kHz standard speed
154
+
155
+ // === 2. Scan I2C to verify ES8311 is reachable ===
156
+ Wire.beginTransmission(ES8311_ADDR);
157
+ if (Wire.endTransmission() == 0) {
158
+ Serial.printf("✅ ES8311 found at I2C address 0x%02X\n", ES8311_ADDR);
159
+ } else {
160
+ Serial.printf("❌ ES8311 NOT found at I2C address 0x%02X! Check wiring.\n", ES8311_ADDR);
161
+ }
162
+
57 163
init_ES8311();
58 164
59
- // 3. Initialize I2S peripheral
60
- i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK); // BCLK, LRCK, DOUT, DIN, MCLK
61
- if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT)) {
62
- Serial.println("Failed to initialize I2S!");
165
+ // === 2b. Power up DAC and start output path ===
166
+ start_ES8311_DAC();
167
+
168
+ // === 3. Initialize I2S peripheral (STEREO to match ES8311) ===
169
+ i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK);
170
+ if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
171
+ Serial.println("❌ Failed to initialize I2S!");
63 172
while (1);
64 173
}
65
- Serial.println("I2S initialized successfully.");
174
+ Serial.println("✅ I2S initialized successfully (STEREO).");
66 175
}
67 176
68 177
void loop() {
... ...
@@ -70,34 +179,42 @@ void loop() {
70 179
const float frequency = 440.0; // 440Hz (A4 note)
71 180
const int ramp_duration_ms = 3000; // 3 seconds ramp
72 181
const int hold_duration_ms = 2000; // 2 seconds hold at max
73
- const int buffer_size = 512;
74
- int16_t audio_buffer[buffer_size];
182
+ const int buffer_samples = 256; // mono samples
183
+ int16_t audio_buffer[buffer_samples * 2]; // stereo: L,R interleaved
75 184
76 185
static uint32_t sample_index = 0;
186
+ static uint32_t last_print = 0;
77 187
uint32_t ramp_samples = sample_rate * (ramp_duration_ms / 1000.0);
78 188
uint32_t hold_samples = sample_rate * (hold_duration_ms / 1000.0);
79 189
uint32_t total_samples_in_cycle = ramp_samples + hold_samples;
80 190
81
- for (int i = 0; i < buffer_size; i++) {
191
+ for (int i = 0; i < buffer_samples; i++) {
82 192
uint32_t current_pos = sample_index % total_samples_in_cycle;
83 193
float volume;
84 194
85 195
if (current_pos < ramp_samples) {
86
- // Phase 1: Ramp from 0 to 1 over 3 seconds
87 196
volume = (float)current_pos / ramp_samples;
88 197
} else {
89
- // Phase 2: Hold at 1 for 2 seconds
90 198
volume = 1.0f;
91 199
}
92 200
93
- // Generate sine wave
94 201
float sin_val = sin(2.0 * PI * frequency * sample_index / sample_rate);
202
+ int16_t sample = (int16_t)(sin_val * volume * 32767);
95 203
96
- // Scale to 16-bit range
97
- audio_buffer[i] = (int16_t)(sin_val * volume * 32767);
204
+ // Write same sample to both Left and Right channels
205
+ audio_buffer[i * 2] = sample; // Left
206
+ audio_buffer[i * 2 + 1] = sample; // Right
98 207
99 208
sample_index++;
100 209
}
101 210
102
- i2s.write((uint8_t*)audio_buffer, sizeof(audio_buffer));
211
+ size_t written = i2s.write((uint8_t*)audio_buffer, sizeof(audio_buffer));
212
+
213
+ // Print status every ~2 seconds
214
+ if (millis() - last_print > 2000) {
215
+ last_print = millis();
216
+ uint32_t sec = sample_index / sample_rate;
217
+ Serial.printf("▶ Streaming: %lu sec, sample=%d, bytes=%d\n",
218
+ sec, audio_buffer[0], written);
219
+ }
103 220
}
... ...
\ No newline at end of file
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk3-melody/ES8311-code-spk3-melody.ino
... ...
@@ -0,0 +1,312 @@
1
+#include <Wire.h>
2
+#include <ESP_I2S.h> // Uses the standard ESP32 Arduino I2S library
3
+
4
+// Fallback in case Arduino core doesn't define PI
5
+#ifndef PI
6
+#define PI 3.141592653589793f
7
+#endif
8
+
9
+// Define your board's pin layout (Change these values to match your specific board schematic)
10
+#define I2S_BCLK 14
11
+#define I2S_LRCK 12
12
+#define I2S_DOUT 13
13
+#define I2S_DIN -1 // not used (DAC playback only)
14
+
15
+#define I2S_MCLK 6
16
+
17
+#define I2C_SDA 5
18
+#define I2C_SCL 4
19
+
20
+
21
+// NS4150 CTRL pin: hardware-pulled HIGH (no GPIO needed)
22
+
23
+#define ES8311_ADDR 0x18 // Default I2C Address for ES8311
24
+
25
+I2SClass i2s;
26
+
27
+// Helper to write to ES8311 registers over I2C
28
+void writeReg(uint8_t reg, uint8_t value) {
29
+ Wire.beginTransmission(ES8311_ADDR);
30
+ Wire.write(reg);
31
+ Wire.write(value);
32
+ Wire.endTransmission();
33
+}
34
+
35
+uint8_t readReg(uint8_t reg) {
36
+ Wire.beginTransmission(ES8311_ADDR);
37
+ Wire.write(reg);
38
+ Wire.endTransmission(false);
39
+ Wire.requestFrom((uint16_t)ES8311_ADDR, (uint8_t)1);
40
+ if (Wire.available()) return Wire.read();
41
+ return 0;
42
+}
43
+
44
+void init_ES8311() {
45
+ // === ES8311 Register Map (from arduino-audio-driver ES8311.h) ===
46
+ // 0x00=RESET, 0x01=CLK_MGR1, 0x02=CLK_MGR2, 0x03=CLK_MGR3(ADC OSR),
47
+ // 0x04=CLK_MGR4(DAC OSR), 0x05=CLK_MGR5(ADC/DAC div),
48
+ // 0x06=CLK_MGR6(BCLK div), 0x07=CLK_MGR7(LRCK H), 0x08=CLK_MGR8(LRCK L),
49
+ // 0x09=SDP_IN(DAC I2S), 0x0A=SDP_OUT(ADC I2S),
50
+ // 0x0B-0x0C=SYSTEM, 0x0D=ANALOG_PWR, 0x0E=SYSTEM,
51
+ // 0x10-0x11=SYSTEM, 0x12-0x13=SYSTEM,
52
+ // 0x14=SYSTEM(PGA/analog), 0x15-0x1C=ADC,
53
+ // 0x31-0x35=DAC, 0x37=DAC_CTRL, 0x32=DAC_VOL,
54
+ // 0xFD=CHIP_ID1, 0xFE=CHIP_ID2
55
+
56
+ // === 1. Initial register setup (before reset) ===
57
+ writeReg(0x01, 0x30); // CLK_MGR1: enable main clocks
58
+ writeReg(0x02, 0x00); // CLK_MGR2: clear pre-divider
59
+ writeReg(0x03, 0x10); // CLK_MGR3: ADC OSR=16x (default)
60
+ writeReg(0x16, 0x24); // ADC_REG16: MIC gain initial
61
+ writeReg(0x04, 0x10); // CLK_MGR4: DAC OSR=16x
62
+ writeReg(0x05, 0x00); // CLK_MGR5: clear ADC/DAC dividers
63
+ writeReg(0x0B, 0x00); // SYSTEM_REG0B
64
+ writeReg(0x0C, 0x00); // SYSTEM_REG0C
65
+ writeReg(0x10, 0x1F); // SYSTEM_REG10
66
+ writeReg(0x11, 0x7F); // SYSTEM_REG11
67
+
68
+ // === 2. Reset chip ===
69
+ writeReg(0x00, 0x80); // RESET: trigger reset
70
+ delay(20);
71
+
72
+ // === 3. Set Slave Mode (ESP32 is I2S Master) ===
73
+ uint8_t regv = readReg(0x00);
74
+ regv &= 0xBF; // Clear bit 6 → Slave mode
75
+ writeReg(0x00, regv);
76
+
77
+ // === 4. Enable all internal clocks, use BCLK as clock source ===
78
+ // Using BCLK (SCLK) instead of MCLK pin avoids MCLK frequency mismatch
79
+ writeReg(0x01, 0x3F); // CLK_MGR1: all clocks ON
80
+ regv = readReg(0x01);
81
+ regv |= 0x80; // Set bit 7 → clock source = BCLK (SCLK pin)
82
+ writeReg(0x01, regv);
83
+
84
+ // === 5. Clock dividers for 16kHz @ 4.096MHz MCLK (256*Fs) ===
85
+ // From coefficient table: {4096000, 16000, pre=1, mult=1, adc=1, dac=1,
86
+ // fs=0, lrch=0, lrcl=0xFF, bck=4, osr=0x10}
87
+ writeReg(0x02, 0x00); // CLK_MGR2: pre_div=1, multi=1
88
+ writeReg(0x03, 0x10); // CLK_MGR3: fs_mode=0, adc_osr=0x10
89
+ writeReg(0x04, 0x10); // CLK_MGR4: dac_osr=0x10
90
+ writeReg(0x05, 0x00); // CLK_MGR5: adc_div=1, dac_div=1
91
+ writeReg(0x06, 0x03); // CLK_MGR6: bclk_div=4
92
+ writeReg(0x07, 0x00); // CLK_MGR7: lrck_h=0
93
+ writeReg(0x08, 0xFF); // CLK_MGR8: lrck_l=0xFF
94
+
95
+ // === 6. I2S Format: 16-bit Phillips (standard I2S) ===
96
+ writeReg(0x09, 0x0C); // SDP_IN: 16-bit I2S for DAC
97
+ writeReg(0x0A, 0x0C); // SDP_OUT: 16-bit I2S for ADC
98
+
99
+ // === 7. System init (from official driver) ===
100
+ writeReg(0x13, 0x10); // SYSTEM_REG13
101
+ writeReg(0x1B, 0x0A); // ADC_REG1B
102
+ writeReg(0x1C, 0x6A); // ADC_REG1C
103
+
104
+ Serial.println("ES8311 Init done (clock + I2S format).");
105
+
106
+ // === Verify chip ID ===
107
+ uint8_t chip_id1 = readReg(0xFD);
108
+ uint8_t chip_id2 = readReg(0xFE);
109
+ Serial.printf("ES8311 Chip ID: 0x%02X%02X (expect 0x8311)\n", chip_id1, chip_id2);
110
+}
111
+
112
+void start_ES8311_DAC() {
113
+ // === START sequence for DAC playback (from official driver) ===
114
+ // Powers up DAC, unmutes, routes audio to output
115
+
116
+ // 1. Set PGA / analog control (max analog gain)
117
+ writeReg(0x14, 0x3B); // SYSTEM_REG14: max PGA gain, no mic bias
118
+
119
+ // 2. Unmute DAC on I2S interface (clear bit 6 in SDP_IN)
120
+ uint8_t dac_iface = readReg(0x09) & 0xBF;
121
+ writeReg(0x09, dac_iface);
122
+
123
+ // 3. Unmute ADC on I2S interface (not needed, but harmless)
124
+ uint8_t adc_iface = readReg(0x0A) & 0xBF;
125
+ writeReg(0x0A, adc_iface);
126
+
127
+ // 4. ADC digital volume = max
128
+ writeReg(0x17, 0xBF); // ADC_REG17
129
+
130
+ // 5. System analog enable
131
+ writeReg(0x0E, 0x02); // SYSTEM_REG0E
132
+
133
+ // 6. System control
134
+ writeReg(0x12, 0x00); // SYSTEM_REG12
135
+
136
+ // 7. Power up analog (DAC + ADC + full analog blocks)
137
+ writeReg(0x0D, 0x03); // SYSTEM_REG0D: power up DAC + ADC analog
138
+
139
+ // 8. ADC control
140
+ writeReg(0x15, 0x40); // ADC_REG15
141
+
142
+ // 9. DAC control - max output drive
143
+ writeReg(0x37, 0x78); // DAC_REG37: max DAC output drive (was 0x68)
144
+
145
+ // 10. GPIO / digital
146
+ writeReg(0x45, 0x00); // GP_REG45
147
+
148
+ // 11. DAC digital volume (0x00=mute, 0xBF=0dB, 0xFF=+6dB max)
149
+ writeReg(0x32, 0xFF); // DAC_REG32: MAXIMUM volume
150
+
151
+ Serial.println("ES8311 DAC STARTED (powered, unmuted, routed).");
152
+}
153
+
154
+void setup() {
155
+ Serial.begin(115200);
156
+ delay(1000); // Wait for Serial monitor
157
+
158
+ // === 1. Fire up I2C Bus ===
159
+ Wire.begin(I2C_SDA, I2C_SCL);
160
+ Wire.setClock(100000); // 100kHz standard speed
161
+
162
+ // === 2. Scan I2C to verify ES8311 is reachable ===
163
+ Wire.beginTransmission(ES8311_ADDR);
164
+ if (Wire.endTransmission() == 0) {
165
+ Serial.printf("✅ ES8311 found at I2C address 0x%02X\n", ES8311_ADDR);
166
+ } else {
167
+ Serial.printf("❌ ES8311 NOT found at I2C address 0x%02X! Check wiring.\n", ES8311_ADDR);
168
+ }
169
+
170
+ init_ES8311();
171
+
172
+ // === 2b. Power up DAC and start output path ===
173
+ start_ES8311_DAC();
174
+
175
+ // === 3. Initialize I2S peripheral (STEREO to match ES8311) ===
176
+ i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK);
177
+ if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
178
+ Serial.println("❌ Failed to initialize I2S!");
179
+ while (1);
180
+ }
181
+ Serial.println("✅ I2S initialized successfully (STEREO).");
182
+}
183
+
184
+// === Melody: "Twinkle Twinkle Little Star" ===
185
+// Frequencies in Hz
186
+#define NOTE_C4 262
187
+#define NOTE_D4 294
188
+#define NOTE_E4 330
189
+#define NOTE_F4 349
190
+#define NOTE_G4 392
191
+#define NOTE_A4 440
192
+#define NOTE_B4 494
193
+#define NOTE_C5 523
194
+#define NOTE_REST 0
195
+
196
+struct Note {
197
+ uint16_t freq; // Hz, 0 = rest
198
+ uint16_t duration; // ms
199
+};
200
+
201
+const Note melody[] = {
202
+ // Twinkle twinkle little star
203
+ {NOTE_C4, 400}, {NOTE_C4, 400}, {NOTE_G4, 400}, {NOTE_G4, 400},
204
+ {NOTE_A4, 400}, {NOTE_A4, 400}, {NOTE_G4, 800},
205
+ // How I wonder what you are
206
+ {NOTE_F4, 400}, {NOTE_F4, 400}, {NOTE_E4, 400}, {NOTE_E4, 400},
207
+ {NOTE_D4, 400}, {NOTE_D4, 400}, {NOTE_C4, 800},
208
+ // Up above the world so high
209
+ {NOTE_G4, 400}, {NOTE_G4, 400}, {NOTE_F4, 400}, {NOTE_F4, 400},
210
+ {NOTE_E4, 400}, {NOTE_E4, 400}, {NOTE_D4, 800},
211
+ // Like a diamond in the sky
212
+ {NOTE_G4, 400}, {NOTE_G4, 400}, {NOTE_F4, 400}, {NOTE_F4, 400},
213
+ {NOTE_E4, 400}, {NOTE_E4, 400}, {NOTE_D4, 800},
214
+ // Twinkle twinkle little star
215
+ {NOTE_C4, 400}, {NOTE_C4, 400}, {NOTE_G4, 400}, {NOTE_G4, 400},
216
+ {NOTE_A4, 400}, {NOTE_A4, 400}, {NOTE_G4, 800},
217
+ // How I wonder what you are
218
+ {NOTE_F4, 400}, {NOTE_F4, 400}, {NOTE_E4, 400}, {NOTE_E4, 400},
219
+ {NOTE_D4, 400}, {NOTE_D4, 400}, {NOTE_C4, 800},
220
+ // Pause before repeat
221
+ {NOTE_REST, 600},
222
+};
223
+const int melody_len = sizeof(melody) / sizeof(Note);
224
+
225
+const int SAMPLE_RATE = 16000;
226
+const int BUFFER_SAMPLES = 256;
227
+
228
+// Timing constants (in ms)
229
+const int ATTACK_MS = 12; // note attack ramp
230
+const int RELEASE_MS = 15; // note release ramp
231
+const int GAP_MS = 3; // silence gap between notes
232
+const int XFADE_MS = 8; // frequency crossfade duration
233
+
234
+// State
235
+static float phase = 0.0f;
236
+static uint8_t note_idx = 0;
237
+static uint32_t note_start_ms = 0;
238
+static float prev_freq = melody[0].freq;
239
+static bool first_buffer = true;
240
+
241
+void loop() {
242
+ int16_t audio_buffer[BUFFER_SAMPLES * 2]; // stereo L,R interleaved
243
+ uint32_t now = millis();
244
+ uint32_t note_elapsed = now - note_start_ms;
245
+ Note current = melody[note_idx];
246
+
247
+ // --- Note transition ---
248
+ if (note_elapsed >= current.duration + GAP_MS) {
249
+ prev_freq = current.freq;
250
+ note_idx++;
251
+ if (note_idx >= melody_len) note_idx = 0;
252
+ note_start_ms = now;
253
+ current = melody[note_idx];
254
+ Serial.printf("♪ Note %d: freq=%d Hz, dur=%d ms\n",
255
+ note_idx, current.freq, current.duration);
256
+ }
257
+ // Recalculate note_elapsed AFTER possible transition (fixes envelope bug)
258
+ note_elapsed = now - note_start_ms;
259
+
260
+ // --- Crossfade frequency between old and new note ---
261
+ float xfade_k = (note_elapsed < XFADE_MS) ? (note_elapsed / (float)XFADE_MS) : 1.0f;
262
+ float freq = prev_freq * (1.0f - xfade_k) + current.freq * xfade_k;
263
+
264
+ // --- Generate audio buffer ---
265
+ int gap_samples = GAP_MS * SAMPLE_RATE / 1000;
266
+ int attack_samples = ATTACK_MS * SAMPLE_RATE / 1000;
267
+ int release_samples = RELEASE_MS * SAMPLE_RATE / 1000;
268
+ // current elapsed in samples (estimate, tracking from note_start)
269
+ uint32_t sample_offset = (uint32_t)((float)note_elapsed * SAMPLE_RATE / 1000.0f);
270
+ uint32_t dur_samples = (uint32_t)((float)current.duration * SAMPLE_RATE / 1000.0f);
271
+
272
+ for (int i = 0; i < BUFFER_SAMPLES; i++) {
273
+ uint32_t s = sample_offset + i;
274
+ int16_t sample;
275
+
276
+ // Silence during gap between notes
277
+ if (s < (uint32_t)gap_samples) {
278
+ sample = 0;
279
+ }
280
+ // Silence during rest (after crossfade)
281
+ else if (current.freq == 0 && note_elapsed >= XFADE_MS) {
282
+ sample = 0;
283
+ }
284
+ else {
285
+ // Envelope: attack → sustain → release
286
+ float envelope = 0.75f;
287
+ uint32_t note_s = s - gap_samples; // sample pos relative to note body
288
+ if (note_s < (uint32_t)attack_samples) {
289
+ envelope *= (float)note_s / attack_samples; // linear attack
290
+ } else if (note_s > dur_samples - release_samples && dur_samples > (uint32_t)(attack_samples + release_samples)) {
291
+ uint32_t rel = dur_samples - note_s;
292
+ envelope *= (float)rel / release_samples; // linear release
293
+ }
294
+
295
+ sample = (int16_t)(sinf(phase) * envelope * 28000);
296
+ phase += 2.0f * PI * freq / SAMPLE_RATE;
297
+ if (phase > 2.0f * PI) phase -= 2.0f * PI;
298
+ }
299
+ audio_buffer[i * 2] = sample; // Left
300
+ audio_buffer[i * 2 + 1] = sample; // Right
301
+ }
302
+
303
+ size_t written = i2s.write((uint8_t*)audio_buffer, sizeof(audio_buffer));
304
+ if (written != sizeof(audio_buffer)) {
305
+ Serial.printf("⚠ I2S write short: %d / %d bytes\n", written, sizeof(audio_buffer));
306
+ }
307
+
308
+ if (first_buffer) {
309
+ Serial.println("▶ Melody started: Twinkle Twinkle Little Star");
310
+ first_buffer = false;
311
+ }
312
+}
... ...
\ No newline at end of file
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk4/ES8311-code-spk4.ino
... ...
@@ -0,0 +1,307 @@
1
+/*
2
+ * ES8311 Codec + NS4150 Amplifier — Melody Player (Arduino)
3
+ *
4
+ * Reference: ESP-IDF official example
5
+ * https://github.com/espressif/esp-idf/blob/master/examples/peripherals/i2s/i2s_codec/i2s_es8311/main/i2s_es8311_example.c
6
+ *
7
+ * Key settings from ESP-IDF reference:
8
+ * - Sample Rate: 16000 Hz
9
+ * - MCLK Multiple: 384 (MCLK = 6.144 MHz) — matches ES8311 coeff table
10
+ * - I2S Format: Philips (standard I2S)
11
+ * - Bit Width: 16-bit
12
+ * - Channels: 2 (stereo)
13
+ * - Codec Mode: Slave (ESP32 is I2S master)
14
+ * - PA_CTRL pin: High = amplifier enabled
15
+ *
16
+ * Wiring (match your board):
17
+ * ES8311 SDA -> GPIO 5
18
+ * ES8311 SCL -> GPIO 4
19
+ * ES8311 MCLK -> GPIO 6
20
+ * ES8311 BCLK -> GPIO 14
21
+ * ES8311 LRCK -> GPIO 12
22
+ * ES8311 SDIN -> GPIO 13 (I2S data INTO ES8311 = ESP32 DOUT)
23
+ * NS4150 CTRL -> hardware pull-up HIGH (no GPIO needed, or use PA_CTRL)
24
+ */
25
+
26
+#include <Wire.h>
27
+#include <ESP_I2S.h>
28
+
29
+// PI fallback (Arduino defines PI, but ensure M_PI as well)
30
+#ifndef PI
31
+#define PI 3.141592653589793f
32
+#endif
33
+#ifndef M_PI
34
+#define M_PI PI
35
+#endif
36
+
37
+// ==================== Pin Definitions ====================
38
+#define I2C_SDA 5
39
+#define I2C_SCL 4
40
+
41
+#define I2S_BCLK 14
42
+#define I2S_LRCK 12
43
+#define I2S_DOUT 13
44
+#define I2S_DIN -1 // unused (DAC playback only)
45
+#define I2S_MCLK 6
46
+
47
+#define PA_CTRL -1 // set to GPIO if you have amp enable pin, -1 = not used
48
+
49
+#define ES8311_ADDR 0x18
50
+
51
+// ==================== Audio Parameters (from ESP-IDF example) ====================
52
+#define SAMPLE_RATE 16000
53
+#define MCLK_MULTIPLE 384 // ESP-IDF uses 384 for 16-bit
54
+// MCLK = SAMPLE_RATE * MCLK_MULTIPLE = 6,144,000 Hz (in ES8311 coeff table)
55
+#define BIT_WIDTH 16
56
+#define CHANNELS 2
57
+
58
+// ==================== I2S ====================
59
+I2SClass i2s;
60
+
61
+// ==================== ES8311 Register Helpers ====================
62
+void writeReg(uint8_t reg, uint8_t value) {
63
+ Wire.beginTransmission(ES8311_ADDR);
64
+ Wire.write(reg);
65
+ Wire.write(value);
66
+ Wire.endTransmission();
67
+}
68
+
69
+uint8_t readReg(uint8_t reg) {
70
+ Wire.beginTransmission(ES8311_ADDR);
71
+ Wire.write(reg);
72
+ Wire.endTransmission(false);
73
+ Wire.requestFrom((uint16_t)ES8311_ADDR, (uint8_t)1);
74
+ if (Wire.available()) return Wire.read();
75
+ return 0;
76
+}
77
+
78
+// ==================== ES8311 Init (based on ESP-IDF esp_codec_dev driver) ====================
79
+void es8311_init() {
80
+ // --- Step 1: Pre-reset defaults ---
81
+ writeReg(0x01, 0x30);
82
+ writeReg(0x02, 0x00);
83
+ writeReg(0x03, 0x10);
84
+ writeReg(0x16, 0x24);
85
+ writeReg(0x04, 0x10);
86
+ writeReg(0x05, 0x00);
87
+ writeReg(0x0B, 0x00);
88
+ writeReg(0x0C, 0x00);
89
+ writeReg(0x10, 0x1F);
90
+ writeReg(0x11, 0x7F);
91
+
92
+ // --- Step 2: Reset ---
93
+ writeReg(0x00, 0x80);
94
+ delay(20);
95
+
96
+ // --- Step 3: Slave mode (ESP32 is master, same as ESP-IDF: master_mode=false) ---
97
+ uint8_t r = readReg(0x00);
98
+ r &= 0xBF; // clear bit 6 → slave
99
+ writeReg(0x00, r);
100
+
101
+ // --- Step 4: Clock source = BCLK (avoids MCLK frequency dependency) ---
102
+ // ESP-IDF uses MCLK at 384×Fs which is also valid; BCLK source is simpler
103
+ writeReg(0x01, 0x3F);
104
+ r = readReg(0x01);
105
+ r |= 0x80; // bit 7 = 1 → use BCLK/SCLK as PLL source
106
+ writeReg(0x01, r);
107
+
108
+ // --- Step 5: Clock dividers for 16kHz ---
109
+ // From ES8311 coefficient table entry {6144000, 16000, ...}
110
+ // These work for both MCLK and BCLK clock sources
111
+ writeReg(0x02, 0x00); // pre_div=1, multi=1
112
+ writeReg(0x03, 0x10); // adc_osr=16x
113
+ writeReg(0x04, 0x10); // dac_osr=16x
114
+ writeReg(0x05, 0x00); // adc_div=1, dac_div=1
115
+ writeReg(0x06, 0x03); // bclk_div=4
116
+ writeReg(0x07, 0x00); // lrck_h
117
+ writeReg(0x08, 0xFF); // lrck_l
118
+
119
+ // --- Step 6: I2S format — Philips (standard I2S) ---
120
+ // ESP-IDF uses I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG
121
+ writeReg(0x09, 0x0C); // SDP_IN: 16-bit I2S Philips
122
+ writeReg(0x0A, 0x0C); // SDP_OUT: 16-bit I2S Philips
123
+
124
+ // --- Step 7: System init (from official driver) ---
125
+ writeReg(0x13, 0x10);
126
+ writeReg(0x1B, 0x0A);
127
+ writeReg(0x1C, 0x6A);
128
+
129
+ // --- Verify ---
130
+ uint8_t id1 = readReg(0xFD);
131
+ uint8_t id2 = readReg(0xFE);
132
+ Serial.printf("ES8311 Chip ID: 0x%02X%02X (expect 0x8311)\n", id1, id2);
133
+}
134
+
135
+// ==================== ES8311 DAC Start (power-up + unmute) ====================
136
+void es8311_dac_start() {
137
+ writeReg(0x14, 0x3B); // analog gain, no mic bias
138
+
139
+ uint8_t dac = readReg(0x09) & 0xBF; // unmute DAC
140
+ writeReg(0x09, dac);
141
+ uint8_t adc = readReg(0x0A) & 0xBF; // unmute ADC (harmless)
142
+ writeReg(0x0A, adc);
143
+
144
+ writeReg(0x17, 0xBF); // ADC digital vol
145
+ writeReg(0x0E, 0x02); // analog enable
146
+ writeReg(0x12, 0x00); // system ctrl
147
+ writeReg(0x0D, 0x03); // power: DAC + ADC analog
148
+ writeReg(0x15, 0x40); // ADC ctrl
149
+ writeReg(0x37, 0x48); // DAC output drive (reduced from 0x78)
150
+ writeReg(0x45, 0x00); // GPIO
151
+
152
+ // DAC digital volume: 0x00=mute, 0xBF=0dB, 0xFF=+6dB
153
+ writeReg(0x32, 0x20); // very soft
154
+
155
+ Serial.println("ES8311 DAC started.");
156
+}
157
+
158
+// ==================== Melody ====================
159
+#define NOTE_C4 262
160
+#define NOTE_D4 294
161
+#define NOTE_E4 330
162
+#define NOTE_F4 349
163
+#define NOTE_G4 392
164
+#define NOTE_A4 440
165
+#define NOTE_B4 494
166
+#define NOTE_C5 523
167
+#define NOTE_REST 0
168
+
169
+struct Note { uint16_t freq; uint16_t dur; };
170
+
171
+const Note melody[] = {
172
+ {NOTE_C4,400},{NOTE_C4,400},{NOTE_G4,400},{NOTE_G4,400},
173
+ {NOTE_A4,400},{NOTE_A4,400},{NOTE_G4,800},
174
+ {NOTE_F4,400},{NOTE_F4,400},{NOTE_E4,400},{NOTE_E4,400},
175
+ {NOTE_D4,400},{NOTE_D4,400},{NOTE_C4,800},
176
+ {NOTE_G4,400},{NOTE_G4,400},{NOTE_F4,400},{NOTE_F4,400},
177
+ {NOTE_E4,400},{NOTE_E4,400},{NOTE_D4,800},
178
+ {NOTE_G4,400},{NOTE_G4,400},{NOTE_F4,400},{NOTE_F4,400},
179
+ {NOTE_E4,400},{NOTE_E4,400},{NOTE_D4,800},
180
+ {NOTE_C4,400},{NOTE_C4,400},{NOTE_G4,400},{NOTE_G4,400},
181
+ {NOTE_A4,400},{NOTE_A4,400},{NOTE_G4,800},
182
+ {NOTE_F4,400},{NOTE_F4,400},{NOTE_E4,400},{NOTE_E4,400},
183
+ {NOTE_D4,400},{NOTE_D4,400},{NOTE_C4,800},
184
+ {NOTE_REST,600},
185
+};
186
+const int MELODY_LEN = sizeof(melody) / sizeof(Note);
187
+
188
+// ==================== Audio Generator ====================
189
+const int BUF_SAMPLES = 256;
190
+const int ATTACK_MS = 12;
191
+const int RELEASE_MS = 15;
192
+const int GAP_MS = 4;
193
+const int XFADE_MS = 10;
194
+
195
+static float g_phase = 0.0f;
196
+static uint8_t g_note_idx = 0;
197
+static uint32_t g_note_start = 0;
198
+static float g_prev_freq = melody[0].freq;
199
+static bool g_first_run = true;
200
+
201
+void loop() {
202
+ int16_t buf[BUF_SAMPLES * 2]; // stereo interleaved
203
+ uint32_t now = millis();
204
+
205
+ // First run: sync clock so we don't skip the first note
206
+ if (g_first_run) {
207
+ g_note_start = now;
208
+ g_first_run = false;
209
+ Serial.printf("♪ [0] freq=%d dur=%d\n", melody[0].freq, melody[0].dur);
210
+ }
211
+
212
+ uint32_t elapsed = now - g_note_start;
213
+ Note cur = melody[g_note_idx];
214
+
215
+ // --- Note transition ---
216
+ if (elapsed >= cur.dur + GAP_MS) {
217
+ g_prev_freq = cur.freq;
218
+ g_note_idx = (g_note_idx + 1) % MELODY_LEN;
219
+ g_note_start = now;
220
+ cur = melody[g_note_idx];
221
+ Serial.printf("♪ [%d] freq=%d dur=%d\n", g_note_idx, cur.freq, cur.dur);
222
+ }
223
+ elapsed = now - g_note_start; // recalibrate after possible transition
224
+
225
+ // --- Crossfade ---
226
+ float xf = (elapsed < XFADE_MS) ? (elapsed / (float)XFADE_MS) : 1.0f;
227
+ float freq = g_prev_freq * (1.0f - xf) + cur.freq * xf;
228
+
229
+ // --- Timing in samples ---
230
+ int gap_s = GAP_MS * SAMPLE_RATE / 1000;
231
+ int att_s = ATTACK_MS * SAMPLE_RATE / 1000;
232
+ int rel_s = RELEASE_MS * SAMPLE_RATE / 1000;
233
+ uint32_t off = (uint32_t)(elapsed * SAMPLE_RATE / 1000.0f);
234
+ uint32_t dur_s = (uint32_t)(cur.dur * SAMPLE_RATE / 1000.0f);
235
+
236
+ for (int i = 0; i < BUF_SAMPLES; i++) {
237
+ uint32_t s = off + i;
238
+ int16_t smp;
239
+
240
+ if (s < (uint32_t)gap_s) {
241
+ smp = 0;
242
+ } else if (cur.freq == 0 && elapsed >= XFADE_MS) {
243
+ smp = 0;
244
+ } else {
245
+ float env = 0.75f;
246
+ uint32_t ns = s - gap_s;
247
+ if (ns < (uint32_t)att_s)
248
+ env *= (float)ns / att_s;
249
+ else if (ns > dur_s - rel_s && dur_s > (uint32_t)(att_s + rel_s))
250
+ env *= (float)(dur_s - ns) / rel_s;
251
+
252
+ smp = (int16_t)(sinf(g_phase) * env * 6000); // very soft
253
+ g_phase += 2.0f * (float)M_PI * freq / SAMPLE_RATE;
254
+ if (g_phase > 2.0f * (float)M_PI) g_phase -= 2.0f * (float)M_PI;
255
+ }
256
+ buf[i * 2] = smp;
257
+ buf[i * 2 + 1] = smp;
258
+ }
259
+
260
+ size_t w = i2s.write((uint8_t*)buf, sizeof(buf));
261
+ if (w != sizeof(buf))
262
+ Serial.printf("⚠ I2S short write: %d/%d\n", w, sizeof(buf));
263
+}
264
+
265
+// ==================== Setup ====================
266
+void setup() {
267
+ Serial.begin(115200);
268
+ delay(1000);
269
+ Serial.println("\n=== ES8311 Melody Player (ESP-IDF ref) ===");
270
+
271
+ // --- PA_CTRL (amplifier enable) ---
272
+ if (PA_CTRL >= 0) {
273
+ pinMode(PA_CTRL, OUTPUT);
274
+ digitalWrite(PA_CTRL, HIGH);
275
+ Serial.printf("PA_CTRL: GPIO%d = HIGH\n", PA_CTRL);
276
+ }
277
+
278
+ // --- I2C ---
279
+ Wire.begin(I2C_SDA, I2C_SCL);
280
+ Wire.setClock(100000);
281
+
282
+ Wire.beginTransmission(ES8311_ADDR);
283
+ if (Wire.endTransmission() == 0)
284
+ Serial.printf("✅ ES8311 found at 0x%02X\n", ES8311_ADDR);
285
+ else {
286
+ Serial.printf("❌ ES8311 NOT found at 0x%02X!\n", ES8311_ADDR);
287
+ while (1);
288
+ }
289
+
290
+ // --- Init ES8311 ---
291
+ es8311_init();
292
+ es8311_dac_start();
293
+
294
+ // --- I2S (Philips standard, 16kHz, 16-bit, stereo, ESP32=master) ---
295
+ i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK);
296
+ if (!i2s.begin(I2S_MODE_STD, SAMPLE_RATE,
297
+ I2S_DATA_BIT_WIDTH_16BIT,
298
+ I2S_SLOT_MODE_STEREO,
299
+ I2S_STD_SLOT_BOTH)) {
300
+ Serial.println("❌ I2S init failed!");
301
+ while (1);
302
+ }
303
+ Serial.printf("✅ I2S started: %d Hz, %d-bit, stereo, Philips\n",
304
+ SAMPLE_RATE, BIT_WIDTH);
305
+ Serial.println("▶ Playing: Twinkle Twinkle Little Star");
306
+}
307
+
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-dat.md
... ...
@@ -1,6 +1,8 @@
1 1
2 2
# ES8311-dat
3 3
4
+- [[oscilloscope-dat]] - [[ES8311-dat]]
5
+
4 6
- [[adc-dat]] - [[DAC-dat]] - [[record-dat]] - [[playback-dat]] - [[everest-semi-dat]]
5 7
6 8
- [[audio-dat]] - [[ES8311-dat]]
... ...
@@ -12,6 +14,7 @@
12 14
13 15
- [[NS4150-dat]]
14 16
17
+- [[I2S-dat]]
15 18
16 19
17 20
## board
... ...
@@ -120,6 +123,11 @@ digital microhpone
120 123
![](2025-11-01-19-36-04.png)
121 124
122 125
126
+## SCH 3
127
+
128
+![](2026-07-23-16-10-50.png)
129
+
130
+![](2026-07-23-16-11-27.png)
123 131
124 132
125 133
## ref
Chip-dat/ST-dat/STM32-dat/STM32-HDK-dat/2026-07-23-16-41-57.png
... ...
Binary files /dev/null and b/Chip-dat/ST-dat/STM32-dat/STM32-HDK-dat/2026-07-23-16-41-57.png differ
Chip-dat/ST-dat/STM32-dat/STM32-HDK-dat/STM32-HDK-dat.md
... ...
@@ -71,6 +71,13 @@ stm32flash -w firmware.bin -v -g 0x0 /dev/ttyUSB0
71 71
72 72
- [[Lora-HDK-dat]]
73 73
74
+
75
+
76
+## SCH
77
+
78
+![](2026-07-23-16-41-57.png)
79
+
80
+
74 81
## ref
75 82
76 83
- [[STM32-dat]]
Chip-dat/TI-dat/TI-Motor-dat/ULN2003-dat/2026-07-23-16-52-28.png
... ...
Binary files /dev/null and b/Chip-dat/TI-dat/TI-Motor-dat/ULN2003-dat/2026-07-23-16-52-28.png differ
Chip-dat/TI-dat/TI-Motor-dat/ULN2003-dat/ULN2003-dat.md
... ...
@@ -6,6 +6,13 @@
6 6
![](2025-05-04-13-59-56.png)
7 7
8 8
9
+
10
+
11
+## SCH
12
+
13
+![](2026-07-23-16-52-28.png)
14
+
15
+
9 16
## ref
10 17
11 18
- [chip link](https://www.ti.com/product/ULN2003A)
Sensor-dat/sensor-dat.md
... ...
@@ -1,6 +1,9 @@
1 1
2 2
# sensor-dat
3 3
4
+
5
+- [[sensor-weight-dat]] - [[HX711-dat]] - [[sensor-dat]] - [[ADC-dat]]
6
+
4 7
- [[sensor-Camera-dat]] - [[sensor-microphone-dat]]
5 8
6 9
- [[sensor-motion-dat]] - [[sensor-PIR-dat]] - [[radar-sensor]] - [[3-axis-Accelerometer-dat]] - [[3-axis-gyroscope-dat]] - [[3-axis-magnetic-dat]] - [[6-axis-dat]]
... ...
@@ -106,6 +109,9 @@ Here’s a list of 30 commonly used types of sensors, categorized by their typic
106 109
- Piezoelectric Vibration Sensors
107 110
108 111
### Force and Weight Sensors
112
+
113
+- [[sensor-weight-dat]] - [[HX711-dat]] - [[sensor-dat]]
114
+
109 115
- Load Cells
110 116
- Force Sensitive Resistors (FSRs)
111 117
Sensor-dat/sensor-gas-dat/2026-07-23-16-25-20.png
... ...
Binary files /dev/null and b/Sensor-dat/sensor-gas-dat/2026-07-23-16-25-20.png differ
Sensor-dat/sensor-gas-dat/sensor-gas-dat.md
... ...
@@ -10,6 +10,14 @@
10 10
11 11
- [[sensor-TVOC-dat]]
12 12
13
+- [[SGP30-dat]]
14
+
15
+
16
+
17
+
18
+## SGP30
19
+
20
+![](2026-07-23-16-25-20.png)
13 21
14 22
## ref
15 23
Sensor-dat/sensor-motion-dat/sensor-motion-dat.md
... ...
@@ -29,6 +29,8 @@
29 29
30 30
## Sensor Comparison Table
31 31
32
+- [[TCRT5000-dat]] - [[SMO1070-dat]]
33
+
32 34
- [[sensor-radar-dat]]
33 35
34 36
| | **PIR** | **RCWL** | **Radar** | **Lidar** |
Tech-dat/Interface-dat/I2S-dat/I2S-dat.md
... ...
@@ -44,7 +44,7 @@ To get this working, you simply need to map your microphone's pins to the ESP32
44 44
45 45
| Microphone Label | I2S Standard Name | variants | ESP32 Function | Role |
46 46
|:------------------|:---------------------|---|:---------------|:--------------------------------------------------|
47
-| **CLK** (or BCLK) | **SCK** (Bit Clock) | CLK | Output | The heartbeat that times every individual bit. |
47
+| **CLK** (or BCLK SCLK) | **SCK** (Bit Clock) | CLK | Output | The heartbeat that times every individual bit. |
48 48
| **L/R** (or WS) | **WS** (Word Select) | FS | Output | Toggles to define the start of Left/Right frames. |
49 49
| **DATA** (or SD) | **SDIN** (Data In) | TX | Input | The digital audio stream entering the ESP32. |
50 50
Tech-dat/Interface-dat/Serial-dat/2026-07-23-16-17-36.png
... ...
Binary files /dev/null and b/Tech-dat/Interface-dat/Serial-dat/2026-07-23-16-17-36.png differ
Tech-dat/Interface-dat/Serial-dat/Serial-dat.md
... ...
@@ -205,6 +205,16 @@ While originally designed in the 20th century to connect computers (DTE) to tele
205 205
* **Telecommunications:** Network routers and switches still frequently use full serial interfaces for console management.
206 206
207 207
208
+## SCH
209
+
210
+- [[CH340-dat]] with - [[isolation-dat]]
211
+
212
+![](2026-07-23-16-17-36.png)
213
+
214
+
215
+
216
+
217
+
208 218
## ref
209 219
210 220
software [[com-monitor-dat]]
Tech-dat/acturator-dat/relay-dat/2026-07-23-16-20-23.png
... ...
Binary files /dev/null and b/Tech-dat/acturator-dat/relay-dat/2026-07-23-16-20-23.png differ
Tech-dat/acturator-dat/relay-dat/relay-dat.md
... ...
@@ -127,7 +127,9 @@ For fast-switching applications, a 1N5819 Schottky diode (rated 40V, 1A) might b
127 127
128 128
129 129
130
+## SCH
130 131
132
+![](2026-07-23-16-20-23.png)
131 133
132 134
133 135
## ref
Tech-dat/audio-dat/2026-07-23-16-45-37.png
... ...
Binary files /dev/null and b/Tech-dat/audio-dat/2026-07-23-16-45-37.png differ
Tech-dat/audio-dat/audio-dat.md
... ...
@@ -114,6 +114,13 @@ SCH2
114 114
115 115
116 116
117
+## unisound
118
+
119
+- [[unisound-dat]] - [[audio-dat]]
120
+
121
+![](2026-07-23-16-45-37.png)
122
+
123
+
117 124
## ref
118 125
119 126
- [[video-dat]] - [[HDMI-dat]]
Tech-dat/interactive-dat/display-dat/OLED-dat/2026-07-23-16-28-32.png
... ...
Binary files /dev/null and b/Tech-dat/interactive-dat/display-dat/OLED-dat/2026-07-23-16-28-32.png differ
Tech-dat/interactive-dat/display-dat/OLED-dat/OLED-dat.md
... ...
@@ -37,6 +37,8 @@
37 37
38 38
## SCH
39 39
40
+![](2026-07-23-16-28-32.png)
41
+
40 42
### using with STM32 SPI2
41 43
42 44
![](2024-01-13-17-43-38.png)
Tech-dat/memory-dat/flash-dat/spi-flash-dat/2026-07-23-16-26-18.png
... ...
Binary files /dev/null and b/Tech-dat/memory-dat/flash-dat/spi-flash-dat/2026-07-23-16-26-18.png differ
Tech-dat/memory-dat/flash-dat/spi-flash-dat/spi-flash-dat.md
... ...
@@ -33,6 +33,10 @@ Yes, 8-bit SPI flash does exist in the context of the ESP32 and similar chips. T
33 33
34 34
## SPI Flash SCH
35 35
36
+general 1
37
+
38
+![](2026-07-23-16-26-18.png)
39
+
36 40
general design
37 41
38 42
![](2026-01-23-03-42-16.png)
app-dat/alert-dat/2026-07-23-16-47-33.png
... ...
Binary files /dev/null and b/app-dat/alert-dat/2026-07-23-16-47-33.png differ
app-dat/alert-dat/alert-dat.md
... ...
@@ -0,0 +1,9 @@
1
+
2
+
3
+# alert-dat
4
+
5
+![](2026-07-23-16-47-33.png)
6
+
7
+
8
+
9
+## ref
... ...
\ No newline at end of file
app-dat/line-follower-dat/2026-07-23-16-51-20.png
... ...
Binary files /dev/null and b/app-dat/line-follower-dat/2026-07-23-16-51-20.png differ
app-dat/line-follower-dat/line-follower-dat.md
... ...
@@ -0,0 +1,15 @@
1
+
2
+# line-follower-dat
3
+
4
+
5
+- [[line-follower-dat]] - [[TCRT5000-dat]] - [[SMO1070-dat]]
6
+
7
+
8
+## SCH
9
+
10
+![](2026-07-23-16-51-20.png)
11
+
12
+
13
+
14
+## ref
15
+
fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-36-27.png
... ...
Binary files /dev/null and b/fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-36-27.png differ
fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-37-52.png
... ...
Binary files /dev/null and b/fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-37-52.png differ
fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-38-21.png
... ...
Binary files /dev/null and b/fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/2026-07-23-15-38-21.png differ
fab-tools-dat/fab-tools-electronic-dat/Oscilloscope-dat/oscilloscope-dat.md
... ...
@@ -63,6 +63,24 @@ $299 12bit == https://youtu.be/3hyp0-0ns9U?t=680
63 63
64 64
65 65
66
+## test demo
67
+
68
+
69
+normal mode - 5V - 50uS
70
+
71
+- [[ES8311-dat]] - [[oscilloscope-dat]]
72
+
73
+pin MCLK
74
+
75
+![](2026-07-23-15-36-27.png)
76
+
77
+pin LRCK
78
+
79
+![](2026-07-23-15-37-52.png)
80
+
81
+pin SCLK
82
+
83
+![](2026-07-23-15-38-21.png)
66 84
67 85
## ref
68 86
power-dat/LDO-dat/2026-07-23-16-53-04.png
... ...
Binary files /dev/null and b/power-dat/LDO-dat/2026-07-23-16-53-04.png differ
power-dat/LDO-dat/LDO-dat.md
... ...
@@ -247,7 +247,9 @@ MAX1735 - 200mA, Negative-Output, Low-Dropout Linear Regulator in SOT23
247 247
- [[maxim-dat]]
248 248
249 249
250
+## breakout board
250 251
252
+![](2026-07-23-16-53-04.png)
251 253
252 254
253 255
## ref