Serial.print печатает, а lcd.print - нет.
Следующий код считывает текстовый файл с SD-карты, находит соответствующий символ и печатает следующие 12 символов:
...
char temp;
byte who = random(1, 13); // 1 to 12
temp = findName(who);
Serial.print(who);
Serial.print(" ==> ");
Serial.println(temp);
...
char findName (byte number) {
char text[12];
byte i;
txt = SD.open("test.txt");
txt.seek(12 * (number - 1));
for (i = 0; i < 11; i++) text[i] = txt.read();
txt.close();
return text;
}
А вот следующее на ЖК-дисплее этого не делает. (setCursor и т. д. опущены для ясности)
...
char temp;
byte who = random(1, 13); // от 1 до 12
temp = findName(who);
lcd.print(who);
lcd.print(" ==> ");
lcd.print(temp);
...
Я уверен, что причина в несоответствии типа данных переменной, но не знаю, как ее решить. Любая помощь приветствуется.
Спасибо.
@ghpg2, 👍0
Обсуждение1 ответ
Лучший ответ:
В функции findName() вы объявляете массив символов с именем text. Внутренне text является указателем на блок памяти размером 12 байт.
Когда вы возвращаете текст внутри функции findName(), вы передаете обратно указатель на блок памяти. Тип возвращаемого значения char несовместим с командой возврата. Но, вероятно, более проблематичным является то, что после завершения findName() память, выделенная для массива text, помечается как неиспользуемая. Он больше не зарезервирован для хранения чего-либо и может быть перераспределен в любое время с помощью какой-либо другой функции или операции.
В C/C++ переменные массива относятся не ко всему массиву, а к первому элементу массива. Тот факт, что ваша программа работает с Serial.print(), вероятно, просто удача. lcd.print() может объявлять некоторую переменную или буфер, которые перезаписывают то, что функция findName() поместила в эти 12 байтов.
Чтобы решить эту проблему, можно использовать множество подходов. Один из способов — объявить массивы символов в «самой высокой» области видимости, в которой они будут использоваться, и объявить их с самым большим размером, который вы когда-либо видели в работе вашей программы.
В вашем случае вы можете:
...
char temp[12];
byte who = random(1, 13); // от 1 до 12
findName(temp, who);
Serial.print(who);
Serial.print(" ==> ");
Serial.println(temp);
...
void findName (char *text, byte number) {
byte i;
txt = SD.open("test.txt");
txt.seek(12 * (number - 1));
for (i = 0; i < 11; i++) text[i] = txt.read();
txt.close();
}
Что это делает:
tempтеперь представляет собой массив символовfindName()принимает указатель на массив символов и число в качестве аргументов.findName()изменяетtext, который ссылается на тот же блок уже выделенной памяти, что иtemp, и этот блок памяти не исчезать в концеfindName().- Поскольку
findName()не возвращает значение, тип возвращаемого значения —void.
Спасибо, сэр! Многому научился из вашего ответа, и ваш фрагмент наконец решил проблему. Теперь я наконец могу продолжить. Еще раз спасибо., @ghpg2
- Чтение текста с SD-карты возвращает странные символы
- Как отобразить символ º на ЖК-дисплее?
- Почему я не могу распечатать значения логических переменных (0 и 1) с помощью функции println?
- Потенциометр 10 кОм против резистора 10 кОм на ЖК-дисплее
- Чтение SMS с помощью Arduino Uno и SIM800L и печать на LCD (16x2 буквенно-цифровых) с использованием последовательного соединения
- Сделать CS (chip select) для работаты в SPI (для и SD карты и OLED)
- Печать массива с помощью функции печати и последовательной записи в Arduino Uno
- Использование экрана SD-карты на Arduino Due
что такое переменная
lcd, @Jaromanda XКак узнать, что ваш ЖК-дисплей работает? ... запустите пример эскиза ЖК-дисплея в Arduino IDE, чтобы убедиться, @jsotola
ЖК-дисплей работает. Переменная представляет собой массив символов, созданный функцией findName()., @ghpg2
Тип
lcdи библиотека?, @JurajПеременная представляет собой массив символов... так зачем же массиву символов иметь методprint?, @Jaromanda XЮрай, обычный символьный ЖК на шине i2c, библиотека LiquidCrystal_I2C.h. Джароманда X, мне следует преобразовать его в строку? Если да, то как? Спасибо., @ghpg2