← Back to ratslair.com
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdvin <[email protected]>2025-04-30 08:27:49 +0200
committerEdvin <[email protected]>2025-04-30 08:27:49 +0200
commite34ba56ce272a48896f57db6668ec72cc5ae0a86 (patch)
tree78b7fcee18839b48e16f8475901d03d57c6077bd
parent864bb8edacb3a34e98ca804bc439b7188c397c5b (diff)
Implemented LCD with Arduino
-rw-r--r--I2C_LCD_driver.py178
-rw-r--r--LCD_test.py5
-rw-r--r--arduino/arduino.ino128
-rwxr-xr-xmain.py22
4 files changed, 140 insertions, 193 deletions
diff --git a/I2C_LCD_driver.py b/I2C_LCD_driver.py
deleted file mode 100644
index 0a58e30..0000000
--- a/I2C_LCD_driver.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# -*- 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
deleted file mode 100644
index 196f674..0000000
--- a/LCD_test.py
+++ /dev/null
@@ -1,5 +0,0 @@
-import I2C_LCD_driver as LCD
-
-AGVlcd = LCD.lcd()
-
-AGVlcd.lcd_display_string("Hello World!", 1)
diff --git a/arduino/arduino.ino b/arduino/arduino.ino
new file mode 100644
index 0000000..b02fd48
--- /dev/null
+++ b/arduino/arduino.ino
@@ -0,0 +1,128 @@
+#include <LiquidCrystal_I2C.h>
+
+// To H-bridges
+const int D1 = 10;
+const int D2 = 11;
+const int D3 = 6;
+const int D4 = 5;
+
+// UART communication
+char c;
+String received = "";
+
+// LCD
+LiquidCrystal_I2C lcd(0x27, 20, 4);
+
+int emptySpace = 0;
+
+void setup() {
+ pinMode(D1, OUTPUT);
+ pinMode(D2, OUTPUT);
+ pinMode(D3, OUTPUT);
+ pinMode(D4, OUTPUT);
+ digitalWrite(D1, LOW);
+ digitalWrite(D2, LOW);
+ digitalWrite(D3, LOW);
+ digitalWrite(D4, LOW);
+
+ pinMode(LED_BUILTIN, OUTPUT);
+ digitalWrite(LED_BUILTIN, LOW);
+
+ Serial.begin(9600);
+
+ lcd.init();
+ lcd.backlight();
+ lcd.setCursor(2, 0);
+ lcd.print("AGV booting!");
+ received = "Dot dot dot dot";
+}
+
+void loop() {
+ if (Serial.available() > 0) {
+ received = Serial.readStringUntil('\n');
+ //Serial.println(received);
+ }
+
+ if (received.indexOf("Bluetooth up") >= 0) {
+ lcd.clear();
+ lcd.setCursor(2, 0);
+ lcd.print("Bluetooth up");
+ lcd.setCursor(6, 1);
+ lcd.print("....");
+ emptySpace = 0;
+ received = "Dot dot dot dot"; // Reset received message so that LCD does not clear and rewrite every tick
+ }
+
+ if (received.indexOf("Dot dot dot dot") >= 0) {
+ String dot;
+ for (int i = 0;i < 4;i++) {
+ if (i == emptySpace) {
+ dot = " ";
+ } else {
+ dot = ".";
+ }
+ lcd.setCursor(6 + i, 1);
+ lcd.print(dot);
+ }
+ emptySpace++;
+ if (emptySpace > 3) {
+ emptySpace = 0;
+ }
+ delay(500);
+ }
+
+ if (received.indexOf("Bluetooth connected") >= 0) {
+ lcd.clear();
+ lcd.setCursor(2, 0);
+ lcd.print("Connected to");
+ lcd.setCursor(2, 1);
+ lcd.print(received.substring(20, 32)); // Message as 'Bluetooth connected XXXXXXXXXXXX' with MAC-address.
+ received = "";
+ delay(2000);
+ lcd.clear();
+ }
+
+ if (received.indexOf("Closing down") >= 0) {
+ lcd.clear();
+ lcd.setCursor(2, 0);
+ lcd.print("AGV booting!");
+ received = "Dot dot dot dot";
+
+ Serial.end();
+
+ delay(5000);
+
+ Serial.begin(9600);
+ }
+
+ if (received.indexOf("Forward") >= 0) { // Forward
+ digitalWrite(D1, HIGH);
+ digitalWrite(D2, LOW);
+ digitalWrite(D3, HIGH);
+ digitalWrite(D4, LOW);
+ }
+ else if (received.indexOf("Backward") >= 0) { // Backward
+ digitalWrite(D1, LOW);
+ digitalWrite(D2, HIGH);
+ digitalWrite(D3, LOW);
+ digitalWrite(D4, HIGH);
+ }
+ else if (received.indexOf("Right") >= 0) { // Right
+ digitalWrite(D1, HIGH);
+ digitalWrite(D2, LOW);
+ digitalWrite(D3, LOW);
+ digitalWrite(D4, HIGH);
+ }
+ else if (received.indexOf("Left") >= 0) { // Left
+ digitalWrite(D1, LOW);
+ digitalWrite(D2, HIGH);
+ digitalWrite(D3, HIGH);
+ digitalWrite(D4, LOW);
+ }
+ else {
+ digitalWrite(D1, LOW);
+ digitalWrite(D2, LOW);
+ digitalWrite(D3, LOW);
+ digitalWrite(D4, LOW);
+ }
+}
diff --git a/main.py b/main.py
index 4f690dc..5a666dd 100755
--- a/main.py
+++ b/main.py
@@ -4,14 +4,16 @@ import signal
import serial
import select
from time import sleep
-# import I2C_LCD_driver as LCD
-# AGVlcd = LCD.lcd()
+# Open serial port to Arduino Nano
+NANO = serial.Serial('/dev/ttyUSB1', 9600, timeout=1)
+sleep(2)
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)
+NANO.write(b"Bluetooth up\n")
print(BluetoothProcess.stdout.readline().strip())
# Connected?
@@ -27,14 +29,12 @@ 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)
+ nanoBtMessage = "Bluetooth connected " + bto[13:].translate({ord(c): None for c in ':'}) # Address to send to nano
+ NANO.write(nanoBtMessage.encode())
+ print(nanoBtMessage)
# LIDAR Process Code
- LIDARProcess = subprocess.Popen(["./home/pi/TNE107-RPI/LIDARProg", "--channel", "--serial", "/dev/ttyUSB1", "460800"], stdout=open(os.devnull, 'wb'))
+ LIDARProcess = subprocess.Popen(["/home/pi/TNE107-RPI/LIDARProg", "--channel", "--serial", "/dev/ttyUSB0", "460800"], stdout=open(os.devnull, 'wb'))
print(f"LIDAR PID: {LIDARProcess.pid}")
# DWM Process Code
@@ -78,14 +78,16 @@ if bto.find("Connected") != -1:
# NANO.write(b"Left\n")
leftTurn = leftTurnIndex
rightTurn = 0
- elif bto == "0":
+ else:
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")
+ NANO.write(b"Closing down\n")
+ sleep(1)
+ NANO.close()
print("Terminating LIDAR process")
os.kill(LIDARProcess.pid, signal.SIGINT)