20×4使用Python控制LCD模块

28

本文基于我之前的文章 16×2使用Python控制LCD模块16×2个带背光开关的LCD模块控制。 20×4个LCD模块相对容易获得且价格便宜。它们具有与16个LCD模块相同的16针接口×2个模块,但仍然只需要Pi上有6个GPIO引脚(背光开关需要一个额外的引脚)。

这些模块与Hitachi HD44780 液晶屏控制器兼容。在eBay上有很多可用的背光颜色可供选择。

液晶模组硬件

该模块的引脚排列为:

  1. 地面
  2. VCC(通常+ 5V)
  3. 对比度调整(VO)
  4. 寄存器选择(RS)。
    RS = 0:命令,RS = 1:数据
  5. 读/写(R / W)。
    R / W = 0:写,R / W = 1:读
  6. 启用
  7. 位0(4位操作中不需要)
  8. 位1(4位操作中不需要)
  9. 位2(4位操作中不需要)
  10. 位3(4位操作中不需要)
  11. Bit 4
  12. Bit 5
  13. Bit 6
  14. Bit 7
  15. LED背光阳极(+)
  16. LED背光阴极(-)

通常,设备需要8条数据线才能将数据提供给位0-7。但是,此LCD可以配置为使用“4 bit” mode which allows you to send data in two chunks (or nibbles) of 4位s. This reduces the number of 通用输入输出 connections you need when interfacing with your Pi.

这是我连接液晶显示器的方式:

液晶屏针功能Pi功能Pin
01地线地线P1-06
02+5V+5VP1-02
03对比
04RS 通用输入输出7P1-26
05RW地线P1-06
06E通用输入输出8P1-24
07Data 0
08Data 1
09Data 2
10Data 3
11Data 4通用输入输出25P1-22
12Data 5通用输入输出24P1-18
13Data 6通用输入输出23P1-16
14Data 7通用输入输出18P1-12
15+ 5V通过560欧姆
16地线P1-06

注意 : RW引脚允许将设备置于读取或写入模式。我将此引脚接地,以防止模块尝试向Pi发送数据,因为Pi不能承受其GPIO接头上的5V输入。

引脚3:为了控制对比度,您可以调整引脚3上显示的电压。我使用10K欧姆微调器向引脚3提供0-5V可变电压,从而可以调整对比度。

针脚15:这为背光LED提供电源。为了允许打开和关闭背光灯,我使用了一个晶体管(BC547,BC548或等效晶体管)来切换此引脚。这需要一个额外的GPIO引脚来切换晶体管,但允许我的Python脚本控制背光。

接线检查

在首次给电路上电之前,这里有一些完整性检查:

  • 针脚1(GND),3(对比度),5(RW)和16(LED-)(应接地)。
  • 引脚2应该连接到5V。针脚15的串联电阻应为5V,以保护背光。
  • 引脚7-10未连接
  • 引脚11-14连接到Pi上的GPIO引脚

蟒蛇

下面的脚本主要基于我的16×2带背光开关的LCD模块控制文章中提供的代码。这样可以打开和关闭背光灯,以及一些基本的文本对齐方式。

和往常一样,我使用的是出色的 RPi.GPIO库 提供对Python中GPIO的访问。

此设置的功能包括:

  • 10k可变电阻器可调节对比度
  • 2k可变电阻器可调节背光亮度
  • 一个晶体管,可以打开和关闭背光
  • 左对齐,居中和右对齐文本

面包板电路如下所示:

对比度调整

引脚3通过10K欧姆微调电位器接地,以便可以调节显示对比度。

背光亮度和切换

15/16引脚通过NPN转接器与560欧姆和2K欧姆微调电位器串联,该转接器由一个额外的GPIO连接激活。 液晶屏背光的处理方式与我之前切换标准LED的方式完全相同 使用GPIO输出引脚控制LED 文章。使用固定电阻可确保永远无法将电阻调节到560欧姆以下,如果将微调电位器设置为零欧姆,则可以保护背光。晶体管的基极通过一个27K欧姆的电阻连接到另一个GPIO引脚。

文字对齐

功能“lcd_string”接受第二个参数(1、2或3),该参数确定文本在屏幕上的显示方式。

蟒蛇

这是代码:

#!/usr/bin/python
#--------------------------------------
#    ___  ___  _ ____
#   / _ \/ _ \(_) __/__  __ __
#  / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/  /_/___/ .__/\_, /
#                /_/   /___/
#
#  lcd_16x2.py
#  20x4 液晶屏 Test Script with
#  backlight control 和 text justification
#
# Author : 马特 Hawkins
# Date   : 06/04/2015
#
# //www.ytguangda.com/
#
#--------------------------------------

# The wiring for the 液晶屏 is as follows:
# 1 : 地线
# 2 : 5V
# 3 : 对比 (0-5V)*
# 4 : RS  (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 6 : 启用 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: 液晶屏 Backlight +5V**
# 16: 液晶屏 Backlight 地线

#import
import RPi.GPIO as 通用输入输出
import time

# Define 通用输入输出 to 液晶屏 mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
LED_ON = 15

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

LCD_LINE_1 = 0x80#第一行的LCD RAM地址
LCD_LINE_2 = 0xC0 # 液晶屏 RAM address for the 2nd line
LCD_LINE_3 = 0x94 # 液晶屏 RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # 液晶屏 RAM address for the 4th line

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

def main():
  # Main program block

  通用输入输出.setmode(GPIO.BCM)       # Use BCM 通用输入输出 numbers
  通用输入输出.setup(LCD_E, 通用输入输出.OUT)  # E
  通用输入输出.setup(LCD_RS, 通用输入输出.OUT) # RS 
  通用输入输出.setup(LCD_D4, 通用输入输出.OUT) # DB4
  通用输入输出.setup(LCD_D5, 通用输入输出.OUT) # DB5
  通用输入输出.setup(LCD_D6, 通用输入输出.OUT) # DB6
  通用输入输出.setup(LCD_D7, 通用输入输出.OUT) # DB7
  通用输入输出.setup(LED_ON, 通用输入输出.OUT) # Backlight enable

  # Initialise 显示
  lcd_init()

  # Toggle backlight 上-off-on
  lcd_backlight(True)
  time.sleep(0.5)
  lcd_backlight(False)
  time.sleep(0.5)
  lcd_backlight(True)
  time.sleep(0.5)

  while True:

    # Send some centred test
    lcd_string("--------------------",LCD_LINE_1,2)
    lcd_string("Rasbperry Pi",LCD_LINE_2,2)
    lcd_string("Model B",LCD_LINE_3,2)
    lcd_string("--------------------",LCD_LINE_4,2)

    time.sleep(3) # 3 second delay

    lcd_string("Raspberrypi-spy",LCD_LINE_1,3)
    lcd_string(".co.uk",LCD_LINE_2,3)
    lcd_string("",LCD_LINE_3,2)
    lcd_string("20x4 液晶屏 Module Test",LCD_LINE_4,2)

    time.sleep(3) # 20 second delay

    # Blank 显示
    lcd_byte(0x01, 液晶屏_CMD)

    time.sleep(3) # 3 second delay

def lcd_init():
  # Initialise 显示
  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 显示
  time.sleep(E_DELAY)

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

  通用输入输出.output(LCD_RS, mode) # RS 

  # High bits
  通用输入输出.output(LCD_D4, False)
  通用输入输出.output(LCD_D5, False)
  通用输入输出.output(LCD_D6, False)
  通用输入输出.output(LCD_D7, False)
  if bits&0x10==0x10:
    通用输入输出.output(LCD_D4, True)
  if bits&0x20==0x20:
    通用输入输出.output(LCD_D5, True)
  if bits&0x40==0x40:
    通用输入输出.output(LCD_D6, True)
  if bits&0x80==0x80:
    通用输入输出.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

  # Low bits
  通用输入输出.output(LCD_D4, False)
  通用输入输出.output(LCD_D5, False)
  通用输入输出.output(LCD_D6, False)
  通用输入输出.output(LCD_D7, False)
  if bits&0x01==0x01:
    通用输入输出.output(LCD_D4, True)
  if bits&0x02==0x02:
    通用输入输出.output(LCD_D5, True)
  if bits&0x04==0x04:
    通用输入输出.output(LCD_D6, True)
  if bits&0x08==0x08:
    通用输入输出.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

def lcd_toggle_enable():
  # Toggle enable
  time.sleep(E_DELAY)
  通用输入输出.output(LCD_E, True)
  time.sleep(E_PULSE)
  通用输入输出.output(LCD_E, False)
  time.sleep(E_DELAY)

def lcd_string(message,line,style):
  # Send string to 显示
  # style=1 Left justified
  # style=2 Centred
  # style=3 Right justified

  if style==1:
    message = message.ljust(LCD_WIDTH," ")
  elif style==2:
    message = message.center(LCD_WIDTH," ")
  elif style==3:
    message = message.rjust(LCD_WIDTH," ")

  lcd_byte(line, 液晶屏_CMD)

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

