简体   繁体   中英

Arduino LCD Display showing jumbled letters

When switching between states, the lines get jumbled and the characters get mixed up. Nothing I've seen online helps and example code in the library works just fine. The main issue I think comes from when the LCD is wiped clean, but then I don't know where it should be wiped. I've moved it from loop() to the cases multiple times, and delays don't help.

#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;

  }
}

You're creating nonsense instructions for your LCD if you execute commands in an ISR while already executing instructions in your normal program.

Let's say the serial command to write letter A is "WRITEA" and the command for clearing the display is "CLEAR".

Now while sending the letter A to your display you push the button, your display will receive something like "WRCLEARTEB" which it cannot make sense of. Or maybe it receives "WRITECLEARA" and it will write C instead of A.

Please note that this is just to give you an idea what is going on. Of course the data sent to the display is different.

But you're creating a mess by interleaving commands.

Update your display in a loop and use ISRs only to update variables that are then used in the next frame. Clocks with second precision are usually updated once per second.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM