Agentkubus
Posts: 5
Joined: Wed Jan 13, 2016 12:51 am

LCD HD44780 menu

Tue Jan 19, 2016 10:50 am

hello, ( sory for my bad english.. ) im trying make a simple menu using lcd 16x2 HD44780 , 5 buttons and raspberry pi 2. I trying to do with code Adafruit_CharLCDPlate but there is using converter I2C, my display does not have I2c . How can i rewrite this code ?

Adafruit_CharLCDPlate

Code: Select all

#!/usr/bin/python

# Python library for Adafruit RGB-backlit LCD plate for Raspberry Pi.
# Written by Adafruit Industries.  MIT license.

# This is essentially a complete rewrite, but the calling syntax
# and constants are 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 Adafruit_I2C import Adafruit_I2C
from time import sleep


class Adafruit_CharLCDPlate(Adafruit_I2C):

    # ----------------------------------------------------------------------
    # Constants

    # Port expander registers
    MCP23017_IOCON_BANK0    = 0x0A  # IOCON when Bank 0 active
    MCP23017_IOCON_BANK1    = 0x15  # IOCON when Bank 1 active
    # These are register addresses when in Bank 1 only:
    MCP23017_GPIOA          = 0x09
    MCP23017_IODIRB         = 0x10
    MCP23017_GPIOB          = 0x19

    # Port expander input pin definitions
    SELECT                  = 0
    RIGHT                   = 1
    DOWN                    = 2
    UP                      = 3
    LEFT                    = 4

    # LED colors
    OFF                     = 0x00
    RED                     = 0x01
    GREEN                   = 0x02
    BLUE                    = 0x04
    YELLOW                  = RED + GREEN
    TEAL                    = GREEN + BLUE
    VIOLET                  = RED + BLUE
    WHITE                   = RED + GREEN + BLUE
    ON                      = RED + GREEN + BLUE

    # LCD 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 on/off control
    LCD_DISPLAYON           = 0x04
    LCD_DISPLAYOFF          = 0x00
    LCD_CURSORON            = 0x02
    LCD_CURSOROFF           = 0x00
    LCD_BLINKON             = 0x01
    LCD_BLINKOFF            = 0x00

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

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

    # Line addresses for up to 4 line displays.  Maps line number to DDRAM address for line.
    LINE_ADDRESSES = { 1: 0xC0, 2: 0x94, 3: 0xD4 }

    # Truncation constants for message function truncate parameter.
    NO_TRUNCATE       = 0
    TRUNCATE          = 1
    TRUNCATE_ELLIPSIS = 2

    # ----------------------------------------------------------------------
    # Constructor

    def __init__(self, busnum=-1, addr=0x20, debug=False, backlight=ON):

        self.i2c = Adafruit_I2C(addr, busnum, debug)

        # I2C is relatively slow.  MCP output port states are cached
        # so we don't need to constantly poll-and-change bit states.
        self.porta, self.portb, self.ddrb = 0, 0, 0b00000010

        # Set initial backlight color.
        c          = ~backlight
        self.porta = (self.porta & 0b00111111) | ((c & 0b011) << 6)
        self.portb = (self.portb & 0b11111110) | ((c & 0b100) >> 2)

        # Set MCP23017 IOCON register to Bank 0 with sequential operation.
        # If chip is already set for Bank 0, this will just write to OLATB,
        # which won't seriously bother anything on the plate right now
        # (blue backlight LED will come on, but that's done in the next
        # step anyway).
        self.i2c.bus.write_byte_data(
          self.i2c.address, self.MCP23017_IOCON_BANK1, 0)

        # Brute force reload ALL registers to known state.  This also
        # sets up all the input pins, pull-ups, etc. for the Pi Plate.
        self.i2c.bus.write_i2c_block_data(
          self.i2c.address, 0, 
          [ 0b00111111,   # IODIRA    R+G LEDs=outputs, buttons=inputs
            self.ddrb ,   # IODIRB    LCD D7=input, Blue LED=output
            0b00111111,   # IPOLA     Invert polarity on button inputs
            0b00000000,   # IPOLB
            0b00000000,   # GPINTENA  Disable interrupt-on-change
            0b00000000,   # GPINTENB
            0b00000000,   # DEFVALA
            0b00000000,   # DEFVALB
            0b00000000,   # INTCONA
            0b00000000,   # INTCONB
            0b00000000,   # IOCON
            0b00000000,   # IOCON
            0b00111111,   # GPPUA     Enable pull-ups on buttons
            0b00000000,   # GPPUB
            0b00000000,   # INTFA
            0b00000000,   # INTFB
            0b00000000,   # INTCAPA
            0b00000000,   # INTCAPB
            self.porta,   # GPIOA
            self.portb,   # GPIOB
            self.porta,   # OLATA
            self.portb ]) # OLATB

        # Switch to Bank 1 and disable sequential operation.
        # From this point forward, the register addresses do NOT match
        # the list immediately above.  Instead, use the constants defined
        # at the start of the class.  Also, the address register will no
        # longer increment automatically after this -- multi-byte
        # operations must be broken down into single-byte calls.
        self.i2c.bus.write_byte_data(
          self.i2c.address, self.MCP23017_IOCON_BANK0, 0b10100000)

        self.displayshift   = (self.LCD_CURSORMOVE |
                               self.LCD_MOVERIGHT)
        self.displaymode    = (self.LCD_ENTRYLEFT |
                               self.LCD_ENTRYSHIFTDECREMENT)
        self.displaycontrol = (self.LCD_DISPLAYON |
                               self.LCD_CURSOROFF |
                               self.LCD_BLINKOFF)

        self.write(0x33) # Init
        self.write(0x32) # Init
        self.write(0x28) # 2 line 5x8 matrix
        self.write(self.LCD_CLEARDISPLAY)
        self.write(self.LCD_CURSORSHIFT    | self.displayshift)
        self.write(self.LCD_ENTRYMODESET   | self.displaymode)
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)
        self.write(self.LCD_RETURNHOME)


    # ----------------------------------------------------------------------
    # Write operations

    # The LCD data pins (D4-D7) connect to MCP pins 12-9 (PORTB4-1), in
    # that order.  Because this sequence is 'reversed,' a direct shift
    # won't work.  This table remaps 4-bit data values to MCP PORTB
    # outputs, incorporating both the reverse and shift.
    flip = ( 0b00000000, 0b00010000, 0b00001000, 0b00011000,
             0b00000100, 0b00010100, 0b00001100, 0b00011100,
             0b00000010, 0b00010010, 0b00001010, 0b00011010,
             0b00000110, 0b00010110, 0b00001110, 0b00011110 )

    # Low-level 4-bit interface for LCD output.  This doesn't actually
    # write data, just returns a byte array of the PORTB state over time.
    # Can concatenate the output of multiple calls (up to 8) for more
    # efficient batch write.
    def out4(self, bitmask, value):
        hi = bitmask | self.flip[value >> 4]
        lo = bitmask | self.flip[value & 0x0F]
        return [hi | 0b00100000, hi, lo | 0b00100000, lo]


    # The speed of LCD accesses is inherently limited by I2C through the
    # port expander.  A 'well behaved program' is expected to poll the
    # LCD to know that a prior instruction completed.  But the timing of
    # most instructions is a known uniform 37 mS.  The enable strobe
    # can't even be twiddled that fast through I2C, so it's a safe bet
    # with these instructions to not waste time polling (which requires
    # several I2C transfers for reconfiguring the port direction).
    # The D7 pin is set as input when a potentially time-consuming
    # instruction has been issued (e.g. screen clear), as well as on
    # startup, and polling will then occur before more commands or data
    # are issued.

    pollables = ( LCD_CLEARDISPLAY, LCD_RETURNHOME )

    # Write byte, list or string value to LCD
    def write(self, value, char_mode=False):
        """ Send command/data to LCD """

        # If pin D7 is in input state, poll LCD busy flag until clear.
        if self.ddrb & 0b00000010:
            lo = (self.portb & 0b00000001) | 0b01000000
            hi = lo | 0b00100000 # E=1 (strobe)
            self.i2c.bus.write_byte_data(
              self.i2c.address, self.MCP23017_GPIOB, lo)
            while True:
                # Strobe high (enable)
                self.i2c.bus.write_byte(self.i2c.address, hi)
                # First nybble contains busy state
                bits = self.i2c.bus.read_byte(self.i2c.address)
                # Strobe low, high, low.  Second nybble (A3) is ignored.
                self.i2c.bus.write_i2c_block_data(
                  self.i2c.address, self.MCP23017_GPIOB, [lo, hi, lo])
                if (bits & 0b00000010) == 0: break # D7=0, not busy
            self.portb = lo

            # Polling complete, change D7 pin to output
            self.ddrb &= 0b11111101
            self.i2c.bus.write_byte_data(self.i2c.address,
              self.MCP23017_IODIRB, self.ddrb)

        bitmask = self.portb & 0b00000001   # Mask out PORTB LCD control bits
        if char_mode: bitmask |= 0b10000000 # Set data bit if not a command

        # If string or list, iterate through multiple write ops
        if isinstance(value, str):
            last = len(value) - 1 # Last character in string
            data = []             # Start with blank list
            for i, v in enumerate(value): # For each character...
                # Append 4 bytes to list representing PORTB over time.
                # First the high 4 data bits with strobe (enable) set
                # and unset, then same with low 4 data bits (strobe 1/0).
                data.extend(self.out4(bitmask, ord(v)))
                # I2C block data write is limited to 32 bytes max.
                # If limit reached, write data so far and clear.
                # Also do this on last byte if not otherwise handled.
                if (len(data) >= 32) or (i == last):
                    self.i2c.bus.write_i2c_block_data(
                      self.i2c.address, self.MCP23017_GPIOB, data)
                    self.portb = data[-1] # Save state of last byte out
                    data       = []       # Clear list for next iteration
        elif isinstance(value, list):
            # Same as above, but for list instead of string
            last = len(value) - 1
            data = []
            for i, v in enumerate(value):
                data.extend(self.out4(bitmask, v))
                if (len(data) >= 32) or (i == last):
                    self.i2c.bus.write_i2c_block_data(
                      self.i2c.address, self.MCP23017_GPIOB, data)
                    self.portb = data[-1]
                    data       = []
        else:
            # Single byte
            data = self.out4(bitmask, value)
            self.i2c.bus.write_i2c_block_data(
              self.i2c.address, self.MCP23017_GPIOB, data)
            self.portb = data[-1]

        # If a poll-worthy instruction was issued, reconfigure D7
        # pin as input to indicate need for polling on next call.
        if (not char_mode) and (value in self.pollables):
            self.ddrb |= 0b00000010
            self.i2c.bus.write_byte_data(self.i2c.address,
              self.MCP23017_IODIRB, self.ddrb)


    # ----------------------------------------------------------------------
    # Utility methods

    def begin(self, cols, lines):
        self.currline = 0
        self.numlines = lines
        self.numcols = cols
        self.clear()


    # Puts the MCP23017 back in Bank 0 + sequential write mode so
    # that other code using the 'classic' library can still work.
    # Any code using this newer version of the library should
    # consider adding an atexit() handler that calls this.
    def stop(self):
        self.porta = 0b11000000  # Turn off LEDs on the way out
        self.portb = 0b00000001
        sleep(0.0015)
        self.i2c.bus.write_byte_data(
          self.i2c.address, self.MCP23017_IOCON_BANK1, 0)
        self.i2c.bus.write_i2c_block_data(
          self.i2c.address, 0, 
          [ 0b00111111,   # IODIRA
            self.ddrb ,   # IODIRB
            0b00000000,   # IPOLA
            0b00000000,   # IPOLB
            0b00000000,   # GPINTENA
            0b00000000,   # GPINTENB
            0b00000000,   # DEFVALA
            0b00000000,   # DEFVALB
            0b00000000,   # INTCONA
            0b00000000,   # INTCONB
            0b00000000,   # IOCON
            0b00000000,   # IOCON
            0b00111111,   # GPPUA
            0b00000000,   # GPPUB
            0b00000000,   # INTFA
            0b00000000,   # INTFB
            0b00000000,   # INTCAPA
            0b00000000,   # INTCAPB
            self.porta,   # GPIOA
            self.portb,   # GPIOB
            self.porta,   # OLATA
            self.portb ]) # OLATB


    def clear(self):
        self.write(self.LCD_CLEARDISPLAY)


    def home(self):
        self.write(self.LCD_RETURNHOME)


    row_offsets = ( 0x00, 0x40, 0x14, 0x54 )
    def setCursor(self, col, row):
        if row > self.numlines: row = self.numlines - 1
        elif row < 0:           row = 0
        self.write(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))


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


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


    def cursor(self):
        """ Underline cursor on """
        self.displaycontrol |= self.LCD_CURSORON
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def noCursor(self):
        """ Underline cursor off """
        self.displaycontrol &= ~self.LCD_CURSORON
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def ToggleCursor(self):
        """ Toggles the underline cursor On/Off """
        self.displaycontrol ^= self.LCD_CURSORON
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def blink(self):
        """ Turn on the blinking cursor """
        self.displaycontrol |= self.LCD_BLINKON
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)


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


    def ToggleBlink(self):
        """ Toggles the blinking cursor """
        self.displaycontrol ^= self.LCD_BLINKON
        self.write(self.LCD_DISPLAYCONTROL | self.displaycontrol)


    def scrollDisplayLeft(self):
        """ These commands scroll the display without changing the RAM """
        self.displayshift = self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT
        self.write(self.LCD_CURSORSHIFT | self.displayshift)


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


    def leftToRight(self):
        """ This is for text that flows left to right """
        self.displaymode |= self.LCD_ENTRYLEFT
        self.write(self.LCD_ENTRYMODESET | self.displaymode)


    def rightToLeft(self):
        """ This is for text that flows right to left """
        self.displaymode &= ~self.LCD_ENTRYLEFT
        self.write(self.LCD_ENTRYMODESET | self.displaymode)


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


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


    def createChar(self, location, bitmap):
        self.write(self.LCD_SETCGRAMADDR | ((location & 7) << 3))
        self.write(bitmap, True)
        self.write(self.LCD_SETDDRAMADDR)


    def message(self, text, truncate=NO_TRUNCATE):
        """ Send string to LCD. Newline wraps to second line"""
        lines = str(text).split('\n')    # Split at newline(s)
        for i, line in enumerate(lines): # For each substring...
            address = self.LINE_ADDRESSES.get(i, None)
            if address is not None:      # If newline(s),
                self.write(address)      #  set DDRAM address to line
            # Handle appropriate truncation if requested.
            linelen = len(line)
            if truncate == self.TRUNCATE and linelen > self.numcols:
                # Hard truncation of line.
                self.write(line[0:self.numcols], True)
            elif truncate == self.TRUNCATE_ELLIPSIS and linelen > self.numcols:
                # Nicer truncation with ellipses.
                self.write(line[0:self.numcols-3] + '...', True)
            else:
                self.write(line, True)



    def backlight(self, color):
        c          = ~color
        self.porta = (self.porta & 0b00111111) | ((c & 0b011) << 6)
        self.portb = (self.portb & 0b11111110) | ((c & 0b100) >> 2)
        # Has to be done as two writes because sequential operation is off.
        self.i2c.bus.write_byte_data(
          self.i2c.address, self.MCP23017_GPIOA, self.porta)
        self.i2c.bus.write_byte_data(
          self.i2c.address, self.MCP23017_GPIOB, self.portb)


    # Read state of single button
    def buttonPressed(self, b):
        return (self.i2c.readU8(self.MCP23017_GPIOA) >> b) & 1


    # Read and return bitmask of combined button state
    def buttons(self):
        return self.i2c.readU8(self.MCP23017_GPIOA) & 0b11111


    # ----------------------------------------------------------------------
    # Test code

if __name__ == '__main__':

    lcd = Adafruit_CharLCDPlate()
    lcd.begin(16, 2)
    lcd.clear()
    lcd.message("Adafruit RGB LCD\nPlate w/Keypad!")
    sleep(1)

    col = (('Red' , lcd.RED) , ('Yellow', lcd.YELLOW), ('Green' , lcd.GREEN),
           ('Teal', lcd.TEAL), ('Blue'  , lcd.BLUE)  , ('Violet', lcd.VIOLET),
           ('Off' , lcd.OFF) , ('On'    , lcd.ON))

    print "Cycle thru backlight colors"
    for c in col:
       print c[0]
       lcd.clear()
       lcd.message(c[0])
       lcd.backlight(c[1])
       sleep(0.5)

    btn = ((lcd.SELECT, 'Select', lcd.ON),
           (lcd.LEFT  , 'Left'  , lcd.RED),
           (lcd.UP    , 'Up'    , lcd.BLUE),
           (lcd.DOWN  , 'Down'  , lcd.GREEN),
           (lcd.RIGHT , 'Right' , lcd.VIOLET))
    
    print "Try buttons on plate"
    lcd.clear()
    lcd.message("Try buttons")
    prev = -1
    while True:
        for b in btn:
            if lcd.buttonPressed(b[0]):
                if b is not prev:
                    print b[1]
                    lcd.clear()
                    lcd.message(b[1])
                    lcd.backlight(b[2])
                    prev = b
                break
Adafruit_I2C

Code: Select all

#!/usr/bin/python
import re
import smbus

# ===========================================================================
# Adafruit_I2C Class
# ===========================================================================

class Adafruit_I2C(object):

  @staticmethod
  def getPiRevision():
    "Gets the version number of the Raspberry Pi board"
    # Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
    try:
      with open('/proc/cpuinfo', 'r') as infile:
        for line in infile:
          # Match a line of the form "Revision : 0002" while ignoring extra
          # info in front of the revsion (like 1000 when the Pi was over-volted).
          match = re.match('Revision\s+:\s+.*(\w{4})$', line)
          if match and match.group(1) in ['0000', '0002', '0003']:
            # Return revision 1 if revision ends with 0000, 0002 or 0003.
            return 1
          elif match:
            # Assume revision 2 if revision ends with any other 4 chars.
            return 2
        # Couldn't find the revision, assume revision 0 like older code for compatibility.
        return 0
    except:
      return 0

  @staticmethod
  def getPiI2CBusNumber():
    # Gets the I2C bus number /dev/i2c#
    return 1 if Adafruit_I2C.getPiRevision() > 1 else 0

  def __init__(self, address, busnum=-1, debug=False):
    self.address = address
    # By default, the correct I2C bus is auto-detected using /proc/cpuinfo
    # Alternatively, you can hard-code the bus version below:
    # self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
    # self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
    self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
    self.debug = debug

  def reverseByteOrder(self, data):
    "Reverses the byte order of an int (16-bit) or long (32-bit) value"
    # Courtesy Vishal Sapre
    byteCount = len(hex(data)[2:].replace('L','')[::2])
    val       = 0
    for i in range(byteCount):
      val    = (val << 8) | (data & 0xff)
      data >>= 8
    return val

  def errMsg(self):
    print "Error accessing 0x%02X: Check your I2C address" % self.address
    return -1

  def write8(self, reg, value):
    "Writes an 8-bit value to the specified register/address"
    try:
      self.bus.write_byte_data(self.address, reg, value)
      if self.debug:
        print "I2C: Wrote 0x%02X to register 0x%02X" % (value, reg)
    except IOError, err:
      return self.errMsg()

  def write16(self, reg, value):
    "Writes a 16-bit value to the specified register/address pair"
    try:
      self.bus.write_word_data(self.address, reg, value)
      if self.debug:
        print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
         (value, reg, reg+1))
    except IOError, err:
      return self.errMsg()

  def writeRaw8(self, value):
    "Writes an 8-bit value on the bus"
    try:
      self.bus.write_byte(self.address, value)
      if self.debug:
        print "I2C: Wrote 0x%02X" % value
    except IOError, err:
      return self.errMsg()

  def writeList(self, reg, list):
    "Writes an array of bytes using I2C format"
    try:
      if self.debug:
        print "I2C: Writing list to register 0x%02X:" % reg
        print list
      self.bus.write_i2c_block_data(self.address, reg, list)
    except IOError, err:
      return self.errMsg()

  def readList(self, reg, length):
    "Read a list of bytes from the I2C device"
    try:
      results = self.bus.read_i2c_block_data(self.address, reg, length)
      if self.debug:
        print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
         (self.address, reg))
        print results
      return results
    except IOError, err:
      return self.errMsg()

  def readU8(self, reg):
    "Read an unsigned byte from the I2C device"
    try:
      result = self.bus.read_byte_data(self.address, reg)
      if self.debug:
        print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
         (self.address, result & 0xFF, reg))
      return result
    except IOError, err:
      return self.errMsg()

  def readS8(self, reg):
    "Reads a signed byte from the I2C device"
    try:
      result = self.bus.read_byte_data(self.address, reg)
      if result > 127: result -= 256
      if self.debug:
        print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
         (self.address, result & 0xFF, reg))
      return result
    except IOError, err:
      return self.errMsg()

  def readU16(self, reg, little_endian=True):
    "Reads an unsigned 16-bit value from the I2C device"
    try:
      result = self.bus.read_word_data(self.address,reg)
      # Swap bytes if using big endian because read_word_data assumes little 
      # endian on ARM (little endian) systems.
      if not little_endian:
        result = ((result << 8) & 0xFF00) + (result >> 8)
      if (self.debug):
        print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
      return result
    except IOError, err:
      return self.errMsg()

  def readS16(self, reg, little_endian=True):
    "Reads a signed 16-bit value from the I2C device"
    try:
      result = self.readU16(reg,little_endian)
      if result > 32767: result -= 65536
      return result
    except IOError, err:
      return self.errMsg()

if __name__ == '__main__':
  try:
    bus = Adafruit_I2C(address=0)
    print "Default I2C bus is accessible"
  except:
    print "Error accessing default I2C bus"
Please help mi because i want to do project with that! Thanks for reply. :ugeek:

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: LCD HD44780 menu

Tue Jan 19, 2016 11:26 am

google is full (i mean FULL) of code to drive HD44780 displays without the adapter.. please take a look there..

PS: also this forum is FULL of code to drive hd44780 displays

Agentkubus
Posts: 5
Joined: Wed Jan 13, 2016 12:51 am

Re: LCD HD44780 menu

Tue Jan 19, 2016 11:59 am

i know that, google is full of code to this display, but all code making MENU using adapter I2C or C++ ( i want wirte in python) . I spent a many hours searching all posible ways, there is no one, believe me :?

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: LCD HD44780 menu

Tue Jan 19, 2016 1:13 pm

Agentkubus wrote:i know that, google is full of code to this display, but all code making MENU using adapter I2C or C++ ( i want wirte in python) . I spent a many hours searching all posible ways, there is no one, believe me :?
so you want a code that does exactly what you want to do with your setup and your ideas?
have a nice coding. This is how it works.
or pay someone to code it for you

BMS Doug
Posts: 3824
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: LCD HD44780 menu

Tue Jan 19, 2016 1:39 pm

As Massi says, find code that works to drive your HD44780 display and then modify it and the Adafruit code so that you can do what you want.

The adafruit code is all nicely commented and sectioned so it should be relatively easy to modify.
Doug.
Building Management Systems Engineer.

User avatar
RST8
Posts: 64
Joined: Tue Nov 25, 2014 1:57 pm

Re: LCD HD44780 menu

Tue Jan 19, 2016 2:16 pm

Agentkubus wrote:hello, ( sory for my bad english.. ) im trying make a simple menu using lcd 16x2 HD44780 , 5 buttons and raspberry pi 2. I trying to do with code Adafruit_CharLCDPlate but there is using converter I2C, my display does not have I2c . How can i rewrite this code ?

Please help mi because i want to do project with that! Thanks for reply. :ugeek:
It sounds like you're trying to do something similar to :
viewtopic.php?t=23375
Or do you have a display that has buttons as part the display itself?

Joe

Agentkubus
Posts: 5
Joined: Wed Jan 13, 2016 12:51 am

Re: LCD HD44780 menu

Tue Jan 19, 2016 9:43 pm

Ok i did it 8-)

When you are not using I2c you have to change this code

Code: Select all

    # Read state of single button
    def buttonPressed(self, b):
        return (self.i2c.readU8(self.MCP23017_GPIOA) >> b) & 1
on this

Code: Select all

    def buttonPressed(self, b):
        self.GPIO.setmode(GPIO.BCM)
        self.GPIO.setup(b, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        test = GPIO.input(b)			
        return (test == False)
and it works. Nevermind, THANKS ... for help. Forum is for getting help , not to wrote " use google and forum " . Normal people have first thought " i will check google" . More chill guys :ugeek:

JimmyN
Posts: 1109
Joined: Wed Mar 18, 2015 7:05 pm
Location: Virginia, USA

Re: LCD HD44780 menu

Wed Jan 20, 2016 12:56 pm

Agentkubus wrote:hello, ( sory for my bad english.. ) im trying make a simple menu using lcd 16x2 HD44780 , 5 buttons and raspberry pi 2. I trying to do with code Adafruit_CharLCDPlate but there is using converter I2C, my display does not have I2c . How can i rewrite this code ?
Use the Adafruit library for the HD44780 without I2C. It's "Adafruit_CharLCD", rather than Adafruit_CharLCDPlate. Of course you'll have to set up the buttons separately. The library for the plate is provided so you don't need 7 pins for the LCD, plus additional pins for the buttons, you can do it all with I2C using only two pins.

But if you don't have an I2C backpack I'd go with the "CharLCD" library so you won't have to modify everything, and then write some script to handle your button inputs.

Return to “Python”