这个项目展示了如何制作一个基于 Arduino 的 midi 播放器。Arduino 连接到包含 SD 卡读卡器的 DS1307 数据记录器扩展板。Arduino 输出保存到 Data Logger Shield 中 SD 卡的 midi 文件的 midi 流。此 MIDI 流可以连接到任何可以播放音乐的 MIDI 合成器或 MIDI 设备。
这是主要组件
这个 Arduino 扩展板可从多个来源获得;亚马逊、eBay 和全球速卖通等等。
Adafruit 发布的盾牌版本 2 有一个很好的概述
https://learn.adafruit.com/adafruit-data-logger-shield/overview
该项目中使用的扩展板是硬件版本 1,与 Adafruit 描述的不同。但是,所有代码和示例都适用于版本 1。
DS1307 是一个实时时钟芯片,用于提供精确的时间值。它可以与备用电池一起使用,因此即使关闭周围电路的电源也不会浪费时间。
该项目中使用的数据记录器扩展板包括一个 DS1307 和一个 SD 读卡器。屏蔽的主要用途是记录来自传感器的数据,并在读数中添加精确的时间戳。此信息存储在 SD 卡上,可以随时检索以进行分析。
对于这个特定项目,我们不使用 DS1307 功能,只使用 SD 读卡器(抱歉)。
这是盾牌的图片。
盾牌的一些有趣的特点
Arduino 通过 SPI 接口与 SD 卡通信。这是引脚分配。
在连接屏蔽层之前,通过以下步骤测试 SD 卡是否正常工作:
/* SDlistFiles
This example shows how print out the files in a directory on a SD card
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 10
This example code is in the public domain.
*/
#include
#include
File root;
// Chip Select for SD Card - Pin 10 for shield
const int chipSelect = 10;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
pinMode(chipSelect,OUTPUT);
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
}
void loop() {
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
delay(5000);
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
施密特触发器反相器用于确保 MIDI 信号包含正确电压的干净方波。施密特触发器电路包括滞后功能,可确保数字信号从高电平到低电平以及从低电平到高电平的精确转换。
链接到数据表
https://www.mouser.com/datasheet/2/308/MC74HC14A-D-601265.pdf
如果您对施密特触发器逆变器背后的理论感兴趣,互联网上有许多描述其操作的文章。
这是该项目中使用的电路示意图:
如图所示的电路连接在屏蔽的原型区域。这需要一些精细的工作,但这是可能的。这是完成的盾牌的图片。
作为替代方案,电路可以构建在无焊料面包板上。参考www.midi.orgt上的一篇文章hat 描述了这种方法
https://www.midi.org/midi-articles/arduino-midi-output-basics
完成后,将扩展板连接到 Arduino
为了使代码工作,需要安装以下库。
使用 Tools → Manage Libraries 进行安装。截图如下:
Midi 库的文档位于这两个链接
https://github.com/MajicDesigns/MD_MIDIFile
https://majicdesigns.github.io/MD_MIDIFile/
GitHub 存储库中包含的示例概述了该库的工作原理。此外,还包括一些示例 MIDI 文件。
要播放 midi 文件,请按照以下步骤操作:
#include
#include
#define SERIAL_RATE 31250 // Midi standard serial rate is 31250 baud
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
const byte SD_SELECT = 10; // Chip select for Sd card is pin 10
const char *loopfile = "LOOPDEMO.MID"; // pointer to midi file on SD card
const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
bool playFile = false; // boolean variable indicating if a file should be played
SDFAT SD;
MD_MIDIFile SMF; // create an instance of a midi file
// Called by the MIDIFile library when a file event needs to be processed
// thru the midi communications interface.
// This callback is set up in the setup() function.
void midiCallback(midi_event *pev){
if ((pev->data[0] >= 0x80) && (pev->data[0] <= 0xe0)){
Serial.write(pev->data[0] | pev->channel);
Serial.write(&pev->data[1], pev->size-1);
}
else {
Serial.write(pev->data, pev->size);
}
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // use built in pullup resistor with push button
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(SERIAL_RATE);
// Initialize SD Card
if (!SD.begin(SD_SELECT, SPI_FULL_SPEED)){
while (true) ;
}
// Initialize MIDIFile
SMF.begin(&SD);
SMF.setMidiHandler(midiCallback);
SMF.looping(false);
}
void loop() {
// Wait for pushbutton input
int reading = digitalRead(buttonPin);
// If push button is depressed, load midi file and switch on LED
if (reading == LOW) {
playFile = true;
digitalWrite(ledPin, HIGH); // Switch on LED
SMF.load(loopfile);
}
// play the file if playFile is true
if(playFile == true){
// Play until end of file is reached
while (!SMF.isEOF()){
SMF.getNextEvent();
}
}
// Once file is finished playing, close midi file and switch off LED
playFile = false;
digitalWrite(ledPin, LOW);
SMF.close();
}
作为对这个最小 midi 播放器的增强,可以从 SD 卡播放多首歌曲。以下是说明:
这是一个最小的播放器,并且没有在代码中内置所有可能的错误检查。需要一些额外的开发来添加额外的功能。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !