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