Skip to content

Week 14 Interface and Application Programming

MIT App Inventor - McKinnon Collins

MIT App Inventor is a visual, block-based programming platform developed to simplify mobile application development. It allows users to design user interfaces and program application behavior without requiring advanced knowledge of traditional programming languages.

In the context of Interface and Application Programming, MIT App Inventor is used to create user-friendly mobile interfaces that interact with embedded systems, enabling control, monitoring, and data visualization.

Key Concepts

1. User Interface (UI) Design

  • Drag-and-drop interface builder
  • Components such as:
  • Buttons
  • Sliders
  • Labels
  • Text inputs
  • Images
  • Real-time layout preview

2. Event-Driven Programming

  • Logic is triggered by user actions (events)
  • Examples:
  • Button clicks
  • Screen initialization
  • Timer events

3. Block-Based Logic

  • Uses visual blocks instead of text-based code
  • Prevents syntax errors
  • Encourages logical thinking and flow design

4. App–Hardware Interaction

  • Communicates with microcontrollers via:
  • Bluetooth
  • Wi-Fi (HTTP requests)
  • Sends commands and receives data

Example Workflow

  1. Design the interface (buttons, labels, controls)
  2. Assign behaviors using blocks
  3. Connect to external hardware (e.g., ESP32, Arduino)
  4. Send/receive data
  5. Display results in real time

Example Logic (Pseudocode)

When Button1.Click:
    Send "ON" signal to device

When Button2.Click:
    Send "OFF" signal to device

When data is received:
    Update Label with sensor value

MQTT — Yian Hu

What is MQTT?

MQTT, which stands for Message Queuing Telemetry Transport, is a lightweight messaging protocol that uses a publish/subscribe model. Rather than having devices talk to each other directly, all messages are sent through a central server called a broker. A device can either publish data to a named channel called a topic, or subscribe to a topic to receive messages sent to it.

MQTT is commonly used in IoT projects because it is designed to be lightweight, making it well-suited for microcontrollers with limited memory and networks that may not always be reliable.

How It Works

An MQTT system has three main components:

  • Broker — the central server that receives published messages and forwards them to subscribers on the matching topic. A common open-source broker is Mosquitto.
  • Publisher — a device that sends data to the broker under a specific topic (e.g., lab/temperature).
  • Subscriber — a device or application that listens to a topic and receives any messages published to it.

A typical message flow looks like this:

Device A → publishes "72.5" to topic "lab/temp"
              MQTT Broker
Device B → subscribed to "lab/temp" → receives "72.5"

Publishers and subscribers do not need to know about each other, which makes it easy to add or remove devices from the system without changing anything else.

Pros and Cons of MQTT

To better understand when to use MQTT, I put together this chart comparing its advantages and disadvantages.

Pros Cons
Complexity Simple to set up and use with just a few lines of code Requires a broker to be running at all times
Performance Very lightweight — works well on microcontrollers with limited memory Not ideal for large data transfers like images or files
Scalability Easy to add more devices without changing existing ones Managing many topics can become disorganized without planning
Reliability Supports quality-of-service (QoS) levels to ensure messages are delivered At the lowest QoS level, messages can be lost with no confirmation
Security Supports username/password authentication and TLS encryption Security has to be configured manually — it is not enabled by default
Network Works well on slow or unreliable networks Requires a constant network connection to the broker

Tkinter (Python) - Max Negrin

Tkinter is Python’s built-in GUI library. It comes installed with Python so there is nothing extra to download — you just import it and start building. The idea is that you create a window, add widgets to it (buttons, labels, text boxes, etc.), and then tell each widget what to do when a user interacts with it.

It is not the most modern-looking UI toolkit, but for getting a functional interface running quickly without any extra dependencies, it does the job.

Basic Structure

Every Tkinter program follows the same pattern:

  1. Create the main window with Tk()
  2. Add widgets to it
  3. Bind events or commands to those widgets
  4. Call mainloop() to keep the window open and listening
import tkinter as tk

root = tk.Tk()
root.title("My Window")

label = tk.Label(root, text="Hello from Tkinter")
label.pack()

root.mainloop()

mainloop() is the part that keeps everything running. Without it, the window opens and immediately closes. It sits in a loop waiting for user events — clicks, keypresses, timer callbacks — and handles them as they come in.

