我有一个Arduino Uno V3。我正在处理的草图有几个全局变量,其中存储了目录中的文件,我想在Adafruit Music Maker盾牌上播放。一切都很好,只要我只想播放实例化中的vars中引用的文件,但是当我调用我需要修改这些char数组的函数时,我的程序或Arduino会挂起或崩溃。
这些是我的变量:
// mp3 player variables
boolean plrStartPlaying = false; // Is set to true in case an nfc tag is present with information on tracks to play
char plrCurrentFile[13] = "track001.mp3"; // which track is the player playing?
char plrCurrentFolder[9] = "system00"; // from which directory is the player playing?
char filename[23] = "/system00/track001.mp3"; // path and filename of the track to play
byte firstTrackToPlay = 1; // the track number as received from the tag
char curTrackCharNumber[4] = "001";
这是我的功能,我打电话来修改它们:
// stores the file to play in the global var filename - it is created from the gloal vars plrCurrentFolder and plrCurrentFile
boolean createFileNameToPlay(byte trackNo) {
// fill global var curTrackCharNumber with provided trackNo - we need it next to create the global var plrCurrentFile
sprintf(curTrackCharNumber, "%03d", trackNo);
// create the name of the track to play from the curTrack
strcpy(plrCurrentFile[0], '\0');
strcat(plrCurrentFile, "track");
strcat(plrCurrentFile, curTrackCharNumber);
//strcat(plrCurrentFile, sprintf(plrCurrentFile, "%03d", trackNo));
strcat(plrCurrentFile, ".mp3");
// create the filename of the track to play, including path, so we can feed it to the music player
strcpy(filename[0], '\0');
strcat(filename, "/");
strcat(filename, plrCurrentFolder);
strcat(filename, "/");
strcat(filename, plrCurrentFile);
if (SD.exists(filename)) {
return (true);
} else {
return (false);
}
}
如上所述它不起作用 - 我通过评论函数中的所有strcat()
和strcpy()
调用进行检查,然后我的程序运行正常。但是如果代码是活动的,它实际上会导致我的Arduino挂起或程序崩溃。无论原因是什么,效果是我的程序在调用此函数后不会前进,并且在一段时间后,Arduino会重置。
有人可以向我解释为什么会这样吗?
答案 0 :(得分:2)
您尝试使用strcpy()
将字符复制到字符,而不是字符指针的字符指针 - 问题会发生(至少)两次:
strcpy(plrCurrentFile[0], '\0');
…
strcpy(filename[0], '\0');
那应该是生成编译器错误;两个参数都应该是char *
,但两者都不是char *
。写下:
plrCurrentFile[0] = '\0';
…
filename[0] = '\0';
或:
strcpy(plrCurrentFile, "");
…
strcpy(filename, "");
为什么不注意编译器警告?如果你没有得到至少警告,为什么不呢?找到创建此类警告所需的选项,并最好使它们出错。例如,使用GCC,请考虑:
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes …
这是我的基本选择;我没有运行那些没有用这些选项干净地编译的代码。我有时会添加更多。