我正在开展一个非常重要的学校项目,这是一个带有网络界面的MP3播放器和一个使用arduino mega的网络服务器。 当我想使用以太网lib的任何功能时,我必须暂停音乐,因为以太网屏蔽和mp3播放器屏蔽使用相同的spi总线。但是当我改变音量时,会导致音乐中的1s冻结。为了避免我创建了暂停音乐的新功能,调用以太网lib和简历的功能。
bool clientAvailable(EthernetClient &client){
MP3player.pauseDataStream ();
bool a = client.connected();
MP3player.resumeDataStream ();
return a;
}
int clientConnected(EthernetClient &client){
MP3player.pauseDataStream ();
int a = client.available();
MP3player.resumeDataStream ();
return a;
}
void stopClient(EthernetClient &client){
MP3player.pauseDataStream ();
client.stop();
MP3player.resumeDataStream ();
}
void checkForClient(int loading){
String firstLine;
MP3player.pauseDataStream ();
EthernetClient client = server.available();
MP3player.resumeDataStream();
if (client) {
if(!loading){
Serial.println(F("new client")); // CRASH HERE
bool endLn(false);
char chr;
int i(0);
while (clientConnected(client)) {
char received[clientAvailable(client)+2];
while (clientAvailable(client)) {
MP3player.pauseDataStream ();
char c = client.read();
MP3player.resumeDataStream ();
received[i] = c;
Serial.print(c); // OR HERE
if(!endLn){
firstLine += c;
if (c == '\n'){
endLn = true;
}
}
++i;
}
received[i+1] = '\0';
i = 0;
if(endLn){
Serial.println();
endLn = false;
Serial.print(F("first line : "));
Serial.println(firstLine);
}
我得到的输出:
new û192.168.0.123
最后有一个IP,因为这是arduino重启的地方,这是我展示的第一件事。 如果我删除" client.println(F(" new client"))行,则会在client.print(c)行上显示错误(显示3或4个字符后)。如果我也删除了这个,它会在某处崩溃,但我不知道在哪里。
我检查了内存,我在程序的这一点上还剩600个字节。
有什么想法吗?
感谢。
答案 0 :(得分:0)
你的RAM状况可能很低。
此外,您不应将String
类用于firstLine
。它会导致许多问题,其中一些问题可能会在随机时间发生。
只需像received
那样使用字符数组。将每个字符存储在数组中,直到换行符到达为止,并增加每个字符的长度:
void checkForClient(int loading){
char firstLine[60];
uint8_t firstLineLen = 0;
MP3player.pauseDataStream ();
EthernetClient client = server.available();
MP3player.resumeDataStream();
if (client) {
if(!loading){
Serial.println(F("new client")); // CRASH HERE
bool endLn(false);
char chr;
int i(0);
while (clientConnected(client)) {
char received[clientAvailable(client)+2];
while (clientAvailable(client)) {
MP3player.pauseDataStream ();
char c = client.read();
MP3player.resumeDataStream ();
received[i] = c;
Serial.print(c); // OR HERE
if (!endLn) {
if (firstLineLength < sizeof(firstLine)-2)
firstLine[ firstLineLength++ ] = c;
if (c == '\n') {
endLn = true;
firstLine[ firstLineLength ] = '\0'; // NUL-terminate
}
}
++i;
}
received[i+1] = '\0';
i = 0;
if(endLn){
Serial.println();
endLn = false;
Serial.print(F("first line : "));
Serial.println(firstLine);
}
这也将节省大约1600字节的程序空间。避免使用String有很多理由,很多人都写过关于陷阱的文章。如果您在程序的其他地方使用String
,则应使用类似的方法来消除它。
减少RAM的另一种技术是避免在数据进入时存储数据,然后再使用它。相反,立即使用它:
void checkForClient(int loading){
MP3player.pauseDataStream ();
EthernetClient client = server.available();
MP3player.resumeDataStream();
if (client) {
if(!loading){
Serial.println(F("new client")); // CRASH HERE
Serial.print(F("first line : "));
bool endLn(false);
char chr;
int i(0);
while (clientConnected(client)) {
char received[clientAvailable(client)+2];
while (clientAvailable(client)) {
MP3player.pauseDataStream ();
char c = client.read();
MP3player.resumeDataStream ();
received[i] = c;
if (!endLn) {
Serial.print(c); // printed now instead of saved for later
if (c == '\n') {
endLn = true;
}
}
++i;
}
received[i+1] = '\0';
i = 0;
if (endLn) {
Serial.println();
endLn = false;
//Serial.println(firstLine); // NOT NEEDED, already printed!
}
这将保存您用于firstLine
的所有RAM。
您没有发布整个程序供我们审核,因此您必须查找其他变量太大,或者可以在 例程中声明即,一个局部变量)而不是在文件范围(即,在任何例程之外声明的全局变量)。