Bài 8: Buzzer và tạo âm thanh

Mục tiêu bài học

  • Làm quen với linh kiện Buzzer (loa nhỏ).
  • Sử dụng các hàm tone()noTone() để tạo âm thanh.
  • Phát một đoạn nhạc đơn giản.

Giới thiệu về Buzzer

Buzzer là thiết bị phát âm thanh khi được cấp tín hiệu dao động. Có hai loại:

  • Active Buzzer: phát âm thanh khi cấp nguồn.
  • Passive Buzzer: cần tín hiệu dao động để phát âm thanh (thường dùng với Arduino).

Kết nối phần cứng

  • Kết nối chân dương của buzzer vào chân D11 (hoặc chân digital bất kỳ).
  • Chân âm của buzzer nối GND.

Hướng dẫn nạp code

Bước 1: Kết nối Arduino Uno với máy tính

  • Sử dụng cáp USB (loại USB A to B, giống cáp máy in).

  • Cắm một đầu vào Arduino Uno, đầu còn lại vào cổng USB của máy tính.

Bước 2: Cài đặt phần mềm Arduino IDE

Bước 3: Mở Arduino IDE và thiết lập cấu hình

  1. Mở Arduino IDE.

  2. Vào menu Tools (Công cụ)Board (Bo mạch) → chọn Arduino Uno.

  3. Vào ToolsPort → chọn đúng cổng COM (thường là COM3, COM4,... tùy máy).

    Nếu không thấy cổng COM, hãy kiểm tra driver USB hoặc cài CH340 Driver nếu Arduino dùng chip CH340.

Bước 4: Cài đặt phần mềm Arduino IDE

  • Nhấn nút Upload (mũi tên →) trên thanh công cụ.

  • Quan sát thanh trạng thái, khi hiện "Done uploading" nghĩa là nạp thành công.

Ví dụ: Phát âm thanh đơn

#define BUZZER_PIN 11

void setup() {
  tone(BUZZER_PIN, 1000);  // Phát âm thanh tần số 1000Hz
  delay(1000);             // Kêu trong 1 giây
  noTone(BUZZER_PIN);      // Tắt âm thanh
}

void loop() {
  // Không cần gì thêm
}

Phát nhạc đơn giản (mã hóa giai điệu)

#define BUZZER_PIN 11

int melody[] = {
  262, 294, 330, 349, 392, 440, 494, 523
};

void setup() {
  for (int i = 0; i < 8; i++) {
    tone(BUZZER_PIN, melody[i]);
    delay(300);
    noTone(BUZZER_PIN);
    delay(100);
  }
}

void loop() {
}
🎵

Một số hàm chính

Hàm Chức năng
tone(pin, frequency) Phát âm thanh với tần số xác định (Hz) trên chân pin.
tone(pin, frequency, duration) Phát âm thanh với tần số và thời gian xác định (ms).
noTone(pin) Dừng phát âm thanh trên chân pin.

Tạo bản nhạc Vì Nhân Dân Quên Mình

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <avr/pgmspace.h>  // Thư viện hỗ trợ đọc Flash

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buzzerPin = 11;
const int buttonPin = 10;
bool isPlaying = false;

struct Note {
  const char* noteName;
  float duration;
  const char* lyric;
};

