DCC - Selectrix - Kombi - Fahrmodul

Schon meine "alte" Trixzentrale CC2000 konnte ein wenig Mischbetrieb DCC (Lenz) und Selectrix.
Die Einschränkungen sind die 14 Fahrstufen und 64 Lokadressen und 1 Funktion im DCC-Betrieb.

Multi-Protokoll-Zentralen sind meines Wissens bei diversen Herstellern im Programm oder sind
angekündigt ( Rautenhaus MDVR ). Aufwendige Geräte die ihren Preis haben (müssen).

Weil ich ein Freund der kleinen Lösungen bin, habe ich darüber nachgedacht, ob es nicht eine
praktikable Möglichkeit gibt, ein Modul am SX-Bus zu betreiben, das einen Booster unter SX1-
Kontrolle so ansteuert, dass auch DCC-Loks auf dem selben Gleis fahren können.

Die erste Frage war,  wie man die beiden Systeme Selectrix und DCC "unter einen Hut" bringen kann.
Bei Selectrix ist die Abfolge der Adressen und Daten eindeutig definiert. Ebenso der Adressraum
und das Datenformat. DCC hingegen verwendet ein frequenzmoduliertes Gleissignal und sendet
nach diesem Verfahren "Instruktions-Pakete" unterschiedlichster Länge, deren Dauer nicht nur
von der Anzahl der übertragenen Bytes abhängt sondern auch von deren Wert.
Selectrix ist ein taktgesteuertes System und der Takt selbst ist im codierten Datensignal enthalten,
d.h. wird ständig mitgeliefert. Für die Decodierung ist keine exakte Zeitbasis notwendig.
DCC hingegen definiert den logischen Zustand eines Bit's mir der Dauer der eines Impulses mit
zulässigen Toleranzen. NMRA RP 9.1.2 lautet:

2.1.2. Power Station input signal
A Power Station should not alter the signal from its Power Station Interface input to its track
output terminals outside the range of the following:

Ton rising edge delay
Toff falling edge delay
The total skew (Ton) should not exceed 5 micro seconds.
The total distortion (the combination of | Toff minus Ton | ) should not exceed 2 micro seconds.


Damit ist klar, dass das Selectrix Prinzip auf einem gemischten Gleisprotokoll nicht mehr gelten kann.
Also stellt sich sofort die Frage nach dem Timing auf einem "Misch-Gleis" und die Antwort kann nur
sein:
        "Je nach dem!" , oder: "Es kommt darauf an, was gerade notwendig ist!"

Ergo kann nur die Beschränkung auf das Notwendige Ziel führend sein, und das wiederum können
auf dem Gleis höchstens die vorhandenen Loks sein. Mindestens aber die "fahrenden", genauer,
nur diejenigen, die von virtuellen Lokführern gerade gesteuert werden.

Es werden aber nur so viele Lokomotiven aktiv sein können, wie auch Fahrregler vorhanden sind.
Dazu zählen auch die "Software-Fahrregler" in Stellwerksprogrammen, nicht nur "Hardware-Spezi"

Über die Anzahl lässt sich trefflich streiten und für Kinderzimmer, Museum, Club und
Ausstellungen wird sich nicht einmal ein gemeinsames Maximum feststellen lassen.
Ein Dutzend sind für mich schon "eine ganze Menge".

Die Beschränkung auf wenige "aktive" Lokomotiven ist auf einer Privatanlage in jedem Fall zulässig,
denn die Anzahl der "Lokomotivführer" und Fahrdienstleiter ist doch sehr überschaubar, ebenso die
Anzahl der gleichzeitig nutzbaren Strecken.
Dies darf aber der freien Adressbelegung nicht im Wege stehen, denn die Vitrinen-Lok's sollen auch
genutzt werden können, genauso die "Gastlokomotiven" der Freunde.

Gemischtes Gleisprotokoll.

Jeder Decoder "lauert" darauf, in dem Gleissignal seine Adresse zu finden, damit er die dazugehörigen
Daten decodieren kann. Das DCC-Protokoll ist so definiert, dass in einem Informationspaket nur die
Daten für eine Adresse enthalten sind, sofern es sich nicht um sogenannte "Broadcast-befehle" handelt,
die an "Alle" gehen.

Der Selectrixerfinder hat sich da etwas anders ausgedacht und "versteckt" in jedem der 16 Grundrahmen
jeweils die Datenbytes für 7 Adressen. Diese Adressnummern sind aber nicht aufeinanderfolgende,
sondern steigen um 16. D.h. im Grundrahmen mit der Nummer "0" werden  die Datenbytes der
Adressen 00, 16, 32, 48, 64, 80 und 96 gesendet. Die Bitfolge ist insgesamt 96 Bit lang und hat eine
Sendedauer von nominal 4,8 Millisekunden. Die 16 Grundrahmen für alle SX1 Adressen sind also
innerhalb 76,8 Millisekunden ausgegeben, was die Selectrix Refresh-Rate von ca. 13 pro Sekunde
für 112  Adressen ergibt. Das ist "fein schnell" und seit jeher ein wichtiges Argument der Selectrix-
Anhänger und Betreiber. Der PX-Bus, so nennt sich die Gleiscodierung des SX1-Datenstroms, ist dabei
immer bitsynchron zum SX-Bus, was nicht verwundert, weil es ja das identische Signal ist, nur elektrisch
anders codiert.
Für den PX-Decoder bedeutet das, dass er sich aus dem Bitstrom für 7 Adressen seine Information
herauspicken muss. Das gelingt mit simplem Abzählen der empfangenen Bit nach erkannter
Grundrahmenadresse.

Die Betriebssicherheit der digital gesteuerten Lok's ist unter anderem umso höher, je öfter die
Information empfangen wird. Das ist besonders bei "fahrenden" Decodern wichtig, weil ständig
Kontaktschwierigkeiten im System Schiene, Rad, Schleifer auftreten können. Verstümmelte Daten-
ströme sind die Folge. Um Fehlinterpretationen besser ausschließen zu können gibt es im DCC-
System nicht nur die "ellenlange" Präambel von mehr als 12 1-Bit, sondern zwischen den Bytes ein
Synchron 0-Bit und das abschließende 1-Bit.
Ein PX Decoder hat bestenfalls die Chance die Anzahl der Bit zwischen den Synchronzeichen zu
prüfen. Das kann der Grund dafür sein, dass ein Selectrix D&H Decoder einen singulären Grundrahmen
nicht akzeptiert, im Gegensatz zum DCC-Decoder.

Der wesentliche Nachteil des DCC-Systems ist, dass nur das Protokoll auf dem Gleis definiert ist, was
ursprünglich richtig war, denn man wollte "Fahren". Natürlich kann auch ein stationärer Decoder seine
Daten finden und damit Weichen und Sonstiges steuern. Und schon bekommt auch eine mittelgroße
Modellbahn ein Refreshproblem, und die Lastabhängigkeit ( und die Datenabhängigkeit ) des DCC-
Prinzips schlägt sich in langen Reaktionszeiten nieder.
Eine weitere Eigenschaft des DCC-Protokolls ist die datentechnische "Einbahnstraße" ( bis jetzt noch ),
was dazu führt, dass man einen separaten "Meldebus" braucht, der im günstigeren Fall auch "Schaltbus"
sein sollte.

Wenn ein solches Bussystem vorhanden ist, gibt es keinen Grund, Schaltdecoder am Gleis anzuschließen,
die bei Kurzschluss oder NotAus nichts mehr tun können, außer warten.
Nur Fahren mit DCC-Decodern, besonders mit den modernen Alleskönnern, ist aber mehr als eine
Alternative zu den Selectrix-Decodern und mit weniger als einem Dutzend aktiv gesteuerter Lok's sogar
ein Vorteil bezüglich der Refresh-Rate, wenn die Zentrale nur diese bedient. Auch hiefür gibt es
"intelligente, dynamische" Systeme mit so schlauen Features wie automatische Priorität der Ausgabe u.Ä.
Und schon sind Sound und 1024 CV's Teil des "Spiels". Mit der feinen Möglichkeit der Programmierung
auf dem Hauptgleis ( PoM ) "on the fly".


Der Fahrregler,

ist oft ein mobiles Gerät, das an der Anlage dort angesteckt wird, wo man die Lok, die man steuert, auch
sehen kann. Elegant ist es, wenn man für jede aktive Lok ein eigenes, zugeordnetes, Bediengerät hat.

So verstehe ich zumindest das Prinzip der FREMO mit ihren FRED's ( FRemos Einfacher Drehregler) und
Loconet mit den Mäusen.

Wie und Wer, Wo, Was, Wem zuordnet ist vielfältig ausführbar und ich kenne keines dieser Systeme.


Mein SX-PX-DCC Kombi Fahrmodul

ist eine Hilfs-Fahrzentrale am SX-Bus die einen Booster ansteuert der ein beliebiges Wechselspannungs
Fahrsignal für das Gleis erzeugen kann. Die Steuerleitungen sind rasch definiert, weil sie sich an der üblich
verwendeten Motor-Vollbrücke orientieren:

    GL 0    schaltet den Brückenzweig für das rote Gleis,
    GL 1    schaltet den Brückenzweig für das blaue Gleis,
    ENA    Brücke Ein-Aus
    GND    System-Masse

Nach der Standardlogik sind alle Brückentransistoren aus, wenn ENA == log. Aus, oder die Steuersignale
gleichen Logikpegel haben.
Damit kann sowohl das PX-Signal erzeugt werden, bei dem zur Taktrückgewinnung der "Alle Aus" Zustand
im Betrieb während dem 10 uSek Takt nötig ist, als auch DCC und das MM Format, die nur + und - brauchen.

Ein Selectrix-Booster kann das immer, ein für DCC entwickelter nicht selbstverständlich.

Die Informationszentrale ist und bleibt ein SX1-Gerät, weil auf diesem Bus alle Kommandos und Meldungen
ausgeführt werden.
Das Fahrmodul muss also zumindest alle Adressen lesen und zwischenspeichern können. Zur Kommunikation
mit einem "übergeordneten" PC habe ich eine RS232-Schnittstelle vorgesehen, die nicht unbedingt die SX1
Interfacenorm zu erfüllen braucht. Ein evt. vorhandenes Stellwerk und Fahrprogramm kommuniziert mit der
Sx1-Zentrale und nicht direkt mit dem Fahrmodul.

Die notwendige Hardware ist minimal und entspricht im Umfang meiner Mini-Zentrale. Die Schaltung ist fast
identisch.


Die Adressvergabe und Verwaltung

In jedem Fall und für jedes Protokoll muss das Fahrmodul die physikalischen Adressen auf dem Gleissignal
erzeugen. Das gilt für SX und für DCC gleichermaßen. Wie oben erläutert ist jede Adresse der DCC-Decoder
gleichwertig und ohne Nachteile verwendbar, weil sie auf dem SX-Bus nicht direkt verwendet werden.
Die DCC-Decoder benötigen eine SX-Pseudoadresse und eine Zuweisungstabelle.

Für die Vergabe der SX-Lokadressen ist es notwendig die Adress-Struktur zu beachten wenn das Fahrmodul
vorteilhaft arbeiten soll. Im günstigsten Fall sind alle SX-Adressen in einem SX-Grundrahmen enthalten. Der
schlechteste und zeitlich ungünstigste Fall sind 16 aktive SX-Lokomotiven mit aufeinanderfolgenden Adressen,
weil dann alle SX-Grundrahmen gesendet werden müssen. Multi-Protokoll-Decoder sollte man im DCC-Mode
betreiben.

