Почему на моем ЖК-дисплее 16x2 отображаются странные буквы и не удается вставить клавишу с клавиатуры?

Я новичок в Arduino, и это мой первый проект на ЖК-дисплее 16x2, клавиатуре 4x4 и других. Итак, история такова, после того, как я загрузил программу для будильника Arduino моей группы на плату Arduino, на ЖК-дисплее отображаются черные квадраты в первой строке ЖК-дисплея. Но после повторной пайки контактов ЖК-дисплея и подключения Vo к потенциометру на 10 кОм ЖК-дисплей может правильно отображать «приветственную» часть. Это видно на двух картинках ниже. Добро пожаловать

Проект TIME Однако через некоторое время во второй строке ЖК-дисплея появляются странные буквы, которые снова и снова мигают от первого изображения ниже ко второму. Кроме того, я не мог ввести какую-либо клавишу с клавиатуры на ЖК-дисплей, так как дисплей застрял там. появляются странные буквы

снова появляются странные буквы Я не уверен, есть ли проблема в схеме или в программировании. Я здесь совсем запутался. Ниже приведен код, который я загрузил на плату 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);
}

, 👍0

Обсуждение

Какие из многих библиотек 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


1 ответ


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