Forum: Mikrocontroller und Digitale Elektronik DCC Dekoder mit AtTiny45


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Michael (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hallo an alle,

ich hab schon einiges zu dem ganzen gelesen und auch hier im Forum viele 
Beiträge dazu gesehen aber mein Problem ist vermutlich anders gelagert 
und ich bin noch zu unerfahren als dass ich es hinbekommen.

Ich habe es bereits erreicht, dass ich den uC(AtTiny45) "am Gleis" 
sprich über Gleichrichter, Glättung und Festspannungsregler an die 
Gleisspannung (H0) anschließen kann.
Doch wenn es nun um das Messen des Digitalen Signales geht bin ich etwas 
überfordert. Ich komme aus der informatischen Richtung also ist der 
Source-Code erstmal nicht das Problem viel mehr die Frage wie kann ich 
überhaupt die Flankenwechsel mit dem uC messen bzw. welche Bauteile 
müssen noch zwischen Gleis(wechsel)spannung und Eingangs-Pin damit der 
uC nicht gleich gegrillt wird.

Michael

von Trumper (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bei www.opendcc.de findest Du sicher ein paar Anregungen.

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Ich komme aus der informatischen Richtung also ist der
> Source-Code erstmal nicht das Problem viel mehr die Frage wie kann ich
> überhaupt die Flankenwechsel mit dem uC messen bzw. welche Bauteile
> müssen noch zwischen Gleis(wechsel)spannung und Eingangs-Pin damit der
> uC nicht gleich gegrillt wird.

Du musst prüfen welche Spannungen dein System ausgibt und mit welcher 
Spannung dein µC läuft. Dazwischen musst du dann einen Pegelwandler 
schalten. Im einfachsten Fall kann das ein ohmischer Spannungsteiler 
sein.
Einen Flankenwechsel kann man mit den AVRs (und auch mit anderen µCs) 
leicht erfassen, bei den AVRs kann man für jeden IO-Pin einen Interrupt 
einstellen der sich Pin-Change-Interrupt nennt, damit bekommt man jeden 
Flankenwechsel hin.
Dann gibt es noch beim ein und anderen AVR den ein und anderen externen 
Interrupt, damit kann man auch gezielt auf steigende oder fallende 
Flanken triggern, beim oben erwähnten Pin-Change-Interrupt muss man im 
Interrupt schaun ob es eine steigende oder fallende Flanke war. Das 
macht man einfach damit, dass man sich den Pegel des entsprechenden Pins 
im Interrupt anschaut.

: Bearbeitet durch User
von Christian M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> wie kann ich überhaupt die Flankenwechsel mit dem uC messen

Ich habe bei meinen Dekodern immer problemlos diese Schaltung verwendet:

http://www.digital-bahn.de/shop/media/pdf/weichzwei_1v04_schaltplan.pdf

Ist zwar für PIC, aber die HW ist ähnlich.

M. K. schrieb:
> damit kann man auch gezielt auf steigende oder fallende Flanken triggern

Für die DCC-dekodierung reicht das auch!

Gruss Chregu

von Michael (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal für die antworten.

Ich hab mir jetzt mal den Schaltplan angesehen und dazu einige Fragen.

1. Warum die 47pF zwischen dem "Datenstrom" und GND.

2. Gehe ich recht in der Annahme das auf der Beschriftung des 12F629-SN 
VDD die Versorgungsspannung und VSS GND ist??

3. Für was ist die ganze Schaltung hinter dem IC1 da?

Michael

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
1
#define DCCPIN PIND
2
#define DCCPORT PORTD
3
#define DCCBIT 2
4
#define TRACKLEVEL  (!!(DCCPIN & (1 << DCCBIT)))
5
#define DCCSYNC 12
6
7
ISR(INT0_vect)
8
{
9
   TrackData = 1;
10
   GTCCR |= (1 << TSM) | (1 << PSRASY);
11
   TCNT2 = 0;
12
   TIFR2 = TIFR2;
13
   GTCCR &= ~(1 << TSM);
14
}
15
16
ISR(TIMER2_COMPA_vect)
17
{
18
   static unsigned char state = 0;
19
   static unsigned char syncct = 0;
20
   static unsigned char bitmask = 0;
21
   static unsigned char byteind = 0;
22
   static unsigned char xor = 0;
23
   static unsigned char data[8] = {0};
24
25
   if(TrackData)
26
   {
27
      TrackData = 0;
28
29
      if(!TRACKLEVEL)         //Synchronisation
30
      {
31
         if(syncct < DCCSYNC) syncct++; else state = 0;
32
      }
33
      else                    //Paketstart
34
      {
35
         if(!state && (syncct == DCCSYNC)) state = 1;
36
         syncct = 0;
37
      }
38
39
      switch(state)
40
      {
41
         case 1:              //Beginn Datenempfang
42
            bitmask = 0x80;
43
            byteind = 0;
44
            xor = 0;
45
            state = 2;
46
            break;
47
48
         case 2:              //Daten
49
            if(!TRACKLEVEL) data[byteind] |= bitmask; else data[byteind] &= ~bitmask;
50
            bitmask >>= 1;
51
            if(!bitmask)
52
            {
53
               xor ^= data[byteind++];
54
               if(byteind == sizeof(data))
55
               {
56
                  state = 0;
57
                  syncct = 0;
58
               }
59
               else
60
               {
61
                  bitmask = 0x80;
62
                  state = 3;
63
               }
64
            }
65
            break;
66
67
         case 3:
68
            if(!TRACKLEVEL)      //Paketende
69
            {
70
               if(!xor)
71
               {
72
                  //Auswertung der empfangenen Daten
73
                  //Adresse steht in data[0] 
74
                  //bzw. in data[0] und data[1] bei
75
                  //langen Adressen
76
               }
77
               state = 0;
78
               syncct = 1;              
79
            }
80
            else state = 2; //Startbit f. naechstes Datenbyte
81
      }
82
   }
83
}

Das ist meine Version für den Atmega48...328. Es wird Timer2 verwendet. 
Das Programm lässt sich einfach an einen anderen 8-Bit-Timer oder einen 
anderen externen Interrupt anpassen.

Der Timer läuft mit einer Frequenz von 15KHz. F_CPU sollte >= 8MHz sein. 
Die Verwendung des internen Oszillators ist problemlos. Der INT0 
arbeitet mit steigender Flanke.

Als "Eingangsbeschaltung" am DCC Pin reicht auch ein Widerstand mit 4K7. 
Etwas "sauberer" ist ein Transistor als OC, der den internen Pullup des 
Ports zieht. Auf welcher Gleisseite dieser angeklemmt wird, ist egal.

Der Dekoder läuft auf allen AVR, inkl. Attiny13.

: Bearbeitet durch User
von Michael (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Etwas "sauberer" ist ein Transistor als OC, der den internen Pullup des
> Ports zieht.

Was meinst du damit genau?
Zunächst für was steht OC kann mir das grade nicht ableiten.

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Zunächst für was steht OC

Open Collector. Das ist DIE Grundschaltung für Schalttransistoren.

von Toralf W. (willi)


Bewertung
1 lesenswert
nicht lesenswert
Abend,

hier: http://www.opencarsystem.de/dcc_decoder/t85/t85.html
ist meine Version von einem DCC Decoder zu finden. Der ist auf möglichst 
wenige Bauteile getrimmt.

DCC Empfang auf dem Gleis nur mit dem Pin-Change-Interrupt halte ich 
allerdings für zu störanfällig. Der Rad / Schiene Kontakt bei einem 
Lokdecoder erzeugt einfach zu viel ungewollte Flanken.

Bei fest verdrahteten Zubehör Dekoder sieht das schon wieder anders aus. 
Der Wolfgang Kufer von OpenDCC hat dazu hier etwas geschrieben:
http://www.opendcc.de/elektronik/opendecoder/opendecoder_sw_dcc.html

LG Willi

von Christian M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Toralf W. schrieb:
> DCC Empfang auf dem Gleis nur mit dem Pin-Change-Interrupt halte ich
> allerdings für zu störanfällig. Der Rad / Schiene Kontakt bei einem
> Lokdecoder erzeugt einfach zu viel ungewollte Flanken.

Ich bin jetzt einfach mal davon ausgegangen, dass nach Verwerfen solcher 
Pakete noch genügend "Gute" durchkommen...

Michael schrieb:
> Warum die 47pF zwischen dem "Datenstrom" und GND.

Warscheinlich deswegen auch.

Michael schrieb:
> Für was ist die ganze Schaltung hinter dem IC1 da?

Das solltest Du nicht so genau anschauen, ist ein bisschen Murks. Ist 
zum Verstärken des Signals da, und für das Decoder-Typische 
OC-Verhalten.

Gruss Chregu

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Toralf W. schrieb:
> DCC Empfang auf dem Gleis nur mit dem Pin-Change-Interrupt halte ich
> allerdings für zu störanfällig. Der Rad / Schiene Kontakt bei einem
> Lokdecoder erzeugt einfach zu viel ungewollte Flanken.

Ich verwende die einfache Interrupt-Auswertung auch nur für 
Beleuchtungsdekoder. Dabei spielt es eine untergeordnete Rolle, wenn der 
Dekoder nicht sofort reagiert. Es ist ein Unterschied, ob das Licht im 
Waggon manchmal mit einer kleinen Verzögerung an oder aus geht oder ob 
die Lok im Kopfbahnhof über den Querbahnsteig ins Bahnhofsgebäude 
durchbrettert.

Bei den Fahrdekodern vertraue ich auf die Industrie. Allerdings sieht 
dein Lokdekoder recht interessant aus. Wenn ich mal Zeit und Lust habe, 
werde ich mir den vielleicht mal vornehmen.

von Michael (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Erstmal danke für die weiteren Tipps.

Der Dekoder den ich mir da konstruieren will soll nicht für die Lok 
selbst sondern für Signale/Weichen und sowas sein.

Spielt der Lok/Schiene Kontakt auch mich rein? Kann das nicht unbedingt 
abschätzen.

Ich persönlich würde einfach nach ein PCINT mit einer Taktung von etwa 
10-20 µs den Pin Status über Timer Compare Matches prüfen und dadurch 
die "fehlerhaften" Flanken versuchen 'rauszulöschen'

Michael

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Der Dekoder den ich mir da konstruieren will soll nicht für die Lok
> selbst sondern für Signale/Weichen und sowas sein.

Also eine gekabelte Verbindung. Somit gibt gibt es auch keinen 
Rad-Schiene-Übergang mit all seinen Problemchen. Da reicht der von mir 
gezeigte Einfachdekoder vollkommen aus, um hundertprozentig zu erkennen.

Nach einer Flanke wird 75µs später geguckt, ob der Pegel gewechselt hat. 
Hat er sich geändert, hast du eine 1 empfangen, ist er gleich eben eine 
0. Wenn du statt des Pinchange-Interrupt den INTx nimmst, ersparst du 
dir einigen Aufwand, da diese entweder auf positive oder auf negative 
Flanke triggern können. Denn du benötigst nur die eine Flanke. Im 
Gegensatz zum Pinchange, der immer bei beiden Flanken triggert und du 
jeden zweiten Interrupt verwerfen mußt.

von Michael (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Wenn du statt des Pinchange-Interrupt den INTx nimmst, ersparst du
> dir einigen Aufwand, da diese entweder auf positive oder auf negative
> Flanke triggern können.

Aber ist es dann nicht so, dass ich Signale "verpasse"?

Angenommen ich trigger im µC auf positive Flanken.
DCC sendet seine Date unabhängig ob nun + oder - die 'Startflanke' ist.

Wenn ich dann doch noch vor dem senden des Signals positiv anliegen hab 
und dann das Signal losgeschickt wird und auf negativ gewechselt wird 
dann verpasse ich doch das erste Bit weil zu spät angefangen wird zu 
messen oder?

Nebenbei es treten ja auch Wechsel auf die gar keine DCC-Signale sind 
also muss ich ja auch noch weiter messen als zwei mal?!

Michael

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Das ist eine 1: ____----

Das auch: ----____

Das ist eine 0: ________--------

Das ebenso: --------________

Bei der 1 ist eine Flanke 58µs lang, bei der 0 >=100µs. Also das ganze 
Bit 116 bzw >=200µs.

Eine 1 hast du empfangen, wenn nach 58µs der Pegel wechselt. Daher 
kommen die von mir festgelegten 75µs. Das liegt etwa in der Mitte 
zwischen 58 und 100. Damit wird die Toleranz der Zentrale, die bei 
+/-3µs liegt, mehr als ausgeglichen.

Ob nun das jeweilige Bit mit einem Low- oder High-Pegel beginnt, hängt 
bei einem Fahrzeug davon ab, wie herum es aufgegleist ist. Da das mal 
so, mal so ist, muß es dem Dekoder egal sein.

Beginnt das Bit mit High, gehört der folgende Low-Pegel zu diesem Bit. 
Beginnt das Bit mit Low und es wird auf High getriggert findet die 
Messung nach 75µs bei einer 0 auf dem immer noch anliegenden High statt, 
bei einer 1 auf der Low-Flanke des nächsten Bits. Das stört aber keinen 
großen Geist.

BTW: Die oben von mir vorgestellte Auswertung funktioniert. Das ist 
nicht nur Wunschdenken. Und DCC ist auch keine Raketentechnik.

Michael schrieb:
> Nebenbei es treten ja auch Wechsel auf die gar keine DCC-Signale sind
> also muss ich ja auch noch weiter messen als zwei mal?

Wo sollen denn die herkommen? Willst du mit Multiprotokoll fahren?
Das ist etwas für Clubanlagen, wo sich die Mitglieder nicht auf ein 
System einigen können.

: Bearbeitet durch User
von Michael (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Michael schrieb:
>> Nebenbei es treten ja auch Wechsel auf die gar keine DCC-Signale sind
>> also muss ich ja auch noch weiter messen als zwei mal?
>
> Wo sollen denn die herkommen? Willst du mit Multiprotokoll fahren?
> Das ist etwas für Clubanlagen, wo sich die Mitglieder nicht auf ein
> System einigen können.

Nein nichts mit Multiprotokoll
Aber der Strom auf der Bahn wechselt doch auch ganz ohne das irgend ein 
Signal übertragen wird oder?
Das ist doch Wechselstrom der auf die Bahn kommt??

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Aber der Strom auf der Bahn wechselt doch auch ganz ohne das irgend ein
> Signal übertragen wird oder?
> Das ist doch Wechselstrom der auf die Bahn kommt??

Ja, das muß auch so sein. Deswegen sendet die Zentrale auch immer 
Datenpakete. Im Minimum Idle-Packets.

Es MÜSSEN immer DCC-Pakete anliegen. Sonst machen viele Industriedekoder 
eigenartige Sachen. Z.B. wechseln Lenz-Dekoder nach 30ms ohne DCC-Signal 
in den Analogmodus.

Aber selbst wenn die 30ms, die in der NEM festgeschrieben sind, ständig 
ausgereizt oder auch überschritten werden, passiert in einem Dekoder, 
der keine Umschaltung eingebaut hat, so wie in meinem, nichts. Absolut 
nichts. Und das nächste Datenpaket, egal für wen es ist, beginnt wieder 
mit mind. 12 Sync-Bits.

Die nächste Sicherheitsstufe ist der Booster. Wenn der nicht jedes 
undefinierte Rauschen gnadenlos durchlässt, sondern das Signal von der 
Zentrale bewertet, wird bei Nichtvorhandensein eines DCC-Signals das 
Gleis einfach abgeschaltet. Mein Beispiel oben stammt übrigens genau 
daher.

: Bearbeitet durch User
von Michael (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ahh das erklärt einiges :D

Vielen Dank für die Info das wusste ich echt nicht

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Es MÜSSEN immer DCC-Pakete anliegen.

...ggf. bis auf die Lücke für die bidirektionale Kommunikation nach 
DCC-BiDi
http://www.opendcc.de/info/railcom/railcom.html

von Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht lesenswert
Wolfgang schrieb:
> ...ggf. bis auf die Lücke für die bidirektionale Kommunikation nach
> DCC-BiDi

Diese ist aber kürzer als 30ms. Somit ist die Spezifikation nach NEM für 
das ständige Senden von DCC-Paketen immer noch erfüllt. Wäre dies nicht 
so, würden alte Dekoder ggf. abschmieren.

Aber schön, daß du auch etwas zur Sache beigetragen hast.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.