You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
6.3 KiB

#import "@preview/diatypst:0.9.0": *
#import sym: arrow
#set text(font: "TeX Gyre Adventor")
#show heading.where(level: 3): it =>[
#block(it.body)
]
#show: slides.with(
title: "Abfahrtsanzeiger Hacken 2.0",
date: "17.05.2026",
authors: ("Christian Seiler, flop"),
// Optional (for more see docs at https://mdwm.org/diatypst/)
ratio: 16/9,
layout: "medium",
title-color: blue.darken(30%),
toc: false,
)
= Was bisher geschah
== Erstkontakt mit den Stadtwerken (Februar 2023)
#figure(
grid(
columns: 2,
gutter: 2mm,
image("stadtwerke1.PNG", width: auto),
image("stadtwerke2.PNG", width: auto),
)
)
== Anlieferung der Anzeiger (Oktober 2023)
#figure(
grid(
columns: 2,
gutter: 2mm,
image("36cbc47d30c88e94.png", width: auto),
image("7c3f89ceae88b388.jpg", width: auto),
)
)
== Reverse Engineering Versuche
#figure(
grid(
columns: 2,
gutter: 2mm,
image("06229735a9d36e8c.jpg", width: auto),
image("e993d285f6279cdd.jpg", width: auto),
)
)
== Durchbruch in Entropia (April 2025)
#align(center)[
#image("entropia.jpg", width: auto)
]
== Erster Einsatz auf der GPN 2025
#grid(
columns: 2,
gutter: 15mm,
"\n- ESP32\n- Embedded Rust\n- Daten aus Pretalx",
image("0c914abfddc86330.png", width: auto),
)
== Weitere Einsätze: TDF4 & Cyborx
#figure(
grid(
columns: 2,
gutter: 2mm,
image("ae85ca78a01cae0d.png", width: auto),
image("a05077ee7e192d99.jpg", width: auto),
)
)
= Erste Weiterentwicklung Hardware & Firmware
== Datenformat 1.0
Binärformat, das aus einer Liste von Elementen besteht, die gezeichnet werden sollen.
=== Features
- Bilder
- Animationen
- Scrollende Bilder (vorgerenderter Lauftext)
=== Bilddaten
- Koordinaten fangen bei (0, 0) an
- 1 bit pro Pixel
- Pixel Index: $n(x, y) = y * W + x$
- Byte Index: $B(x, y) = floor(n(x, y) / 8)$
- Bit Index: $b(x, y) = n(x, y) mod 8$
== Spaß am 39C3 (Dezember 2025)
#grid(
columns: 2,
gutter: 15mm,
image("IMG_20251226_173113.jpg", width: auto),
[
- Mikrocontroller + Firmware
- Basierend auf Entropia-Arbeit (Rust, ESP32)
- Modifikationen zum Rendering des Datenformats
- Busanzeiger Paint (Webinterface)
- Zeichnen mit verschiedenen Pixelgrößen
- Rudimentäres Textrendering
- Importieren von Bildern/GIFs
- Erstellung von Animationen
- "Vibe-Coding for the win"
- Round-Robin Bilder / Animationen vom Server
- CLI-Tool zur Vorschau (#arrow.r Demo)
]
)
== Custom PCB 1.0
#grid(
columns: 2,
gutter: 15mm,
image("IMG_20260309_214103.jpg", width: auto),
[
- LVDS-Transceiver auf Platine (#arrow.r altes Mainboard nicht mehr benötigt)
- Anschluss per 8p8c ("RJ45") Stecker (#arrow.r kein Custom Lötjub)
- Eigene Spannungsversorgung für Mikrocontroller
- Alternativer Anschluss für Seeed ESP32-S3 (kleineres Format)
- Funktioniert ohne Firmware-Änderung auf bestehendem Mikrocontroller #emoji.face
]
)
#align(center)[
#image("erste_funktion.jpeg", width: 60%)
]
#align(center)[
#image("erstes_logo1.jpeg", width: auto)
]
#grid(
columns: 2,
gutter: 15mm,
image("alte_platine.jpeg", width: auto),
[
=== Not Everything is Perfect #emoji.face.sad
- PIN-Reihe für alte Mikros nicht korrekt
- Stromversorgung für Seeed ESP32S3 nicht korrekt
- Bohrlöcher falsch platziert
- Falsche LVDS-Polarität
=== Learnings
- Prototyp-Platine war gute Testing-Platform
- Aber: konzentrieren auf einen Mikrocontroller (#arrow.r Seeed ESP32-S3, da 8 MiB SRAM und sehr klein und günstig)
- Kleinere Platine wäre besser, v.a. wenn mehr produziert werden sollen
]
)
= Let's Do it All Again
== Custom PCB
#grid(
columns: 2,
gutter: 5mm,
image("neue_platinen.jpeg", width: 8cm),
[
- Kleiner Formfaktor (5 cm x 5 cm)
- Separate Spannungsversorgungs-Platine (DC-DC)
- Hardware-Bugs gefixed (Polarität, Spannungsversorgung)
- Nur noch ESP32-S3
- Selbst bestückt
- Montage separat per 3D-Druck-Gehäuse
- Spannungsversorgung für Displays integriert (optional)
]
)
#align(center)[
#image("new_pcb.jpeg", width: auto)
]
== Datenformat 2.0
=== Neue Features
- Auswahl, ob auf Vorder- oder Rückseite angezeigt
- Support für Text und Fonts
- Support, die aktuelle Uhrzeit anzuzeigen
- Zeitspezifische Anzeigen
- Animation kurz einblenden
- Vorabauslieferung, falls WLAN ausfällt
== Firmware (WiP)
- Rewrite in C++
- ESP32-Rust-Ökosystem noch zu sehr im Fluss, mehrfach darüber geflucht, dass wir ständig refactorn mussten
- ESP32-S3 noch nicht 100% gut supported in Rust
- Unfähigkeit von uns, UART0 nicht für Debug-Ausgaben von Rust verwenden zu lassen
- Für später: A/B OTA Updates gehen mit ESP-Rust aktuell nicht
- Web-Konfiguration
- Deckel bleibt zu
- Temporärer AP und Web-UI beim ersten Start #arrow.r Web-Konfiguration
- Uhrzeit via SNTP
== Web-Konfiguration (WiP, vibes)
#align(center)[
#image("wifi.png", width: 70%)
]
== Web-Editor (WiP, vibes)
#align(center)[
#image("webeditor.png", width: auto)
]
== Montage
#align(center)[
#image("case1.jpeg", width: auto)
]
#align(center)[
#image("neue_platine.jpeg", width: 100%)
]
= Einsätze
== Lichti-Maskenball
#align(center)[
#image("abfahrt3.jpeg", width: 90%)
]
== TDF5 2026
#align(center)[
#image("saal_bool.jpeg", width: 90%)
]
= Ausblick
== Ausblick
- 23.05. AfD-Verbot jetzt! Demo (Tübingen)
- 04.06. GPN 2026 (Karlsruhe)
- 04.07. Tübix 2026 (Tübingen)
- "First Stable Release"
- Automatische pretalx-Integration (serverseitig)
- ICS-Integration (serverseitig)
- Mehr Busanzeiger flott machen
= Danksagung
== Danksagung
- Stadtwerke Tübingen für die Anzeiger
- We stand on the shoulders of giants
- Menschen, die das initiale Reverse Engineering gemacht haben
- Entropia e.V.
- Auslesen des Flash des Original-Mainboards: CC 86 e.V. Heilbronn
- Pascal (\@cal) für den Anfang der Slides
- Rüdiger für 39c3 Busanzeiger Paint
#grid(
columns: 2,
gutter: 25mm,
image("case_closed.jpeg", width: 5cm),
[
\
\
\
*Case Closed*
]
)