Arduino-basierter VFD-Ansteuerungs-Controller (Vacuum Fluorescent Display)
Komponenten und Materialien
| Bauteil | Menge | Hinweise |
|---|---|---|
| Arduino UNO (oder beliebiger 8-Bit-Arduino) | 1 | |
| VFD-Display | 1 | Ziel-Display |
| CD4094 (Schieberegister, 8-Stufig) | 2 | Für Anoden (Segmente) |
| CD4017 (Dezimalzähler/Decoder) | 2 | Für Gitter (Grids) |
| BC557 (PNP-Transistor) | 17 | oder 2N3906, 2SA733, höhere Spannung möglich |
| BC547 (NPN-Transistor) | 2 | oder 2N3904, 2SC945 |
| PC817 (Optokoppler) | 1 | Für Grid-Spannungsebene |
| 1N4007 Diode | 4 | Hochspannung |
| Elko (verschiedene Werte/Spannungen) | 4 | Siehe Schaltplan |
| 470 nF Kondensator | 1 | Beliebig |
| Lochrasterplatine | 1 | |
| 1/4 W Widerstände | 24 | Siehe Schaltplan |
| Dupont-Jumper / Draht | 1 Set | Für Verbindungen |
Benötigte Werkzeuge
- Lötkolben
- Lötzinn (0,5 mm, gute Qualität)
- Seitenschneider
Projektübersicht
Wozu dient das?
VFD-Röhren (Vacuum Fluorescent Displays) sind zwar nicht mehr State-of-the-Art, aber faszinierend: Glasgehäuse, Glühfaden, Vakuum, extrem helle, oft farbige Anzeige. Meist benötigt man dedizierte Treiber-ICs (I²C/SPI). Fehlt dieser, ist der direkte Anschluss nicht trivial. Dieses Design bietet eine universelle, diskrete Ansteuerung für fast jedes VFD – auch vintage „Röhren“-Typen. Matrix-Displays mit sehr vielen Segmente sind jedoch weniger geeignet.
Vor- & Nachteile
| Pro | Contra |
|---|---|
| Fast kostenlos (Standardbauteile) | Benötigt mehrere Spannungen (typisch für VFD) |
| Bauteile leicht beschaffbar | Keine Dimm-Funktion (außer über Anodenspannung) |
| Hohe Anodenspannung möglich (bis ~50 V bei BC557) | Belegt SPI & Timer1 am Arduino |
| Unabhängige Grid-/Anoden-Spannungen | Mikrocontroller darf nicht hängen (Einfrieren = Segment-Brennen) |
| Nur 3 digitale Datenleitungen nötig | Etwas Aufwand (kein Plug-&-Play) |
| Erweiterbar (mehr CD4094/4017) | |
| Code für alle 8-Bit-Arduinos fertig |
Funktionsprinzip
VFDs arbeiten multiplex: Kathode (Glühfaden) wird geheizt und auf GND gelegt. Ein Grid (Steuergitter, X-Achse) und ein Anoden-Pin (Segment, Y-Achse) erhalten positive Spannung → ein Segment leuchtet. Durch schnelles sequentielles Auswählen der Grids und gleichzeitiges Setzen der zugehörigen Anoden entsteht über Persistence of Vision (POV) ein stehendes Bild.
Dieser Schaltkreis nutzt:
- 2× CD4094 für Anoden – speichern High/Low-Zustände, gut für Segmente.
- 2× CD4017 für Grids – 10 sequenzielle Ausgänge, ideal für Grid-Multiplexing.
Nach Laden der CD4094 wird per Strobe-Signal die Konfiguration übernommen und gleichzeitig der CD4017 um einen Schritt weitergeschaltet (automatisches Sequenzieren).
Leistungsteil
- BC557 ziehen Anoden auf Anodenspannung (höher als 5 V).
- 100 kΩ an den Basen lassen Spannung abfallen, wenn Segment aus.
- CD4017 treiben Grids direkt; Optokoppler PC817 ermöglicht höhere Grid-Spannung (>5 V) und Pegeltrennung zu CD4094.
Arduino-Software
Timer1-Interrupt (~1000 Hz) lädt die CD4094 bei jedem Grid-Wechsel neu. Bei 10 Grids ergibt sich 100 Hz Bildwiederholrate. Ein Datenarray segments[gridAmount] hält die Segmentmuster; der Interrupt überträgt sie per SPI (hardwarenah, ohne Arduino-SPI-Lib, da innerhalb ISR).
Spannungsversorgung
- Grid-Spannung (CD4017): 5–18 V DC, ≥50 mA, ungeregelt. 12 V meist ausreichend.
- Anoden-Spannung: 0–50 V DC (max. BC557), typisch 20–30 V, ungeregelt, ≥50 mA.
- Digitalversorgung: 5 V (oder 3,3 V), ~100 mA. Bei Problemen SPI-Takt reduzieren.
- Filament (Heizung): ≥5 V, 200–300 mA. Nicht mit Arduino-Versorgung teilen! Brückengleichrichter + 1000 µF Elko bei AC-Quelle. Typisch ~3 V, 150 mA.
Tipps & Hinweise
- Pinbelegung des VFD vorab testen: 2× AA für Filament, 2× 9 V Block in Reihe für Grid/Anoden.
- „Anode 0“ finden (meist erstes Segment), um Software-Reihenfolge zu matchen.
- Filamentstrom langsam steigern, bis Drähte schwach glühen – dann leicht zurücknehmen.
- Grid/Anoden-Spannungen vorsichtig erhöhen; Phosphor kann einbrennen.
- Ein einziger Trafo für alle Spannungen ideal; Schaltnetzteile (geerdet) können stören.
- Erweiterbar: weitere CD4094 (Anoden) oder CD4017 (Grids). Weniger Grids → Jumper auf CD4017-Ausgang nach letztem Grid setzen.
- Keine Basiswiderstände an BC557 → schnell, aber CD4094 liefern ~4 mA/Pin. Strom prüfen.
- Alte, dunkle Displays: Filament kurzzeitig überlasten („Current Shock“) – riskant, Drähte können reißen.
Code
/* Versatile VFD Display Hardware Interface
Copyright (C) 2019 Genny A. Carogna – GPL v3 */
#define ledLed 13
#define strobePin 4
#define strobeHold 10 // µs
// Display-spezifisch (Beispiele) – anpassen oder löschen, nur gridAmount/anodeAmount definieren
#define JVC
#define mitsubishiGrids 10
#define mitsubishiAnodes 9
#define marantzGrids 9
#define marantzAnodes 14
#define JVCGrids 11
#define JVCAnodes 19
#if defined mitsubishi
#define gridAmount mitsubishiGrids
#define anodeAmount mitsubishiAnodes
#elif defined marantz
#define gridAmount marantzGrids
#define anodeAmount marantzAnodes
#elif defined JVC
#define gridAmount JVCGrids
#define anodeAmount JVCAnodes
#endif
// Segment-Datenarray (automatisch 8/16/32 Bit je nach anodeAmount)
#if anodeAmount > 16
volatile uint32_t segments[gridAmount] = {0};
#elif anodeAmount > 8
volatile uint16_t segments[gridAmount] = {0};
#else
volatile uint8_t segments[gridAmount] = {0};
#endif
void setup() {
// SPI-Pins & Strobe direkt als Output
*portModeRegister(digitalPinToPort(PIN_SPI_SS)) |= digitalPinToBitMask(PIN_SPI_SS);
*portModeRegister(digitalPinToPort(PIN_SPI_MOSI)) |= digitalPinToBitMask(PIN_SPI_MOSI);
*portModeRegister(digitalPinToPort(PIN_SPI_SCK)) |= digitalPinToBitMask(PIN_SPI_SCK);
*portModeRegister(digitalPinToPort(strobePin)) |= digitalPinToBitMask(strobePin);
*portOutputRegister(digitalPinToPort(strobePin)) &= ~digitalPinToBitMask(strobePin); // Low
*portModeRegister(digitalPinToPort(ledLed)) |= digitalPinToBitMask(ledLed);
*portOutputRegister(digitalPinToPort(ledLed)) &= ~digitalPinToBitMask(ledLed);
delay(800); // CD4017 Reset abwarten
cli(); // Interrupts sperren
// Timer1: Interrupt bei (160000 / gridAmount) → gesamt 100 Hz
TCCR1A = 0; TCCR1B = 0; TCNT1 = 0;
OCR1A = 160000 / gridAmount;
TCCR1B |= (1 << WGM12) | (1 << CS10);
TIMSK1 |= (1 << OCIE1A);
// SPI: Master, 1 MHz (SPR0), keine Interrupts
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
// SPSR |= (1 << SPI2X); // Halbieren falls CD4094 zu langsam
sei(); // Interrupts frei
// Weitere Setup-Codes hier...
}
void loop() {
show(); // Demo-Screensaver – löschen/ersetzen
}
// Timer1 ISR – wird bei jedem Grid-Schritt aufgerufen
ISR(TIMER1_COMPA_vect) {
static uint8_t turn = 1; // Start bei 1 (siehe Kommentar im Code)
// 32/16/8 Bit je nach anodeAmount per SPI senden (invertiert wegen PNP)
#if anodeAmount > 24
SPDR = ~uint8_t(segments[turn] >> 24); while (!(SPSR & (1 << SPIF)));
#endif
#if anodeAmount > 16
SPDR = ~uint8_t(segments[turn] >> 16); while (!(SPSR & (1 << SPIF)));
#endif
#if anodeAmount > 8
SPDR = ~uint8_t(segments[turn] >> 8); while (!(SPSR & (1 << SPIF)));
#endif
SPDR = ~uint8_t(segments[turn]); while (!(SPSR & (1 << SPIF)));
// Strobe: Daten übernehmen & CD4017 weiterschalten
*portOutputRegister(digitalPinToPort(strobePin)) |= digitalPinToBitMask(strobePin);
delayMicroseconds(strobeHold);
*portOutputRegister(digitalPinToPort(strobePin)) &= ~digitalPinToBitMask(strobePin);
turn++; if (turn == gridAmount) turn = 0;
}
// Demo-Funktionen (show, mitsubishiPrintNum, marantzPrintNum, JVCPrintNum) – siehe Original.
Schaltplan
Jumper auf CD4017 (rote Linie): Auf Ausgang nach letztem Grid löten (z. B. 11. Ausgang bei 10 Grids).
Arduino-Verbindungen rot markiert. USB-Strom für Arduino OK, aber für Rest klassischer Trafo empfohlen.
Filament: ~3 V/150 mA → 5 V AC Trafo + Kugelwiderstand/Leistungspotentiometer.
CD4017 an Grid-Spannung, Reset per RC-Glied (~0,1 s).
„Ghetto-AND“ für CD4017-Kaskade via NPN + Optokoppler – schnell genug.
Mehrere Masse-Punkte beachten!
Herstellungsprozess
- Squid Game Puppe mit Arduino UNO bauen – Interaktives DIY-Projekt
- Professionelle Bitmap-Animation auf dem ILI9341 2,4″ TFT Touchscreen Shield mit Visuino
- Web-gesteuertes DMX-Lichtsystem – Arduino Master Controller
- Klassisches Pong-Spiel auf Arduino UNO mit OLED-Display bauen – Schritt-für-Schritt-Tutorial
- DIY Arduino USB Gaming Controller – Bauen Sie Ihren eigenen High-Performance Gamepad
- Unopad: Nahtloser Arduino MIDI-Controller für Ableton Live
- Arduino Temperaturoverwachung & Echtzeituhr mit 3,2″ TFT-Display
- Interaktives Nextion HMI Projekt mit Arduino Mega und Sensoren
- DIY-Voltmeter mit Arduino und Nokia 5110 Display – Schritt-für-Schritt-Anleitung
- BME280 Temperatur, Luftfeuchte & Druck auf Nextion Touchscreen anzeigen