Сбой Arduino и перезагрузка в «случайных точках»

Я работаю над очень важным школьным проектом, который состоит из MP3-плеера с веб-интерфейсом и веб-сервера с использованием Arduino Mega.
когда я хочу использовать какую-либо функцию из ethernet lib, я должен приостановить воспроизведение музыки, потому что экран ethernet и экран mp3-плеера используют одну шину spi. Но когда я изменяю громкость, это вызывает зависание музыки на 1 с. чтобы избежать этого, я создал новые функции, которые приостанавливают воспроизведение музыки, вызывают функцию lib из ethernet и резюме.

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 (« новый клиент »))», в строке client.print (c) возникнет ошибка (после отображения 3 или 4 символов). где-нибудь разбиться, но я не знаю где.

Я проверил память, у меня осталось около 600 байтов в этой точке программы.

Есть идеи ?

Благодарю.

0

Решение

Вероятно, у вас недостаточно памяти.

Кроме того, вы не должны использовать 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 в другом месте вашей программы вы должны использовать аналогичный подход для его устранения.

Другой метод сокращения оперативной памяти — избегать хранения данных при их поступлении, а затем использовать их позже. Вместо этого используйте это немедленно:

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,

Вы не опубликовали всю программу для нашего обзора, поэтому вам придется искать другие переменные, которые слишком велики или могут быть объявлены внутри подпрограмма (то есть локальная переменная) вместо области видимости файла (т.е. глобальная переменная, объявленная вне каких-либо подпрограмм).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]