From 864bb8edacb3a34e98ca804bc439b7188c397c5b Mon Sep 17 00:00:00 2001 From: Edvin Date: Fri, 25 Apr 2025 10:15:50 +0200 Subject: Added some test for the LCD and fixed paths to programs to be absolute. --- I2C_LCD_driver.py | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ LCD_test.py | 5 ++ main.py | 24 ++++++-- 3 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 I2C_LCD_driver.py create mode 100644 LCD_test.py diff --git a/I2C_LCD_driver.py b/I2C_LCD_driver.py new file mode 100644 index 0000000..0a58e30 --- /dev/null +++ b/I2C_LCD_driver.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +# Original code found at: +# https://gist.github.com/DenisFromHR/cc863375a6e19dce359d + +""" +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 + +""" + +# i2c bus (0 -- original Pi, 1 -- Rev 2 Pi) +I2CBUS = 0 + +# LCD Address +ADDRESS = 0x27 + +import smbus +from time import sleep + +class i2c_device: + def __init__(self, addr, port=I2CBUS): + 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) + + +# 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 with optional char positioning + def lcd_display_string(self, string, line=1, pos=0): + 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) + + # 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) diff --git a/LCD_test.py b/LCD_test.py new file mode 100644 index 0000000..196f674 --- /dev/null +++ b/LCD_test.py @@ -0,0 +1,5 @@ +import I2C_LCD_driver as LCD + +AGVlcd = LCD.lcd() + +AGVlcd.lcd_display_string("Hello World!", 1) diff --git a/main.py b/main.py index 811e982..4f690dc 100755 --- a/main.py +++ b/main.py @@ -4,10 +4,14 @@ import signal import serial import select from time import sleep +# import I2C_LCD_driver as LCD -BluetoothProcess = subprocess.Popen(["python", "-u", "bt.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, text=True) +# AGVlcd = LCD.lcd() + +BluetoothProcess = subprocess.Popen(["python", "-u", "/home/pi/TNE107-RPI/bt.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, text=True) # Waiting on connection +# AGVlcd.lcd_display_string("Waiting for Bluetooth connection...", 1) print(BluetoothProcess.stdout.readline().strip()) # Connected? @@ -15,26 +19,32 @@ print(BluetoothProcess.stdout.readline().strip()) bto = BluetoothProcess.stdout.readline().strip() print(bto) + newCommand = False -rightTurnIndex = 5 +rightTurnIndex = 50 rightTurn = 0 -leftTurnIndex = 2 +leftTurnIndex = 20 leftTurn = 0 if bto.find("Connected") != -1: + # AGVlcd.lcd_clear() + # AGVlcd.lcd_display_string(bto) + # Open serial port to Arduino Nano NANO = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) # LIDAR Process Code - LIDARProcess = subprocess.Popen(["./LIDARProg", "--channel", "--serial", "/dev/ttyUSB1", "460800"], stdout=open(os.devnull, 'wb')) + LIDARProcess = subprocess.Popen(["./home/pi/TNE107-RPI/LIDARProg", "--channel", "--serial", "/dev/ttyUSB1", "460800"], stdout=open(os.devnull, 'wb')) print(f"LIDAR PID: {LIDARProcess.pid}") # DWM Process Code - DWMProcess = subprocess.Popen(["python", "DWM.py"], stdout=open(os.devnull, 'wb')) + DWMProcess = subprocess.Popen(["python", "/home/pi/TNE107-RPI/DWM.py"], stdout=open(os.devnull, 'wb')) print(f"DWM PID: {DWMProcess.pid}") + # sleep(3) + while bto != "1000": - ready, _, _ = select.select([BluetoothProcess.stdout], [], [], 0.01) + ready, _, _ = select.select([BluetoothProcess.stdout], [], [], 0.001) if ready: bto = BluetoothProcess.stdout.readline().strip() @@ -71,6 +81,8 @@ if bto.find("Connected") != -1: elif bto == "0": NANO.write(b"Stop\n") + # Print current status (current command, heading? position? Could we include a cool progress bar? TO MISSION COMPLETEION?????) + print("Terminating Serial port to Arduino Nano") NANO.write(b"Stop\n") -- cgit v1.2.3