Modellbahn DCC-Zentrale selbst bauen mit Arduino – Kostenlose App inklusive
Komponenten und Zubehör
| Komponente | Menge | Hinweise |
|---|---|---|
| SparkFun Arduino Pro Mini 328 - 5V/16MHz | 1 | |
| LMD18200T H-Brücke | 1 | 2 A Laststrom |
| PCB (geätzt) | 1 | Auf eBay erhältlich |
| Linearer Regler 7805 | 1 | |
| Z-Diode 3,6 V 0,5 W | 1 | |
| HC-06 Bluetooth Modul | 1 | |
| Widerstand 0,1 Ω 2 W | 1 | Strommesswiderstand |
| Elko 220 µF 16 V | 1 | |
| Elko 10 µF 16 V | 1 | |
| Keramikkondensator 0,1 µF | 3 | |
| Widerstand 10 kΩ | 2 | |
| Widerstand 4,7 kΩ | 1 | |
| Schraubklemme 2-polig 3,5 mm | 1 | Gleisanschluss |
| Schraubklemme 6-polig 2,54 mm | 1 | |
| 4-polige Buchsenleiste 2,54 mm | 1 | Für HC-06 |
| 12-polige Buchsenleiste 2,54 mm | 2 | Für Arduino Pro Mini |
Apps und Online-Dienste
- LocoMotive – kostenlose Version (Google Play Store)
- LocoMotive DCC – Vollversion (£5 + Steuer, Google Play Store), CV 1–255 lesen/schreiben
Projektbeschreibung
Was ist das Besondere? Eine sehr einfache Elektronik liefert das DCC-Signal und die Gleisspannung, aber die App auf dem Smartphone erledigt die eigentliche Arbeit! Der Prozessor im Handy konstruiert die DCC-Datenpakete, was den Arduino massiv entlastet.
Updates:
- 16.08.2019: Neue App-Version mit CV 1–255 Read/Write (kostenpflichtig).
- 18.05.2019: Bis zu 28 Funktionen mit editierbaren Titeln, Sichtbarkeit und Taster-Modus. Gleichzeitige Steuerung von 4 Loks mit Geschwindigkeitsbalken.
- 17.02.2019: HC-06 Reichweite durch 31,2 mm Draht (λ/4 bei 2,4 GHz) als Antenne verlängern.
- 29.01.2019: Taster-Modus für F2/F3 (Horn), max. Geschwindigkeit pro Lok speicherbar.





Keine teuren proprietären Systeme nötig – komplett eigenständige DCC-Zentrale, betrieben per kostenloser App „LocoMotive“. Funktioniert mit NMRA-konformen Decodern. DCC-Pakete werden in der App zusammengestellt und per Bluetooth an den Arduino gesendet, der sie mit dem DCC-Takt kombiniert.
Gesamtkosten ca. 20 € (eBay).
Merkmale
- Steuerung von 1–20 Loks
- Ideal für kleine bis mittlere Anlagen
- 2 A Laststrom → bis 16 Loks (OO/HO)
- Erweiterbar mit stärkerer H-Brücke
- Kurzschlussfest
- Automatische Überstromabschaltung (im Code einstellbar)
- Licht und Fahrtrichtung
- Funktionen F1–F8
- Funktionsnamen, Sichtbarkeit, Taster-Modus editierbar
- Weichen/ Zubehör: bis 8 Ausgänge
- Weichennamen editierbar
- Eigene Loknamen, max. Geschwindigkeit pro Lok
- CV1 (Adresse) programmieren
- CV 1–255 lesen/schreiben (Vollversion)
- Eigene Zubehöradressen
- Gleichspannungsversorgung 12–20 V passend zur Spur (Z/N/HO/O/G)
Weiterentwicklung früherer Bluetooth-DCC-Systeme: HC-06 Modul + LMD18200 H-Brücke (2 A) auf eigener PCB.
Schritt 1: Arduino Sketch
Der vollständige Sketch ist angehängt. Hier der Kern: Loop und Datenempfang. Die Android-App sendet ein vollständiges Paket, das hier in ein Datenarray decodiert wird. Je nach 3 oder 4 Bytes wird das korrekte DCC-Paketformat generiert.
void loop() {
if (bluetooth.available() > 0) {
inString = bluetooth.readStringUntil('\n');
}
if (inString.substring(0,1) == "D") { string(); }
delay(20);
}
Die Funktion string() zerlegt den Textstring und setzt jedes Byte an die richtige Stelle im DCC-Paket.
Beispiel 4-Byte Speed-Paket: DD, 3, 63, 12, 48 → Loco 3, Speed Steps, Speed, XOR-Check.
Beispiel 3-Byte Function-Paket: DD, 1, 129, 128 → Loco 1, F1 an, XOR-Check.
NMRA Standard: S-9.2.1
LMD18200: DCC-Signal an DIR-Pin, PWM-Pin auf HIGH.
Schritt 2: Fritzing Schaltplan
Arduino Pro Mini empfängt Bluetooth-Daten via HC-06, generiert NMRA-konforme Taktzyklen. Empfangene Daten unterbrechen die Sequenz und aktualisieren das DCC-Paket.

