查看: 749|回复: 0

LCD1602多引脚面对Raspberry Pi 引脚有限的解决方法

[复制链接]

该用户从未签到

发表于 2016-2-26 08:50:20 | 显示全部楼层 |阅读模式
分享到:
LCD1602多引脚面对Raspberry Pi 引脚有限的情况,就显得由为重要。

先来来Python 的实现方法,主要是利用python-smbus
方案方法
sudo apt-get install python-smbus
sudo apt-get install i2c-tools


MCP8574 的代码如下Qtgz_PCF8574.py

  • from Qtgz_I2C import Qtgz_I2C
  • import smbus
  • import time

  • class Qtgz_MCP8574(object):
  •     OUTPUT = 0
  •     INPUT = 1

  •     def __init__(self, address, num_gpios, busnum=-1):
  •      assert num_gpios >= 0 and num_gpios <= 8, "Number of GPIOs must be between 0 and 16"
  •      self.i2c = Qtgz_I2C(address=address, busnum=busnum)
  •      self.address = address
  •      self.num_gpios = num_gpios

  •     def _changebit(self, bitmap, bit, value):
  •      assert value == 1 or value == 0, "Value is %s must be 1 or 0" % value
  •      if value == 0:
  •          return bitmap & ~(1 << bit)
  •      elif value == 1:
  •          return bitmap | (1 << bit)

  •     def _readandchangepin(self, pin, value, currvalue = None):
  •      assert pin >= 0 and pin < self.num_gpios, &quotin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
  •      #assert self.direction & (1 << pin) == 0, &quotin %s not set to output" % pin
  •      if not currvalue:
  •           currvalue = self.i2c.readRaw8()
  •      newvalue = self._changebit(currvalue, pin, value)
  •      self.i2c.writeRaw8(newvalue)
  •      return newvalue

  •     def config(self, pin, mode):
  •      if self.num_gpios <= 8:
  •          self.direction = self._readandchangepin(pin, mode)
  •      return self.direction

  •     def output(self, pin, value):
  •      if self.num_gpios <= 8:
  •          self.outputvalue = self._readandchangepin(pin, value, self.i2c.readRaw8())
  •      return self.outputvalue

  •     def input(self, pin):
  •      assert pin >= 0 and pin < self.num_gpios, &quotin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
  •      assert self.direction & (1 << pin) != 0, &quotin %s not set to input" % pin
  •      if self.num_gpios <= 8:
  •          value = self.i2c.readRaw8()
  •      return value & (1 << pin)

  •     def readU8(self):
  •      result = self.i2c.readRaw8()
  •      return(result)

  •     def readS8(self):
  •      result = self.i2c.readRaw8()
  •      if (result > 127): result -= 256
  •      return result

  •     def write8(self, value):
  •      self.i2c.writeRaw8(value)

  • class PCF8574_GPIO(object):
  •     OUT = 0
  •     IN = 1
  •     BCM = 0
  •     BOARD = 0
  •     def __init__(self, busnum, address, num_gpios):
  •      self.chip = Qtgz_MCP8574(address, num_gpios, busnum)
  •     def setmode(self, mode):
  •      # do nothing
  •      pass
  •     def setup(self, pin, mode):
  •      self.chip.config(pin, mode)
  •     def input(self, pin):
  •      return self.chip.input(pin)
  •     def output(self, pin, value):
  •      self.chip.output(pin, value)

  • if __name__ == '__main__':
  •     # ***************************************************
  •     # Set num_gpios to 8 for MCP8574
  •     # ***************************************************
  •     mcp = Qtgz_MCP8574(address = 0x27, num_gpios = 8) # MCP8574

  •     mcp.config(3, mcp.OUTPUT)

  •     # Set pin 3 to input with the pullup resistor enabled
  •     #mcp.config(3, mcp.INPUT)

  •     # Read input pin and display the results
  •     #print &quotin 3 = %d" % (mcp.input(3) >> 3)

  •     # Python speed test on output 3 toggling at max speed
  •     print "Starting blinky on pin 3 (CTRL+C to quit)"
  •     while (True):
  •      mcp.output(3, 1) # Pin 0 High
  •      time.sleep(1);
  •      mcp.output(3, 0) # Pin 0 Low
  •      time.sleep(1);
复制代码
LCD1602 的代码

  • from time import sleep


  • class Adafruit_CharLCD(object):

  •     # 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=25, pin_e=24, pins_db=[23, 17, 21, 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
  •          GPIO.setwarnings(False)
  •      self.GPIO = GPIO
  •      self.pin_rs = pin_rs
  •      self.pin_e = pin_e
  •      self.pins_db = pins_db

  •      self.GPIO.setmode(GPIO.BCM) #GPIO=None use Raspi PIN in BCM mode
  •      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

  •     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 off """
  •      self.displaycontrol &= ~self.LCD_CURSORON
  •      self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)

  •     def cursor(self):
  •      """ Turns the underline cursor on """
  •      self.displaycontrol |= self.LCD_CURSORON
  •      self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)

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

  •     def blink(self):
  •      """ Turn the blinking cursor on """
  •      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 == "1":
  •             self.GPIO.output(self.pins_db[::-1], True)
  •      self.pulseEnable()
  •      for pin in self.pins_db:
  •          self.GPIO.output(pin, False)
  •      for i in range(4, 8):
  •          if bits == "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 = Adafruit_CharLCD()
  •     lcd.clear()
  •     lcd.message(" Adafruit 16x2\n Standard LCD")
复制代码
实现代码如下,打印内部温度,内存使用情况

  • #!/usr/bin/python
  • # -*- coding: utf-8 -*-
  • from Adafruit_CharLCD import Adafruit_CharLCD
  • from Qtgz_PCF8574 import PCF8574_GPIO

  • from subprocess import *
  • from time import sleep, strftime
  • from datetime import datetime
  • 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'


  • bus = 1       # Note you need to change the bus number to 0 if running on a revision 1 Raspberry Pi.
  • address = 0x27 # I2C address of the PCF8574 chip.
  • gpio_count = 8 # Number of GPIOs exposed by the PCF8574 chip, should be 8 or 16 depending on chip.

  • # Create PCF8574 GPIO adapter.
  • mcp = PCF8574_GPIO(bus, address, gpio_count)
  • # Create LCD, passing in MCP GPIO adapter.
  • lcd = Adafruit_CharLCD(pin_rs=0, pin_e=2, pins_db=[4,5,6,7], GPIO=mcp)


  • if __name__ == '__main__':

  •     while(1):
  •      lcd.clear()
  •      lcd.message( get_ip_info() )
  •      sleep(1)

  •      lcd.clear()
  •      lcd.message( get_time_now() )
  •      sleep(1)

  •      lcd.clear()
  •      lcd.message( get_mem_info() )
  •      sleep(1)

  •      lcd.clear()
  •      lcd.message( 'CPU: ' + get_cpu_temp()+'\n' )
  •      lcd.message( 'GPU: ' + get_gpu_temp() )
  •      sleep(1)
复制代码
效果如下

热门推荐:
树莓派经验分享全攻略
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

手机版|小黑屋|与非网

GMT+8, 2024-4-20 05:13 , Processed in 0.130980 second(s), 17 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.