手头有一块 LCD1602显示屏,于是尝试着用树莓派控制它的显示。网上直接找到现成的例子,操作成功,在此记录。
树莓派版本:Model 3B+
树莓派系统:Raspbian Stretch with desktop and recommended software,April 2019
参考资料:《》。
在树莓派电源关闭时,根据参考资料中的连接方式(截图如下)连接树莓派、LCD显示屏和电位器,因为很多引脚需要连接正负极,树莓派上没有足够多的5v,所以我用了一个面包板。
连接好后如下图所示。我的线太长了,显得有些乱,大家接线的时候小心短路。
树莓派开机。
LCD 显示屏就会亮,但没有显示内容。
将参考资料中的两个 python 文件保存至树莓派中的同一文件夹下,长文件命名为1602led.py,短文件命名为1602.py。代码如下,点击+展开:
#!/usr/bin/python## 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#from time import sleepclass 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): # Emulate the old behavior of using RPi.GPIO if we haven't been given # an explicit GPIO interface to use 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.setwarnings(False) 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 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("hello world!")
#!/usr/bin/python from lcd1602 import *from datetime import *import commands def get_cpu_temp(): tmp = open('/sys/class/thermal/thermal_zone0/temp') cpu = tmp.read() tmp.close() return '{:.2f}'.format( float(cpu)/1000 ) + ' C' def get_gpu_temp(): tmp = commands.getoutput('vcgencmd measure_temp|awk -F= \'{print $2}\'').replace('\'C','') gpu = float(tmp) return '{:.2f}'.format( gpu ) + ' C' def get_time_now(): return datetime.now().strftime(' %H:%M:%S\n %Y-%m-%d') def get_ip_info(): return commands.getoutput('ifconfig wlan0|grep inet|awk -Faddr: \'{print $2}\'|awk \'{print $1}\'') def get_mem_info(): total= commands.getoutput('free -m|grep Mem:|awk \'{print $2}\'') free = commands.getoutput('free -m|grep cache:|awk \'{print $4}\'') return 'MEM:\n ' + free +' / '+ total +' M' lcd = lcd1602()lcd.clear() if __name__ == '__main__': while(1): lcd.clear() lcd.message( get_ip_info() ) sleep(5) lcd.clear() lcd.message( get_time_now() ) sleep(5) lcd.clear() lcd.message( get_mem_info() ) sleep(5) lcd.clear() lcd.message( 'CPU: ' + get_cpu_temp()+'\n' ) lcd.message( 'GPU: ' + get_gpu_temp() ) sleep(5)
代码需用 python2.7 运行,终端进入对应的文件夹下,执行 python 1602.py ,就能发现显示屏变化了。注意,可能需要旋转电位器转轴来矫正显示屏。
运行结果:
该程序是无限循环的,终止程序后(control+C),显示屏会保留最后状态。
相关文章