Teileliste:
- PCB (eBay)
- Arduino Pro Mini Atmega328P 5V/16M (eBay)
- LMD18200T H-Brücke (eBay)
- HC-06 Bluetooth Modul (eBay)
- 0,1 Ω 2W Metallfilm-Widerstand (eBay)
- 3× 0,1 µF Kondensator (eBay)
- 2× 10 kΩ Widerstand (eBay)
- 10 µF 25 V Elko (eBay)
- 220 µF 16 V Elko (eBay)
- Phoenix Contact MKDS 1/2-3,5 2-polig (eBay)
- 4,7 kΩ Widerstand (eBay)
- L7805CV Spannungsregler (eBay)
- 4-polige Pfostenleiste 2,54 mm (eBay)
- 2× 12-polige Pfostenleiste 2,54 mm (eBay)
- 6-polige Schraubklemme 2,54 mm (eBay)
- Z-Diode 3,6 V 0,5 W 1N4732A (eBay)
- Draht
- Netzteil: Für HO/OO 14 V DC (z. B. Laptop-Netzteil 2,5 A), passende Buchse beachten.
HC-06 Antenne verlängern: Massivdraht (z. B. Erdleiter) 31,2 mm an Antennenende löten, mit Schrumpfschlauch isolieren. Achtung: HC-06 RX→RX, TX→TX (nicht gekreuzt!).
Strommessung / Kurzschlussschutz: 0,1 Ω Messwiderstand gibt 0–200 mV bei 0–2 A an Arduino A0. Interne 1,1 V Referenz → ca. 1,08 mV/Digit → 10,8 mA/Digit. Bei >2 A (C>2000) wird D13 HIGH gesetzt → LMD18200 Bremseingang aktiv → Ausgang kurzgeschlossen. Stromwert wird jede Sekunde per Bluetooth an App gesendet.
if (C > 2000) { Serial.println("Over Current"); digitalWrite(13, HIGH); }
void send_c() { if (millis()-lastmillis >= 1000) { bluetooth.write(sensorValue); bluetooth.write('c'); lastmillis = millis(); } }
Schritt 3: Android App
- Kostenlose App: LocoMotive (Google Play)
- Vollversion: LocoMotive DCC (Google Play, £5,99)
- Anleitung für Vollversion beiliegend.
Arduino Code (locomotive_dcc_sep19.ino)
// 1 Sep 2019 // sketch for use with Android App 'Locomotive DCC' using LMD18200 h-bridge
// CV read/write facility added
#include
SoftwareSerial bluetooth(8,9); // RX TX
int C; int sensorValue;
long t=0, lastmillis=0, interval=1000;
String inString;
int a[8];
int preamable_type = 0;
int Address;
float CV_VAL, cv_val, cv_val0, cv_val1, cv_val2, cv_val3, cv_val4, cv_val5, cv_val6, cv_val7;
int test_num, cv_write_val, Cs;
boolean cv_logic, ok;
int num;
#define TIMER_SHORT 0x8D // 58µs
#define TIMER_LONG 0x1B // 116µs
unsigned char last_timer=TIMER_SHORT, flag=0, every_second_isr=0;
#define PREAMBLE 0
#define SEPERATOR 1
#define SENDBYTE 2
unsigned char state=PREAMBLE, preamble_count=16, outbyte=0, cbit=0x80;
unsigned char xdata=0, data=0, data_f=0, data_f1=0, data_f2=0;
int locoAdr = 9;
struct Message { unsigned char data[7]; unsigned char len; };
#define MAXMSG 3
struct Message msg[MAXMSG] = {
{ {0xFF,0,0xFF,0,0,0,0}, 3 }, // Idle
{ {locoAdr,0,0,0,0,0,0}, 3 } // Loco Speed 128 steps
};
int msgIndex=0, byteIndex=0;
void SetupTimer2() {
TCCR2A=0; TCCR2B= (0<=MAXMSG) msgIndex=0; byteIndex=0; }
break;
case SEPERATOR: flag=0; state=SENDBYTE; cbit=0x80; outbyte=msg[msgIndex].data[byteIndex]; break;
case SENDBYTE:
if (outbyte & cbit) flag=1; else flag=0;
cbit >>= 1;
if (cbit==0) {
byteIndex++;
if (byteIndex >= msg[msgIndex].len) {
state=PREAMBLE;
preamble_count = (preamable_type==0)?16:24;
} else state=SEPERATOR;
}
break;
}
if (flag) { latency=TCNT2; TCNT2=latency+TIMER_SHORT; last_timer=TIMER_SHORT; }
else { latency=TCNT2; TCNT2=latency+TIMER_LONG; last_timer=TIMER_LONG; }
}
}
void setup() {
Serial.begin(115200); analogReference(INTERNAL);
pinMode(13,OUTPUT); bluetooth.begin(9600); delay(500);
Serial.println("Bluetooth Started"); bluetooth.println("Bluetooth Started");
DDRD = B01100000; // D5, D6 Output
SetupTimer2();
t=millis(); lastmillis=millis();
digitalWrite(6,LOW); digitalWrite(13,HIGH); // Bridge aus
int get_cv_val = cv_calc(test_num);
}
void current() {
int value=0;
for(int i=0;i<5;i++){ value+=analogRead(A0); delay(1); }
sensorValue=value/5;
C = 10.8 * sensorValue; // mA
if(C>2000){
Serial.println("Over Current"); bluetooth.println("Short!");
digitalWrite(6,LOW); digitalWrite(13,HIGH);
bluetooth.println(C);
}
}
void loop() {
if(bluetooth.available()){ inString=bluetooth.readStringUntil('\n'); Serial.println(inString); }
if(inString.substring(0,1)=="D"){ string(); }
if(inString.substring(0,1)=="C"){ digitalWrite(6,HIGH); digitalWrite(13,LOW); } // Reset nach Überstrom
if(inString.substring(0,1)=="G"){ digitalWrite(6,HIGH); digitalWrite(13,LOW); current(); bluetooth.println(C); } // Stromabfrage
if(inString.substring(0,1)=="A"){ digitalWrite(6,HIGH); digitalWrite(13,LOW); get_cv_data(); cv1_prog(); digitalWrite(6,LOW); digitalWrite(13,HIGH); } // CV1 schreiben
if(inString.substring(0,3)=="get"){ cv_val=0; digitalWrite(6,HIGH); digitalWrite(13,LOW); get_cv_num(); cv_read(); digitalWrite(6,LOW); digitalWrite(13,HIGH); } // CV lesen
if(inString.substring(0,3)=="add"){ cv_write_val=0; digitalWrite(6,HIGH); digitalWrite(13,LOW); get_cv_new_val(); repeat_cv_write(); digitalWrite(6,LOW); digitalWrite(13,HIGH); } // CV schreiben
if(inString.substring(0,1)=="V"){ delay(50); bluetooth.print("CV1 updated"); Serial.println(Address); }
if(inString.substring(0,1)=="E"){ digitalWrite(6,LOW); digitalWrite(13,HIGH); } // Notaus
inString="";
}
// ... (weitere Funktionen: string(), amend_len3/4, assemble_3/4_byte, print_data,
// cv_current, cv_read, cv1_prog, reset_packet, page_preset_packet, cv1_write_packet,
// cv_verify1/0_packet, cv_write_packet, valid_packet, repeat_cv_write, cv_write, cv_calc)
Gehäuse

Schaltpläne
- Bluetooth-Empfänger / H-Brücke Verstärker:
bluetooth_android_dcc_lmd18200_S8NTVsI4LY.fzz - App-Anleitung (PDF)
Herstellungsprozess
- MrRobot: Ubuntu-Mobile-gesteuerter Rapiro-Roboter mit Sprache, Touch & Schüttel-Interaktion
- Arduino-gesteuerte 6-Shot-Getränkemischstation – Bauen Sie Ihren eigenen Cocktail-Automaten
- Arduino Digitaler Würfel: LCD-Würfel mit Zufallszahlen (1–6)
- DIY Arduino USB Gaming Controller – Bauen Sie Ihren eigenen High-Performance Gamepad
- LCD-Animationen & Spiele mit Arduino UNO erstellen
- Intelligente selbstschnürende Schuhe mit integrierter Energiegewinnung
- Echtzeit-Entfernungsmessung mit Arduino Sonar & Processing-Visualisierung
- Pixel Chaser: Interaktives One-Tap-LED-Spiel mit Arduino Nano
- Stufenlose LED-Helligkeitssteuerung mit Bolt IoT und Arduino UNO
- Tragbare Arduino-Wetterstation für 10$ bauen (Nano, DHT22, BMP180 & LCD)