Przykład użycia biblioteki RPi_I2C_driver.py w celu uzyskania różnych efektów na wyświetlaczu hd44780 w tym znaków specjalnych użytkownika.
Wymagania:
- nowa wersja biblioteki RPi_I2C_driver.py w jednym katalogu ze skryptem przykładowym
- ekran hd44780 podłączony wg. instrukcji https://malinowo.secu.com.pl/raspberry-pi-ekran-lcd-4×20-hd44780-konwerter-i2c/
RPi_I2C_driver.py
Nowa wersja biblioteki do obsługi wyświetlacza HD44780 podłączonego przez interfejs I2C posiada umieszczone wszystkie klasy i funkcje w jednym pliku.
Autor dodał w niej możliwość wyświetlania znaków w dowolnym miejscu oraz możliwość dopisania 8 własnych znaków graficznych do pamięci wyświetlacza.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# -*- coding: utf-8 -*- """ Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic Made available under GNU GENERAL PUBLIC LICENSE # Modified Python I2C library for Raspberry Pi # as found on http://www.recantha.co.uk/blog/?p=4849 # Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library # added bits and pieces from various sources # By DenisFromHR (Denis Pleic) # 2015-02-10, ver 0.1 """ # # import smbus from time import * class i2c_device: def __init__(self, addr, port=1): self.addr = addr self.bus = smbus.SMBus(port) # Write a single command def write_cmd(self, cmd): self.bus.write_byte(self.addr, cmd) sleep(0.0001) # Write a command and argument def write_cmd_arg(self, cmd, data): self.bus.write_byte_data(self.addr, cmd, data) sleep(0.0001) # Write a block of data def write_block_data(self, cmd, data): self.bus.write_block_data(self.addr, cmd, data) sleep(0.0001) # Read a single byte def read(self): return self.bus.read_byte(self.addr) # Read def read_data(self, cmd): return self.bus.read_byte_data(self.addr, cmd) # Read a block of data def read_block_data(self, cmd): return self.bus.read_block_data(self.addr, cmd) # LCD Address ADDRESS = 0x27 # 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 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 # flags for backlight control LCD_BACKLIGHT = 0x08 LCD_NOBACKLIGHT = 0x00 En = 0b00000100 # Enable bit Rw = 0b00000010 # Read/Write bit Rs = 0b00000001 # Register select bit class lcd: #initializes objects and lcd def __init__(self): self.lcd_device = i2c_device(ADDRESS) self.lcd_write(0x03) self.lcd_write(0x03) self.lcd_write(0x03) self.lcd_write(0x02) self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE) self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON) self.lcd_write(LCD_CLEARDISPLAY) self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT) sleep(0.2) # clocks EN to latch command def lcd_strobe(self, data): self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT) sleep(.0005) self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT)) sleep(.0001) def lcd_write_four_bits(self, data): self.lcd_device.write_cmd(data | LCD_BACKLIGHT) self.lcd_strobe(data) # write a command to lcd def lcd_write(self, cmd, mode=0): self.lcd_write_four_bits(mode | (cmd & 0xF0)) self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0)) # write a character to lcd (or character rom) 0x09: backlight | RS=DR< # works! def lcd_write_char(self, charvalue, mode=1): self.lcd_write_four_bits(mode | (charvalue & 0xF0)) self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0)) # put string function def lcd_display_string(self, string, line): if line == 1: self.lcd_write(0x80) if line == 2: self.lcd_write(0xC0) if line == 3: self.lcd_write(0x94) if line == 4: self.lcd_write(0xD4) for char in string: self.lcd_write(ord(char), Rs) # clear lcd and set to home def lcd_clear(self): self.lcd_write(LCD_CLEARDISPLAY) self.lcd_write(LCD_RETURNHOME) # define backlight on/off (lcd.backlight(1); off= lcd.backlight(0) def backlight(self, state): # for state, 1 = on, 0 = off if state == 1: self.lcd_device.write_cmd(LCD_BACKLIGHT) elif state == 0: self.lcd_device.write_cmd(LCD_NOBACKLIGHT) # add custom characters (0 - 7) def lcd_load_custom_chars(self, fontdata): self.lcd_write(0x40); for char in fontdata: for line in char: self.lcd_write_char(line) # define precise positioning (addition from the forum) def lcd_display_string_pos(self, string, line, pos): if line == 1: pos_new = pos elif line == 2: pos_new = 0x40 + pos elif line == 3: pos_new = 0x14 + pos elif line == 4: pos_new = 0x54 + pos self.lcd_write(0x80 + pos_new) for char in string: self.lcd_write(ord(char), Rs) |
RPi_I2C_driver_example.py
przykład użycia biblioteki RPi_I2C_driver.py :
- wyświetlenie znaków graficznych
- pasek postępu
- poziomy scrool
- equalizer
- losowe znaki
- ramka interfejsu użytkownika
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
#!/usr/bin/python # requires RPi_I2C_driver.py import RPi_I2C_driver from time import * import random """RPi_I2C_driver_example.py: example usage RPi_I2C_driver.py """ __author__ = "zbiros" __copyright__ = "Copyright 2015, Malinowo.net.pl" __credits__ = ["Denis Pleic"] __license__ = "GPL" __version__ = "1.0.1" __maintainer__ = "zbiros" __email__ = "zbiros@malinowo.secu.com.pl" __status__ = "Development" lcd = RPi_I2C_driver.lcd() # ============== example 1 =============================== custom_char = [ # network signal [ 0x01, 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15 ], # right arrow [ 0x00, 0x00, 0x04, 0x02, 0x1F, 0x02, 0x04, 0x00 ], # left arrow [ 0x00, 0x00, 0x04, 0x08, 0x1F, 0x08, 0x04, 0x00 ], # enter [ 0x01, 0x01, 0x05, 0x09, 0x1F, 0x08, 0x04, 0x00 ], # clock [ 0x00, 0x0E, 0x15, 0x15, 0x13, 0x11, 0x0E, 0x00 ], # face [ 0x0E, 0x1F, 0x15, 0x1F, 0x1F, 0x11, 0x0E, 0x00 ], # arrow down [ 0x04, 0x04, 0x04, 0x04, 0x15, 0x0E, 0x04, 0x00 ], # arrow up [ 0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00 ], ] lcd.lcd_clear() lcd.lcd_display_string_pos("Example1:custom characters",1,0) # row 1, column 1 lcd.lcd_load_custom_chars(custom_char) # 0x80 row 1 # 0xC0 row 2 # 0x94 row 3 # 0xD4 row 4 # write chars to row 3 lcd.lcd_write(0x94) lcd.lcd_write_char(0) lcd.lcd_write_char(1) lcd.lcd_write_char(2) lcd.lcd_write_char(3) lcd.lcd_write_char(4) lcd.lcd_write_char(5) lcd.lcd_write_char(6) lcd.lcd_write_char(7) sleep(5) # ============== example 2 =============================== lcd.lcd_clear() lcd.lcd_display_string_pos("Examp.2:progress bar",1,0) # row 1, column 1 block = chr(255) # block character, built-in for x in range (0,10): lcd.lcd_display_string_pos(block,3,x) lcd.lcd_display_string_pos(`x*10` + "%",3,12) sleep(0.5) sleep(3) # ============== example 3 =============================== lcd.lcd_clear() lcd.lcd_display_string_pos("Exam.3:horiz.scrool",1,0) # row 1, column 1 custom_char = [ # heart [ 0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00 ], ] lcd.lcd_load_custom_chars(custom_char) lcd.lcd_display_string_pos(unichr(0),3,3) # display heart in row 3 column 3 lcd.lcd_display_string_pos(unichr(0),3,16) scrool_txt = "Hello.This is example long scroll text." scrool_txt = scrool_txt + " " lcd.lcd_display_string_pos(scrool_txt[:12], 3,4) # initially show just the first part for i in range (0,len(scrool_txt)): lcd_text = scrool_txt[i:(i+12)] lcd.lcd_display_string_pos(lcd_text,3,4) sleep(0.2) # ============== example 4 =============================== lcd.lcd_clear() lcd.lcd_display_string_pos("Example 4:equalizer",1,0) # row 1, column 1 custom_char = [ # 10 % bar [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F ], # 30 % bar [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F ], # 70 % bar [ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F ], # 90 % bar [ 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F ], ] lcd.lcd_load_custom_chars(custom_char) for x in range (0,64): for y in range (3,17): rand = random.randint(0,3) lcd.lcd_display_string_pos(unichr(rand),3,y) # display heart in row 3 column 3 sleep(0.1) # ============== example 5 =============================== lcd.lcd_clear() lcd.lcd_display_string_pos("Example5:random char",1,0) # row 1, column 1 blocks = ['`','~','!','@','$','%','^','&','*','(',')','_','-','+','=','{','}','[',']','|',';'] for x in range (0,192): rand_row = random.randint(2,4) rand_col = random.randint(0,19) lcd.lcd_display_string_pos(random.choice(blocks),rand_row,rand_col) sleep(0.1) # ============== example 6 =============================== lcd.lcd_clear() lcd.lcd_display_string_pos("Example 6:interface",1,0) # row 1, column 1 custom_char = [ # left up corner [0x00, 0x0F, 0x08, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A], # right up corner [0x00, 0x1E, 0x02, 0x1A, 0x0A, 0x0A, 0x0A, 0x0A], # vertical bars [0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A], # left down corner [0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x08, 0x0F, 0x00], # right down corner [0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x02, 0x1E, 0x00], # top bars [0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00], # down bars [0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00], ] lcd.lcd_load_custom_chars(custom_char) lcd.lcd_display_string_pos(unichr(0),2,6) lcd.lcd_display_string_pos(unichr(5),2,7) lcd.lcd_display_string_pos(unichr(5),2,8) lcd.lcd_display_string_pos(unichr(5),2,9) lcd.lcd_display_string_pos(unichr(5),2,10) lcd.lcd_display_string_pos(unichr(5),2,11) lcd.lcd_display_string_pos(unichr(1),2,12) lcd.lcd_display_string_pos(unichr(2),3,6) lcd.lcd_display_string_pos(unichr(2),3,12) lcd.lcd_display_string_pos(unichr(3),4,6) lcd.lcd_display_string_pos(unichr(6),4,7) lcd.lcd_display_string_pos(unichr(6),4,8) lcd.lcd_display_string_pos(unichr(6),4,9) lcd.lcd_display_string_pos(unichr(6),4,10) lcd.lcd_display_string_pos(unichr(6),4,11) lcd.lcd_display_string_pos(unichr(4),4,12) for x in range(0,5): lcd.lcd_display_string_pos("Hello",3,7) sleep(0.5) lcd.lcd_display_string_pos(" ",3,7) sleep(0.5) |
Strony przydatne do generowania znaków:
http://www.quinapalus.com/hd44780udg.html
http://omerk.github.io/lcdchargen/
Inspiracje do tworzenie własnych znaków:
Program do generowania znaków:
http://eshortcircuit.blogspot.com/2012/04/hd44780-custom-character-generator.html