import time
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Define GPIO to LCD mapping
LCD_RS = 4
LCD_E = 17
LCD_D4 = 18
LCD_D5 = 27
LCD_D6 = 22
LCD_D7 = 23
R1 = 5
R2 = 6
R3 = 12
R4 = 13
C1 = 16
C2 = 19
C3 = 20
C4 = 26
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
GPIO.setup(LCD_E, GPIO.OUT) # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7
GPIO.setup(R1, GPIO.OUT)
GPIO.setup(R2, GPIO.OUT)
GPIO.setup(R3, GPIO.OUT)
GPIO.setup(R4, GPIO.OUT)
GPIO.setup(C1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(C2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(C3, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(C4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Define some device constants
LCD_WIDTH = 16 # Maximum characters per line
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD) # 110011 Initialise
lcd_byte(0x32,LCD_CMD) # 110010 Initialise
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
def lcd_byte(bits, mode):
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10;==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20;==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40;==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80;==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01;==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02;==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04;==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08;==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
def lcd_toggle_enable():
# Toggle enable
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
def lcd_string(message,line):
# Send string to display
message = message.ljust(LCD_WIDTH," ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
def readRow(line, characters):
GPIO.output(line, GPIO.HIGH)
time.sleep(0.02)
if(GPIO.input(C1) == 1):
if line == R4:
lcd_string('',LCD_LINE_2)
time.sleep(0.01)
else:
lcd_string(characters[0],LCD_LINE_2)
if(GPIO.input(C2) == 1):
lcd_string(characters[1],LCD_LINE_2)
time.sleep(0.01)
if(GPIO.input(C3) == 1):
lcd_string(characters[2],LCD_LINE_2)
time.sleep(0.01)
if(GPIO.input(C4) == 1):
lcd_string(characters[3],LCD_LINE_2)
time.sleep(0.01)
GPIO.output(line, GPIO.LOW)
time.sleep(0.02)
def calculator(matrix_char):
size=len(matrix_char)
func=''
result=0
number_before_char=[]
number_after_char=[]
for i in range(size):
if matrix_char[i] == '+' or matrix_char[i] == '-' or matrix_char[i] == 'x' or matrix_char[i] == '/' :
func=matrix_char[i]
for j in range(i):
number_before_char.append(matrix_char[j])
for k in range(i+1,size):
number_after_char.append(matrix_char[k])
number_before_int=[float(element) for element in number_before_char]
result1 = 0
for i in range(len(number_before_int)):
result1 = result1 * 10 + number_before_int[i]
number_after_int=[int(element) for element in number_after_char]
result2 = 0
for i in range(len(number_after_int)):
result2 = result2 * 10 + number_after_int[i]
if func=='+':
result= result1+result2
if func=='-':
result= result1-result2
if func=='x':
result= result1*result2
if func=='/':
result=result1/result2
return result
def key_pad(line, col,matrix_char):
GPIO.output(line, GPIO.HIGH)
time.sleep(0.01)
if(GPIO.input(C1) == 1):
if line == R4:
lcd_string('',LCD_LINE_1)
matrix_char.clear()
else:
lcd_string(col[0],LCD_LINE_1)
matrix_char.append((col[0]))
time.sleep(0.1)
if(GPIO.input(C2) == 1):
lcd_string(col[1],LCD_LINE_1)
matrix_char.append((col[1]))
time.sleep(0.1)
if(GPIO.input(C3) == 1):
if line == R4:
a=calculator(matrix_char)
lcd_string(str(a),LCD_LINE_1)
matrix_char.clear()
matrix_char.append(str(a))
time.sleep(0.1)
else:
lcd_string(col[2],LCD_LINE_1)
matrix_char.append((col[2]))
time.sleep(0.1)
if(GPIO.input(C4) == 1):
lcd_string(col[3],LCD_LINE_1)
matrix_char.append((col[3]))
time.sleep(0.1)
GPIO.output(line, GPIO.LOW)
time.sleep(0.01)
# Define delay between readings
lcd_init()
matrix_char=[]
try:
while 1:
key_pad(R1, ["7","8","9","/"],matrix_char)
key_pad(R2, ["4","5","6","x"],matrix_char)
key_pad(R3, ["1","2","3","-"],matrix_char)
key_pad(R4, ["C","0","=","+"],matrix_char)
finally:
GPIO.cleanup()