Eine Hobbyanlage mit mehr als 8 Fahrreglern, die gleichzeitig belegt und aktiv sind, kann ich mir nur schwer
vorstellen, selbst bei 18 tlg. Lokschuppen und 20 Schattenbahnhofsgleisen. Der anspruchsvolle "Normal-
modellbahner" braucht evt. im BW zwei, im Rangierbahnhof weitere zwei plus noch mal vier für die Strecken
aber nur wenn er 8 Hände und genügend viele Augen hat. Im Automatikbetrieb ist das weniger kritisch, weil
ohne Fahrpulte und mit Verbindung zum Fahrmodul.


Die Fahrmodulbedienung

erfolgt über programmierbare Fahrpulte oder mit dem PC via COM-Schnittstelle. Als Fahrpult ist natürlich auch
jedes Universal-SX-Handgerät verwendbar, denn die Kommandos laufen ja über den SX-Bus auf irgendwelchen
Adressen mit Bit's irgendwelcher Bedeutung. Adresschaos und Fehlschaltungen werden sich kaum vermeiden
lassen.
Deshalb ist ein Standard-Fahrpult wünschenswert, dem Dieter Sekunde den Arbeitstitel "SEPP" gegeben
hat. Da kommt man als Bayer  ins Schmunzeln und freut sich über das:

     "SX-fähige, Einfach Programmierbare, Fahr-Pult".

Die Minimal-Version hat einen Drehregler und eine Taste zur Fahrtrichtungsumkehr. Wie einst im Mai, Opa's
Märklin-Trafo. Das ist dann heutzutage ein Impulsgeber mit Taste und dem Mikro, der auf den SX-Bus schreibt.
Für den Hobby-Elektroniker, 5€ Bauteile plus Plastikschachtel und Kabel. Ein echter "Spar-Sepp"!

Als Prototyp habe ich das Mini-Fahrpult entwickelt, mit Drehimpulsgeber und Taste, eine LCD Anzeige 2 x 16 Zch.
und 2 Doppel-Tastschaltern.das ganze in einem Etuigehäuse 130 x 40 x 26 mm klein. Dem Bedientwerg habe ich
einen eigenen Aufsatz spendiert.

Prinzipiell ist eine die Adress- und Funktionszuweisung an ein Fahrpult nicht notwendig, denn erst das Fahrmodul
ordnet die Fahrkommandos, Geschwindigkeit, Richtung usw. den physikalischen Decoderadressen zu und setzt
die Funktionsbit entsprechen um. Es ist also ausreichend, wenn das Fahrmodul die SX-Adresse jedes Fahr-
pultes kennt. Am simpelsten funktioniert das mit fixen Adressen, die frei wählbar sind.


Die Pseudoadressen sind keine Busadressen, sondern geben den Index für die Liste an, aus der die Fahr-
modulsoftware die pysikalische Decoderadresse und den Typ liest.


Die Software im Fahrmodul

Wieder ist der Rechenzwerg ein Atmel Mega8 den ich aber für diese Anwendung mit 16 MHz und Quarz betreibe
um die Impulszeiten für das DCC-Protokoll genau und mit geringem Jitter erzeugen zu können.

Ohne SX1-Bus kann das Modul aber nicht arbeiten, denn der SX-Takt wird auch für die Erzeugung des PX-Gleis-
Signales verwendet. Das Lesen aller SX1-Adressen geschieht interruptgesteuert, die Daten werden im SX-Timing
ständig aktualisiert und zwischengespeichert.

Synchronisierung zum SX-Datenstrom

Die ersten 12 Bit eines jeden Grundrahmens enthält 3 aufeinanderfolgende 0-Bit eingerahmt von 2 1-Bit. Mit
steigender Taktflanke wird der logische Zustand der Datenleitung in ein Schieberegister übernommen. ( Int 16)

