繁体   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