d3087f8df8759ddd31c66dc414dfe0945db0b35d
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 |  |
| 43 | 43 | |
| 44 | +SCH 2 |
|
| 45 | + |
|
| 46 | + |
|
| 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 | + |
|
| 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 |  |
| 121 | 124 | |
| 122 | 125 | |
| 126 | +## SCH 3 |
|
| 127 | + |
|
| 128 | + |
|
| 129 | + |
|
| 130 | + |
|
| 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 | + |
|
| 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 |  |
| 7 | 7 | |
| 8 | 8 | |
| 9 | + |
|
| 10 | + |
|
| 11 | +## SCH |
|
| 12 | + |
|
| 13 | + |
|
| 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 | +
|
|
| 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 | +
|
|
| 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 | + |
|
| 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 | + |
|
| 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 | + |
|
| 41 | + |
|
| 40 | 42 | ### using with STM32 SPI2 |
| 41 | 43 | |
| 42 | 44 |  |
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 | + |
|
| 39 | + |
|
| 36 | 40 | general design |
| 37 | 41 | |
| 38 | 42 |  |
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 | + |
|
| 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 | + |
|
| 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 | +
|
|
| 76 | +
|
|
| 77 | +pin LRCK
|
|
| 78 | +
|
|
| 79 | +
|
|
| 80 | +
|
|
| 81 | +pin SCLK
|
|
| 82 | +
|
|
| 83 | +
|
|
| 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 | + |
|
| 251 | 253 | |
| 252 | 254 | |
| 253 | 255 | ## ref |