float noteFreq(const char* note) {
  if (strcmp(note, "C4") == 0) return 261.62;
  if (strcmp(note, "E4") == 0) return 329.62;
  if (strcmp(note, "G4") == 0) return 392;
  if (strcmp(note, "D4") == 0) return 293.66;
  if (strcmp(note, "B4") == 0) return 493.88;
  if (strcmp(note, "D5") == 0) return 587.32;
  if (strcmp(note, "C5") == 0) return 523.25;
  if (strcmp(note, "A4") == 0) return 440;
  if (strcmp(note, "E5") == 0) return 659.26;
  if (strcmp(note, "F4") == 0) return 349.22;
  if (strcmp(note, "G#4") == 0) return 415.3;
  return 0; // REST
}
// Lưu trữ mảng trong Flash
const Note melody[] PROGMEM= {
  {"C4", 4, "Vi"},
  {"E4", 10, "nhan"},
  {"G4", 3, "dan"},
  {"E4", 4, "quen"},
  {"D4", 14, "quen"},
  {"C4", 3, "minh"},
  {"C4", 4, "Vi"},
  {"E4", 10, "nhan"},
  {"G4", 3, "dan"},
  {"B4", 4, "hy"},
  {"D5", 14, "hy"},
  {"C5", 3, "sinh"},
  {"C5", 4, "Anh"},
  {"C5", 10, "em"},
  {"C5", 3, "oi"},
  {"A4", 4, "vi"},
  {"B4", 14, "nhan"},
  {"C5", 3, "dan"},
  {"B4", 4, "quen"},
  {"A4", 12, "quen"},
  {"G4", 1.5, "minh"},
  {"G4", 4, "Doan"},
  {"A4", 10, "Ve"},
  {"E5", 3, "Quoc"},
  {"E5", 4, "chung"},
  {"D5", 14, "chung"},
  {"C5", 3, "ta"},
  {"G4", 4, "o"},
  {"A4", 12, "nhan"},
  {"C5", 3, "dan"},
  {"B4", 4, "ma"},
  {"G4", 12, "ma"},
  {"A4", 3, "ra"},
  {"D4", 4, "Duoc"},
  {"F4", 10, "dan"},
  {"A4", 3, "men"},
  {"D4", 4, "duoc"},
  {"E4", 12, "dan"},
  {"G4", 3, "tin"},
  {"E4", 4, "muon"},
  {"D4", 12, "phan"},
  {"C4", 1.5, "phan"},
  {"C4", 4, "The"},
  {"E4", 10, "vi"},
  {"G4", 3, "dan"},
  {"G4", 4, "suot"},
  {"E4", 14, "doi"},
  {"E4", 2.5, "doi"},
  {"E4", 4, "The"},
  {"G4", 10, "tranh"},
  {"A4", 3, "dau"},
  {"A4", 4, "khong"},
  {"F4", 14, "khong"},
  {"F4", 2.5, "ngung"},
  {"F4", 4, "Vi"},
  {"A4", 10, "dat"},
  {"C5", 3, "nuoc"},
  {"B4", 4, "than"},
  {"A4", 10, "yeu"},
  {"G4", 3, "ma"},
  {"E4", 4, "hy"},
  {"F4", 10, ""},
  {"G4", 1.5, "sinh"},
  {"G4", 4, "The"},
  {"A4", 10, "diet"},
  {"E5", 3, "het"},
  {"E5", 4, "de"},
  {"D5", 10, "quoc"},
  {"C5", 3, "kia"},
  {"G4", 4, "Danh"},
  {"A4", 10, "tu"},
  {"A4", 3, "do"},
  {"A4", 4, "hoa"},
  {"G#4", 14, ""},
  {"A4", 2.5, "binh"},
  {"G4", 4, "Doan"},
  {"A4", 12, "ve"},
  {"D5", 3, "quoc"},
  {"B4", 4, "quen"},
  {"A4", 12, "minh"},
  {"G4", 3, "vi"},
  {"E4", 4, "nhan"},
  {"G4", 10, ""},
  {"C5", 1.5, "dan"}
};

const int melodyLength = sizeof(melody) / sizeof(melody[0]);
const float speedFactor = 1.5;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  lcd.setCursor(0, 0);
  lcd.print("Dang phat nhac...");
  delay(1000);
}

void loop() {
  waitForPlay();

  for (int i = 0; i < melodyLength; i++) {
    Note temp;
    memcpy_P(&temp, &melody[i], sizeof(Note)); // Đọc dữ liệu từ Flash

    float freq = noteFreq(temp.noteName);
    int duration = (1000 / temp.duration) * speedFactor;

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Vi dan quen minh");
    lcd.setCursor(0, 1);
    lcd.print("Note:");
    lcd.print(temp.noteName);
    lcd.print(" | ");
    lcd.print(temp.lyric);

    if (freq > 0) tone(buzzerPin, freq);

    int elapsed = 0;
    const int step = 10;
    while (elapsed < duration) {
      if (digitalRead(buttonPin) == LOW) {
        noTone(buzzerPin);
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Tam dung...");
        delay(500);

        while (digitalRead(buttonPin) == HIGH) delay(50);

        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Tiep tuc...");
        delay(500);

        if (freq > 0) tone(buzzerPin, freq);
      }

      delay(step);
      elapsed += step;
    }

    noTone(buzzerPin);
    delay(duration * 0.3);
  }

  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Het nhac.");
  delay(2000);
}

void waitForPlay() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Phat nhac");
  while (digitalRead(buttonPin) == HIGH) delay(50);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Dang phat nhac...");
  delay(1000);
}

Nhấn nút trong hình để phát nhạc

NOTE GND VCC SD A SC L GND D10

Nhận xét

Mới hơn Cũ hơn