Arduino Uno按键电话玩具SD卡音频播放故障求助
Arduino Uno按键电话玩具组合后无法播放SD卡音频
问题描述
我制作了一款基于Arduino Uno的按键电话玩具,使用旧按键、SD卡读卡器和低音质扬声器。各组件单独测试均工作正常,但组合后无法播放SD卡中存储的音频——按键、SD读卡器、扬声器各自功能正常,找不到解决办法,附上代码及设备图片:


原代码
#include <Arduino.h> #include <Keypad.h> #include <SD.h> // need to include the SD library //#define SD_ChipSelectPin 53 //example uses hardware SS pin 53 on Mega2560 #define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328, can use other pins #include <TMRpcm.h> // also need to include this library... #include <SPI.h> // C++ code //#define buzer A0; TMRpcm tmrpcm; unsigned long time = 0; const byte ROWS = 4; const byte COLS = 4; byte rowPins[ROWS] = {A5, A4, A3, A2}; byte colPins[COLS] = {5, 3, 2, 0}; char keys[ROWS][COLS] ={ {'3','2','1','a'}, {'*','0','9','b'}, {'7','6','5','c'}, {'.','8',',','d'}, }; Keypad klawiatura = Keypad(makeKeymap(keys), rowPins,colPins,ROWS,COLS); String tekst; const String tel_book[3] = {"","123","321"}; // tu wpisujemy numery pod którymi znajdują sie scieżki dźwiękowe char* track_list[3] = {"","test.wav","0002.wav"}; // tu wpisujemy nazwy ścieżek dźwiekowych int lokalizator; void setup() { tmrpcm.speakerPin = 10; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc //Complimentary Output or Dual Speakers: //pinMode(10,OUTPUT); Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45 Serial.begin(9600); pinMode(13,OUTPUT); //LED Connected to analog pin 0 | w sumie to nie wiem ale bez tego nie działa if (!SD.begin(SD_ChipSelectPin)) { // sprawdza czy karta sd jest poprawnie zainstalowana na miejscu Serial.println("SD fail"); return; // jeśli nie to wyłącza program } else{ Serial.println("SD ok"); } tmrpcm.volume(4); tmrpcm.play("test.wav"); // odgrywa testowy dźwięk po włączeniu urządzenia } void loop() { char klawisz = klawiatura.getKey(); // pobiera dane z klawiatury i przypisuje do zmiennej if (klawisz) { tekst += klawisz; //wybieranie numeru Serial.println(tekst); if (tekst.length()==3) // gdy długość numeru jest odpowiednia zaczyna szukac go w książce telefonicznej { for (int i = 0; i < sizeof(tel_book)/sizeof(*tel_book); i++) { if (tel_book[i] == tekst) { lokalizator = i+1; // po znaleziemiu odpowiedniego numeru wybiera jego pozycje z listy //Serial.println(i); //delay(1000); //Serial.println(lokalizator); Serial.println("corect num"); tekst = ""; return; }else{ tmrpcm.play("0001.wav");// odtworzenie informacji o błednie wybranym numerze Serial.println("wrong num"); lokalizator = 0; tekst = ""; return; } } // wcześniej odnaleziony numer inicjuje odtworzenie odpowiedniej ścieżki dźwiękowej tmrpcm.play(track_list[lokalizator]); // to powinno już działac ale jeszcze nie wiem czy tak jak chce tekst = ""; } } }
问题分析与修复
代码存在几个关键逻辑错误,导致组合后无法正确触发音频播放:
- 循环逻辑错误:匹配电话号码的
for循环中,只要第一个元素不匹配就立刻执行错误分支返回,根本不会检查后续的电话号码。比如输入123时,i=0时tel_book[0]是空字符串,不匹配就直接播放错误音频返回,永远到不了i=1的匹配逻辑。 - 播放代码位置错误:正确匹配后的播放代码被放在
for循环外面,但因为匹配成功后直接return了,这段代码永远不会被执行。 - 变量初始化问题:
lokalizator没有初始值,可能导致意外行为。
修正后的代码
#include <Arduino.h> #include <Keypad.h> #include <SD.h> #define SD_ChipSelectPin 4 #include <TMRpcm.h> #include <SPI.h> TMRpcm tmrpcm; const byte ROWS = 4; const byte COLS = 4; byte rowPins[ROWS] = {A5, A4, A3, A2}; byte colPins[COLS] = {5, 3, 2, 1}; // 将原0号引脚替换为1号,避免串口RX冲突 char keys[ROWS][COLS] ={ {'3','2','1','a'}, {'*','0','9','b'}, {'7','6','5','c'}, {'.','8',',','d'}, }; Keypad klawiatura = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); String tekst; const String tel_book[3] = {"", "123", "321"}; char* track_list[3] = {"", "test.wav", "0002.wav"}; int lokalizator = 0; // 初始化变量 void setup() { tmrpcm.speakerPin = 10; Serial.begin(9600); pinMode(13, OUTPUT); if (!SD.begin(SD_ChipSelectPin)) { Serial.println("SD fail"); return; } Serial.println("SD ok"); tmrpcm.volume(4); tmrpcm.play("test.wav"); } void loop() { char klawisz = klawiatura.getKey(); if (klawisz) { tekst += klawisz; Serial.println(tekst); if (tekst.length() == 3) { bool numFound = false; // 从i=1开始遍历,跳过空字符串元素 for (int i = 1; i < sizeof(tel_book)/sizeof(*tel_book); i++) { if (tel_book[i] == tekst) { lokalizator = i; Serial.println("correct num"); tmrpcm.play(track_list[lokalizator]); // 匹配成功后立即播放音频 numFound = true; break; } } // 所有号码都不匹配时播放错误提示 if (!numFound) { tmrpcm.play("0001.wav"); Serial.println("wrong num"); } tekst = ""; // 重置输入字符串,等待下一次输入 } } }
额外注意事项
- 音频文件格式:确保SD卡中的WAV文件为8位、单声道、采样率≤32kHz,文件名采用8.3格式(如
0001.wav),无中文或特殊字符。 - 引脚冲突:原代码中按键列引脚使用了0号(串口RX),会影响串口调试和按键读取,已替换为1号引脚,若使用其他引脚需确保无冲突。
- 电源稳定性:SD卡读卡器和扬声器同时工作时电流需求较高,建议使用外部5V电源供电,避免USB口供电不足导致的异常。
内容的提问来源于stack exchange,提问作者pawko774
相关产品推荐
相关产品推荐

