the_python_code
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
the_python_code [2016/12/21 15:43] – walkeradmin | the_python_code [2023/03/09 22:35] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 9: | Line 9: | ||
==== The Code Running the LCD ==== | ==== The Code Running the LCD ==== | ||
\\ | \\ | ||
- | By now you should have your Raspberry Pi and LCD running. | + | By now you should have your Raspberry Pi and LCD running. |
+ | \\ | ||
+ | \\ | ||
+ | ==== The Code === | ||
+ | \\ | ||
+ | On each Raspberry Pi there is a file called <color red> | ||
+ | \\ | ||
+ | \\ | ||
+ | <color red> | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== The File Header ==== | ||
+ | This is to identify to the Linux system what this file type is, and to allow the author to add some information (anything following a hash # is just a comment) | ||
+ | \\ | ||
+ | < | ||
+ | # | ||
+ | # | ||
+ | # 16x2 LCD Test Script | ||
+ | # | ||
+ | # Author : Alan Walker | ||
+ | # Date : 16/ | ||
+ | # | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== A reminder of the pin outs ==== | ||
+ | The following section is just comments, but it is a nice reminder of which GPIO pins on the Raspberry Pi that this Python code is going to try to address. | ||
+ | \\ | ||
+ | < | ||
+ | # The wiring for the LCD is as follows: | ||
+ | # 1 : GND | ||
+ | # 2 : 5V | ||
+ | # 3 : Contrast (0-5V)* | ||
+ | # 4 : RS (Register Select) | ||
+ | # 5 : R/W (Read Write) | ||
+ | # 6 : Enable 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 - GPIO pin 13 - Physical pin 33 | ||
+ | # 12: Data Bit 5 - GPIO pin 06 - Physical pin 31 | ||
+ | # 13: Data Bit 6 - GPIO pin 05 - Physical pin 29 | ||
+ | # 14: Data Bit 7 - GPIO pin 11 - Physical pin 23 | ||
+ | # 15: LCD Backlight | ||
+ | # 16: LCD Backlight | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Import Python Libraries ==== | ||
+ | Python uses standard libraries to provide standard functions, so you don't have to code everyday tasks such as printing etc. Here we are importing some standard libraries for our project. | ||
+ | \\ | ||
+ | < | ||
+ | #import | ||
+ | import RPi.GPIO as GPIO | ||
+ | import time | ||
+ | import socket | ||
+ | import fcntl | ||
+ | import struct | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Define some Constants ==== | ||
+ | Rather than referring to GPIO pin numbers in the code, we are declaring some variables that we can use to reference the GPIO pin numbers to actual functions. (So the LCD Reset that uses GPIO pin 26 can be called by using just LCD_RS for example). | ||
+ | \\ | ||
+ | \\ | ||
+ | The advantage of using this method is, if a pin number changes, we can change it here, and not have to hunt through the code for every occurrence of that pin number. | ||
+ | \\ | ||
+ | < | ||
+ | # Define GPIO to LCD mapping | ||
+ | LCD_RS = 26 | ||
+ | LCD_E = 19 | ||
+ | LCD_D4 = 13 | ||
+ | LCD_D5 = 6 | ||
+ | LCD_D6 = 5 | ||
+ | LCD_D7 = 11 | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Import Python Libraries ==== | ||
+ | Below we are defining some more constants, these are to do with the LCD lines and chars, as well as the timing. | ||
+ | \\ | ||
+ | < | ||
+ | # Define some device constants | ||
+ | LCD_WIDTH = 40 # Maximum characters per line | ||
+ | LCD_CHR = True | ||
+ | LCD_CMD = False | ||
+ | |||
+ | # Address for 40 char display | ||
+ | LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line | ||
+ | LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line | ||
+ | |||
+ | # Timing constants | ||
+ | E_PULSE = 0.0005 | ||
+ | E_DELAY = 0.0005 | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Code Start ==== | ||
+ | This is where the main code starts, as this program runs in a loop, anything above the line <color red>def main():</ | ||
+ | \\ | ||
+ | \\ | ||
+ | <color red> | ||
+ | \\ | ||
+ | < | ||
+ | def main(): | ||
+ | # Main program block | ||
+ | |||
+ | GPIO.setwarnings(False) | ||
+ | GPIO.setmode(GPIO.BCM) | ||
+ | GPIO.setup(LCD_E, | ||
+ | GPIO.setup(LCD_RS, | ||
+ | GPIO.setup(LCD_D4, | ||
+ | GPIO.setup(LCD_D5, | ||
+ | GPIO.setup(LCD_D6, | ||
+ | GPIO.setup(LCD_D7, | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Program Start ==== | ||
+ | This is the main body of the code that runs the LCD, to save splitting this up I will comment in this section. | ||
+ | \\ | ||
+ | < | ||
+ | ########################################## | ||
+ | # | ||
+ | ########################################## | ||
+ | |||
+ | |||
+ | # Initialise display | ||
+ | lcd_init() | ||
+ | |||
+ | # If using DHCP this is required, or code runs before network is ready. | ||
+ | lcd_string(" | ||
+ | time.sleep(5) | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Read File ==== | ||
+ | Here we are opening the file <color red>'/ | ||
+ | \\ | ||
+ | < | ||
+ | while True: | ||
+ | ## Open the file with read only permit | ||
+ | f = open('/ | ||
+ | |||
+ | ## use readlines to read all the lines in the file | ||
+ | ## The variable " | ||
+ | # readline 400 is read in 400 chars | ||
+ | # replace removed the carriage return and new line | ||
+ | # [:40] truncates to 40 chars | ||
+ | |||
+ | line1 = f.readline(400).replace(" | ||
+ | line2 = f.readline(400).replace(" | ||
+ | line3 = f.readline(400).replace(" | ||
+ | line4 = f.readline(400).replace(" | ||
+ | line5 = f.readline(400).replace(" | ||
+ | line6 = f.readline(400).replace(" | ||
+ | line7 = f.readline(400).replace(" | ||
+ | line8 = f.readline(400).replace(" | ||
+ | |||
+ | ## close the file after reading the lines. | ||
+ | f.close() | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== Set which line to write to the LCD ==== | ||
+ | The code below sets what lines from the 8 lines are used (so Master Pi displays lines 1&2, the fourth Pi displays Lines 7&8. | ||
+ | \\ | ||
+ | \\ | ||
+ | line< | ||
+ | \\ | ||
+ | \\ | ||
+ | This above example tells the Pi to use Line <color red> | ||
+ | \\ | ||
+ | < | ||
+ | # write line 1 and 2 to the LCD (Line7 and Line8 because this is UMD4) | ||
+ | lcd_string(" | ||
+ | lcd_string(" | ||
+ | |||
+ | time.sleep(1) # x second delay | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | ==== LCD Write Code ==== | ||
+ | The code below takes our text and writes it to the LCD, do not make any changes to this section. | ||
+ | \\ | ||
+ | < | ||
+ | ########################################## | ||
+ | # | ||
+ | ########################################## | ||
+ | |||
+ | |||
+ | def get_ip_address(ifname): | ||
+ | s = socket.socket(socket.AF_INET, | ||
+ | return socket.inet_ntoa(fcntl.ioctl( | ||
+ | s.fileno(), | ||
+ | 0x8915, | ||
+ | struct.pack(' | ||
+ | )[20:24]) | ||
+ | |||
+ | |||
+ | def lcd_init(): | ||
+ | # Initialise display | ||
+ | lcd_byte(0x33, | ||
+ | lcd_byte(0x32, | ||
+ | lcd_byte(0x06, | ||
+ | lcd_byte(0x0C, | ||
+ | lcd_byte(0x28, | ||
+ | lcd_byte(0x01, | ||
+ | time.sleep(E_DELAY) | ||
+ | |||
+ | def lcd_byte(bits, | ||
+ | # Send byte to data pins | ||
+ | # bits = data | ||
+ | # mode = True for character | ||
+ | # False for command | ||
+ | |||
+ | GPIO.output(LCD_RS, | ||
+ | |||
+ | # High bits | ||
+ | GPIO.output(LCD_D4, | ||
+ | GPIO.output(LCD_D5, | ||
+ | GPIO.output(LCD_D6, | ||
+ | GPIO.output(LCD_D7, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D4, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D5, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D6, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D7, | ||
+ | |||
+ | # Toggle ' | ||
+ | lcd_toggle_enable() | ||
+ | |||
+ | # Low bits | ||
+ | GPIO.output(LCD_D4, | ||
+ | GPIO.output(LCD_D5, | ||
+ | GPIO.output(LCD_D6, | ||
+ | GPIO.output(LCD_D7, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D4, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D5, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D6, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D7, | ||
+ | |||
+ | # Toggle ' | ||
+ | lcd_toggle_enable() | ||
+ | |||
+ | def lcd_toggle_enable(): | ||
+ | # Toggle enable | ||
+ | time.sleep(E_DELAY) | ||
+ | GPIO.output(LCD_E, | ||
+ | time.sleep(E_PULSE) | ||
+ | GPIO.output(LCD_E, | ||
+ | time.sleep(E_DELAY) | ||
+ | |||
+ | def lcd_string(message, | ||
+ | # Send string to display | ||
+ | |||
+ | message = message.ljust(LCD_WIDTH," | ||
+ | |||
+ | lcd_byte(line, | ||
+ | |||
+ | for i in range(LCD_WIDTH): | ||
+ | lcd_byte(ord(message[i]), | ||
+ | |||
+ | if __name__ == ' | ||
+ | |||
+ | try: | ||
+ | main() | ||
+ | except KeyboardInterrupt: | ||
+ | pass | ||
+ | finally: | ||
+ | # | ||
+ | # | ||
+ | GPIO.cleanup() | ||
+ | </ | ||
+ | \\ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | \\ | ||
+ | \\ | ||
+ | ===== Complete Code Set ===== | ||
+ | \\ | ||
+ | Below is the complete file without any breaks, you can cut and paste this to create your own UMD LCD. | ||
+ | \\ | ||
+ | \\ | ||
+ | < | ||
+ | # | ||
+ | # | ||
+ | # 16x2 LCD Test Script | ||
+ | # | ||
+ | # Author : Alan Walker | ||
+ | # Date : 16/ | ||
+ | # | ||
+ | |||
+ | # The wiring for the LCD is as follows: | ||
+ | # 1 : GND | ||
+ | # 2 : 5V | ||
+ | # 3 : Contrast (0-5V)* | ||
+ | # 4 : RS (Register Select) | ||
+ | # 5 : R/W (Read Write) | ||
+ | # 6 : Enable 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 - GPIO pin 13 - Physical pin 33 | ||
+ | # 12: Data Bit 5 - GPIO pin 06 - Physical pin 31 | ||
+ | # 13: Data Bit 6 - GPIO pin 05 - Physical pin 29 | ||
+ | # 14: Data Bit 7 - GPIO pin 11 - Physical pin 23 | ||
+ | # 15: LCD Backlight | ||
+ | # 16: LCD Backlight | ||
+ | |||
+ | #import | ||
+ | import RPi.GPIO as GPIO | ||
+ | import time | ||
+ | import socket | ||
+ | import fcntl | ||
+ | import struct | ||
+ | |||
+ | # Define GPIO to LCD mapping | ||
+ | LCD_RS = 26 | ||
+ | LCD_E = 19 | ||
+ | LCD_D4 = 13 | ||
+ | LCD_D5 = 6 | ||
+ | LCD_D6 = 5 | ||
+ | LCD_D7 = 11 | ||
+ | |||
+ | |||
+ | # Define some device constants | ||
+ | LCD_WIDTH = 40 # Maximum characters per line | ||
+ | LCD_CHR = True | ||
+ | LCD_CMD = False | ||
+ | |||
+ | # Do I need to change line 2 address for 40 char display? | ||
+ | LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line | ||
+ | LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line | ||
+ | |||
+ | # Timing constants | ||
+ | E_PULSE = 0.0005 | ||
+ | E_DELAY = 0.0005 | ||
+ | |||
+ | def main(): | ||
+ | # Main program block | ||
+ | |||
+ | GPIO.setwarnings(False) | ||
+ | GPIO.setmode(GPIO.BCM) | ||
+ | GPIO.setup(LCD_E, | ||
+ | GPIO.setup(LCD_RS, | ||
+ | GPIO.setup(LCD_D4, | ||
+ | GPIO.setup(LCD_D5, | ||
+ | GPIO.setup(LCD_D6, | ||
+ | GPIO.setup(LCD_D7, | ||
+ | |||
+ | ########################################## | ||
+ | # | ||
+ | ########################################## | ||
+ | |||
+ | |||
+ | # Initialise display | ||
+ | lcd_init() | ||
+ | |||
+ | lcd_string(" | ||
+ | time.sleep(5) | ||
+ | |||
+ | |||
+ | while True: | ||
+ | ## Open the file with read only permit | ||
+ | f = open('/ | ||
+ | |||
+ | ## use readlines to read all the lines in the file | ||
+ | ## The variable " | ||
+ | # readline 400 is read in 400 chars | ||
+ | # replace removed the carriage return and new line | ||
+ | # [:40] truncates to 40 chars | ||
+ | |||
+ | line1 = f.readline(400).replace(" | ||
+ | line2 = f.readline(400).replace(" | ||
+ | line3 = f.readline(400).replace(" | ||
+ | line4 = f.readline(400).replace(" | ||
+ | line5 = f.readline(400).replace(" | ||
+ | line6 = f.readline(400).replace(" | ||
+ | line7 = f.readline(400).replace(" | ||
+ | line8 = f.readline(400).replace(" | ||
+ | |||
+ | ## close the file after reading the lines. | ||
+ | f.close() | ||
+ | |||
+ | # write line 1 and 2 to the LCD (Line7 and Line8 because this is UMD4) | ||
+ | lcd_string(" | ||
+ | lcd_string(" | ||
+ | |||
+ | time.sleep(1) # x second delay | ||
+ | |||
+ | |||
+ | ########################################## | ||
+ | # | ||
+ | ########################################## | ||
+ | |||
+ | |||
+ | def get_ip_address(ifname): | ||
+ | s = socket.socket(socket.AF_INET, | ||
+ | return socket.inet_ntoa(fcntl.ioctl( | ||
+ | s.fileno(), | ||
+ | 0x8915, | ||
+ | struct.pack(' | ||
+ | )[20:24]) | ||
+ | |||
+ | |||
+ | def lcd_init(): | ||
+ | # Initialise display | ||
+ | lcd_byte(0x33, | ||
+ | lcd_byte(0x32, | ||
+ | lcd_byte(0x06, | ||
+ | lcd_byte(0x0C, | ||
+ | lcd_byte(0x28, | ||
+ | lcd_byte(0x01, | ||
+ | time.sleep(E_DELAY) | ||
+ | |||
+ | def lcd_byte(bits, | ||
+ | # Send byte to data pins | ||
+ | # bits = data | ||
+ | # mode = True for character | ||
+ | # False for command | ||
+ | |||
+ | GPIO.output(LCD_RS, | ||
+ | |||
+ | # High bits | ||
+ | GPIO.output(LCD_D4, | ||
+ | GPIO.output(LCD_D5, | ||
+ | GPIO.output(LCD_D6, | ||
+ | GPIO.output(LCD_D7, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D4, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D5, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D6, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D7, | ||
+ | |||
+ | # Toggle ' | ||
+ | lcd_toggle_enable() | ||
+ | |||
+ | # Low bits | ||
+ | GPIO.output(LCD_D4, | ||
+ | GPIO.output(LCD_D5, | ||
+ | GPIO.output(LCD_D6, | ||
+ | GPIO.output(LCD_D7, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D4, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D5, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D6, | ||
+ | if bits& | ||
+ | GPIO.output(LCD_D7, | ||
+ | |||
+ | # Toggle ' | ||
+ | lcd_toggle_enable() | ||
+ | |||
+ | def lcd_toggle_enable(): | ||
+ | # Toggle enable | ||
+ | time.sleep(E_DELAY) | ||
+ | GPIO.output(LCD_E, | ||
+ | time.sleep(E_PULSE) | ||
+ | GPIO.output(LCD_E, | ||
+ | time.sleep(E_DELAY) | ||
+ | |||
+ | def lcd_string(message, | ||
+ | # Send string to display | ||
+ | |||
+ | message = message.ljust(LCD_WIDTH," | ||
+ | |||
+ | lcd_byte(line, | ||
+ | |||
+ | for i in range(LCD_WIDTH): | ||
+ | lcd_byte(ord(message[i]), | ||
+ | |||
+ | if __name__ == ' | ||
+ | |||
+ | try: | ||
+ | main() | ||
+ | except KeyboardInterrupt: | ||
+ | pass | ||
+ | finally: | ||
+ | # | ||
+ | # | ||
+ | GPIO.cleanup() | ||
+ | </ |
the_python_code.txt · Last modified: 2023/03/09 22:35 by 127.0.0.1