Почему на моем ЖК-дисплее 16x2 отображаются странные буквы и не удается вставить клавишу с клавиатуры?
Я новичок в Arduino, и это мой первый проект на ЖК-дисплее 16x2, клавиатуре 4x4 и других. Итак, история такова, после того, как я загрузил программу для будильника Arduino моей группы на плату Arduino, на ЖК-дисплее отображаются черные квадраты в первой строке ЖК-дисплея. Но после повторной пайки контактов ЖК-дисплея и подключения Vo к потенциометру на 10 кОм ЖК-дисплей может правильно отображать «приветственную» часть. Это видно на двух картинках ниже.
Однако через некоторое время во второй строке ЖК-дисплея появляются странные буквы, которые снова и снова мигают от первого изображения ниже ко второму. Кроме того, я не мог ввести какую-либо клавишу с клавиатуры на ЖК-дисплей, так как дисплей застрял там.
Я не уверен, есть ли проблема в схеме или в программировании. Я здесь совсем запутался. Ниже приведен код, который я загрузил на плату Arduino. Заранее спасибо.
#include <EEPROM.h>
#include <Keypad.h>
#include <DS1307.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <LiquidCrystal.h>
DS1307 rtc(SDA, SCL);
LiquidCrystal lcd(A3, A2, A1, A0, 5, 4);
Time t;
#define buz 3
int Hor, Min, Sec, h, m, s;
int ASCII = 48;
char* tim;
char* dat;
const char key = 0;
char buffer[2];
const byte numRows= 4;
const byte numCols= 4;
char keymap[numRows][numCols]=
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {12, 11, 10, 9};
byte colPins[numCols]= {8, 7, 6, 5};
Keypad myKeypad= Keypad(makeKeymap(keymap),rowPins, colPins, numRows, numCols);
void setup() {
Wire.begin();
rtc.begin();
pinMode(buz, OUTPUT);
lcd.begin(16, 2);
welcome();
rtc.setDOW(SATURDAY); //Установить день недели на ВОСКРЕСЕНЬЕ
rtc.setTime(10, 54, 0); //Установите время на 12:00:00 (24-часовой формат)
rtc.setDate(7, 1, 2017); //День месяц год
}
void loop() {
t = rtc.getTime();
Hor = t.hour;
Min = t.min;
Sec = t.sec;
tim = rtc.getTimeStr();
dat = rtc.getDateStr();
char key = myKeypad.getKey();
if (key == 'C'){
digitalWrite(buz, LOW);
EEPROM.write(2, ASCII+6);
EEPROM.write(3, ASCII);
}
if(key == '#'){
lcd.setCursor(0,0);
lcd.print("Enter New Time");
lcd.setCursor(0,1);
int j =0;
int i=0;
while( j<6)
{
if(i==2 || i == 5){
lcd.print(":");
lcd.display();
i++;
}
key=myKeypad.getKey();
if(key)
{
lcd.print(key);
lcd.display();
EEPROM.write(j,key);
j++;
i++;
}
}
}
changealarm();
checkalarm();
timedate();
}
void checkalarm(){
if( Hor == h && Min == m)
{
delay(3000);
lcd.setCursor(0,1);
lcd.print("Hold C");
digitalWrite(buz, HIGH);
delay(3000);
}
}
void changealarm(){
buffer[0]=EEPROM.read(0);
buffer[1]=EEPROM.read(1);
h = atoi(buffer);
buffer[0]=EEPROM.read(2);
buffer[1]=EEPROM.read(3);
m = atoi(buffer);
buffer[0]=EEPROM.read(4);
buffer[1]=EEPROM.read(5);
s = atoi(buffer);
}
void timedate(){
lcd.setCursor(0,0);
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
lcd.setCursor(0,1);
lcd.print("Date: ");
lcd.print(rtc.getDateStr());
delay(3000);
lcd.setCursor(0,1);
lcd.print("Alarm: ");
lcd.print(h);
lcd.print(".");
lcd.print(m);
lcd.print(".");
lcd.print(s);
delay(3000);
}
void welcome(){
lcd.setCursor(0,0);
lcd.print("Welcome");
lcd.setCursor(0,1);
lcd.print("To");
delay(3000);
lcd.setCursor(0,1);
lcd.print("TIMeProject");
delay(3000);
}
1 ответ
В вашей функции changealarm()
вы вызываете atoi(buffer)
, а buffer
определяется как char buffer[2 ]
.
atoi()
ожидает строку в стиле c, заканчивающуюся нулем, и вы должны включить пробел для завершающего нуля символа ('\0'
, 0
, 0x00
и т. д.), но вы записываете в оба выделенных пространства в функции changealarm()
. Если ваш 2-й байт каждого пространства EEPROM (1, 3, 5) отличен от нуля, то у вас есть незавершенная строка.
atoi()
ожидает строку с завершающим нулем, поэтому поведение неожиданное. Вероятно, atoi()
работает в другой памяти. Если отправляемая строка не может быть представлена типом int
, то поведение atoi()
undefined.
Быстрым решением было бы увеличить размер buffer
и гарантировать нулевое завершение:
char buffer[3]; // Делаем буфер длиной 3 байта
[...]
void changealarm() {
buffer[2]=0; // Установить 3-й байт равным нулю для нулевого завершения
buffer[0]=EEPROM.read(0);
buffer[1]=EEPROM.read(1);
h = atoi(buffer);
buffer[0]=EEPROM.read(2);
buffer[1]=EEPROM.read(3);
m = atoi(buffer);
buffer[0]=EEPROM.read(4);
buffer[1]=EEPROM.read(5);
s = atoi(buffer);
}
Я понимаю. Но что я должен делать? Должен ли я изменить часть atoi()? Я немного смущен., @Nur Syahzanani Huda
Я обновил свой ответ, чтобы показать решение проблемы переполнения. (В вашем коде есть и другие проблемы, такие как множество задержек в 3000 мс, когда ничего не может произойти, даже нажатия клавиш), @jose can u c
Я изменил часть changealarm()
в соответствии с вашим решением. И я попытался изменить задержки на 1000 мс. Но все равно происходит такое же отображение. Итак, я предполагаю, что что-то не так в части if(key == '#') ...
?, @Nur Syahzanani Huda
Через какое время после запуска скетча появляется мусорное отображение? Это происходит, если вы вообще не нажимаете никаких клавиш?, @jose can u c
После того, как я изменил задержки на 1000 мс, нежелательное отображение появляется через секунду после отображения lcd.print("TIMEProject");
. Он продолжает автоматически мигать нежелательным дисплеем. И да, это происходит, если я вообще не нажимаю никаких клавиш сразу после того, как загрузил код на доску., @Nur Syahzanani Huda
Проблемы со странными буквами решены! Оказывается, контакты клавиатуры были подключены по-разному с загруженным кодом., @Nur Syahzanani Huda
- Постоянное хранилище Adafruit Trinket M0 ?
- Код датчика отпечатков пальцев некорректно работает с LCD дисплеем 16x2
- Нет функции сопоставления для вызова 'DS3231 (const uint8_t &, const uint8_t &)
- LCD экран печатает одни и те же символы дважды
- ЖК-дисплеи мешают работе SD-карты регистратора данных Adafruit
- Wire.h отсутствует — не удалось загрузить скетч ЖК-дисплея I2C 16x2.
- Как преобразовать мою настройку Arduino в настройку PIC?
- Оператор Switch застрял в цикле
Какие из многих библиотек DS1307 вы используете в частности?, @jose can u c
Я использую библиотеку DS1307 с этого сайта http://www.rinkydinkelectronics.com/library.php?id=34., @Nur Syahzanani Huda
Только новичок будет пытаться сделать полноценный проект. Более опытный программист делает небольшую часть и проверяет, работает ли она, затем другую часть и так далее. Например, вы можете сделать небольшой набросок, чтобы протестировать кнопки. Текст имеет нулевой терминатор. Сделайте свой буфер равным 10, 16 или 40, но не только размером 2. Перед вызовом atoi установите для буфера [2] значение '\0'. «Ключ» напечатан на дисплее, я думаю, это то, что вы видите., @Jot
Я уже изменил код
changealarm()
в соответствии с решением jose can u c, но странные буквы все еще там. Что я должен делать?, @Nur Syahzanani Huda