sytes = (unsigned char)(sync >> 8);          // Im oberen Byte stehen Sync-Bits
sytes &= 0x1F;                                        
// Die unteren 5 gelten 1 0 0 0 1 = Sync

if (sytes == 0x11)
                                    // Sync ok., Gruppenadresse testen

Wenn der Decoder das Muster "10001" im oberen Byte erkennt, ist die Synchronisierung gegeben, und die
Gruppenadresse kann aus dem unteren Byte decodiert werden:

temp = sync >> 1;                     // x g t a3 a2 t a1 a0
adrdat = temp & 3;                  
// 0 0 0 0 0 0 a1 a0
temp = temp >> 1;                   
// x x g t a3 a2 t a1
temp = temp & 0b00001100;
    // 0 0 0 0 a3 a2 0 0
adrdat |= temp;
                        // 0 0 0 0 a3 a2 a1 a0
lesadr = adrdat ^ 0X0F;
            // Adresse invertiert
lescnt = 84;
                             // 84 Bit des Grundrahmen lesen
                                               // Lesebeginn im nächsten Takt

Nach SX-Definition wird die Gruppenadresse invertiert gesendet. Nach den 12 Bit Synchron-Adress-Bit folgen
die 7 Datenbytes in Tripelbit-Codierung. D.h. jedes 3. Bit ist ein 1-Bit, so dass immer 12 Bit 1 Byte darstellen.
Der Bitzähler muss also zum Lesestart auf 7 x 12 = 84 gestellt werden.

Das Auslesen der Daten beginnt mit dem nächsten Interrupt :

sync = (sync << 1);             // Schieberegister Daten
if (PIND & 16) sync |= 1;   
// Datenleitung übernehmen

