Пролистывающая текстовая программа Arduino через некоторое время зависает
Я использую 16x2 символьный ЖК-дисплей для отображения текста. То, что я хочу, это первая строка исправлена, а вторая строка прокрутки.
Я написал программу, которая работает нормально, но проблема в том, что через некоторое время Arduino не отвечает. Я подозреваю, что в коде может быть ошибка или утечка памяти.
Соответствующий код похож на это.
void scrollTextFromRight(int line, char text[])
{
const char space[16] = " ";
char screen[16];
char * longText;
longText = malloc(sizeof(char) * (sizeof(text) + 17));
memset(longText, '\0', sizeof(char) * (sizeof(text) + 17));
memset(screen, '\0', sizeof(screen));
for (int i = 0; i < 16; ++i)
{
longText[i] = space[i];
}
for (int j = 0; j < sizeof(text) + 17; ++j)
{
longText[16+j] = text[j];
}
for (int i = 0; i < sizeof(text) + 17; ++i)
{
lcd.setCursor(0, line);
strncpy(screen, longText + i, 17 );
lcd.print(screen);
delay(350);
}
}
Я вызываю эту функцию из основной программы следующим образом:
scrollTextFromRight(1, "Scrolling text");
Обновление 1:
После прочтения комментариев и ответов я освободил выделенное место в памяти с помощью свободной функции. Я загрузил новый код и проверил, работает ли он должным образом.
Я добавил эту часть после третьего цикла for.
free longText;
Обновление 2:
После прочтения комментариев я решил использовать класс Arduino String. Код стал таким:
void scrollTextFromRight(int line, String text)
{
const String space = " ";
const String longText = space + text + ' ';
int displaySize = 16;
for (int i = 0; i <= longText.length(); ++i)
{
lcd.setCursor(0, line);
String display = longText.substring(i, i + displaySize);
lcd.print(display);
delay(350);
}
}
1 ответ
Когда вы объявляете аргумент как char text[]
компилятор переводит это как char* text
, То есть это указатель.
И получить размер указателя (например, sizeof(text)
) дает вам размер указателя, а не то, на что он указывает. Если это байтовая строка с нулевым символом в конце, используйте strlen
чтобы получить длину (но учтите, что нулевой терминатор не учитывается).
Или, что еще лучше, прекратите использовать строки и функции C, потому что Arduino фактически запрограммирован на C++ и имеет свой собственный стандарт. String
класс, который должен использоваться для всех строк.
Также обратите внимание, что
const char space[16] = " ";
создает массив из 16 элементов и устанавливает все эти элементы в символ пробела ' '
, Но это не строка с нулевым символом в конце, потому что терминатор не помещается в массив.
Вы также знаете о memset
функция, но, кажется, забыл memcpy
функция при копировании из ваших массивов.
Вместо явного цикла копирования из space
Вы могли бы просто сделать
memcpy(longText, space, sizeof space); // Using sizeof since space is not null-terminated
И наконец, будьте осторожны с strncpy
функция может не завершать строку назначения.