【得捷Follow me第3期】XIAO-PWM音乐播放器
[复制链接]
演示视频:【得捷Follow me第3期】项目总结-EEWORLD大学堂
项目介绍
有幸参加了这次得捷Follow me第3期活动。通过这个活动,深入了解了Seeed Studio XIAO ESP32C3开发板及相关组件的使用,涉及了MicroPython、OLED屏幕、蜂鸣器、WiFi网络、外部传感器等多个方面。以下是我在每个任务中的具体实现过程。
任务1:使用MicroPython系统
熟悉Seeed Studio XIAO ESP32C3开发板基本操作,安装esptool,并给开发板刷写MicroPython系统,完成入门程序的运行
搭配器件:Seeed Studio XIAO ESP32C3
硬件准备
使用Seeed Studio XIAO ESP32C3和扩展板作为硬件。
软件准备
1 下载安装 Thonny IDE (Windows
2 下载esptool-win64
3 下载 ESP32_GENERIC_C3-20231005-v1.21.0.bin
烧录固件
按住BOOT按钮,同时按住BOOT按钮,将电路板连接到PC,然后释放它以进入bootloader模式。
然后进入esptool-v4.6.2-win64目录执行烧录命令:
./esptool.exe --chip esp32c3 --port COM18 --baud 921600 --before default_reset --after hard_reset --no-stub write_flash --flash_mode dio --flash_freq 80m 0x0 .\ESP32_GENERIC_C3-20231005-v1.21.0.bin
测试MicroPython状态;
任务2:驱动扩展板上的OLED屏幕
使用扩展板上的OLED屏幕显示文字和图形
搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO
安装驱动OLED显示屏需要的ssd1306库
import time
from machine import Pin, SoftI2C
import ssd1306
import math
# ESP8266 Pin assignment
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
oled.fill(0) # Clear the screen
oled.text("FollowMe3 !", 10, 15)
oled.text("/////", 30, 40)
oled.text("(`3`)y", 30, 55)
oled.show() # Show the text
这段代码通过ESP32C3控制SSD1306 OLED显示屏,在屏幕上显示"FollowMe3"等文本信息。它使用SoftI2C进行I2C通信,初始化硬件引脚并清空显示屏,然后在指定位置显示文本,最后更新显示。
import time
from machine import Pin, SoftI2C
import ssd1306
# ESP8266 Pin assignment
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
# Clear the screen
oled.fill(0)
# Square parameters
square_size = 20
center_x = oled_width // 2
center_y = oled_height // 2
# Draw a square in the center of the screen
square_x = center_x - square_size // 2
square_y = center_y - square_size // 2
oled.fill_rect(square_x, square_y, square_size, square_size, 1)
# Update the OLED display
oled.show()
# Wait for a while before exiting
time.sleep(5)
这段代码使用ssd1306库在OLED显示屏中心绘制一个正方形,通过调整参数可以改变正方形的大小。代码首先初始化OLED显示屏,清空屏幕,计算正方形在屏幕中心的位置,然后使用fill_rect方法绘制一个填充的矩形(正方形),最后更新显示并等待5秒后退出。
任务3:控制蜂鸣器播放音乐
使用Seeed Studio XIAO ESP32C3控制蜂鸣器发出不同频率的声音,并播放一段音乐
搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO
import time
import machine
# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
while True:
buzzer.freq(500)
buzzer.duty(512)
time.sleep(1)
buzzer.duty(0)
time.sleep(1)
buzzer.freq(1000)
buzzer.duty(512)
time.sleep(1)
buzzer.duty(0)
time.sleep(1)
在这个代码中,首先播放500 Hz的音调,然后播放1000 Hz的音调。
import machine
import time
# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)
# Defining frequency of each music note
NOTE_C4 = 262
NOTE_D4 = 294
NOTE_E4 = 330
NOTE_F4 = 349
NOTE_G4 = 392
NOTE_A4 = 440
NOTE_B4 = 494
NOTE_C5 = 523
NOTE_D5 = 587
NOTE_E5 = 659
NOTE_F5 = 698
NOTE_G5 = 784
NOTE_A5 = 880
NOTE_B5 = 988
# Music notes of the song, 0 is a rest/pulse
notes = [
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
NOTE_C5, NOTE_A4, NOTE_B4, 0,
NOTE_A4, NOTE_A4,
#Repeat of first part
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
NOTE_A4, NOTE_G4, NOTE_A4, 0,
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
NOTE_D5, NOTE_E5, NOTE_A4, 0,
NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
NOTE_C5, NOTE_A4, NOTE_B4, 0,
#End of Repeat
NOTE_E5, 0, 0, NOTE_F5, 0, 0,
NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
NOTE_D5, 0, 0, NOTE_C5, 0, 0,
NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4,
NOTE_E5, 0, 0, NOTE_F5, 0, 0,
NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
NOTE_D5, 0, 0, NOTE_C5, 0, 0,
NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4
]
# Durations (in ms) of each music note of the song
# Quarter Note is 250 ms when songSpeed = 1.0
durations = [
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 125, 250, 125,
125, 125, 250, 125, 125,
250, 125, 250, 125,
125, 125, 250, 125, 125,
125, 125, 375, 375,
250, 125,
#Rpeat of First Part
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 375, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 250, 125, 125,
125, 125, 125, 250, 125,
125, 125, 250, 125, 125,
250, 125, 250, 125,
125, 125, 250, 125, 125,
125, 125, 375, 375,
#End of Repeat
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 125, 125, 125, 375,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 500,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 125, 125, 125, 375,
250, 125, 375, 250, 125, 375,
125, 125, 125, 125, 125, 500
]
def play_song():
total_notes = len(notes)
for i in range(total_notes):
current_note = notes[i]
wait = durations[i]
if current_note != 0:
buzzer.duty(512) # Set duty cycle for sound
buzzer.freq(current_note) # Set frequency of the note
else:
buzzer.duty(0) # Turn off the sound
time.sleep_ms(wait)
buzzer.duty(0) # Turn off the sound
while True:
# Play the song
play_song()
这段代码使用MicroPython的time的machine模块控制ESP32C3开发板上的蜂鸣器(buzzer)播放了一首简单的音乐。通过定义音符和它们的频率,以及每个音符的时长,代码按照指定的音乐谱演奏音乐。音符和时长以列表的形式存储,其中0表示休止符。play_song 函数遍历这些列表,根据当前音符的频率和时长设置蜂鸣器,并在每次演奏后暂停一段时间。
在主循环中,代码持续播放这首音乐。如果想要播放其他曲目或调整音乐的音符和时长,只需修改 notes 和 durations 列表即可。
任务4:连接WiFi网络
将Seeed Studio XIAO ESP32C3连接到WiFi网络,并访问互联网信息
搭配器件:Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO、RF ANT 2.4GHZ/5.5GHZ PCB TRACE
时区API查找:
Full list of Timezones, via World Time API: Simple JSON/plain-text API to obtain the current time in, and related data about, a timezone.
在这个任务中,我使用了时区API来获取当前时间和相关时区信息。通过这个经验,我了解了如何通过网络服务获取实时时间,这对于实际项目中的时间同步非常有用。
from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import time
import network
import urequests
import ujson
# ESP32 Pin assignment
# i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
# ESP8266 Pin assignment
i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
station = network.WLAN(network.STA_IF)
station.active(True)
# Network settings
wifi_ssid = "CMCC-uE3n"
wifi_password = "q8n94w3n"
url = "http://worldtimeapi.org/api/timezone/Asia/Shanghai"
print("Scanning for WiFi networks, please wait...")
authmodes = ['Open', 'WEP', 'WPA-PSK' 'WPA2-PSK4', 'WPA/WPA2-PSK']
for (ssid, bssid, channel, RSSI, authmode, hidden) in station.scan():
print("* {:s}".format(ssid))
print(" - Channel: {}".format(channel))
print(" - RSSI: {}".format(RSSI))
print(" - BSSID: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*bssid))
print()
# Continually try to connect to WiFi access point
while not station.isconnected():
# Try to connect to WiFi access point
print("Connecting...")
station.connect(wifi_ssid, wifi_password)
time.sleep(10)
# Display connection details
print("Connected!")
print("My IP Address:", station.ifconfig()[0])
while True:
# Perform HTTP GET request on a non-SSL web
response = urequests.get(url)
# Check if the request was successful
if response.status_code == 200:
# Parse the JSON response
data = ujson.loads(response.text)
# Extract the "datetime" field for New York
ny_datetime = data["datetime"]
# Split the date and time components
date_part, time_part = ny_datetime.split("T")
# Get only the first two decimal places of the time
time_part = time_part[:8]
# Get the timezone
timezone = data["timezone"]
# Clear the OLED display
oled.fill(0)
# Display the New York date and time on separate lines
oled.text("Shanghai Date:", 0, 0)
oled.text(date_part, 0, 10)
oled.text("Shanghai Time:", 0, 20)
oled.text(time_part, 0, 30)
oled.text("Timezone:", 0, 40)
oled.text(timezone, 0, 50)
# Update the display
oled.show()
else:
oled.text("Failed to get the time for New York!")
# Update the display
oled.show()
这段代码连接到Wi-Fi网络后,向在线API发出HTTP GET请求以获取上海的当前日期和时间信息,然后将这些信息显示在SSD1306 OLED的屏幕上。代码首先扫描可用的Wi-Fi网络,尝试连接到指定的网络。一旦连接成功,它会持续地从在线API获取上海的日期、时间和时区信息,并将这些信息显示在OLED屏幕上。
任务5:使用外部传感器
连接环境光传感器或温湿度传感器,获取传感器的数值,并转换成真实的物理量
搭配器件: Seeed Studio XIAO ESP32C3、Seeed Studio Expansion Board Base for XIAO、 Grove - AHT20 I2C Industrial Grade Temperature and Humidity Sensor、Grove - Light Sensor v1.2
该任务实现是通过Arudion平台实现的
//#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include "AHT20.h"
AHT20 AHT;
// U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); //Low spped I2C
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
const int sensorPin = A0;
void setup(void) {
u8x8.begin();
u8x8.setFlipMode(0); // set number from 1 to 3, the screen word will rotary 180
pinMode(sensorPin, INPUT); // declare the sensorPin as an INPUT
AHT.begin();
Serial.begin(115200);
while (!Serial);
}
const char *convert_FPS(uint16_t fps) {
static char buf[6];
strcpy(buf, u8g2_u8toa( (uint8_t)(fps), 3));
buf[3] = '.';
buf[4] = (fps % 10) + '0';
buf[5] = '\0';
return buf;
}
void show_result(const char *s, uint16_t fps) {
// assign default color value
// u8g2.setColorIndex(draw_color);
u8x8.setFont(u8g2_font_8x13B_tf);
// u8x8.clearBuffer();
u8x8.drawString(0,12, s);
u8x8.drawString(0,24, convert_FPS(fps));
// u8g2.sendBuffer();
}
void loop(void) {
float humi, temp;
int ret = AHT.getSensor(&humi, &temp);
// read the value from the sensor:
int light = analogRead(sensorPin);
if(ret) // GET DATA OK
{
Serial.print("humidity: ");
Serial.print(humi*100);
Serial.print("%\t temerature: ");
Serial.print(temp);
Serial.print("%\t light: ");
Serial.println(light);
}
else // GET DATA FAIL
{
Serial.println("GET DATA FROM AHT20 FAIL");
}
u8x8.setFont(u8x8_font_torussansbold8_r);
u8x8.setCursor(0, 0);
u8x8.printf("%.2f %.2f %d", temp,humi*100, (uint8_t)light);
// delay(1000);
}
这段Arduino代码使用AHT20传感器读取环境温湿度,同时通过Light传感器获取环境光强度,并将这些数据显示在连接的SSD1306 OLED屏幕上。代码还通过串口输出将温湿度和光照度数据发送到串口监视器。
任务6:XIAO-PWM任意音乐播放器
在前几个任务中,已经成功体验了Seeed Studio XIAO ESP32C3的基本操作,包括MicroPython系统的刷写、OLED屏幕的驱动、蜂鸣器的控制等。最后一项任务是任务3的基础之上进一步实现任意音乐的播放。为了简化音乐代码的添加,使用MuseScore 3软件MID文件进行初步转换,最终通过转换工具自动生成相应的音乐代码。
1. 使用软件和准备工作
使用了以下软件:
2. 获取音乐对应的MID文件
首先,我们需要获得音乐的MID文件。你可以直接下载MID格式音乐文件,或者将某段音乐转换为MID文件。在这个例子中,我们使用现成的MIDI文件。如果需要将其他格式音乐转换为MID格式,可以参考网络上的相关教程。
3. 将MID文件转为MUSICXML文件
MusicXML 是一种用于表示音乐符号、音符、和其他与音乐相关的信息的 XML 文件格式。
打开 MuseScore 3,将MID文件拖拽或添加进软件。然后点击“文件”→“导出”,设置输出文件为musicxml格式。
4. 提取MUSICXML文件关键字,自动生成音乐代码
接下来,我们使用 C 语言编写代码,用于提取musicxml文件中的音符信息。以下是代码的主要结构:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int convertCharToInt(char x);
void parseMusicXML(const char* filename);
int main() {
char filename[] = "china.musicxml";
parseMusicXML(filename);
return 0;
}
void parseMusicXML(const char* filename) {
FILE* filePointer;
char musicSymbol[11] = {0};
int noteCount = 0;
int errorCount = 0;
int flag = 0;
int beatsPerMeasure = 0;
int printCounter = 0;
int divisions = 1;
int noteDuration = 1;
int currentPosition = 0;
filePointer = fopen(filename, "r");
if (filePointer == NULL) {
printf("Failed to open file\n");
return;
}
printf("Number of beats per measure: ");
scanf("%d", &beatsPerMeasure);
printf("Number of beats per measure: %d ", beatsPerMeasure);
for (int i = 0;; i++) {
fseek(filePointer, i, SEEK_SET);
musicSymbol[0] = fgetc(filePointer);
if (musicSymbol[0] == EOF)
break;
for (int j = 1; j < 11; j++) {
fseek(filePointer, i + j, SEEK_SET);
musicSymbol[j] = fgetc(filePointer);
if (musicSymbol[j] == EOF)
break;
}
if (musicSymbol[0] == '<' && strncmp(&musicSymbol[1], "divisions>", 10) == 0) {
for (int j = 0;; j++) {
fseek(filePointer, i + 11 + j, SEEK_SET);
if (fgetc(filePointer) == '<')
break;
else {
if (j == 0) {
fseek(filePointer, i + 11 + j, SEEK_SET);
divisions = convertCharToInt(fgetc(filePointer));
} else {
fseek(filePointer, i + 11 + j, SEEK_SET);
divisions = 10 * divisions + convertCharToInt(fgetc(filePointer));
}
}
}
printf("%d,", divisions);
break;
}
}
while (!feof(filePointer)) {
fseek(filePointer, currentPosition, SEEK_SET);
musicSymbol[0] = fgetc(filePointer);
if (musicSymbol[0] == EOF)
break;
for (int i = 1; i < 11; i++) {
fseek(filePointer, currentPosition + i, SEEK_SET);
musicSymbol[i] = fgetc(filePointer);
if (musicSymbol[i] == EOF)
break;
}
if (musicSymbol[0] == '<' && strncmp(&musicSymbol[1], "step>", 5) == 0) {
fseek(filePointer, currentPosition + 6, SEEK_SET);
char step = fgetc(filePointer);
fseek(filePointer, currentPosition + 32, SEEK_SET);
char nextChar = fgetc(filePointer);
if (nextChar == '>') {
fseek(filePointer, currentPosition + 33, SEEK_SET);
nextChar = fgetc(filePointer);
for (int i = 0; !feof(filePointer); i++) {
fseek(filePointer, currentPosition + 81 + i, SEEK_SET);
char c = fgetc(filePointer);
if (c == '<')
break;
else {
if (i == 0)
noteDuration = convertCharToInt(c);
else
noteDuration = 10 * noteDuration + convertCharToInt(c);
}
}
} else {
fseek(filePointer, currentPosition + 61, SEEK_SET);
nextChar = fgetc(filePointer);
if (nextChar == '<') {
fseek(filePointer, currentPosition + 60, SEEK_SET);
nextChar = fgetc(filePointer);
}
for (int i = 0; !feof(filePointer); i++) {
fseek(filePointer, currentPosition + 109 + i, SEEK_SET);
char c = fgetc(filePointer);
if (c == '<')
break;
else {
if (i == 0)
noteDuration = convertCharToInt(c);
else
noteDuration = 10 * noteDuration + convertCharToInt(c);
}
}
}
if (flag == 0) {
printf("%d,", beatsPerMeasure);
flag++;
printf("\n");
}
if (step < 'A' || step > 'G')
errorCount++;
if (nextChar < '0' || nextChar > '9')
errorCount++;
printf("NOTE_%c%c,%d,", step, nextChar, noteDuration);
noteCount++;
printCounter++;
if (printCounter == 3) {
printf("\n");
printCounter = 0;
}
}
currentPosition++;
}
fclose(filePointer);
printf("0\n");
printf("Parse Done %d, Error num: %d\n", noteCount, errorCount);
system("pause");
}
int convertCharToInt(char x) {
if (x >= '0' && x <= '9')
return x - '0';
return -1;
}
这段C代码实现了解析MusicXML文件的功能。首先,用户输入小节的拍号信息,然后通过遍历文件找到 <divisions> 标签,提取每小节的拍号。接着,循环遍历文件,查找 <step> 标签,提取音符、音符时值等信息,并输出解析结果。
5. 手动生成音乐代码
将上一步获取到的musicxml格式文件的路径添加到代码中,手动输入每分钟节拍数,运行控制台即可生成音乐代码。将生成的代码复制并粘贴到我们之前任务中的 music[] 数组中。
12,30,
NOTE_G6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_E7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,2,
NOTE_D7,2,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,9,NOTE_D6,3,NOTE_D6,3,
NOTE_D6,1,NOTE_D6,1,NOTE_D6,4,
NOTE_D6,4,NOTE_D6,4,NOTE_D6,6,
NOTE_G6,18,NOTE_G6,6,NOTE_G6,9,
NOTE_G6,3,NOTE_D6,6,NOTE_E6,3,
NOTE_F6,3,NOTE_G6,12,NOTE_G6,12,
NOTE_B6,6,NOTE_G6,6,NOTE_A6,3,
NOTE_B6,3,NOTE_D7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_B6,3,NOTE_G6,6,
NOTE_B6,6,NOTE_D7,9,NOTE_B6,3,
NOTE_A6,12,NOTE_A6,12,NOTE_E7,12,
NOTE_D7,12,NOTE_A6,12,NOTE_B6,12,
NOTE_D7,6,NOTE_B6,6,NOTE_D7,6,
NOTE_B6,6,NOTE_A6,3,NOTE_B6,3,
NOTE_G6,12,NOTE_B6,24,NOTE_D6,6,
NOTE_E6,6,NOTE_G6,6,NOTE_G6,6,
NOTE_B6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_A6,6,NOTE_A6,3,
NOTE_A6,3,NOTE_E6,12,NOTE_A6,12,
NOTE_D6,6,NOTE_G6,12,NOTE_G6,6,
NOTE_B6,12,NOTE_B6,6,NOTE_D7,24,
NOTE_G6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_E7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,3,
NOTE_D7,1,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,12,NOTE_D6,12,NOTE_G6,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,2,
NOTE_D7,2,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,12,NOTE_D6,12,NOTE_G6,12,
NOTE_D6,12,NOTE_G6,12,NOTE_D6,12,
NOTE_G6,12,NOTE_G6,24,NOTE_G4,9,
NOTE_B4,3,NOTE_G4,6,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_G4,6,
NOTE_D5,6,NOTE_B3,24,NOTE_D4,24,
NOTE_C4,12,NOTE_E4,12,NOTE_G4,12,
NOTE_E5,12,NOTE_B3,12,NOTE_D4,12,
NOTE_D5,12,NOTE_B3,9,NOTE_D4,9,
NOTE_G4,9,NOTE_B4,9,NOTE_G4,3,
NOTE_F4,3,NOTE_D5,4,NOTE_F4,4,
NOTE_D5,4,NOTE_F4,4,NOTE_D5,4,
NOTE_G4,12,NOTE_B4,12,NOTE_G4,12,
NOTE_B3,24,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_B3,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D4,6,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_D4,24,NOTE_D4,9,NOTE_G4,9,
NOTE_D4,3,NOTE_G4,3,NOTE_D4,6,
NOTE_E4,3,NOTE_F4,3,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B4,6,
NOTE_G4,6,NOTE_A4,3,NOTE_B4,3,
NOTE_B3,12,NOTE_G4,12,NOTE_D5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D5,12,NOTE_B4,9,NOTE_B4,3,
NOTE_G4,6,NOTE_B4,6,NOTE_B3,24,
NOTE_D4,24,NOTE_B4,9,NOTE_D5,9,
NOTE_B3,3,NOTE_G4,3,NOTE_B4,3,
NOTE_D4,12,NOTE_A4,12,NOTE_D4,12,
NOTE_E4,24,NOTE_A4,24,NOTE_F4,2,
NOTE_A4,12,NOTE_C5,12,NOTE_E5,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D5,12,
NOTE_D4,12,NOTE_F4,2,NOTE_A4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B4,12,NOTE_D5,6,NOTE_B4,6,
NOTE_D5,6,NOTE_B4,6,NOTE_A4,3,
NOTE_B4,3,NOTE_G4,12,NOTE_B4,12,
NOTE_D4,6,NOTE_E4,6,NOTE_G4,6,
NOTE_G4,6,NOTE_B4,9,NOTE_B4,3,
NOTE_D5,6,NOTE_D5,6,NOTE_A4,6,
NOTE_A4,3,NOTE_A4,3,NOTE_E4,12,
NOTE_A4,12,NOTE_D4,6,NOTE_D4,12,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_B4,12,NOTE_G4,6,NOTE_B4,6,
NOTE_D4,18,NOTE_G4,18,NOTE_D4,6,
NOTE_F4,4,NOTE_D5,24,NOTE_D4,24,
NOTE_G4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_D5,6,
NOTE_B3,12,NOTE_D4,12,NOTE_D4,12,
NOTE_C4,12,NOTE_E4,12,NOTE_E5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_D5,12,
NOTE_B3,6,NOTE_D4,6,NOTE_B4,6,
NOTE_G4,6,NOTE_F4,6,NOTE_D5,4,
NOTE_F4,4,NOTE_D5,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,12,
NOTE_G4,9,NOTE_G4,3,NOTE_B3,24,
NOTE_B4,6,NOTE_G4,6,NOTE_F4,6,
NOTE_D5,4,NOTE_F4,4,NOTE_D5,4,
NOTE_F4,4,NOTE_D5,4,NOTE_B3,12,
NOTE_G4,12,NOTE_G4,12,NOTE_B3,24,
NOTE_B4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G2,24,NOTE_D3,24,
NOTE_G3,24,NOTE_B3,24,NOTE_G4,24,
NOTE_G3,18,NOTE_G3,6,NOTE_G3,12,
NOTE_G3,12,NOTE_G3,12,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_D4,4,NOTE_A4,4,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,12,NOTE_A4,12,
NOTE_G4,12,NOTE_G4,18,NOTE_B3,6,
NOTE_G4,6,NOTE_B3,12,NOTE_B3,12,
NOTE_G4,12,NOTE_D4,12,NOTE_A4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,24,NOTE_G4,9,
NOTE_G4,3,NOTE_D4,12,NOTE_A4,12,
NOTE_C4,24,NOTE_E4,24,NOTE_A4,24,
NOTE_C4,12,NOTE_F4,2,NOTE_A4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D4,12,NOTE_A4,12,NOTE_G4,12,
NOTE_G3,24,NOTE_D4,24,NOTE_G3,24,
NOTE_D4,24,NOTE_G3,12,NOTE_D4,12,
NOTE_G4,18,NOTE_F4,18,NOTE_E4,12,
NOTE_D4,12,NOTE_G4,24,NOTE_G4,12,
NOTE_F4,2,NOTE_B3,12,NOTE_G4,12,
NOTE_B3,6,NOTE_G4,6,NOTE_G3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G3,6,
NOTE_D4,6,NOTE_G4,6,NOTE_D4,24,
NOTE_A4,24,NOTE_G4,12,NOTE_G4,6,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_D4,4,NOTE_A4,4,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_G4,12,NOTE_G4,24,NOTE_G4,12,
NOTE_D4,4,NOTE_A4,4,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_E6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,2,NOTE_D6,2,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,9,NOTE_D5,3,
NOTE_D5,3,NOTE_D5,1,NOTE_D5,1,
NOTE_D5,4,NOTE_D5,4,NOTE_D5,4,
NOTE_D5,6,NOTE_G5,18,NOTE_G5,6,
NOTE_G5,9,NOTE_G5,3,NOTE_D5,6,
NOTE_E5,3,NOTE_F5,3,NOTE_G5,12,
NOTE_G5,12,NOTE_B5,6,NOTE_G5,6,
NOTE_A5,3,NOTE_B5,3,NOTE_D6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_B5,3,
NOTE_G5,6,NOTE_B5,6,NOTE_D6,9,
NOTE_B5,3,NOTE_A5,12,NOTE_A5,12,
NOTE_E6,12,NOTE_D6,12,NOTE_A5,12,
NOTE_B5,12,NOTE_D6,6,NOTE_B5,6,
NOTE_D6,6,NOTE_B5,6,NOTE_A5,3,
NOTE_B5,3,NOTE_G5,12,NOTE_B5,24,
NOTE_D5,6,NOTE_E5,6,NOTE_G5,6,
NOTE_G5,6,NOTE_B5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_A5,6,
NOTE_A5,3,NOTE_A5,3,NOTE_E5,12,
NOTE_A5,12,NOTE_D5,6,NOTE_G5,12,
NOTE_G5,6,NOTE_B5,12,NOTE_B5,6,
NOTE_D6,24,NOTE_G5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_E6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,3,NOTE_D6,1,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,12,NOTE_D5,12,
NOTE_G5,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,2,NOTE_D6,2,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,12,NOTE_D5,12,
NOTE_G5,12,NOTE_D5,12,NOTE_G5,12,
NOTE_D5,12,NOTE_G5,12,NOTE_G5,24,
NOTE_G4,9,NOTE_B4,3,NOTE_G4,6,
NOTE_D5,6,NOTE_B3,6,NOTE_D4,6,
NOTE_G4,6,NOTE_D5,6,NOTE_B3,24,
NOTE_D4,24,NOTE_C4,12,NOTE_E4,12,
NOTE_G4,12,NOTE_E5,12,NOTE_B3,12,
NOTE_D4,12,NOTE_D5,12,NOTE_B3,9,
NOTE_D4,9,NOTE_G4,9,NOTE_B4,9,
NOTE_G4,3,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,4,
NOTE_D4,4,NOTE_D4,4,NOTE_A3,4,
NOTE_D4,4,NOTE_A3,4,NOTE_D4,4,
NOTE_D4,4,NOTE_B3,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D4,6,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_D4,24,NOTE_D4,9,NOTE_G4,9,
NOTE_D4,3,NOTE_G4,3,NOTE_A3,6,
NOTE_D4,6,NOTE_E4,3,NOTE_F4,3,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B4,6,NOTE_G4,6,NOTE_A4,3,
NOTE_B4,3,NOTE_B3,12,NOTE_G4,12,
NOTE_D5,12,NOTE_B3,12,NOTE_D4,12,
NOTE_G4,12,NOTE_D5,12,NOTE_B4,9,
NOTE_B4,3,NOTE_G4,6,NOTE_B4,6,
NOTE_B3,24,NOTE_D4,24,NOTE_B4,9,
NOTE_D5,9,NOTE_B3,3,NOTE_G4,3,
NOTE_B4,3,NOTE_A3,12,NOTE_D4,12,
NOTE_A4,12,NOTE_D4,12,NOTE_A3,24,
NOTE_E4,24,NOTE_A4,24,NOTE_A3,12,
NOTE_F4,2,NOTE_A4,12,NOTE_C5,12,
NOTE_E5,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D5,12,NOTE_A3,12,NOTE_D4,12,
NOTE_F4,2,NOTE_A4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B4,12,
NOTE_D5,6,NOTE_B4,6,NOTE_D5,6,
NOTE_B4,6,NOTE_A4,3,NOTE_B4,3,
NOTE_G4,12,NOTE_B4,12,NOTE_D4,6,
NOTE_E4,6,NOTE_G4,6,NOTE_G4,6,
NOTE_B4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_D5,6,NOTE_A4,6,NOTE_A4,3,
NOTE_A4,3,NOTE_E4,12,NOTE_A4,12,
NOTE_D4,6,NOTE_D4,12,NOTE_G4,12,
NOTE_D4,6,NOTE_G4,6,NOTE_B4,12,
NOTE_G4,6,NOTE_B4,6,NOTE_D4,18,
NOTE_G4,18,NOTE_D4,6,NOTE_A3,24,
NOTE_F4,4,NOTE_D5,24,NOTE_D4,24,
NOTE_G4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_D5,6,
NOTE_B3,12,NOTE_D4,12,NOTE_D4,12,
NOTE_C4,12,NOTE_E4,12,NOTE_E5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_D5,12,
NOTE_B3,6,NOTE_D4,6,NOTE_B4,6,
NOTE_G4,6,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,12,
NOTE_G4,9,NOTE_G4,3,NOTE_B3,24,
NOTE_B4,6,NOTE_G4,6,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_B3,12,
NOTE_G4,12,NOTE_G4,12,NOTE_B3,24,
NOTE_B4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_B3,24,NOTE_G4,24,
NOTE_G4,18,NOTE_G4,6,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_D4,2,
NOTE_D4,2,NOTE_D4,2,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B3,12,NOTE_B3,6,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,24,
NOTE_G4,9,NOTE_G4,3,NOTE_D4,12,
NOTE_C4,24,NOTE_C4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G3,24,
NOTE_G3,24,NOTE_G3,12,NOTE_G4,18,
NOTE_F4,18,NOTE_E4,12,NOTE_D4,12,
NOTE_G4,24,NOTE_G4,12,NOTE_F4,2,
NOTE_B3,12,NOTE_B3,6,NOTE_G3,12,
NOTE_G3,6,NOTE_D4,24,NOTE_G4,12,
NOTE_G4,6,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_G4,12,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_G4,24,NOTE_G3,24,
NOTE_G3,24,NOTE_G3,24,NOTE_G3,24,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,0
6. 完整项目示例
最后,我们将生成的音乐代码嵌入到MircoPython项目中。
import machine
import time
# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.freq(1047)
# Defining frequency of each music note
NOTE_C0 = 16
NOTE_D0 = 18
NOTE_E0 = 21
NOTE_F0 = 22
NOTE_G0 = 25
NOTE_A0 = 28
NOTE_B0 = 31
NOTE_C1 = 33
NOTE_D1 = 37
NOTE_E1 = 41
NOTE_F1 = 44
NOTE_G1 = 49
NOTE_A1 = 55
NOTE_B1 = 62
NOTE_C2 = 65
NOTE_D2 = 73
NOTE_E2 = 82
NOTE_F2 = 87
NOTE_G2 = 98
NOTE_A2 = 110
NOTE_B2 = 124
NOTE_C3 = 131
NOTE_D3 = 147
NOTE_E3 = 165
NOTE_F3 = 175
NOTE_G3 = 196
NOTE_A3 = 220
NOTE_B3 = 247
NOTE_C4 = 262
NOTE_D4 = 294
NOTE_E4 = 330
NOTE_F4 = 349
NOTE_G4 = 392
NOTE_A4 = 440
NOTE_B4 = 494
NOTE_C5 = 523
NOTE_D5 = 587
NOTE_E5 = 659
NOTE_F5 = 698
NOTE_G5 = 784
NOTE_A5 = 880
NOTE_B5 = 988
NOTE_C6 = 1057
NOTE_D6 = 1175
NOTE_E6 = 1319
NOTE_F6 = 1397
NOTE_G6 = 1568
NOTE_A6 = 1760
NOTE_B6 = 1976
NOTE_C7 = 2093
NOTE_D7 = 2349
NOTE_E7 = 2637
NOTE_F7 = 2794
NOTE_G7 = 3136
NOTE_A7 = 3520
NOTE_B7 = 3951
NOTE_C8 = 4186
NOTE_D8 = 4698
NOTE_E8 = 5274
NOTE_F8 = 5588
NOTE_G8 = 6272
NOTE_A8 = 7040
NOTE_B8 = 7902
# Music notes of the song, 0 is a rest/pulse
music_data = [
12,30,
NOTE_G6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_E7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,2,
NOTE_D7,2,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,9,NOTE_D6,3,NOTE_D6,3,
NOTE_D6,1,NOTE_D6,1,NOTE_D6,4,
NOTE_D6,4,NOTE_D6,4,NOTE_D6,6,
NOTE_G6,18,NOTE_G6,6,NOTE_G6,9,
NOTE_G6,3,NOTE_D6,6,NOTE_E6,3,
NOTE_F6,3,NOTE_G6,12,NOTE_G6,12,
NOTE_B6,6,NOTE_G6,6,NOTE_A6,3,
NOTE_B6,3,NOTE_D7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_B6,3,NOTE_G6,6,
NOTE_B6,6,NOTE_D7,9,NOTE_B6,3,
NOTE_A6,12,NOTE_A6,12,NOTE_E7,12,
NOTE_D7,12,NOTE_A6,12,NOTE_B6,12,
NOTE_D7,6,NOTE_B6,6,NOTE_D7,6,
NOTE_B6,6,NOTE_A6,3,NOTE_B6,3,
NOTE_G6,12,NOTE_B6,24,NOTE_D6,6,
NOTE_E6,6,NOTE_G6,6,NOTE_G6,6,
NOTE_B6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_A6,6,NOTE_A6,3,
NOTE_A6,3,NOTE_E6,12,NOTE_A6,12,
NOTE_D6,6,NOTE_G6,12,NOTE_G6,6,
NOTE_B6,12,NOTE_B6,6,NOTE_D7,24,
NOTE_G6,9,NOTE_B6,3,NOTE_D7,6,
NOTE_D7,6,NOTE_E7,12,NOTE_D7,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,3,
NOTE_D7,1,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,12,NOTE_D6,12,NOTE_G6,12,
NOTE_B6,9,NOTE_G6,3,NOTE_D7,2,
NOTE_D7,2,NOTE_D7,2,NOTE_B6,12,
NOTE_G6,12,NOTE_D6,12,NOTE_G6,12,
NOTE_D6,12,NOTE_G6,12,NOTE_D6,12,
NOTE_G6,12,NOTE_G6,24,NOTE_G4,9,
NOTE_B4,3,NOTE_G4,6,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_G4,6,
NOTE_D5,6,NOTE_B3,24,NOTE_D4,24,
NOTE_C4,12,NOTE_E4,12,NOTE_G4,12,
NOTE_E5,12,NOTE_B3,12,NOTE_D4,12,
NOTE_D5,12,NOTE_B3,9,NOTE_D4,9,
NOTE_G4,9,NOTE_B4,9,NOTE_G4,3,
NOTE_F4,3,NOTE_D5,4,NOTE_F4,4,
NOTE_D5,4,NOTE_F4,4,NOTE_D5,4,
NOTE_G4,12,NOTE_B4,12,NOTE_G4,12,
NOTE_B3,24,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_B3,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D4,6,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_D4,24,NOTE_D4,9,NOTE_G4,9,
NOTE_D4,3,NOTE_G4,3,NOTE_D4,6,
NOTE_E4,3,NOTE_F4,3,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B4,6,
NOTE_G4,6,NOTE_A4,3,NOTE_B4,3,
NOTE_B3,12,NOTE_G4,12,NOTE_D5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D5,12,NOTE_B4,9,NOTE_B4,3,
NOTE_G4,6,NOTE_B4,6,NOTE_B3,24,
NOTE_D4,24,NOTE_B4,9,NOTE_D5,9,
NOTE_B3,3,NOTE_G4,3,NOTE_B4,3,
NOTE_D4,12,NOTE_A4,12,NOTE_D4,12,
NOTE_E4,24,NOTE_A4,24,NOTE_F4,2,
NOTE_A4,12,NOTE_C5,12,NOTE_E5,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D5,12,
NOTE_D4,12,NOTE_F4,2,NOTE_A4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B4,12,NOTE_D5,6,NOTE_B4,6,
NOTE_D5,6,NOTE_B4,6,NOTE_A4,3,
NOTE_B4,3,NOTE_G4,12,NOTE_B4,12,
NOTE_D4,6,NOTE_E4,6,NOTE_G4,6,
NOTE_G4,6,NOTE_B4,9,NOTE_B4,3,
NOTE_D5,6,NOTE_D5,6,NOTE_A4,6,
NOTE_A4,3,NOTE_A4,3,NOTE_E4,12,
NOTE_A4,12,NOTE_D4,6,NOTE_D4,12,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_B4,12,NOTE_G4,6,NOTE_B4,6,
NOTE_D4,18,NOTE_G4,18,NOTE_D4,6,
NOTE_F4,4,NOTE_D5,24,NOTE_D4,24,
NOTE_G4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_D5,6,
NOTE_B3,12,NOTE_D4,12,NOTE_D4,12,
NOTE_C4,12,NOTE_E4,12,NOTE_E5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_D5,12,
NOTE_B3,6,NOTE_D4,6,NOTE_B4,6,
NOTE_G4,6,NOTE_F4,6,NOTE_D5,4,
NOTE_F4,4,NOTE_D5,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,12,
NOTE_G4,9,NOTE_G4,3,NOTE_B3,24,
NOTE_B4,6,NOTE_G4,6,NOTE_F4,6,
NOTE_D5,4,NOTE_F4,4,NOTE_D5,4,
NOTE_F4,4,NOTE_D5,4,NOTE_B3,12,
NOTE_G4,12,NOTE_G4,12,NOTE_B3,24,
NOTE_B4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G2,24,NOTE_D3,24,
NOTE_G3,24,NOTE_B3,24,NOTE_G4,24,
NOTE_G3,18,NOTE_G3,6,NOTE_G3,12,
NOTE_G3,12,NOTE_G3,12,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_D4,4,NOTE_A4,4,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,12,NOTE_A4,12,
NOTE_G4,12,NOTE_G4,18,NOTE_B3,6,
NOTE_G4,6,NOTE_B3,12,NOTE_B3,12,
NOTE_G4,12,NOTE_D4,12,NOTE_A4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,24,NOTE_G4,9,
NOTE_G4,3,NOTE_D4,12,NOTE_A4,12,
NOTE_C4,24,NOTE_E4,24,NOTE_A4,24,
NOTE_C4,12,NOTE_F4,2,NOTE_A4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D4,12,NOTE_A4,12,NOTE_G4,12,
NOTE_G3,24,NOTE_D4,24,NOTE_G3,24,
NOTE_D4,24,NOTE_G3,12,NOTE_D4,12,
NOTE_G4,18,NOTE_F4,18,NOTE_E4,12,
NOTE_D4,12,NOTE_G4,24,NOTE_G4,12,
NOTE_F4,2,NOTE_B3,12,NOTE_G4,12,
NOTE_B3,6,NOTE_G4,6,NOTE_G3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G3,6,
NOTE_D4,6,NOTE_G4,6,NOTE_D4,24,
NOTE_A4,24,NOTE_G4,12,NOTE_G4,6,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_D4,4,NOTE_A4,4,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_G4,12,NOTE_G4,24,NOTE_G4,12,
NOTE_D4,4,NOTE_A4,4,NOTE_D4,4,
NOTE_A4,4,NOTE_D4,4,NOTE_A4,4,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G3,24,NOTE_D4,24,
NOTE_G4,24,NOTE_G5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_E6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,2,NOTE_D6,2,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,9,NOTE_D5,3,
NOTE_D5,3,NOTE_D5,1,NOTE_D5,1,
NOTE_D5,4,NOTE_D5,4,NOTE_D5,4,
NOTE_D5,6,NOTE_G5,18,NOTE_G5,6,
NOTE_G5,9,NOTE_G5,3,NOTE_D5,6,
NOTE_E5,3,NOTE_F5,3,NOTE_G5,12,
NOTE_G5,12,NOTE_B5,6,NOTE_G5,6,
NOTE_A5,3,NOTE_B5,3,NOTE_D6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_B5,3,
NOTE_G5,6,NOTE_B5,6,NOTE_D6,9,
NOTE_B5,3,NOTE_A5,12,NOTE_A5,12,
NOTE_E6,12,NOTE_D6,12,NOTE_A5,12,
NOTE_B5,12,NOTE_D6,6,NOTE_B5,6,
NOTE_D6,6,NOTE_B5,6,NOTE_A5,3,
NOTE_B5,3,NOTE_G5,12,NOTE_B5,24,
NOTE_D5,6,NOTE_E5,6,NOTE_G5,6,
NOTE_G5,6,NOTE_B5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_A5,6,
NOTE_A5,3,NOTE_A5,3,NOTE_E5,12,
NOTE_A5,12,NOTE_D5,6,NOTE_G5,12,
NOTE_G5,6,NOTE_B5,12,NOTE_B5,6,
NOTE_D6,24,NOTE_G5,9,NOTE_B5,3,
NOTE_D6,6,NOTE_D6,6,NOTE_E6,12,
NOTE_D6,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,3,NOTE_D6,1,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,12,NOTE_D5,12,
NOTE_G5,12,NOTE_B5,9,NOTE_G5,3,
NOTE_D6,2,NOTE_D6,2,NOTE_D6,2,
NOTE_B5,12,NOTE_G5,12,NOTE_D5,12,
NOTE_G5,12,NOTE_D5,12,NOTE_G5,12,
NOTE_D5,12,NOTE_G5,12,NOTE_G5,24,
NOTE_G4,9,NOTE_B4,3,NOTE_G4,6,
NOTE_D5,6,NOTE_B3,6,NOTE_D4,6,
NOTE_G4,6,NOTE_D5,6,NOTE_B3,24,
NOTE_D4,24,NOTE_C4,12,NOTE_E4,12,
NOTE_G4,12,NOTE_E5,12,NOTE_B3,12,
NOTE_D4,12,NOTE_D5,12,NOTE_B3,9,
NOTE_D4,9,NOTE_G4,9,NOTE_B4,9,
NOTE_G4,3,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,4,
NOTE_D4,4,NOTE_D4,4,NOTE_A3,4,
NOTE_D4,4,NOTE_A3,4,NOTE_D4,4,
NOTE_D4,4,NOTE_B3,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_D4,6,
NOTE_G4,12,NOTE_D4,6,NOTE_G4,6,
NOTE_D4,24,NOTE_D4,9,NOTE_G4,9,
NOTE_D4,3,NOTE_G4,3,NOTE_A3,6,
NOTE_D4,6,NOTE_E4,3,NOTE_F4,3,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B3,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B4,6,NOTE_G4,6,NOTE_A4,3,
NOTE_B4,3,NOTE_B3,12,NOTE_G4,12,
NOTE_D5,12,NOTE_B3,12,NOTE_D4,12,
NOTE_G4,12,NOTE_D5,12,NOTE_B4,9,
NOTE_B4,3,NOTE_G4,6,NOTE_B4,6,
NOTE_B3,24,NOTE_D4,24,NOTE_B4,9,
NOTE_D5,9,NOTE_B3,3,NOTE_G4,3,
NOTE_B4,3,NOTE_A3,12,NOTE_D4,12,
NOTE_A4,12,NOTE_D4,12,NOTE_A3,24,
NOTE_E4,24,NOTE_A4,24,NOTE_A3,12,
NOTE_F4,2,NOTE_A4,12,NOTE_C5,12,
NOTE_E5,12,NOTE_D4,12,NOTE_G4,12,
NOTE_D5,12,NOTE_A3,12,NOTE_D4,12,
NOTE_F4,2,NOTE_A4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_B4,12,
NOTE_D5,6,NOTE_B4,6,NOTE_D5,6,
NOTE_B4,6,NOTE_A4,3,NOTE_B4,3,
NOTE_G4,12,NOTE_B4,12,NOTE_D4,6,
NOTE_E4,6,NOTE_G4,6,NOTE_G4,6,
NOTE_B4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_D5,6,NOTE_A4,6,NOTE_A4,3,
NOTE_A4,3,NOTE_E4,12,NOTE_A4,12,
NOTE_D4,6,NOTE_D4,12,NOTE_G4,12,
NOTE_D4,6,NOTE_G4,6,NOTE_B4,12,
NOTE_G4,6,NOTE_B4,6,NOTE_D4,18,
NOTE_G4,18,NOTE_D4,6,NOTE_A3,24,
NOTE_F4,4,NOTE_D5,24,NOTE_D4,24,
NOTE_G4,9,NOTE_B4,3,NOTE_D5,6,
NOTE_B3,6,NOTE_D4,6,NOTE_D5,6,
NOTE_B3,12,NOTE_D4,12,NOTE_D4,12,
NOTE_C4,12,NOTE_E4,12,NOTE_E5,12,
NOTE_B3,12,NOTE_D4,12,NOTE_D5,12,
NOTE_B3,6,NOTE_D4,6,NOTE_B4,6,
NOTE_G4,6,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_A3,4,NOTE_F4,4,
NOTE_D5,4,NOTE_G4,12,NOTE_B4,12,
NOTE_G4,12,NOTE_B3,24,NOTE_D4,12,
NOTE_G4,9,NOTE_G4,3,NOTE_B3,24,
NOTE_B4,6,NOTE_G4,6,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_A3,4,
NOTE_F4,4,NOTE_D5,4,NOTE_B3,12,
NOTE_G4,12,NOTE_G4,12,NOTE_B3,24,
NOTE_B4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_G4,12,NOTE_B3,24,
NOTE_D4,24,NOTE_B3,24,NOTE_G4,24,
NOTE_G4,18,NOTE_G4,6,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_D4,2,
NOTE_D4,2,NOTE_D4,2,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,12,NOTE_G4,12,
NOTE_B3,12,NOTE_B3,6,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_G4,12,NOTE_G4,24,
NOTE_G4,9,NOTE_G4,3,NOTE_D4,12,
NOTE_C4,24,NOTE_C4,12,NOTE_B3,12,
NOTE_D4,12,NOTE_G4,12,NOTE_G3,24,
NOTE_G3,24,NOTE_G3,12,NOTE_G4,18,
NOTE_F4,18,NOTE_E4,12,NOTE_D4,12,
NOTE_G4,24,NOTE_G4,12,NOTE_F4,2,
NOTE_B3,12,NOTE_B3,6,NOTE_G3,12,
NOTE_G3,6,NOTE_D4,24,NOTE_G4,12,
NOTE_G4,6,NOTE_G4,12,NOTE_G4,12,
NOTE_G4,12,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_G4,12,NOTE_G4,24,
NOTE_G4,12,NOTE_D4,4,NOTE_D4,4,
NOTE_D4,4,NOTE_G4,24,NOTE_G3,24,
NOTE_G3,24,NOTE_G3,24,NOTE_G3,24,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,NOTE_D5,2,NOTE_D5,2,
NOTE_D5,2,0
]
sifenyifu = 1000*((60/music_data[1])/4)+0.5
def play_song():
total_notes = (len(music_data)-2)/2
for i in range(total_notes):
current_note = music_data[i*2+2]
wait = int((music_data[i*2+3]/music_data[0])*sifenyifu)
if current_note != 0:
buzzer.duty(512) # Set duty cycle for sound
buzzer.freq(current_note) # Set frequency of the note
else:
buzzer.duty(0) # Turn off the sound
time.sleep_ms(wait)
buzzer.duty(0) # Turn off the sound
while True:
# Play the song
play_song()
心得体会
这次得捷Follow me第3期活动不仅让我深入了解了ESP32C3开发板和相关组件的使用,还拓展了我在嵌入式系统和物联网领域的知识面。通过实际动手操作,我更好地理解了理论知识,并培养了解决问题和调试的能力。
这个项目为我提供了一次全面的嵌入式开发体验。通过实际操作不仅能够更好地理解理论知识,还能够培养解决问题的实际技能。希望未来还能有更多类似的活动,让更多的人深入嵌入式系统的精彩世界。
|