树莓派与LCD屏1602a

1. 1602a LCD屏

  • 接线端子表:
序号 LCD屏 16PIN 树莓派 40PIN 物理序号 备注
1 VSS 06 GND
2 VDD 02 5V
3 V0 电位器 对比度,0-5V
4 RS 08 GPIO-14
5 RW 06 写模式:接地
6 EN 10 GPIO-15
7 D0 -
8 D1 -
9 D2 -
10 D3 -
11 D4 11 GPIO-17
12 D5 12 GPIO-18
13 D6 13 GPIO-27
14 D7 15 GPIO-22
15 A 串约500Ω电阻后接02 背光正
16 K 06 背光负
  • 接线图
树莓派与LCD屏1602a_第1张图片
raspi-lcd1602a.png

2. 代码

  • 目录如下,就两个文件:
.
├───LCD1602a
│   ├───1602.py     # 主程序,可显示时间、CPU、RAM的使用情况
│   └───lcd1602.py  # 配置程序
│...

lcd1602.py

# based on code from lrvick and LiquidCrystal
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp

import time

class lcd1602:
    # commands
    LCD_CLEARDISPLAY        = 0x01
    LCD_RETURNHOME          = 0x02
    LCD_ENTRYMODESET        = 0x04
    LCD_DISPLAYCONTROL      = 0x08
    LCD_CURSORSHIFT         = 0x10
    LCD_FUNCTIONSET         = 0x20
    LCD_SETCGRAMADDR        = 0x40
    LCD_SETDDRAMADDR        = 0x80

    # flags for display entry mode
    LCD_ENTRYRIGHT              = 0x00
    LCD_ENTRYLEFT               = 0x02
    LCD_ENTRYSHIFTINCREMENT     = 0x01
    LCD_ENTRYSHIFTDECREMENT     = 0x00

    # flags for display on/off control
    LCD_DISPLAYON       = 0x04
    LCD_DISPLAYOFF      = 0x00
    LCD_CURSORON        = 0x02
    LCD_CURSOROFF       = 0x00
    LCD_BLINKON         = 0x01
    LCD_BLINKOFF        = 0x00

    # flags for display/cursor shift
    LCD_DISPLAYMOVE     = 0x08
    LCD_CURSORMOVE      = 0x00

    # flags for display/cursor shift
    LCD_DISPLAYMOVE     = 0x08
    LCD_CURSORMOVE      = 0x00
    LCD_MOVERIGHT       = 0x04
    LCD_MOVELEFT        = 0x00

    # flags for function set
    LCD_8BITMODE        = 0x10
    LCD_4BITMODE        = 0x00
    LCD_2LINE           = 0x08
    LCD_1LINE           = 0x00
    LCD_5x10DOTS        = 0x04
    LCD_5x8DOTS         = 0x00



    def __init__(self, pin_rs=14, pin_e=15, pins_db=[17, 18, 27, 22], GPIO = None):
        if not GPIO:
            import RPi.GPIO as GPIO

        self.GPIO = GPIO
        self.pin_rs = pin_rs
        self.pin_e = pin_e
        self.pins_db = pins_db

        self.GPIO.setmode(GPIO.BCM)
        self.GPIO.setup(self.pin_e, GPIO.OUT)
        self.GPIO.setup(self.pin_rs, GPIO.OUT)

        for pin in self.pins_db:
            self.GPIO.setup(pin, GPIO.OUT)

        self.write4bits(0x33) # initialization
        self.write4bits(0x32) # initialization
        self.write4bits(0x28) # 2 line 5x7 matrix
        self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
        self.write4bits(0x06) # shift cursor right

        self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF

        self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
        self.displayfunction |= self.LCD_2LINE

        """ Initialize to default text direction (for romance languages) """
        self.displaymode =  self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)   #  set the entry mode

        self.clear()


    def begin(self, cols, lines):
        if (lines > 1):
            self.numlines = lines
            self.displayfunction |= self.LCD_2LINE
            self.currline = 0


    def home(self):
        self.write4bits(self.LCD_RETURNHOME)    # set cursor position to zero
        self.delayMicroseconds(3000)            # this command takes a long time!
        

    def clear(self):

        self.write4bits(self.LCD_CLEARDISPLAY)  # command to clear display
        self.delayMicroseconds(3000)            # 3000 microsecond sleep, clearing the display takes a long time


    def setCursor(self, col, row):
        self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]

        if ( row > self.numlines ): 
                row = self.numlines - 1         # we count rows starting w/0

        self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))


    def noDisplay(self): 
        """ Turn the display off (quickly) """
        self.displaycontrol &= ~self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def display(self):
        """ Turn the display on (quickly) """
        self.displaycontrol |= self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def noCursor(self):
        """ Turns the underline cursor on/off """
        self.displaycontrol &= ~self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def cursor(self):
        """ Cursor On """
        self.displaycontrol |= self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def noBlink(self):
        """ Turn on and off the blinking cursor """
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def noBlink(self):
        """ Turn on and off the blinking cursor """
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def DisplayLeft(self):
        """ These commands scroll the display without changing the RAM """
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)


    def scrollDisplayRight(self):
        """ These commands scroll the display without changing the RAM """
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);


    def leftToRight(self):
        """ This is for text that flows Left to Right """
        self.displaymode |= self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);


    def rightToLeft(self):
        """ This is for text that flows Right to Left """
        self.displaymode &= ~self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)


    def autoscroll(self):
        """ This will 'right justify' text from the cursor """
        self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)


    def noAutoscroll(self): 
        """ This will 'left justify' text from the cursor """
        self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)


    def write4bits(self, bits, char_mode=False):
        """ Send command to LCD """
        self.delayMicroseconds(1000) # 1000 microsecond sleep
        bits=bin(bits)[2:].zfill(8)

        self.GPIO.output(self.pin_rs, char_mode)

        for pin in self.pins_db:
            self.GPIO.output(pin, False)

        for i in range(4):
            if bits[i] == "1":
                self.GPIO.output(self.pins_db[::-1][i], True)

        self.pulseEnable()

        for pin in self.pins_db:
            self.GPIO.output(pin, False)

        for i in range(4,8):
            if bits[i] == "1":
                self.GPIO.output(self.pins_db[::-1][i-4], True)

        self.pulseEnable()


    def delayMicroseconds(self, microseconds):
        seconds = microseconds / float(1000000)        # divide microseconds by 1 million for seconds
        time.sleep(seconds)


    def pulseEnable(self):
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)                # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, True)
        self.delayMicroseconds(1)                # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)                # commands need > 37us to settle


    def message(self, text):
        """ Send string to LCD. Newline wraps to second line"""
        for char in text:
            if char == '\n':
                self.write4bits(0xC0) # next line
            else:
                self.write4bits(ord(char),True)


