簡體   English   中英

Arduino LCD 顯示屏顯示亂碼

[英]Arduino LCD Display showing jumbled letters

在狀態之間切換時,線條會變得混亂,字符也會混淆。 我在網上看到的任何幫助都沒有,庫中的示例代碼也可以正常工作。 我認為主要問題來自於 LCD 被擦拭干凈時,但我不知道應該在哪里擦拭。 我已經多次將它從 loop() 移到案例中,並且延遲無濟於事。

#include <TimeLib.h>
#include <DS1307RTC.h>

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

#include "RTClib.h"
RTC_DS1307 rtc;

const int hourButton = 2; // Interrupt Pin 0 -- TOP
const int minuteButton = 3; // Interrupt Pin 1 -- 2nd
const int displayStateButton = 18; // Interrupt Pin 5 -- 3rd
const int alarmButton = 19; // Interrupt Pin 4 -- BOTTOM


int buttonState = LOW; 

int redPin = 4; 
int greenPin = 5; // RGB LED Pins
int bluePin = 6;

int alarmPin = 13; // Alarm Pin

enum DeviceDisplayState {CLOCK, ALARM, DATE, YEAR}; // All different states
DeviceDisplayState displayState = CLOCK; // Initially in Clock State

#ifdef DEBOUNCE
long lastDebounceTime = 0;
long debounceDelay = 60;
#endif

void setup() {
  lcd.begin(16, 2);

  Serial.begin(57600);

  // Set the time:: //

  const int hourInit = 1;
  const int minuteInit = 2;
  const int secondInit = 1;
  const int dayInit = 3;
  const int monthInit = 4;
  const int yearInit = 2020;

  rtc.adjust(DateTime(yearInit, monthInit, dayInit, hourInit , minuteInit, secondInit));

  pinMode(hourButton, INPUT_PULLUP);
  pinMode(minuteButton, INPUT_PULLUP);
  pinMode(displayStateButton, INPUT_PULLUP);

  attachInterrupt(0, increaseHour, FALLING); 
  attachInterrupt(1, increaseMinute, FALLING); 
  attachInterrupt(5, SwitchToNextDisplayState, FALLING); 

  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  pinMode(alarmPin, OUTPUT);

  SwitchToClockState();
};

void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
{
  analogWrite(redPin, red_light_value);
  analogWrite(greenPin, green_light_value);
  analogWrite(bluePin, blue_light_value);
}

void increaseHour()
{
  DateTime dt = rtc.now();
  Serial.print("Previous Time: " + dt.hour());

  if (dt.hour() < 23)
  {
    TimeSpan ts(3600);
    dt = dt + ts;
  }
  else // do not roll over the day by upping the hour, go back to zero hours
  {
     TimeSpan ts(3600 * 23);
     dt = dt - ts;
  }
  Serial.print("Changed Time: " + dt.hour());
  Serial.println();
  rtc.adjust(dt);
}

void increaseMinute()
{
  DateTime dt = rtc.now();

  if (dt.minute() < 59)
  {
    TimeSpan ts(60);
    dt = dt + ts;
  }
  else // Don't roll over the minutes into the hours
  {
    TimeSpan ts(60 * 59);
    dt = dt - ts;
  }

  rtc.adjust(dt);
}

void SwitchToClockState()
{
  displayState = CLOCK;
  RGB_color(255, 0, 0);
}

void SwitchToAlarmState()
{
  displayState = ALARM;
  RGB_color(255, 125, 0);
}

void SwitchToDateState()
{
  displayState = DATE;
  RGB_color(0, 255, 0);
}

void SwitchToYearState()
{
  displayState = YEAR;
  RGB_color(0, 0, 255);
}

void SwitchToNextDisplayState()
{
  switch (displayState) {

    case CLOCK:
      SwitchToAlarmState();
      Serial.print("Switching to Alarm State...");
      Serial.println();
      lcd.clear();
      break;

    case ALARM:
      SwitchToDateState();
      Serial.print("Switching to Date State...");
      Serial.println();
      lcd.clear();
      break;

    case DATE:
      SwitchToYearState();
      Serial.print("Switching to Year State...");
      Serial.println();
      lcd.clear();
      break;

    case YEAR:
      SwitchToClockState();
      Serial.print("Switching to Clock State...");
      Serial.println();      
      lcd.clear();
      break;

    default:
      // assert() 
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, LOW);
      break;
  }
}

String WithLeadingZeros(int number)
{
  if (number < 10)
  {
    return "0" + String(number);
  }
  else
  {
    return String(number);
  }
}


void loop() {
  DateTime now = rtc.now();

  int yearInt   = now.year();
  int monthInt  = now.month();
  int dayInt    = now.day();
  int hourInt   = now.hour();
  int minuteInt = now.minute();
  int secondInt = now.second();

  switch (displayState) {
    case CLOCK:
      lcd.print("Robot Slave");
      lcd.setCursor(0, 1);
      lcd.print("Time> " + WithLeadingZeros(now.hour()) + ":" + WithLeadingZeros(now.minute()) + ":" + WithLeadingZeros(now.second()));
      break;

    case ALARM:
      lcd.print("Robot Slave");

    case DATE:
      lcd.print("Robot Slave");
      lcd.setCursor(0, 1);
      lcd.print("Date> " + WithLeadingZeros(now.month()) + " - " + WithLeadingZeros(now.day()));
      break;

    //case YEAR:
      lcd.print("Robot Slave");
      lcd.setCursor(0, 1);
      lcd.print("Year> " + String(now.year()));
      break;

  }
}

如果您在 ISR 中執行命令而已經在正常程序中執行指令,那么您正在為您的 LCD 創建無意義的指令。

假設寫字母A的串行命令是“WRITEA”,清除顯示的命令是“CLEAR”。

現在,在將字母 A 發送到您的顯示器時,您按下按鈕,您的顯示器將收到類似“WRCLEARTEB”之類的信息,這是它無法理解的。 或者它可能收到“WRITECLEARA”,它會寫 C 而不是 A。

請注意,這只是為了讓您了解正在發生的事情。 當然發送到顯示器的數據是不同的。

但是你通過交錯命令造成了混亂。

在循環中更新您的顯示並僅使用 ISR 來更新隨后在下一幀中使用的變量。 具有秒精度的時鍾通常每秒更新一次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM