lcd.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # -*- coding: utf-8 -*-
  2. # Original code found at:
  3. # https://gist.github.com/DenisFromHR/cc863375a6e19dce359d
  4. """
  5. Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic
  6. Made available under GNU GENERAL PUBLIC LICENSE
  7. # Modified Python I2C library for Raspberry Pi
  8. # as found on http://www.recantha.co.uk/blog/?p=4849
  9. # Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library
  10. # added bits and pieces from various sources
  11. # By DenisFromHR (Denis Pleic)
  12. # 2015-02-10, ver 0.1
  13. """
  14. # i2c bus (0 -- original Pi, 1 -- Rev 2 Pi)
  15. I2CBUS = 0
  16. # LCD Address
  17. ADDRESS = 0x3f
  18. import smbus
  19. from time import sleep
  20. class i2c_device:
  21. def __init__(self, addr, port=I2CBUS):
  22. self.addr = addr
  23. self.bus = smbus.SMBus(port)
  24. # Write a single command
  25. def write_cmd(self, cmd):
  26. self.bus.write_byte(self.addr, cmd)
  27. sleep(0.0001)
  28. # Write a command and argument
  29. def write_cmd_arg(self, cmd, data):
  30. self.bus.write_byte_data(self.addr, cmd, data)
  31. sleep(0.0001)
  32. # Write a block of data
  33. def write_block_data(self, cmd, data):
  34. self.bus.write_block_data(self.addr, cmd, data)
  35. sleep(0.0001)
  36. # Read a single byte
  37. def read(self):
  38. return self.bus.read_byte(self.addr)
  39. # Read
  40. def read_data(self, cmd):
  41. return self.bus.read_byte_data(self.addr, cmd)
  42. # Read a block of data
  43. def read_block_data(self, cmd):
  44. return self.bus.read_block_data(self.addr, cmd)
  45. # commands
  46. LCD_CLEARDISPLAY = 0x01
  47. LCD_RETURNHOME = 0x02
  48. LCD_ENTRYMODESET = 0x04
  49. LCD_DISPLAYCONTROL = 0x08
  50. LCD_CURSORSHIFT = 0x10
  51. LCD_FUNCTIONSET = 0x20
  52. LCD_SETCGRAMADDR = 0x40
  53. LCD_SETDDRAMADDR = 0x80
  54. # flags for display entry mode
  55. LCD_ENTRYRIGHT = 0x00
  56. LCD_ENTRYLEFT = 0x02
  57. LCD_ENTRYSHIFTINCREMENT = 0x01
  58. LCD_ENTRYSHIFTDECREMENT = 0x00
  59. # flags for display on/off control
  60. LCD_DISPLAYON = 0x04
  61. LCD_DISPLAYOFF = 0x00
  62. LCD_CURSORON = 0x02
  63. LCD_CURSOROFF = 0x00
  64. LCD_BLINKON = 0x01
  65. LCD_BLINKOFF = 0x00
  66. # flags for display/cursor shift
  67. LCD_DISPLAYMOVE = 0x08
  68. LCD_CURSORMOVE = 0x00
  69. LCD_MOVERIGHT = 0x04
  70. LCD_MOVELEFT = 0x00
  71. # flags for function set
  72. LCD_8BITMODE = 0x10
  73. LCD_4BITMODE = 0x00
  74. LCD_2LINE = 0x08
  75. LCD_1LINE = 0x00
  76. LCD_5x10DOTS = 0x04
  77. LCD_5x8DOTS = 0x00
  78. # flags for backlight control
  79. LCD_BACKLIGHT = 0x08
  80. LCD_NOBACKLIGHT = 0x00
  81. En = 0b00000100 # Enable bit
  82. Rw = 0b00000010 # Read/Write bit
  83. Rs = 0b00000001 # Register select bit
  84. class lcd:
  85. #initializes objects and lcd
  86. def __init__(self):
  87. self.lcd_device = i2c_device(ADDRESS)
  88. self.lcd_write(0x03)
  89. self.lcd_write(0x03)
  90. self.lcd_write(0x03)
  91. self.lcd_write(0x02)
  92. self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
  93. self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
  94. self.lcd_write(LCD_CLEARDISPLAY)
  95. self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
  96. sleep(0.2)
  97. # clocks EN to latch command
  98. def lcd_strobe(self, data):
  99. self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
  100. sleep(.0005)
  101. self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
  102. sleep(.0001)
  103. def lcd_write_four_bits(self, data):
  104. self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
  105. self.lcd_strobe(data)
  106. # write a command to lcd
  107. def lcd_write(self, cmd, mode=0):
  108. self.lcd_write_four_bits(mode | (cmd & 0xF0))
  109. self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))
  110. # write a character to lcd (or character rom) 0x09: backlight | RS=DR<
  111. # works!
  112. def lcd_write_char(self, charvalue, mode=1):
  113. self.lcd_write_four_bits(mode | (charvalue & 0xF0))
  114. self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0))
  115. # put string function with optional char positioning
  116. def lcd_display_string(self, string, line=1, pos=0):
  117. if line == 1:
  118. pos_new = pos
  119. elif line == 2:
  120. pos_new = 0x40 + pos
  121. elif line == 3:
  122. pos_new = 0x14 + pos
  123. elif line == 4:
  124. pos_new = 0x54 + pos
  125. self.lcd_write(0x80 + pos_new)
  126. for char in string:
  127. self.lcd_write(ord(char), Rs)
  128. # clear lcd and set to home
  129. def lcd_clear(self):
  130. self.lcd_write(LCD_CLEARDISPLAY)
  131. self.lcd_write(LCD_RETURNHOME)
  132. # define backlight on/off (lcd.backlight(1); off= lcd.backlight(0)
  133. def backlight(self, state): # for state, 1 = on, 0 = off
  134. if state == 1:
  135. self.lcd_device.write_cmd(LCD_BACKLIGHT)
  136. elif state == 0:
  137. self.lcd_device.write_cmd(LCD_NOBACKLIGHT)
  138. # add custom characters (0 - 7)
  139. def lcd_load_custom_chars(self, fontdata):
  140. self.lcd_write(0x40);
  141. for char in fontdata:
  142. for line in char:
  143. self.lcd_write_char(line)
  144. l = lcd()
  145. l.lcd_display_string("hello world")