if __name__ == '__main__':
    lcd = lcd1602()
    lcd.clear()
    lcd.message(" LCD 1602 Test \n123456789ABCDEF")

1602.py

import os

import time
from lcd1602 import *
from datetime import datetime

# run command
def run_cmd(cmd):
    p = os.popen(cmd).readline().strip().split()
    return p


def now():
    return datetime.now().strftime('%Y-%m-%d %a \n%H:%M:%S')

def cpu():
    cpu_temp = run_cmd('vcgencmd measure_temp')
    cpu_info = run_cmd("top -bn1 | awk '/Cpu\(s\)/'")
    cpu_usage = 1 - float(cpu_info[7])/100.0

    status = 'CPU Temp: {}\n'.format(cpu_temp[0].replace("temp=", ""))
    status += '    Used: {:.2%}'.format(cpu_usage)
    return status

def ram():
    ram_info = run_cmd("free -m | awk '/Mem/'")
    ram_usage = (int(ram_info[1]) - int(ram_info[6])) / float(ram_info[1])

    status = 'RAM Totl: {}M\n'.format(ram_info[1])
    status += '    Used: {:.2%}'.format(ram_usage)
    return status

def ip():
    ip = run_cmd("sudo ifconfig wlan0 | awk '/inet/'")
    return 'IP Addr: \n  {}'.format(ip[1])

print(now(), cpu(), ram(), ip(), sep='\n')


lcd = lcd1602()
lcd.clear()

while(1):
    lcd.clear()
    lcd.message(now())
    time.sleep(10)

    lcd.clear()
    lcd.message(cpu())
    time.sleep(10)

    lcd.clear()
    lcd.message(ram())
    time.sleep(10)

你可能感兴趣的:(树莓派与LCD屏1602a)