2

I have a 16x2 LCD Screen that displays the time and date live. The problem is, it starts automatically on boot, but glitches out when it does.

What happens when it starts on boot

In rc.local, I have added a line that says (sleep 10; python /home/pi/Document/LCD.py) Which will start it on boot. I think it might be starting too early in the process. Something that also makes me believe that is that when I plug the display cable in, it has a better rate of success. Maybe it delays the process enough for the GPIO pins to initialize? I have tried to add it as a system service but it doesn't seem to work.

My code:

# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 6 : Enable or Strobe
# 7 : Data Bit 0             - NOT USED
# 8 : Data Bit 1             - NOT USED
# 9 : Data Bit 2             - NOT USED
# 10: Data Bit 3             - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: LCD Backlight +5V**
# 16: LCD Backlight GND

#import
import RPi.GPIO as GPIO
import time

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18


# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

def main():
  # Main program block

  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7


  # Initialise display
  lcd_init()
  while True:
    e = time.strftime("%H:%M:%S")
    date = time.strftime("%Y:%m:%d") 

    # Send some test
    lcd_string(date,LCD_LINE_1) #Change 'text' to what you want.
    lcd_string(e,LCD_LINE_2)

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = data
  # mode = True  for character
  #        False for command

  GPIO.output(LCD_RS, mode) # RS

  # High bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
  if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

  # Low bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x01==0x01:
    GPIO.output(LCD_D4, True)
  if bits&0x02==0x02:
    GPIO.output(LCD_D5, True)
  if bits&0x04==0x04:
    GPIO.output(LCD_D6, True)
  if bits&0x08==0x08:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

def lcd_toggle_enable():
  # Toggle enable
  time.sleep(E_DELAY)
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display




  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)
    lcd_string("Goodbye!",LCD_LINE_1)
    GPIO.cleanup()

Thanks in advance.

omajid
  • 14,165
  • 4
  • 47
  • 64
henry
  • 103
  • 1
  • 7

1 Answers1

0

I see three problems.

  1. Most HD44780 displays (like this display) require 5V I/O. The Raspberry Pi uses 3.3V I/O, which may not be sufficient for some displays.

  2. Relatedly: if the display ever gets put into read mode, it may attempt to drive 5V onto the data bus. This will damage the I/O pins on the Pi.

  3. GPIO.cleanup() resets any output pins on the Pi to inputs. This will leave inputs on the display floating, which will cause unexpected behavior.

Potential solutions:

  1. Use a display which supports 3.3V I/O natively, or which has a level translator or protocol converter built in. (I2C "backpacks" for these displays are a common solution; they'll also save you a couple of pins.)

  2. Add a level translator between the Pi and the display, and pull the E pin low with a resistor so that it cannot float high while undriven by the Pi.

  • I am using a Raspberry Pi Zero, and using the 5 volt pin, would that mean it would be getting 5v or not? – henry Nov 22 '18 at 06:27
  • That only provides 5V to VCC. The other inputs still have a logical high of 3.3V or less. –  Nov 22 '18 at 06:54
  • Sorry I've been inactive, level translator took a while to come - slow international shipping. I've hooked them up, they are working fine (tested with a voltmeter) pulled the e pin low with a 560 ohm resistor, and got rid of gpio.cleanup(). But, when I boot it, the backlight comes on, but doesn't display any text? – henry Jan 19 '19 at 13:12