Interface and Application Programming

Group Assignment

This week's assignment: Write an application that interfaces a user with an input and/or output device that I made.

I kept things simple this week as I was recovering from a severe cold. I created a simple web server for LLM text-to-speech interaction for my hardware (a mouse). The interface below shows how the user can interact with the Arduino's mode (dog or cat mode) and send messages to ChatGPT. The mode automatically switches based on Arduino sensor readings (H for dog mode, L for cat mode).

Python Code (Server-Side)

Below is the Python code that runs the Flask server and interfaces with ChatGPT and the Arduino.


import threading
import time
import queue
import serial
import openai
from flask import Flask, request, jsonify

# ---- Configuration ----
port = '/dev/cu.usbmodem101'
baud_rate = 9600
openai.api_key = "YOUR_OPENAI_API_KEY_HERE"  # Replace with your key

# Queues for thread communication if needed
serial_queue = queue.Queue()

# Conversation history
conversation_history = [
    {"role": "system", "content": "Act as a happy and friendly dog and say woof woof at the end of sentences."}
]
current_mode = "dog"  # 'dog' or 'cat'

stop_threads = False

def serial_thread(port, baud_rate):
    try:
        ser = serial.Serial(port, baud_rate, timeout=0.1)
        print(f"Opened port: {ser.portstr}")
        time.sleep(2)  # Wait for Arduino reset
        while not stop_threads:
            if ser.in_waiting > 0:
                data = ser.readline()
                if data:
                    line = data.decode('utf-8', errors='replace').strip()
                    serial_queue.put(line)
            time.sleep(0.01)
        ser.close()
        print("Serial port closed.")
    except serial.SerialException as e:
        print(f"Could not open serial port {port}: {e}")

def get_response_from_chatgpt(prompt):
    conversation_history.append({"role": "user", "content": prompt})
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=conversation_history,
        temperature=0.6,
        max_tokens=60
    )
    reply = response['choices'][0]['message']['content']
    conversation_history.append({"role": "assistant", "content": reply})
    return reply

def main_loop():
    global current_mode
    while not stop_threads:
        while not serial_queue.empty():
            latest_line = serial_queue.get()
            print(f"Received: {latest_line}")
            if latest_line == 'H':
                # Switch to dog mode
                current_mode = "dog"
                conversation_history.clear()
                conversation_history.append(
                    {"role": "system", "content": "Act as a happy and friendly dog and say woof woof at the end of sentences."}
                )
            elif latest_line == 'L':
                # Switch to cat mode
                current_mode = "cat"
                conversation_history.clear()
                conversation_history.append(
                    {"role": "system", "content": "Act as an angry and mean cat and say meow meow at the end of sentences."}
                )
        time.sleep(0.05)

# Start the serial thread and main loop in background
t_serial = threading.Thread(target=serial_thread, args=(port, baud_rate), daemon=True)
t_serial.start()

t_main = threading.Thread(target=main_loop, daemon=True)
t_main.start()

# ---- Flask App ----
app = Flask(__name__)

@app.route('/get_mode', methods=['GET'])
def get_mode():
    return jsonify({"mode": current_mode})

@app.route('/send_message', methods=['POST'])
def send_message():
    data = request.get_json()
    user_message = data.get("message", "")
    if user_message.strip():
        response = get_response_from_chatgpt(user_message)
        return jsonify({"response": response})
    else:
        return jsonify({"response": "No message received."})

if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=5000)
    except KeyboardInterrupt:
        stop_threads = True
        t_serial.join()
        t_main.join()
            

HTML Interface

This HTML page provides a simple web interface to interact with the Flask server, showing the current mode and allowing you to send a message to ChatGPT. It automatically updates the mode every 5 seconds and displays responses.







Arduino & ChatGPT Interface



Arduino & ChatGPT Interface

Current Mode: Loading...

Send a Message to ChatGPT

Type your message below and click 'Send' to get a response. The mode (dog or cat) is determined by the Arduino input.



Fetching response...