Adding Buttons

Buttons are wired up using the command parameter. You pass in a function and Tkinter calls it when the button is clicked.

import tkinter as tk

def on_click():
    label.config(text="Button was clicked")

root = tk.Tk()

label = tk.Label(root, text="Press the button")
label.pack()

btn = tk.Button(root, text="Click Me", command=on_click)
btn.pack()

root.mainloop()

When the button is pressed, on_click runs, and the label text updates. That is the core event-driven loop in Tkinter — user action triggers a function, function changes the UI.

Layout

Tkinter has three layout managers: pack, grid, and place. pack stacks widgets vertically or horizontally, grid puts them in rows and columns, and place lets you set exact pixel positions. For most things, grid gives the most control.

import tkinter as tk

root = tk.Tk()

tk.Label(root, text="Name:").grid(row=0, column=0)
tk.Entry(root).grid(row=0, column=1)

tk.Label(root, text="Value:").grid(row=1, column=0)
tk.Entry(root).grid(row=1, column=1)

tk.Button(root, text="Submit").grid(row=2, column=0, columnspan=2)

root.mainloop()

Mixing layout managers in the same container will break things, so pick one and stick with it per frame.

Connecting to Hardware

Where Tkinter becomes useful for Fab Academy work is when you connect it to a serial device — for example, an Arduino or microcontroller sending sensor data over USB. You can read that serial data in a background thread and push updates into the UI using Tkinter’s after() method, which schedules a function to run after a delay without blocking mainloop().

import tkinter as tk
import serial
import threading

ser = serial.Serial('/dev/ttyUSB0', 9600)

def read_serial():
    while True:
        line = ser.readline().decode('utf-8').strip()
        label.config(text=line)

root = tk.Tk()

label = tk.Label(root, text="Waiting for data...")
label.pack()

thread = threading.Thread(target=read_serial, daemon=True)
thread.start()

root.mainloop()

The thread runs in the background reading from serial. When new data comes in, it updates the label. The daemon=True flag means the thread shuts down automatically when the main window closes — otherwise the program hangs.

Pros and Cons of Tkinter

Before committing to Tkinter for a project, it is worth knowing where it holds up and where it does not.

Pros Cons
Setup Built into Python — no installation needed Looks outdated compared to modern UI frameworks
Simplicity Straightforward to learn and get something running fast Limited widget set; missing things like toggles, date pickers, and progress rings
Portability Runs on Windows, macOS, and Linux with no changes UI can look inconsistent across operating systems
Performance Lightweight — low overhead for simple interfaces Not suited for real-time graphics or high-frequency UI updates
Hardware Integration Works well with serial and GPIO when paired with threading Threading requires careful handling to avoid crashes or freezing mainloop()
Community Long history, lots of examples and Stack Overflow coverage Not actively developed — new features are rare

For quick interfaces that talk to hardware — which covers most Fab Academy use cases — Tkinter is a reasonable choice. If the project needs a polished UI or heavy data visualization, something like PyQt or a web-based interface is worth the extra setup.


Python Web Server + MQTT Cloud Interface — Oliver Abbott

Full documentation on Oliver’s personal site — Week 15: Interface and Application Programming

For this week I built two applications that interface users with the custom boards I designed in previous weeks: a local web-based monitoring dashboard and a cloud-connected MQTT agent — both running on the Raspberry Pi 5.

Application 1: Local Web Dashboard

A Python web server running on port 8080 that serves a monitoring interface for the beehive:

What it does:

  • Live camera feeds — dual MJPEG streams from both entrance cameras
  • Real-time sensor data — temperature and humidity from 3× SHT45 sensors (via I²C multiplexer), updated every 2 seconds
  • Snapshot endpoints — single JPEG frames from either camera on demand
  • JSON API — sensor data at /sensors for integration with other tools

How it works:

  1. A background thread selects each multiplexer channel (0, 1, 2), reads the SHT45 sensor, and stores the latest values
  2. Two rpicam-vid processes stream MJPEG from each CSI camera port
  3. An HTML/JS frontend polls /sensors every 2 seconds and displays live-updating values alongside the camera feeds

Endpoints:

Path Description
/ Dashboard — cameras + live sensor readings
/snap0 Camera 0 single JPEG snapshot
/snap1 Camera 1 single JPEG snapshot
/sensors JSON array of sensor readings

Application 2: Cloud MQTT Agent

The hive-monitor-agent — a Python application that bridges physical devices with the user’s cloud dashboard via MQTT and REST APIs.

What it does:

  • Reads sensors — polls SHT45 sensors every 60s via I²C multiplexer, formats into JSON
  • Publishes telemetry — sends sensor data, weight, door/fan/LED state to AWS IoT Core over MQTT
  • Receives commands — subscribes to MQTT topics for door open/close, LED control, camera start/stop
  • Manages device shadow — reports current state, receives desired-state deltas from the cloud
  • Buffers offline — queues publishes in SQLite when network is down, replays on reconnect

Architecture:

┌─────────────────────────────────────────────────────┐
│              hive-monitor-agent (Python)             │
├─────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────┐  │
│  │ Driver       │  │ Telemetry    │  │ Command  │  │
│  │ Scheduler    │  │ Publisher    │  │ Handler  │  │
│  │ • SHT45 read │  │ • 60s cycle  │  │ • door   │  │
│  │ • HX711 read │  │ • JSON fmt   │  │ • LED    │  │
│  │ • door state │  │ • QoS 1      │  │ • camera │  │
│  └──────┬───────┘  └──────┬───────┘  └────┬─────┘  │
│         │                  │               │        │
│  ┌──────▼──────────────────▼───────────────▼─────┐  │
│  │           MQTT Client (paho-mqtt)             │  │
│  │  • mTLS with X.509 cert                      │  │
│  │  • Auto-reconnect with exponential backoff    │  │
│  └──────────────────────┬────────────────────────┘  │
│                         │                           │
│  ┌──────────────────────▼────────────────────────┐  │
│  │         Offline Buffer (SQLite)               │  │
│  │  • 7-day / 500 MB FIFO cap                   │  │
│  │  • Replay at ≤50 msg/s on reconnect          │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘
         │ TCP 8883 (MQTT over mTLS)
   AWS IoT Core → Cloud Dashboard (user interface)

Example telemetry payload (published every 60s):

{
  "timestamp": "2026-05-18T14:30:00Z",
  "sensors": {
    "brood_box": {"temp_c": 34.8, "humidity_pct": 62.1},
    "super_1":   {"temp_c": 31.2, "humidity_pct": 58.4},
    "ambient":   {"temp_c": 22.5, "humidity_pct": 45.0}
  },
  "weight_kg": 38.7,
  "door_state": "open",
  "fan_state": "auto",
  "led_state": "off"
}

Command handling:

  • .../door/command → drives servo to open/close entrance gate
  • .../led/command → toggles LED boards via GPIO MOSFETs
  • .../camera/{channel}/control → starts/stops camera streaming

Each command includes a request_id for idempotent deduplication.

Technologies Used

Technology Purpose
Python Server-side logic, sensor drivers, MQTT client
HTTP server (http.server) Local web dashboard — no external frameworks
MJPEG streaming Live video in the browser via multipart/x-mixed-replace
paho-mqtt MQTT 5 client with mTLS support
I²C (i2c-dev) Reading SHT45 sensors through PCA9548 multiplexer
HTML/CSS/JavaScript Frontend dashboard with live-updating values
SQLite Offline message buffer with FIFO eviction
X.509 certificates Mutual TLS authentication with AWS IoT Core
systemd Service management, auto-restart, conditional startup

Pros and Cons — Python Web Server + MQTT

Pros Cons
Setup No external frameworks needed — Python’s built-in http.server works Not production-grade for high traffic
Hardware access Direct I²C and GPIO access from the same process Requires Linux — won’t run on Windows without modification
Real-time data MJPEG streaming + polling gives live updates without WebSockets Polling every 2s adds slight latency vs push-based approaches
Offline resilience SQLite buffer means no data loss during network outages Buffer has finite capacity (500 MB)
Security mTLS with per-device certs — strong device authentication Certificate management adds operational complexity
Scalability MQTT pub/sub decouples devices from the dashboard Requires a cloud broker (AWS IoT Core) running at all times

Last update: May 19, 2026