def lcd_backlight(flag):
  # Toggle backlight 上-off-on
  通用输入输出.output(LED_ON, flag)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, 液晶屏_CMD)
    lcd_string("Goodbye!",LCD_LINE_1,2)
    通用输入输出.cleanup()

请记住要更新脚本顶部的常量,以匹配您在Pi上使用的GPIO信号。一如既往,这些GPIO引用是Broadcom信号名称,如我 通用输入输出头文章.


看看我的另一个 液晶屏相关帖子 其中包括16的详细信息×本文使用的2版屏幕。

分享。

28条留言

  1. 这是一项出色的工作,我想我将其中之一作为RasPi的外部链接!

    我确实有一个问题,20的型号/零件号是多少×4 液晶屏模块,我在找到一个如图所示的模块时遇到了一些麻烦,并且有点不愿意获得一个’t exactly the same ‘just in case’引脚排列等是不同的。

    看起来HD44780不是’在ðŸ™,上需要搜索的内容

  2. 一个无知但渴望的菜鸟

    嘿—所以我有分线板,一些电线和LCD屏幕。我不穿’有各种电阻。我非常渴望前进,但是显然,我不知道自己在做什么。我不’不想油炸Pi或LCD屏幕。但是有些人直接从GPIO到那里的LCD屏幕接线,那么电阻的必要性是什么?

    我必须找到一个站点,以了解突破委员会的工作原理。我可以’没说我什么都懂,但是肯定有学的。 ðŸ™,

    感谢您的网站,我’我对自己的工作有更多了解后,会回到这里。

    • 电阻在那里限制流向背光输入的电流,并分压至对比度输入。

      不需要对比度电阻,它们只是允许您调整对比度。需要背光电阻,否则有损坏背光的危险。某些LCD模块内置了背光电阻,但没有’一定要弄清楚这些是否存在… so I play it safe.

      我从eBay获得了所有电阻器。花费几磅/美元来收集更常见的值是值得的。在我的电路中,我倾向于使用560、1K,2K,5K,10K和27K值,因此我只购买了100个。

    • 取决于你在哪里’重新定位的Maplins(在英国)可以做到合理的组合(混合价值)。得到通常的肤色’不是蓝色的!它们看起来都很相似,但是一旦您习惯了颜色,’ll be fine.

  3. 亚历山德罗

    干得好,非常好的项目,我’m beginner 和 I’会尝试该项目的,效果很好!但是我’还有一个问题,有人可以帮我在python中为度数符号(°)创建一个特殊字符吗?我发现了很多指南,但是在python中什么也没有!

    • 你好
      在HD44780上搜索一些文档,您可以在值223(0xDF)下找到°字符。然后,例如,您可以构建一个可以像这样发送的字符串:
      线= str(温度)+ chr(223)+‘C’

      那将使一个带有变量值的字符串“temperature”,°符号,然后为摄氏C(… 34°C).

      希望能有所帮助
      司马

  4. 大家好。
    首先,感谢本教程,它帮助我获得了4分×20 JHD 204A 液晶屏可与我的Pi一起使用。
    我第一次使用相同的接线,在PIN 15上没有电阻(LCD板载一个),我’将CONTRAST PIN线接地。
    液晶屏可以正常工作两天,但是现在使用相同的精确接线’不再工作了!!任何想法这是为什么?
    ps:过去,当我尝试使其与PIC MCU配合使用时,我在使用同一LCD时遇到很多问题,’我尝试了每件事,但它赢了’t work.
    i’我开始认为问题出在LCD本身,是这样吗?

    预先感谢您的任何帮助

  5. 可以将另一个引脚用作RS引脚吗?现在已在P1-26 通用输入输出7上配置了该功能,但我已经在此引脚上配置了另一个功能。

  6. 佩德罗·罗德里格斯(Pedro Rodrigues)

    你好

    我有二十×4个带hd44780的LCD模块LCM1602。一世’m using I2c.

    您是否具有在Raspberry Pi B +上与I2c一起使用的示例代码?
    我想滚动(上,下,左,右)和自定义字符。

  7. 菲尔·施瓦兹

    你好,
    我已修改您的程序,以使用Radxa Rock Pro SBC上的pyRock.gpio库。我可以在Radxa论坛上与其他用户共享修改后的程序吗?我保留了前十条评论行,并给予了您充分的信誉,并可以发布指向此网页的链接。如果是,那么我可以在将文章发送给Radxa之前通过电子邮件将其发送给您。

    感谢您分享您的程序,这是这位python新手的灵感。

  8. 嗨,马特,

    首先,感谢您制作了一个很棒的博客,我希望获得这20个博客之一×作为圣诞节项目的4个LCD屏幕,您是否有机会张贴确切的电阻器,晶体管和电位计,我需要在不破坏我的pi的情况下使它正常工作?
    非常感谢,

  9. 我使它与您完全一样,使用了与您相同的代码,但最终胜出’工作。我的显示屏仅在第一行和第三行显示黑条。一件事我’ve注意到它,我的显示器可以在Arduino上正常工作,并且Arduino上的字符比Pi上的字符暗。我怎样才能解决这个问题?谢谢!

  10. 嗨,马特,

    I’我还是初学者,我想对接线图有两个问题:
    –连接到PIN15的第二个可变电阻值(2k或5k)是多少
    –在电路板上,第二个可变电阻器只有2条脚连接,第一个连接到PIN15,第二个通过560欧姆连接到正轨。可变电阻的第三引脚呢?

    • It’s 2K。当我写这篇文章时,我打算使用5K,但将其更改为2K。它没有’真的很重要。它只需要允许您从最小值560开始增加该值。

      如果您使用可变电阻器来分压,则需要使用3个引脚。 1表示最大电压,1表示接地,另一个“sweeps”中间。我这样做是为了对比,因为它需要0到5V之间的可变电压。

      如果您只是希望它充当可变值的电阻器,则只需要使用支脚之一和“sweeps”在其他两个之间。

  11. 不为您工作?我可能找到了您的解决方案(i’我们研究了许多网站,很多人都遇到了这个问题)。一世’我是个初学者,为此我花了好几个小时努力解决同样的问题。白盒子吧?这里’解决方案:GPIO引脚26(RS)是板引脚37(raspi 2)。 通用输入输出引脚24实际上是电路板引脚35。您可能对数据GPIO引脚而言是正确的做法,但是将电路板引脚与LCD引脚4和LCD引脚6相关联。检查这些引脚并确保您’将它们与GPIO引脚26和24(板引脚37和35)相关联。我正在使用板别针26和24。祝您好运。终于对我有用(这里是凌晨4点!而乐趣才刚刚开始)

  12. 菲尔·罗杰斯

    一篇很棒的文章。一世’我使用Raspberry Pi为我自制的太阳能热水器制作了控制器。它读取温度传感器,并根据其值来打开或关闭泵。
    添加显示器将使我能够显示这些温度和泵的状态,从而使我能够优化和优化控制器软件。
    您的文章使我免于试图自己解决所有问题。

  13. 沃尔夫拉姆·埃瑟

    嗨,首先:谢谢你。

    我这边的一个观察/提示:
    使用Python脚本时,我的显示效果非常好“unstable”。它显示正确的文本,背光灯正常工作。看起来不错!但是,当我从Raspberry上拔下以太网或触摸以太网插孔的银色屏蔽时,我的文字被黑色方块抹去了。我什至可以通过仅将手靠近连接Raspi和LCD的电线来重现这一点。查看数据表“black square”等于字符255 = 0xFF =11111111。因此,在您的python脚本终止并显示了文本后,我测量了GPIO引脚–他们都有+ 5V!所以很明显,在这种状态下“大气干扰” was needed for the 显示 to fill everything witch 黑色正方形s.

    然后我发现了一个GPIO.cleanup()–在脚本末尾要做的–确实将所有使用的GPIO切换到输入模式,这意味着它们已连接电流。

    我使LCD稳定的解决方案是:
    =>从您的skript中删除GPIO.cleanup()行。
    Now after your script runs, all my 通用输入输出s have +0V 和 no 黑色正方形s erase my text anymore when I touch or come close to the wires.

    再次感谢您的光临!

    来自德国的Wolfram

  14. 你好,

    感谢您的代码和说明。它帮助我使显示器正常工作。一世’现在玩一玩,看看我能做什么。

    快速问题ðŸ™,在哪里找到LCD LINE的LCD RAM地址信息’s?
    液晶屏_LINE_1 = 0x80#第一行的LCD RAM地址

    谢谢。

    保罗

  15. pingback: Raspberry Pi Plex服务器监视器|平均制造商

发表评论

该网站使用Akismet减少垃圾邮件。 了解如何处理您的评论数据.