if (lescnt)
                          // Solange Bitzähler != 0
{
if (lescnt == 84)                
// Das 1. gelesene Byte
{
ua_les = 0;
testbit = 1;
leserg = 0;                        
// Zwischenspeicher Byte
trecnt = 2;                        
// Trennbitzähler
}
else if (lescnt == 72)
{
sx_dat[ua_les*16+lesadr]=leserg;
// 1. Byte speichern
ua_les = 1;
testbit = 1;
leserg = 0;
}
else if (lescnt == 60)

Mit dem ersten Statement wird das Schieberegister um 1 Stelle nach links geschoben, Bit 0 ist danach "0"
und wird auf "1" gestellt wenn die Datenleitung log. Hi Pegel hat.

In einer switch-case ähnlichen Struktur wird der Lesezähler auf Bytestart geprüft, d.h. bei 84, 72, 60, 48, 36,
24, 12 und 0 wird das Bytelesen neu gestartet und das vorher gescannte Byte abgelegt.

if (trecnt)             // kein Trennbit
{
if( PIND & 16)
    // Datenleitung Hi ?
leserg |= testbit;

testbit <<= 1;
lescnt --;
trecnt --;
if (lescnt == 1)
sx_dat[ua_les*16+lesadr]=leserg;
}
else
{
lescnt --;
trecnt = 2;
}

Die Trennbits werden mit Hilfe des Trennbit-Counters ignoriert. Bei Bitzählerstand "1"   ist das letzte Bit von
Byte 7 schon ausgewertet und kann in das Array sx_dat[lesadr] übernommen werden.


PX-Gleisignal erzeugen

Dazu sind nur wenige Instruktionen bei steigender Taktflanke nötig:

if( px_run)                                     // Px-Signal erzeugen, im 40 uSek. Taktsignal?
{
    if( t0_stat == 3)                         
// sende 0 == alter Zustand
    {
        if(px_alt & 8) PORTB |= 8;
    // PX0 wieder ein
            else PORTB &= ~8;
        if(px_alt & 16) PORTB |= 16;
// PX1 wieder ein
            else PORTB &= ~16;
        t0_stat = 1;                            
// Bit gesendet
    }

    else if( t0_stat == 4)                    
// sende 1 == PX-toggle
    {
        if(px_alt & 8) PORTB &= ~8;
    // PX0 aus
            else PORTB |= 8;
        if(px_alt & 16) PORTB &= ~16;
// PX1 aus
            else PORTB |= 16;
        t0_stat = 1;
                                // Bit gesendet
    }
}

Die Regel ist denkbar einfach: Log. "0" alten Zustand lassen bzw. wieder herstellen,
                                                     lolg.  "1" Steuersignale zum Booster "toggeln".
Während dem 10 uSek.  Takt sind beide Signale auf log. "0".
'
else
if (!(PIND & 8))         // HI-Lo Flanke, Start 10 uSek.
{
    if( px_run)                
    // PX-Signal erzeuegen ?
    {
        px_alt = PINB & 24;
// PB3 = 8 PB4 = 16
        PORTB &= ~24;     
// Im Takt beide aus
        t0_stat = 2;              
// Takt Lo läuft
    }
}
// Ende Lo-Takt

Fertig ist das PX-Protokoll !!

Die Erzeugung des DCC-Protkolls habe ich in einem eigenen "Aufsatz" beschrieben.
Die Programmfragmente stammen alle aus meinem Testprogramm.


Die Kommunikation mit dem PC-Programm

wird via COM-Schnittstelle abgewickelt. Für den Dialog mit dem Fahrmodul musste ich nicht
auf die SX-Interface Kompatibilität achten und verwende ein Multi-Byte-Telegramm mit
variabler Länge und Binärdaten. Das letzte gesendete Byte eines Telegramms ist die 255,
d.h. die 255 darf nicht als Wert vorkommen. Sollte man diesen aber "unbedingt" brauchen,
gibt es den "work around" mit einem Spezialkommando : "Der zu verwendende Wert ist 255".
Das geht dann mit jeder noch freien Kommando-Nummer!

Die Kommando-Nummer ist das vorletzte Byte und das Fahrmodul weiß, per Definition der
Kommandos, wie viele Datenbytes dazugehören und bereits gesendet wurden.


Der Empfangs-Interrupt des UART- ist freigegeben und jedes empfangene Zeichen wandert
in das Zeichen Schieberegister-Array e_val[ ]:

empzch = UDR;         // Neues Zeichen
e_val[5] = e_val[4];    
// Zeichen Schieberegister
e_val[4] = e_val[3];
e_val[3] = e_val[2];    
// Wert
e_val[2] = e_val[1];    
// Listenplatz
e_val[1] = e_val[0];    
// Kommando
e_val[0] = empzch;    
// Letztes Zeichen

if ( empzch == 255)    
// Telegrammende
{
    switch (e_val[1])        
// Kommando
    {
        case 1:
                       // Fahrbefehl speed

Wenn in e_val[0] die 255 steht kann das Kommando in e_val[1] mit einer switch-case-Struktur
bequem ausgewertet werden. Zweckmäßig ist es, das häufigste Kommando als erstes zu "casen".
In meinem Testprogramm ist es die "speed" der aktiven DCC-Lok.

Weil das PC-Programm während des Betriebes nicht gestartet sein muss, kann das Fahrmodul
auf Anfrage Daten an den PC senden. Auf Anfrage ist wichtig, damit das Fahrmodul immer "Slave"
ist und nicht "ins Leere" sendet. Master ist der Fahrdienstleiter am PC, der auch vom schwachen
Geschlecht sein darf!

Die physikalischen Decoderadressen stehen im Array " dcc_adre[ ]", das im Testprogramm nur
3 Werte beinhaltet.
Mit Kommando 16 werden die Adressen zugewiesen:

case 16:
    if (e_val[2] < 3)
    dcc_adr[e_val[2]] = e_val[3];
        // Physikalische Adr. eintragen.
    break;

Die Erweiterung auf weitere Dimensionen für Typ und Eigenschaften ist eine einfache Übung.
Für den reinen Fahrbetrieb ist wahrscheinlich nur die Unterscheidung SX und DCC notwendig,
weil die wichtigen Funktionen NMRA-konform belegt sein sollten.

Die Fahrpulte gehören nach meinem Entwurf zu einem fixen Index im Adressarray. Mit diesem Index
findet das Fahrmodul nicht nur die physikalische Adresse in "dcc_adre" sondern auch in "dcc_speed"
das aktuelle Fahrbyte und in "dcc_bits" die Funktionsbefehle. Auch diese Struktur ist leicht erweiterbar.

Die Fahrfunktion im Fahrmodul

arbeitet die vorgesehenen Protokolle bzw. die dazugehörigen Listen in do-Schleifen ab.
Hierzu gehört auch die Übernahme der Daten aus dem SX-Zwischen-Memory in die entsprechenden
Listenfelder.

Nach Vorbereitung der DCC Instruktionsbytes werden die Pakete gesendet. Das Prinzip ist leicht
erkennbar am Beispiel des einfachsten DCC-Fahrkommandos für drei Decoder  mit den
Pseudoadressen 0, 1, und 2 . Die Fahrpultadressen sind im Array "sepp[ ]" hinterlegt. Mit gleichem
Index steht im Array "sepp_index[ ]" der vorberechnete Offset in das SX-Lesedatenfeld "sx_dat[ ]".


Ablauf DCC-Decoder:

1. SEPP oder SX-Handgerät oder Fahrsoftware schreibt auf der Fixadresse (z.B. 10) den gewünschten
    Fahrwert in Selectrix-Format, d.h. Bit 0 bis Bit 4 die Fahrstufe ( 0 für Stop, 31 für V-max ), Bit 5
    bestimmt Richtung, Bit 6 und 7 Funktionen für Licht und Horn.
    Die SEPP-Adresse "0" steht für nicht vorhanden bzw. inaktiv und wird via PC-Programm gesetzt.
2. V-Wert aus Datenfeld holen, und obere 3 Bit löschen um den Index in die DCC-Fahrtabelle zu
    bilden.
3. DCC Fahrstufe im 28 FS-Mode nach Byte2 im DCC-Paket übernehmen.
4. Richtungsbit und Fahrkommando übernehmen.
5. Funktionsbit in DCC-Funktions-Instruktion übernehmen ( im Testprogramm nicht eingabaut )

for (dcc_bus = 0; dcc_bus < 3; dcc_bus++)         // Nur 3 Adr. 28 FS Mode.
{
    dcc_byte1 = dcc_adr[dcc_bus];
                     // Phys. DCC Adresse bereitstellen

    if
( sepp[dcc_bus] )
                                        // wenn ungleich 0, SEPP aktiv
    {
        sepp_v = sx_dat[sepp_index[dcc_bus]];
        sepp_v1 = sepp_v & 0x1F;                        
// speed o. D = index in speedtabelle

        dcc_byte2 = dcc_speed[sepp_v1];
            // DCC Speedwert o. Richtung
        if ( sepp_v & 32 )                                    
// Richtung von SEPP
            dcc_byte2 |= 32+64;
                            // Richtungsbit dazu u. Kom.
        else
            dcc_byte2 |= 64;                                    
// Kommando 01 in Bit 7,6
    }
    else
        dcc_byte2 = dcc_speed[dcc_bus];                
// V-byte bereitstellen



Ablauf SX-Decoder:

Auf dem PX-Bus werden ausgewählte Grundrahmen ausgegeben. Im Testprogramm sieht die Schleife
so aus:

for (px_adr = 5; px_adr < 7; px_adr++)
{
    busbyte = sx_sync[px_adr]>>8;    
// Sync u. Gruppe 1. Byte
    bustest = 128;
    for (i=0; i<8; i++)
    {
        while (t0_stat != 2)
            ;
                                                // Warten auf Takt LO Ende
        if(busbyte & bustest) t0_stat = 4;
    // 1 senden == toggle
            else t0_stat = 3;
                          // 0 senden
        bustest >>= 1;
    }

    bustest = 128;
    busbyte = sx_sync[px_adr] & 0xFF;    
// Sync u.Gruppe 2. Byte
    for (i=0; i<4; i++)                               
// obere 4 Bit
    {
        while (t0_stat != 2)
            ;
// Warten auf Takt LO Ende
        if(busbyte & bustest) t0_stat = 4;        
// 1 senden == toggle
            else t0_stat = 3;
                            // 0 senden
        bustest >>= 1;
    }

    for( index = 0; index < 97; index+=16)
    {
        busbyte = sx_dat[px_adr + index];    
// Datenbyte senden
        bustest = 1;
        t_cnt = 0;
        for (i=0; i<12; i++)
        {
            while (t0_stat != 2)
                    ;                
// Warten auf Takt LO Ende
            if (t_cnt < 2)
            {
                if(busbyte & bustest) t0_stat = 4;
    // 1 senden == toggle
                    else t0_stat = 3;                        
// 0 senden
                bustest <<= 1;
                t_cnt++;
            }
            else
            {
                t_cnt = 0;
                t0_stat = 4;                                
// Trennbit = 1 Senden
            }
        }
// Ende 12 Bit senden
    }
// Ende 7 Byte senden
}
for (i=0; i<4; i++)                                        
// Nachlauf 4 x 0-Bit
{
    while (t0_stat != 2)
        ;
// Warten auf Takt LO Ende
    t0_stat = 3;                                            
// 1 senden == toggle
}

t0_stat = 0;
px_run = 0;                                                
// PX-Erzeugung Stop

Mit den Flags in "t0_stat" wird die Ausgabe im Interrupt gesteuert.
Und schon fahren die Selectrix-Lokomotiven gemeinsam mit den DCC-Brüdern und Schwestern!

Mal sehen was sich aus diesem Konzept ergibt, wenn sich erfahrene Anlagenbauer mit dieser
relativ simplen Lösung befassen. Mein Testziel habe ich zumindest erreicht. Multi-Protokoll-Fahren
mit Minimalaufwand am SX-Bus.

Hardware, Testaufbau

Der Aufwand ist gering. Das Fahrmodul-Programm läuft auf der Hardware der SX-Px-MiniZentrale
in der neuen Version mit Quarz und MÜT SX1 Steckern. Der Quarz muss aber 16 Mhz haben damit
das NMRA-Timing bezüglich Jitter eingehalten wird.
Die DCC-Lesefunktion ist auf einem Fahrmodul nicht brauchbar, d.h. der Selectrix-Booster muss
nicht umgebaut werden und kann direkt an der PX-Buchse angeschlossen werden.


Das Testprogramm hat diese Bedienoberfläche:




und beinhaltet auch die Erprobung der DCC Programmiermethode PoM
auf dem Gleis, als "beigemischte" DCC-Pakete im Fahrmodus.


Funktion und Bedienung DCC-Testprogramm

Das Programm ist eine C# - .NET Windows-Anwendung. Man braucht keine Installation, des .exe
File kann direkt gestartet werden. .Net2 oder höher muss auf dem PC installiert sein.

Dafür gibt es eine eigene Beschreibung: Anleitung Fahren

Zu diesem Projekt gehört auch das "Mini-Fahrpult" : Mini-Fahrpult

Fazit:

Ob meine Idee mit dem Fahrmodul eine Modelleisenbahn funktionell bereichert, kann ich nicht
beurteilen. Wenn aber auf einer Selectrix SX1-Anlage auch DCC-Lokomotiven fahren sollen
bietet sich für den Hobbyelektroniker ein preiswerter und interessanter Versuch an.


Jonathan Bohmer, im April 2009

Hier die Dateien mit Stand 02.07.09: FAHR_MODUL.zip