002 — ESP32-S3 simulation

An interactive ESP32-S3 circuit simulation you can run free in your browser on Velxio, by a2982887131.

Components

Sketch code

// ==================== 引脚定义 ====================
const uint8_t LED_PINS[8] = {4, 5, 6, 7, 15, 16, 17, 18}; 
const uint8_t BUZZER_PIN  = 21;
const uint8_t BUTTON_PIN  = 14;

const uint8_t LED_COUNT = 8;

// ==================== 音符频率(C大调) ====================
#define NOTE_C4  262
#define NOTE_D4  294
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_G4  392
#define NOTE_A4  440
#define NOTE_B4  494
#define NOTE_C5  523

// ==================== 音符结构体 ====================
struct Note {
  uint16_t freq;   // 频率(Hz),0 表示休止符
  uint16_t dur;    // 时值(ms)
};

// 节奏基准:四分音符 350ms,二分音符 700ms
const uint16_t Q = 350;
const uint16_t H = 700;

// ==================== 曲谱:小星星 ====================
const Note melody[] = {
  // 一闪一闪亮晶晶
  {NOTE_C4, Q}, {NOTE_C4, Q}, {NOTE_G4, Q}, {NOTE_G4, Q},
  {NOTE_A4, Q}, {NOTE_A4, Q}, {NOTE_G4, H},
  // 满天都是小星星
  {NOTE_F4, Q}, {NOTE_F4, Q}, {NOTE_E4, Q}, {NOTE_E4, Q},
  {NOTE_D4, Q}, {NOTE_D4, Q}, {NOTE_C4, H},
  // 挂在天上放光明
  {NOTE_G4, Q}, {NOTE_G4, Q}, {NOTE_F4, Q}, {NOTE_F4, Q},
  {NOTE_E4, Q}, {NOTE_E4, Q}, {NOTE_D4, H},
  // 好像许多小眼睛
  {NOTE_G4, Q}, {NOTE_G4, Q}, {NOTE_F4, Q}, {NOTE_F4, Q},
  {NOTE_E4, Q}, {NOTE_E4, Q}, {NOTE_D4, H},
  // 一闪一闪亮晶晶
  {NOTE_C4, Q}, {NOTE_C4, Q}, {NOTE_G4, Q}, {NOTE_G4, Q},
  {NOTE_A4, Q}, {NOTE_A4, Q}, {NOTE_G4, H},
  // 满天都是小星星
  {NOTE_F4, Q}, {NOTE_F4, Q}, {NOTE_E4, Q}, {NOTE_E4, Q},
  {NOTE_D4, Q}, {NOTE_D4, Q}, {NOTE_C4, H},
};

const int MELODY_LEN = sizeof(melody) / sizeof(melody[0]);

// ==================== 全局状态 ====================
bool isPlaying     = false;   // 是否正在播放
bool stopRequested = false;   // 播放中收到停止请求

// ==================== LED 控制 ====================
void allLedsOff() {
  for (uint8_t i = 0; i < LED_COUNT; i++) {
    digitalWrite(LED_PINS[i], LOW);
  }
}

// 根据当前音符序号,点亮对应位置的 LED(跑马灯效果)
void showLedAt(int index) {
  allLedsOff();
  digitalWrite(LED_PINS[index % LED_COUNT], HIGH);
}

// ==================== 按键读取(带软件消抖) ====================
// 需被周期性调用(约每 5ms 一次)
bool buttonDown() {
  static uint8_t lowCount = 0;
  if (digitalRead(BUTTON_PIN) == LOW) {
    if (lowCount < 3) lowCount++;      // 连续 3 次读到低电平才算按下
  } else {
    lowCount = 0;
  }
  return (lowCount >= 3);
}

// ==================== 播放单个音符 ====================
void playNote(int idx) {
  const Note &n = melody[idx];
  unsigned long start = millis();

  // ---- 发声 & 亮灯阶段(占音符时值的 3/4,形成断奏节奏感)----
  if (n.freq > 0) {
    tone(BUZZER_PIN, n.freq);          // 无源蜂鸣器输出方波
  }
  showLedAt(idx);                      // 点亮一个 LED,位置随音符推进

  unsigned long onTime = (unsigned long)n.dur * 3 / 4;
  while (millis() - start < onTime) {
    if (buttonDown()) {                // 播放中检测按键 -> 停止
      stopRequested = true;
      break;
    }
    delay(5);
  }

  // ---- 熄灭 & 静音,剩余时间作为音符间隔 ----
  noTone(BUZZER_PIN);
  allLedsOff();

  while (millis() - start < n.dur) {
    if (buttonDown()) {
      stopRequested = true;
      break;
    }
    delay(5);
  }
}

// ==================== 播放整首曲子 ====================
void playSong() {
  // 等

More projects by a2982887131