← Tkinter Touchscreen HMI on a Raspberry PLC with Beacons
Fuse test benchRaspberry PLC 19RGPIOHMI / Dashboard
Tkinter Touchscreen HMI on a Raspberry PLC with Beacons — full example
Build a fullscreen Tkinter HMI on a Raspberry PLC touchscreen: live current and temperature displays, mode buttons and stack-light beacons on relays.
Complete, runnable program for the Raspberry PLC 19R (tkinter-gui-beacons-relays.py): wiring header, requirements and integration notes included.
Download the full project pack — freeThis example + the related ones + bill of materials
Read-only preview.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
COMPLETE EXAMPLE — Tkinter GUI on touchscreen + beacons driven by relays
Equipment: Raspberry PLC 19R (Industrial Shields)
Based on: fuse test bench project
Wiring:
- HDMI/USB touchscreen connected to the Raspberry PLC
- R0.1 Green beacon (test running, all OK)
- R0.2 Yellow beacon (ready / standby)
- R0.8 Red beacon (fault or emergency)
Requirements:
pip3 install python3-librpiplc
(Tkinter ships with Raspberry Pi OS)
Integration with the catalog:
- The live values (current, Vdrop, temperature) come from
ads1015-differential-adc-autogain.py and ds18b20-1wire-sensor.py.
- The mode buttons launch fuse-test-sequences.py.
"""
import tkinter as tk
from rpiplc_lib import rpiplc
BEACONS = {"green": "R0.1", "yellow": "R0.2", "red": "R0.8"}
def set_beacon(active_color):
"""Turn on a single beacon and switch off the rest (exclusive state)."""
for color, relay in BEACONS.items():
state = rpiplc.HIGH if color == active_color else rpiplc.LOW
rpiplc.digital_write(relay, state)
class TestBenchGUI:
"""Fullscreen 850x550 GUI designed for fingers: big fonts and buttons."""
def __init__(self, root):
self.root = root
root.title("Fuse test bench")
root.geometry("850x550")
root.attributes("-fullscreen", True) # dedicated touchscreen
# --- Live display: current / Vdrop / temperature -----------------
frame = tk.Frame(root, bg="black")
frame.pack(fill="both", expand=True)
self.lbl_current = self._display(frame, "CURRENT", "0.00 A", 0)
self.lbl_vdrop = self._display(frame, "VDROP", "0.0 mV", 1)
self.lbl_temp = self._display(frame, "TEMPERATURE", "--.- C", 2)
# --- Mode button bar ---------------------------------------------
buttons = tk.Frame(root)
buttons.pack(fill="x", pady=10)
tk.Button(buttons, text="DIRECT MODE", font=("Arial", 18), height=2,
command=self.direct_mode).pack(side="left", expand=True, fill="x")
tk.Button(buttons, text="AUTOMATIC MODE", font=("Arial", 18), height=2,
command=self.automatic_mode).pack(side="left", expand=True, fill="x")
tk.Button(buttons, text="STOP", font=("Arial", 18), height=2, fg="red",
command=self.stop).pack(side="left", expand=True, fill="x")
set_beacon("yellow") # startup: bench ready
self.refresh() # first refresh cycle
def _display(self, parent, title, initial, column):
f = tk.Frame(parent, bg="black")
f.grid(row=0, column=column, padx=20, pady=40, sticky="nsew")
parent.grid_columnconfigure(column, weight=1)
tk.Label(f, text=title, fg="gray", bg="black",
font=("Arial", 16)).pack()
lbl = tk.Label(f, text=initial, fg="lime", bg="black",
font=("Arial", 42, "bold"))
lbl.pack()
return lbl
# On the real bench these values come from the acquisition modules
def read_process(self):
import random
return (random.uniform(31.5, 32.5), # current (A)
random.uniform(95, 105), # Vdrop (mV)
random.uniform(22.0, 23.0)) # temperature (°C)
def refresh(self):
"""Display cycle: Tkinter is in charge, hardware is read via after()."""
amps, vdrop, temp = self.read_process()
self.lbl_current.config(text="%.2f A" % amps)
self.lbl_vdrop.config(text="%.1f mV" % vdrop)
self.lbl_temp.config(text="%.1f C" % temp)
self.root.after(500, self.refresh) # every 500 ms, no threads
def direct_mode(self):
set_beacon("green")
print("Direct mode: the operator sets the setpoint manually")
def automatic_mode(self):
set_beacon("green")
print("Automatic mode: setpoints loaded from a reference file")
def stop(self):
set_beacon("red")
print("STOP requested from the screen")
def main():
rpiplc.init("RPIPLC_19R")
for relay in BEACONS.values():
rpiplc.pin_mode(relay, rpiplc.OUTPUT)
root = tk.Tk()
TestBenchGUI(root)
root.mainloop()
set_beacon(None) # on exit, all beacons off
if __name__ == "__main__":
main()
Download the full project pack — freeThis example + the related ones + bill of materials