from machine import Pin, SPI, UART # Import necessary modules for hardware control
from time import sleep # Import sleep for delays
import st7789 # Import library for ST7789 TFT display
import MessengerPi # Import custom module for Messenger functionalities
from MessengerPi import * # Import all functions from MessengerPi
import vga1_16x32 as font1 # Import a font for larger text
import vga1_8x16 as font # Import a font for smaller text
# Initialize the SPI interface for the TFT display
spi = SPI(1, baudrate=40000000, sck=Pin(10), mosi=Pin(11))
# Configure the ST7789 TFT display
tft = st7789.ST7789(
spi,
width=320, # Screen width in pixels
height=240, # Screen height in pixels
cs=Pin(13, Pin.OUT), # Chip select pin
dc=Pin(24, Pin.OUT), # Data/command pin
backlight=Pin(26, Pin.OUT), # Backlight control pin
reset=Pin(12, Pin.OUT) # Reset pin
)
tft.init()
tft.fill(0) # Clear the screen (fill with black)
# Function to set up the main interface layout
def front_view():
tft.fill(st7789.WHITE) # Fill the screen with white
# Draw the green button and text area borders
tft.fill_rect(0, 195, 230, 3, st7789.GREEN) # Top horizontal line of input box
tft.fill_rect(230, 195, 3, 45, st7789.GREEN) # Right vertical line of input box
tft.fill_rect(0, 237, 230, 3, st7789.GREEN) # Bottom horizontal line of input box
tft.fill_rect(0, 195, 3, 45, st7789.GREEN) # Left vertical line of input box
tft.fill_rect(215, 195, 105, 45, st7789.GREEN) # "Send" button background
tft.text(font1, "Send", 240, 200, st7789.BLUE, st7789.GREEN) # "Send" button label
# Function to draw a blinking cursor at the given position
def cursor(num, y):
tft.fill_rect(num + 8, y, 3, 14, st7789.BLACK) # Draw the cursor
# Function to display messages on the screen
def printing(storage):
z = 0 # Vertical offset for messages
tft.fill_rect(0, 0, 320, 195, st7789.WHITE) # Clear the message display area
# Display messages from storage (most recent at the bottom)
for datq in reversed(storage):
if datq[1] == 0: # Message sent by the user
beta = datq[0]
if "\n" in beta: # If message contains a newline, split it into lines
tft.text(font, beta[:beta.find("\n") + 1], 300 - (len(beta[:beta.find("\n") + 1]) * 7), 155 - z, st7789.BLACK, st7789.YELLOW)
tft.text(font, beta[beta.find("\n") + 1:], 300 - (len(beta[:beta.find("\n") + 1]) * 7), 170 - z, st7789.BLACK, st7789.YELLOW)
z += 30 # Adjust offset for multi-line messages
else:
tft.text(font, datq[0], 300 - (len(datq[0]) * 7), 170 - z, st7789.BLACK, st7789.YELLOW)
z += 20
if datq[1] == 1: # Message received from LoRa
tft.text(font, datq[0], 5, 170 - z, st7789.BLACK, st7789.CYAN)
z += 20
# Initialize keyboard layouts and variables
keys = [keys_capital, keys_small, keys_num_special] # Keyboard layers (capital, small, special characters)
data = "" # To store the user's current input
num = 5 # Initial x-coordinate for input cursor
extra_word = ["ENTER", "SHIFT", "shift", "enter", "BKS", "bks"] # Special keys
key_i = 0 # Keyboard layer index
y = 200 # Initial y-coordinate for input cursor
z = 0 # Placeholder for additional vertical offsets
cycle = 0 # Counter for message cycles
storage = [] # To store sent and received messages
front_view() # Display the main interface
lora_uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) # Configure UART for LoRa communication
# Main loop
while True:
key = MessengerPi.keyboard(keys[key_i]) # Get a key press from the keyboard
if key == "SHIFT" or key == "shift": # Toggle keyboard layer
key_i = (key_i + 1) % 3 # Switch between capital, small, and special character layouts
key = MessengerPi.keyboard(keys[key_i]) # Update the key
data_read = lora_uart.readline() # Read data from LoRa module
if data_read is not None:
print(data_read) # Print received data to console
storage.append([data_read, 1]) # Add received message to storage
printing(storage) # Update the message display
if key == "ENTER" or key == "enter": # Send the message when "Enter" is pressed
sending = data.replace("\n", "") # Prepare the message for sending
lora_uart.write(sending) # Send the message via LoRa
print(sending) # Debug: Print the message being sent
# Highlight the "Send" button momentarily
tft.fill_rect(215, 195, 105, 45, st7789.YELLOW)
tft.text(font1, "Send", 240, 200, st7789.BLUE, st7789.YELLOW)
sleep(0.2)
tft.fill_rect(215, 195, 105, 45, st7789.GREEN)
tft.text(font1, "Send", 240, 200, st7789.BLUE, st7789.GREEN)
# Clear the input area
tft.fill_rect(num, y, 3, 14, st7789.WHITE)
# Reset variables and update storage
storage.append([data, 0]) # Add sent message to storage
data = "" # Clear current input
printing(storage) # Refresh message display
# Update input area based on key press
if key is not None and key not in extra_word:
data += key # Append key to current input
tft.text(font, key, num, y, st7789.BLACK, st7789.WHITE) # Display the key
cursor(num, y) # Update cursor
num += 8 # Move cursor forward
if key == " ":
tft.fill_rect(num, y, 4, 14, st7789.WHITE) # Add space
cursor(num, y)
data += key
num += 8
if key == "bks" or key == "BKS": # Handle backspace
tft.text(font, data[-1:], num - 8, y, st7789.WHITE, st7789.WHITE) # Erase last character
num -= 8 # Move cursor back
cursor(num - 8, y)
data = data[:-1] # Remove last character from input
if num > 205: # Handle line wrap
tft.fill_rect(num, y, 3, 14, st7789.WHITE) # Clear cursor
data += "\n" # Add newline to input
y = 220 # Move to next line
num = 5 # Reset x-coordinate
sleep(0.05) # Small delay to prevent input flooding
Comments
Please log in or sign up to comment.