如何用AT指令实现SIM800C与Arduino UNO通话录音至SD卡
SIM800C + Arduino Uno 通话录音到SD卡解决方案
核心AT指令说明
SIM800C的通话录音依赖文件系统指令+录音指令组合,以下是关键指令:
AT+FSINIT:初始化文件系统,确认SD卡是否被模块识别(返回OK则正常)AT+FSCD="D:":切换存储目录到外部SD卡(模块内部存储为C:,SD卡对应D:)AT+CREC=1,"[唯一文件名].AMR",0:通话中启动录音,参数说明:1:启动录音模式- 文件名:建议用时间戳命名避免覆盖,比如
REC_202405201430.AMR 0:录音格式为AMR(SIM800C仅支持该格式)
AT+CREC=2:停止当前录音AT+FSLS:列出SD卡内的文件,验证录音是否保存
完整操作步骤
模块初始化:
- 上电后发送
AT+FSINIT确认SD卡挂载正常 - 发送
AT+FSCD="D:"切换到SD卡目录 - 配置自动接听(如需要):
ATS0=1(1声铃后自动接听)
- 上电后发送
通话录音流程:
- 呼入/呼出通话接通后,发送
AT+CREC=1,"[文件名].AMR",0启动录音 - 通话过程中保持模块串口空闲,避免干扰录音
- 通话结束前(或主动挂断前)发送
AT+CREC=2停止录音 - 可通过
AT+FSLS确认文件已保存
- 呼入/呼出通话接通后,发送
修正后的Arduino示例代码
解决了你原代码中路径错误、录音指令参数问题,以及AMR文件直接读取到SD卡的逻辑:
#include <SoftwareSerial.h> #include <SD.h> #include <SPI.h> const int chipSelect = 10; // SD卡CS引脚 const int sim800Tx = 2; // SIM800C TX接Arduino RX const int sim800Rx = 3; // SIM800C RX接Arduino TX const int sim800Reset = 9; // SIM800C复位引脚 SoftwareSerial sim800(sim800Rx, sim800Tx); File sdFile; String currentRecordFileName = ""; // 存储当前录音文件名 void setup() { Serial.begin(9600); sim800.begin(9600); pinMode(sim800Reset, OUTPUT); digitalWrite(sim800Reset, HIGH); // 初始化SD卡 if (!SD.begin(chipSelect)) { Serial.println("SD卡初始化失败"); return; } Serial.println("SD卡初始化完成"); // 复位SIM800C resetSIM800(); // 等待网络注册 waitForNetwork(); // 初始化SIM800C文件系统,切换到SD卡目录 initSIM800FileSystem(); // 设置1声铃后自动接听 sim800.println("ATS0=1"); delay(1000); readSIM800Response(); } void loop() { if (sim800.available()) { String response = sim800.readString(); Serial.println("模块返回:" + response); // 检测来电 if (response.indexOf("RING") != -1) { Serial.println("检测到来电,等待自动接听..."); delay(2000); // 等待自动接听完成 startCallRecording(); } // 检测通话结束 if (response.indexOf("NO CARRIER") != -1 || response.indexOf("BUSY") != -1) { Serial.println("通话结束"); stopCallRecording(); saveRecordingToSD(); } } } void resetSIM800() { digitalWrite(sim800Reset, LOW); delay(1000); digitalWrite(sim800Reset, HIGH); delay(3000); // 延长复位等待时间,确保模块重启完成 } void waitForNetwork() { while (true) { sim800.println("AT+CREG?"); delay(1000); if (sim800.find("+CREG: 0,1") || sim800.find("+CREG: 0,5")) { Serial.println("网络注册成功"); readSIM800Response(); // 清空缓存 break; } else { Serial.println("等待网络注册..."); readSIM800Response(); } } } void initSIM800FileSystem() { // 初始化文件系统 sim800.println("AT+FSINIT"); delay(1000); if (sim800.find("OK")) { Serial.println("文件系统初始化成功"); } else { Serial.println("文件系统初始化失败,请检查SD卡连接"); } readSIM800Response(); // 切换到SD卡目录 sim800.println("AT+FSCD=\"D:\""); delay(1000); if (sim800.find("OK")) { Serial.println("已切换到SD卡目录"); } else { Serial.println("切换SD卡目录失败"); } readSIM800Response(); } void startCallRecording() { // 生成唯一文件名(用当前毫秒数简化命名) currentRecordFileName = "REC_" + String(millis()) + ".AMR"; String cmd = "AT+CREC=1,\"" + currentRecordFileName + "\",0"; sim800.println(cmd); delay(1000); if (sim800.find("OK")) { Serial.println("录音已启动,文件名:" + currentRecordFileName); } else { Serial.println("启动录音失败"); } readSIM800Response(); } void stopCallRecording() { sim800.println("AT+CREC=2"); delay(1000); if (sim800.find("OK")) { Serial.println("录音已停止"); } else { Serial.println("停止录音失败"); } readSIM800Response(); } void saveRecordingToSD() { if (currentRecordFileName.isEmpty()) { Serial.println("无有效录音文件名"); return; } String readCmd = "AT+FSREAD=\"" + currentRecordFileName + "\",0"; sim800.println(readCmd); delay(1000); // 打开SD卡文件准备写入 sdFile = SD.open(currentRecordFileName, FILE_WRITE); if (!sdFile) { Serial.println("SD卡打开文件失败"); readSIM800Response(); return; } // 读取SIM800C返回的文件内容(跳过响应头,直接读取数据) bool skipHeader = true; while (sim800.available()) { char c = sim800.read(); // 跳过AT指令响应的OK及换行符,只写入音频数据 if (skipHeader) { if (c == 'O' && sim800.peek() == 'K') { sim800.read(); // 跳过K sim800.read(); // 跳过换行 sim800.read(); // 跳过回车 skipHeader = false; } } else { sdFile.write(c); } } sdFile.close(); Serial.println("录音文件已保存到SD卡:" + currentRecordFileName); currentRecordFileName = ""; // 重置文件名 } void readSIM800Response() { // 清空模块串口缓存 while (sim800.available()) { sim800.read(); } }
关键注意事项
- SIM800C仅支持AMR格式录音,无需在Arduino端转WAV(如需播放可在电脑端转换)
- 必须确保SD卡为FAT32格式,且容量不超过32GB
- 录音指令必须在通话接通后发送,否则会返回错误
- 文件名必须唯一,避免覆盖已有录音文件
内容的提问来源于stack exchange,提问作者Swap
相关产品推荐
相关产品推荐

