Willkommen 
X

🧮 DCC-Monitor auf Arduino-Basis

#1 von Domapi , 18.01.2020 14:22

Im Netz geistern ja einige Arduino-Projekte herum, die die DCC-Gleissignale auswerten und am seriellen Monitor darstellen.
Da manche (zumindest bei mir) nicht sauber liefen, teilweise Auswertungsfehler enthalten waren und ein paar Features fehlten, habe ich mir kurzerhand einen eigenen DCC-Monitor, DCC-Sniffer oder DCC-Schnüffler auf Basis der DCC-NMRA-Library programmiert.

Über ein kleines Menü lässt sich die Darstellung am seriellen Monitor des Arduino beeinflussen, also z.B. welche Befehle überhaupt angezeigt werden und ob alle Befehle oder nur diejenigen mit neuen Kommandos. So eine Zentrale wiederholt sich nämlich fortlaufend. Vor allem bei Loks werden permanent Geschwindigkeitsbefehle und die Funktionen F0 - F4 gesendet. Etwas seltener folgen die anderen Funktionsbefehle etc. So kann man sich z.B. auf Lok-Befehle oder nur auf das Zubehör fokussieren.

Schaltet man bei Loks "nur neue Lok-Pakete …" (Option 4) aus, wird ein endloser Stream von DCC-Befehlen angezeigt. So schnell kann man gar nicht lesen, wie die Textzeilen am Bildschirm durchlaufen - Matrix-Effekt eben.

Ganz interessant ist auch, welche und wieviele DCC-Befehle beim CV-Lesen und -Schreiben aufs Gleis gelegt werden.

Ganz hinten im Programm kann nach Belieben die Liste der Loknamen angepasst werden. Dann wird´s nicht ganz so kryptisch.

So sieht das Ganze am Bildschirm aus (beispielhafte Ausgabe):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 
Domapi´s DCC Monitor V 1.0
 
S t a t i s t i k
-----------------
Zeitraum [sec] : 315
Anzahl empfangene Bytes: 140455
Gültige Kommandos : 38626
Ungültige Kommandos : 0
Idle-Pakete : 12002
Geschwindigkeitsbefehle: 13723
F0 - F4 Funktionen : 10476
F5 - F8 Funktionen : 1494
F9 - F12 Funktionen : 236
F13 - F20 Funktionen : 234
F21 - F28 Funktionen : 182
F29 - F36 Funktionen : 26
Zubehör-Befehle : 40
Dekoder-Reset-Befehle : 162
Zubehör-CV-Befehle : 0
Lok-CV-Befehle : 0
Programmiergleisbefehle: 51
Acknowledgments : 36
Counter Lok : 208
Counter Acc : 2


 
Tastaturbefehle für den seriellen Monitor:
 
1 = Anzeige Loks ein/aus ein
2 = Anzeige Zubehör ein/aus ein
3 = Anzeige CV-Befehle ein/aus ein
4 = Nur neue Lok-Pakete anzeigen ein/aus ein
5 = Nur neue Zubehör-Pakete anzeigen ein/aus ein
6 = Nur neue CV-Befehle ein/aus ein
7 = Statistik anzeigen
? = Befehle anzeigen
 

Lok 4 P4 KPEV FLM F0 f1 f2 f3 f4 0000-0100 1001-0000 1001-0100
Lok 23 BR 23 Trix -->> 116 0001-0111 0011-1111 1111-0101 1101-1101
Lok 23 BR 23 Trix F0 f1 f2 f3 f4 0001-0111 1001-0000 1000-0111
Lok 3910 BR 39 105 grün -->> 115 1100-1111 0100-0110 0011-1111 1111-0100 0100-0010
Lok 3910 BR 39 105 grün F0 f1 f2 f3 f4 1100-1111 0100-0110 1001-0000 0001-1001
Lok 280 BR280 Trix -->> 104 1100-0001 0001-1000 0011-1111 1110-1001 0000-1111
Lok 280 BR280 Trix f0 f1 f2 f3 f4 1100-0001 0001-1000 1000-0000 0101-1001
Lok 80 BR 80 Trix -->> 115 0101-0000 0011-1111 1111-0100 1001-1011
Lok 80 BR 80 Trix F0 f1 f2 f3 f4 0101-0000 1001-0000 1100-0000
Lok 3918 BR 39-186 FLM -->> 104 1100-1111 0100-1110 0011-1111 1110-1001 0101-0111
Lok 3918 BR 39-186 FLM F0 f1 f2 f3 f4 1100-1111 0100-1110 1001-0000 0001-0001
Lok 100 VT10-1 f5 f6 f7 f8 0110-0100 1011-0000 1101-0100
Lok 60 V 60 ESU f5 f6 F7 f8 0011-1100 1011-0100 1000-1000
Lok 36 S3/6 Roco Zimo f5 f6 f7 f8 0010-0100 1011-0000 1001-0100
Lok 98 VT 98 f5 f6 f7 f8 0110-0010 1011-0000 1101-0010
Lok 5501 G 5/5 Bay. F5 f6 f7 f8 1101-0101 0111-1101 1011-0001 0001-1001
Lok 1016 T16 KPEV FLM F5 f6 f7 f8 1100-0011 1111-1000 1011-0001 1000-1010
Lok 10 P10 Trix F5 f6 f7 f8 0000-1010 1011-0001 1011-1011
Lok 79 V80 Roco f5 f6 f7 f8 0100-1111 1011-0000 1111-1111
Lok 236 V 236 Bawa Zimo f5 f6 f7 f8 1100-0000 1110-1100 1011-0000 1001-1100
Lok 4417 BR 44 Trix F5 f6 f7 f8 1101-0001 0100-0001 1011-0001 0010-0001
Lok 5031 BR 50-319 Roco F5 f6 f7 f8 1101-0011 1010-0111 1011-0001 1100-0101
Lok 3624 S3/6 Trix F5 F6 f7 f8 1100-1110 0010-1000 1011-0011 0101-0101
Weichen-Adresse 6 ( 2 : 2) B On 1000-0010 1111-1010 0111-1000
Weichen-Adresse 6 ( 2 : 2) B Off 1000-0010 1111-0010 0111-0000
Weichen-Adresse 6 ( 2 : 2) A On 1000-0010 1111-1011 0111-1001
Weichen-Adresse 6 ( 2 : 2) A Off 1000-0010 1111-0011 0111-0001
Weichen-Adresse 7 ( 2 : 3) A On 1000-0010 1111-1101 0111-1111
Weichen-Adresse 7 ( 2 : 3) A Off 1000-0010 1111-0101 0111-0111
Weichen-Adresse 6 ( 2 : 2) B On 1000-0010 1111-1010 0111-1000
Weichen-Adresse 6 ( 2 : 2) B Off 1000-0010 1111-0010 0111-0000
Weichen-Adresse 7 ( 2 : 3) B On 1000-0010 1111-1100 0111-1110
Weichen-Adresse 7 ( 2 : 3) B Off 1000-0010 1111-0100 0111-0110
Lok 5 EP5 bayr. FLM -->> 118 0000-0101 0011-1111 1111-0111 1100-1101
Lok 5 EP5 bayr. FLM -->> 120 0000-0101 0011-1111 1111-1001 1100-0011
Lok 5 EP5 bayr. FLM -->> 121 0000-0101 0011-1111 1111-1010 1100-0000
Lok 5 EP5 bayr. FLM -->> 119 0000-0101 0011-1111 1111-1000 1100-0010
Lok 5 EP5 bayr. FLM -->> 118 0000-0101 0011-1111 1111-0111 1100-1101
Lok 5 EP5 bayr. FLM -->> 116 0000-0101 0011-1111 1111-0101 1100-1111
Lok 5 EP5 bayr. FLM -->> 115 0000-0101 0011-1111 1111-0100 1100-1110
Lok 5 EP5 bayr. FLM -->> 114 0000-0101 0011-1111 1111-0011 1100-1001
Lok 5 EP5 bayr. FLM -->> 115 0000-0101 0011-1111 1111-0100 1100-1110
Lok 5 EP5 bayr. FLM -->> 116 0000-0101 0011-1111 1111-0101 1100-1111
Prg CV1 Lese Bit #0 0111-1000 0000-0000 1110-0000 1001-1000
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #1 0111-1000 0000-0000 1110-0001 1001-1001
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #2 0111-1000 0000-0000 1110-0010 1001-1010
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #3 0111-1000 0000-0000 1110-0011 1001-1011
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #4 0111-1000 0000-0000 1110-0100 1001-1100
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #5 0111-1000 0000-0000 1110-0101 1001-1101
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #6 0111-1000 0000-0000 1110-0110 1001-1110
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese Bit #7 0111-1000 0000-0000 1110-0111 1001-1111
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Lese CV 0111-0100 0000-0000 0001-0000 0110-0100
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
Prg CV1 Schreibe CV = 16 0111-1100 0000-0000 0001-0000 0110-1100
Prg Dekoder-Reset-Befehl 0000-0000 0000-0000 0000-0000
 
 



Im Programmcode habe ich einiges dokumentiert. Ich habe nur die Ausgaben getestet, die für mich wichtig sind. DCC verwendet nämlich einen ganzen Sack an Kommandos.
Wer schon immer wissen wollte, wie die Kommandos aufgebaut sind, wird im Code ebenfalls fündig. Weitere Doku findet man im Netz.

Viel Spaß bei Schnüffeln

Update 17.12.2020:
Es gibt eine neue Version des DCC-Monitors, siehe:
https://www.stummiforum.de/viewtopic.php?f=5&t=176550&p=2208635#p2208635


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital

zuletzt bearbeitet 19.06.2021 21:32 | Top

RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#2 von fbstr , 08.04.2020 23:25

Hallo Martin,

durch die MobaLedLib bin ich gerade wieder im Arduino-Fieber und stolperte wieder über Deinen DCC-Sniffer.

Gleich mal heute einen Test gemacht


und es funktioniert!


Vielen Dank!


Gruss
Frank
---------------------------------------------------------------------------------------------------------------------
MobaLedLib Wiki
Projekt "Bahnpark Augsburg"
Stummitreff BB: normalerweise jeden 3. Freitag im Monat im Haus Sommerhof in Sindelfingen


 
fbstr
EuroCity (EC)
Beiträge: 1.345
Registriert am: 28.08.2016
Ort: Stuttgart
Gleise Peco Code 75, Trix C
Spurweite H0, H0e
Steuerung DR5000, Lenz LZV100, MLL
Stromart DC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#3 von Domapi , 09.04.2020 09:20

Zitat


und es funktioniert!




Sagˋ ich doch

Erfolgreiches Schnüffeln


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#4 von moppe , 09.04.2020 15:36

Martin

Wenn ist der DCC Ack nötig?

Ich will ihren DCC-Monitor probiere - und vielleicht optimieren und ein kleines Display anhängen.


Klaus


"Meine" Modellbahn:http://www.modelbaneeuropa.dk
Dänisches Bahnforum: http://www.baneforum.dk
PIKO C4 "Horror Gallery": http://moppe.dk/PIKOC4.html


 
moppe
ICE-Sprinter
Beiträge: 5.812
Registriert am: 07.08.2011
Ort: Norddeusche halbinsel
Gleise Roco, PECO, Märklin/Trix, PIKO,
Spurweite H0, N
Steuerung Z21, Lenz, MpC Gahler+Ringsmeier, Games on Track/Faller
Stromart AC, DC, Digital, Analog


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#5 von Domapi , 09.04.2020 16:23

Der ACK-Schaltungsteil ist nur notwendig, wenn man den Monitor am Programmiergleis betreibt und CVs lesen/schreiben will.
Du kannst ihn auch weglassen, da der Monitor selbst ja keine sinnvollen CVs hat.
Ich habe den Code und die Schaltung gelassen, da ich diese Komponenten für meinen Servodekoder verwendet habe.

Allerdings gibt die NRMA-Library beim Lesen einer CV den Wert des entsprechenden EEPROM-Bytes aus.
Beispielsweise bei CV1 den Wert der EEPROM Speicherstelle #0. Bei einem neuen Nano steht dort normalerweise 255.
Falls der Nano schon anderweitig in Betrieb war, ggf. ein anderer Wert.

Der Monitor sendet dann bei empfangenen CV-Befehlen 6ms - Acknowledgement Impulse.
Die Zentrale wertet diese aus und kann dann z.B. einen CV-Wert ausgeben.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#6 von moppe , 12.04.2020 11:44

Martin

Ich hab deiner DCC Monitor gestohlen!
Und natürlich weiterbearbeitet für meiner Zweck, wer ist ein kleines DCC display, wo ich hab ein 4x20 char LCD.

Es gibt natürlich Änderungen. Einer die erste ist ein bisschen mehr kompaktes Anschict der daten.
Ein andere ist Leerzeichen und F zu nutzen für Funktionen und nicht f/F.
Weichenbefehle hab seiner eigenen platz auf der Display.

Ihren Monitor funktioniert auch durch der serieller Schnittstelle mit alle funktionen.

Ich hab ein Problem mit DCC mit 28 fahrstufen. Es reagiert nicht immer, aber es ist die selber mit ihren Monitor....


Geschwindigkeit und richtung


Funktionen F5 bis F8


Funktionen F21 bis 28 (F28 ein)


Funktionen F21 bis 28 (F28 aus)

Klaus


"Meine" Modellbahn:http://www.modelbaneeuropa.dk
Dänisches Bahnforum: http://www.baneforum.dk
PIKO C4 "Horror Gallery": http://moppe.dk/PIKOC4.html


 
moppe
ICE-Sprinter
Beiträge: 5.812
Registriert am: 07.08.2011
Ort: Norddeusche halbinsel
Gleise Roco, PECO, Märklin/Trix, PIKO,
Spurweite H0, N
Steuerung Z21, Lenz, MpC Gahler+Ringsmeier, Games on Track/Faller
Stromart AC, DC, Digital, Analog


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#7 von Domapi , 12.04.2020 12:15

Hallo Klaus,



Die 28 Fahrstufen habe ich ehrlich gesagt nie getestet, da alle meine Loks 128 Fahrstufen nutzen.
Evtl. Ist da noch ein Fehler in der Auswertung. Werde ich mir gelegentlich ˋmal ansehen.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#8 von Domapi , 12.04.2020 13:51

Hier die Korrekturen:

In Zeile 527 hilft eine zusätzliche "0":

else if (((Befehls_Byte & B11000000) == 0) && (pktByteCount == 3))
{
Befehl = 0; // 00RSSSSS
Funktion = Befehls_Byte; // Speed 28 Stufen
z_lok_speed++;

}

Und ab Zeile 1072 stimmen die Berechnungen nicht, korrekt ist (einmal oben 3 abziehen und unten die "-1" löschen):

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case 2:
// Reverse speed step 28 Stufen
// 01xx-xxxx Basis Geschwindigkeits- und Richtungsbefehl
// speed = ((Befehls_Byte & B00001111) << 1) - 3 + bitRead(Befehls_Byte, 4);
speed = ((Befehls_Byte & B00001111) << 1) + ((Befehls_Byte & 0x10) >> 4) - 3;
if (speed == 253 || speed == 254) Serial.print(" Stopp ");
else if (speed == 255 || speed == 0) Serial.print(" Nothalt");
else
{
Serial.print(" <<-- ");
Serial.print(speed);
}
print_spaces(31);
break;
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case 3: // Forward speed step 28 Stufen
// speed = ((Befehls_Byte & B00001111) << 1) - 3 + bitRead(Befehls_Byte, 4);
speed = ((Befehls_Byte & B00001111) << 1) + ((Befehls_Byte & 0x10) >> 4) - 3;
if (speed == 253 || speed == 254) Serial.print(" Stopp ");
else if (speed == 255 || speed == 0) Serial.print(" Nothalt");
else
{
Serial.print(" -->> ");
Serial.print(speed);
}
print_spaces(31);
break;
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#9 von moppe , 19.04.2020 21:32

Hallo Martin

Deiner email hat mir erreicht, und ich hab ihn antwortet, aber der Antwort könnte nicht liefert werden....

Es gibt Problemen mit 28 Fahrstufen, aber weil ich nicht nutze 28 Fahrstufen, ist es egal für mich.

Ich hab auf Version 1.8 geendet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
 
//-------------------------------------------------------------------------------------------------------
/*
DCC-Monitor zur Ausgabe der DCC-Befehle auf dem seriellen Monitor und 4x20 LCD display
======================================================================================
 
V 1.0, 18.01.2020 domapi
erweitert bis V 1.7 mit LCD, bei Moppe 19.04.2020
 
Features:
---------
- Ausgabe der Lok-Befehle
- Ausgabe der Lok-CV-Kommandos
- Ausgabe der Accessory-Befehle
- Ausgabe der Accessory-CV-Kommandos
- Ausgabe der CV-Befehle auf dem Programmiergleis
- Eingaben &#252;ber seriellen Monitor zur Steuerung der Anzeige
- DCC-Paket-Speicher zum Verhindern der mehrfachen Ausgabe von Befehlen
- einstellbar getrennt nach Loks, Accessories und CVs
- Wurde ein g&#252;ltiges Paket gefunden und im seriellen Monitor ausgegeben, wird es in einer Tabelle gespeichert
- Vor jeder Paketausgabe wird gepr&#252;ft, ob es in der Tabelle bereits enthalten ist, d.1h. schon ausgegeben wurde
- Die Tabelle umfasst f&#252;r Loks 240 x 4 Bytes, ohne Pr&#228;ambel und ohne Check-Byte; f&#252;r Zubeh&#246;rbefehle nur 5 x 4 Bytes
(Lok-Befehle werden sehr h&#228;ufig und vor allem periodisch wiederholt, Zubeh&#246;r mehrfach, aber nur bei &#196;nderungen )
- Die Tabelle wird sukzessive aufgef&#252;llt, wenn sie voll ist, wird der erste Eintrag gel&#246;scht und alle anderen Eintr&#228;ge nach vorne geschoben
Das neue Paket wandert dann an die letzte Stelle
- Die Tabellengr&#246;&#223;e sollte f&#252;r ca. 70 Loks reichen
- &#220;ber das Men&#252; kann die Speicherung ein-/aus-geschaltet werden (separat f&#252;r Acc, CVs, Loks)
- Ausgabe der Lokname in Klartext
- Ausgabe einer Statistik &#252;ber die detektierten DCC-Befehle
 
- LCD kann letzter Lok oder Weichen befehl zeigen
 
Hardware:
---------
- Schaltplan, siehe: https://www.stummiforum.de/viewtopic.php?t=165060&amp;start=225#p1957001
- DCC-Signal-Auswertung &#252;ber 6N137 Optokoppler, Schutzdiode (1N4148) und Vorwiderstand (1k). Oder &#252;ber Br&#252;ckengleichrichter (siehe Link).
Pin 6 Optokoppler mit 10 kOhm an 5V reicht aus. Pin 7 muss nicht an 5V angeschlossen sein, er kann unbelegt bleiben.
- ACK-Signal &#252;ber Optokoppler CNY17 und Transistor BC557 anschlie&#223;en, erzeugt Stromimpuls an +/- des Br&#252;ckengleichrichters.
 

Arduino Nano:
// +-----+
// +------------| USB |------------+
// | +-----+ |
// | [ ]D13/SCK MISO/D12[ ] |
// | [ ]3.3V MOSI/D11[ ]~|
// | [ ]V.ref ___ SS/D10[ ]~|
// | [ ]A0 / N D9[ ]~|
// | [ ]A1 / A D8[ ] |
// | [ ]A2 N / D7[ ] |
// | [ ]A3 _0_/ D6[ ]~|
// | [ ]A4/SDA D5[ ]~|
// ACK-Pin | [ ]A5/SCL D4[ ] |
// | [ ]A6 INT1/D3[ ]~|
// | [ ]A7 INT0/D2[ ] | DCC-Eingang &#252;ber Optokoppler Pin 6
// | [ ]5V GND[ ] |
// | [ ]RST RST[ ] |
// | [ ]GND 5V MOSI GND TX1[ ] |
// | [ ]Vin [ ] [ ] [ ] RX1[ ] |
// | [ ] [ ] [ ] |
// | MISO SCK RST |
// | NANO-V3 |
// +-------------------------------+
 
LCD:
LCD RS pin to digital pin 12
LCD Enable pin to digital pin 11
LCD D4 pin to digital pin 6
LCD D5 pin to digital pin 5
LCD D6 pin to digital pin 4
LCD D7 pin to digital pin 3
LCD R/W pin to ground
LCD VSS pin to ground
LCD VCC pin to 5V
10K Pot:
ends to +5V and ground
wiper to LCD VO pin (pin 3)
 

Todos:
 
- Komplettanzeige f&#252;r eine Lok auf Basis Puffer
- Anzeige auf bestimmte Adressen beschr&#228;nken
*/
//-------------------------------------------------------------------------------------------------------
 
#include &lt;NmraDcc.h&gt;
#include &lt;LiquidCrystal.h&gt;
 
NmraDcc Dcc ;
 
//-------------------------------------------------------------------------------------------------------
// Mit diesen Variablen kann man einstellen, was auf dem seriellen Monitor ausgegeben wird
// Die Einstellungen k&#246;nnen w&#228;hrend des laufenden Betriebs des DCC-Monitors sp&#228;ter im seriellen Monitor ge&#228;ndert werden
//-------------------------------------------------------------------------------------------------------
byte Anzeige_Loks = 1; // Lok-Befehle f&#252;r Lok-Dekoder und funktionsdekoder
byte Anzeige_Acc = 1; // Zubeh&#246;r-Befehle f&#252;r Weichendekoder
byte Anzeige_CV = 1; // Ausgabe von CV-Aktionen (Lesen und Schreiben etc.)
 
byte puffern_Lok = 1; // Schaltet die Speicherung und Pr&#252;fung bereits empfangener DCC-Pakete ein/aus
byte puffern_Acc = 1;
byte puffern_CV = 1;
//-------------------------------------------------------------------------------------------------------
 
const byte DccAckPin = A5; // Arduino-Pin zur Erzeugung eines ACK-Signals
 
byte blinker = 5; // toggelt die LED an Pin 13 jedes 5. Mal, wenn ein DCC-Paket gefunden wurde --&gt; zeigt DCC-Signal an
 
const byte bufferSizeAcc = 5; // Schaltartikelbefehle werden nicht andauernd wiederholt; hier reichen ein paar Pufferpl&#228;tze aus
const byte bufferSizeLok = 240;
byte Acc_counter = 0; // l&#228;uft von 1 - bufferSizeAcc
byte Paket_bekannt_A = 0;
byte Lok_counter = 0; // l&#228;uft von 1 - bufferSizeLok
byte Paket_bekannt_L = 0;
 
// Strukturen zur Speicherung der bereits empfangenen Werte
typedef struct
{
int ADR;
byte DIR;
byte COIL;
} ACC_Befehl;
 
typedef struct
{
int ADR;
byte ORDER;
byte FUNC;
} Lok_Befehl;
 

ACC_Befehl Acc_received [bufferSizeAcc];
Lok_Befehl Lok_received [bufferSizeLok];
 

byte pktByteCount = 0;
unsigned int decoderAddress;
unsigned int decoderAddress_alt = 0;
unsigned int weichenadresse;
byte Ausgang;
byte Spule;
byte Befehl;
byte Funktion;
 
byte Befehls_Byte;
byte decoderType; //0=Lok, 1=Zubeh&#246;r/Accessory
 
byte command;
int CV_address;
byte CV_value;
 
byte command_alt = 0;
int CV_address_alt = 0;
byte CV_value_alt = 0;
 
byte speed;
 
byte checksum = 0;
 
// Z&#228;hler f&#252;r die Statistik
unsigned long start_time = 0;
unsigned long z_bytes = 0;
unsigned long z_invalid = 0;
unsigned long z_idle = 0;
unsigned long z_lok_speed = 0;
unsigned long z_lok_F0 = 0;
unsigned long z_lok_F5 = 0;
unsigned long z_lok_F9 = 0;
unsigned long z_lok_F13 = 0;
unsigned long z_lok_F21 = 0;
unsigned long z_lok_F29 = 0;
unsigned long z_acc = 0;
unsigned long z_dec_reset = 0;
unsigned long z_acc_cv = 0;
unsigned long z_lok_cv = 0;
unsigned long z_prg_CV = 0;
unsigned long z_ack = 0;
 
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
 
// these constants won't change. But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;
const int splashdelay = 5000;
 
//-------------------------------------------------------------------------------------------------------
void setup()
//-------------------------------------------------------------------------------------------------------
{
pinMode(13, OUTPUT); // eingebaute LED
Serial.begin(115200);
 
pinMode(DccAckPin, OUTPUT); // Configure the DCC CV Programing ACK pin for an output
 
Serial.println(F("Domapi&#180;s DCC Monitor V 1.0"));
Serial.println(F("und Moppes DCC display"));
 
// set up the LCD's number of columns and rows:
lcd.begin(numCols, numRows);
 
lcd.setCursor(0, 0);
lcd.write("Domapi's DCC-Monitor ");
lcd.setCursor(0, 1);
lcd.write(" erweitert bis:");
lcd.setCursor(0, 2);
lcd.write(" Moppes DCC display");
lcd.setCursor(0, 3);
lcd.write(" von stummiforum.de");
delay(splashdelay);
lcd.clear();
lcd.write("Moppes DCC display ");
 
Dcc.pin(0, 2, 1); // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
 
Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 ); // Call the main DCC Init function to enable the DCC Receiver
 
start_time = millis();
 

 
}
 

//-------------------------------------------------------------------------------------------------------
void loop()
//-------------------------------------------------------------------------------------------------------
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
 
if (Serial.available())
{
// Tastatur-Befehle via seriellen Monitor des Arduinos:
 
// 1 = Anzeige Loks ein/aus
// 2 = Anzeige Zubeh&#246;r ein/aus
// 3 = Anzeige CV-Befehle ein/aus
// 4 = Nur neue Lok-Pakete ein/aus
// 5 = Nur neue Zubeh&#246;r-Pakete ein/aus
// 6 = Nur neue CV-Befehle ein/aus
// 7 = Statistik
// ? = Befehle anzeigen
 
switch (Serial.read())
{
case 49: // 1
Serial.print(F("1 Anzeige Loks ein/aus = "));
Anzeige_Loks = !Anzeige_Loks;
if (Anzeige_Loks) Serial.println("ein");
else Serial.println("aus");
break;
case 50: //2
Serial.print(F("2 Anzeige Zubeh&#246;r ein/aus = "));
Anzeige_Acc = !Anzeige_Acc;
if (Anzeige_Acc) Serial.println("ein");
else Serial.println("aus");
break;
case 51: // 3
Serial.print(F("3 Anzeige CV-Befehle ein/aus = "));
Anzeige_CV = !Anzeige_CV;
if (Anzeige_CV) Serial.println("ein");
else Serial.println("aus");
break;
case 52: // 4
Serial.print(F("4 Nur neue Lok-Pakete anzeigen ein/aus = "));
puffern_Lok = !puffern_Lok;
if (puffern_Lok) Serial.println("ein");
else Serial.println("aus");
break;
case 53: // 5
Serial.print(F("5 Nur neue Zubeh&#246;r-Pakete anzeigen ein/aus = "));
puffern_Acc = !puffern_Acc;
if (puffern_Acc) Serial.println("ein");
else Serial.println("aus");
break;
case 54: // 6
Serial.print(F("6 Nur neue CV-Befehle anzeigen ein/aus = "));
puffern_CV = !puffern_CV;
if (puffern_CV) Serial.println("ein");
else Serial.println("aus");
break;
case 55: // 7
Serial.println();
Serial.println(F("S t a t i s t i k"));
Serial.println(F("-----------------"));
Serial.print(F("Zeitraum [sec] :")); print_Zahl_rechts_ln((millis() - start_time) / 1000);
 
Serial.print(F("Anzahl empfangene Bytes:")); print_Zahl_rechts_ln(z_bytes);
Serial.print(F("G&#252;ltige Kommandos :"));
print_Zahl_rechts_ln(z_invalid + z_idle + z_lok_speed + z_lok_F0 + z_lok_F5 + z_lok_F9 + z_lok_F13 + z_lok_F21 + z_lok_F29 + z_acc + z_dec_reset + z_acc_cv + z_lok_cv + z_prg_CV);
Serial.print(F("Ung&#252;ltige Kommandos :")); print_Zahl_rechts_ln(z_invalid);
Serial.print(F("Idle-Pakete :")); print_Zahl_rechts_ln(z_idle);
 
Serial.print(F("Geschwindigkeitsbefehle:")); print_Zahl_rechts_ln(z_lok_speed);
Serial.print(F("F0 - F4 Funktionen :")); print_Zahl_rechts_ln(z_lok_F0);
Serial.print(F("F5 - F8 Funktionen :")); print_Zahl_rechts_ln(z_lok_F5);
Serial.print(F("F9 - F12 Funktionen :")); print_Zahl_rechts_ln(z_lok_F9);
Serial.print(F("F13 - F20 Funktionen :")); print_Zahl_rechts_ln(z_lok_F13);
Serial.print(F("F21 - F28 Funktionen :")); print_Zahl_rechts_ln(z_lok_F21);
Serial.print(F("F29 - F36 Funktionen :")); print_Zahl_rechts_ln(z_lok_F29);
 
Serial.print(F("Zubeh&#246;r-Befehle :")); print_Zahl_rechts_ln(z_acc);
 
Serial.print(F("Dekoder-Reset-Befehle :")); print_Zahl_rechts_ln(z_dec_reset);
Serial.print(F("Zubeh&#246;r-CV-Befehle :")); print_Zahl_rechts_ln(z_acc_cv);
Serial.print(F("Lok-CV-Befehle :")); print_Zahl_rechts_ln(z_lok_cv);
Serial.print(F("Programmiergleisbefehle:")); print_Zahl_rechts_ln(z_prg_CV);
Serial.print(F("Acknowledgments :")); print_Zahl_rechts_ln(z_ack);
 
Serial.print(F("Counter Lok :")); print_Zahl_rechts_ln(Lok_counter);
Serial.print(F("Counter Acc :")); print_Zahl_rechts_ln(Acc_counter);
break;
case 63: // ?
Serial.println(); Serial.println(F("Tastaturbefehle f&#252;r den seriellen Monitor:")); Serial.println();
Serial.print (F("1 = Anzeige Loks ein/aus "));
if (Anzeige_Loks) Serial.println("ein");
else Serial.println("aus");
Serial.print (F("2 = Anzeige Zubeh&#246;r ein/aus "));
if (Anzeige_Acc) Serial.println("ein");
else Serial.println("aus");
Serial.print (F("3 = Anzeige CV-Befehle ein/aus "));
if (Anzeige_CV) Serial.println("ein");
else Serial.println("aus");
Serial.print (F("4 = Nur neue Lok-Pakete anzeigen ein/aus "));
if (puffern_Lok) Serial.println("ein");
else Serial.println("aus");
Serial.print (F("5 = Nur neue Zubeh&#246;r-Pakete anzeigen ein/aus "));
if (puffern_Acc) Serial.println("ein");
else Serial.println("aus");
Serial.print (F("6 = Nur neue CV-Befehle ein/aus "));
if (puffern_CV) Serial.println("ein");
else Serial.println("aus");
Serial.println(F("7 = Statistik anzeigen"));
Serial.println(F("? = Befehle anzeigen"));
break;
}
Serial.println(" ");
}
}
 

//-------------------------------------------------------------------------------------------------------
// This function is called by the NmraDcc library when a DCC ACK needs to be sent
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
void notifyCVAck()
//-------------------------------------------------------------------------------------------------------
{
digitalWrite( DccAckPin, HIGH );
delay( 6 );
digitalWrite( DccAckPin, LOW );
z_ack++;
}
 

//-------------------------------------------------------------------------------------------------------
void notifyDccMsg(DCC_MSG * Msg)
//-------------------------------------------------------------------------------------------------------
{
// LED toggeln
blinker--;
if (blinker == 0)
{
digitalWrite(13, !digitalRead(13));
blinker = 5;
}
 
//-------------------------------------------------------------------------------------------------------------------------------
// Alle gefunden Bytes XOR-verkn&#252;pfen; muss 0 ergeben, dann wurde ein g&#252;ltiger Befehl gefunden!
//-------------------------------------------------------------------------------------------------------------------------------
 
pktByteCount = Msg-&gt;Size; // Anzahl gefundene Bytes ohne Pr&#228;ambel aber incl. Pr&#252;fbyte !!!
checksum = 0; // Wir starten mit 0
z_bytes = z_bytes + pktByteCount;
 
for (byte n = 0; n &lt; pktByteCount; n++)
{
checksum ^= Msg-&gt;Data[n];
}
if (checksum)
{
z_invalid++;
return; // Ung&#252;ltige Checksumme --&gt; nix tun !
}
 
//-------------------------------------------------------------------------------------------------------------------------------
// Start Dekodierung
//-------------------------------------------------------------------------------------------------------------------------------
 
//-------------------------------------------------------------------------------------------------------------------------------
// Idle Kommando
//-------------------------------------------------------------------------------------------------------------------------------
if (Msg-&gt;Data[0] == B11111111)
{
z_idle++;
return; // Idle packet
}
 

 

 
//-------------------------------------------------------------------------------------------------------------------------------
// Reset Befehl zur Einleitung der CV-Programmierung
//-------------------------------------------------------------------------------------------------------------------------------
if (Msg-&gt;Data[0] == 0)
{
z_dec_reset++;
 
command = Msg-&gt;Data[0];
CV_address = Msg-&gt;Data[1];
CV_value = Msg-&gt;Data[2];
 
// Nur verarbeiten, wenn neuer Befehl!
if (!(((CV_value == CV_value_alt) &amp;&amp; (CV_address == CV_address_alt) &amp;&amp; (command == command_alt)) &amp;&amp; puffern_CV))
{
Serial.print(F("Prg Dekoder-Reset-Befehl"));
print_spaces(43);
printPacket(Msg);
 
command_alt = command;
CV_address_alt = CV_address;
CV_value_alt = CV_value;
}
return;
}
//-------------------------------------------------------------------------------------------------------------------------------
// Programmiermodus auf dem Programmiergleis ohne Adresse !
//-------------------------------------------------------------------------------------------------------------------------------
if ((Msg-&gt;Data[0] &amp; B11110000) == B01110000)
{
/* Service Mode.Prog: [preamble] 0 [0111CCVV] 0 [VVVVVVVV] 0 [DDDDDDDD] 0 [EEEEEEEE] 1
CC = Command
VV VVVVVVVV = 10 bit CV Number
DDDDDDDD = New Value (8 bit)
EEEEEEEE = Checksum
Lesen/Schreiben auf dem Prg.gleis geht ohne Dekoderadresse !
 
Schreiben: z.B. CV 6, Wert 20 (--&gt; 4 Bytes ohne Pr&#228;ambel und Trennbits!)
Byte 0 Byte 1 Byte 2 Byte 3
01111100 -----101 ---10100 10000001
 
0111CCVV VVVVVVVV DDDDDDDD EEEEEEEE
11 = Schreiben
01 = Lesen/&#220;berpr&#252;fen
10 = 10 Bit Manipulation
V = CV - 1 --&gt; 5 = CV 5 + 1 = CV6 !
D = 20 */
z_prg_CV++;
 
// Nur verarbeiten, wenn neuer Befehl!
command = Msg-&gt;Data[0] &amp; B00001100; // 2 Bits enthalten den Schreib-/ Verify-Befehl etc.
CV_address = ((Msg-&gt;Data[0] &amp; B00000011) * 256) + Msg-&gt;Data[1] + 1; // Nummer der CV
CV_value = Msg-&gt;Data[2]; // CV-Wert f&#252;r das Schreiben
 
if (!(((CV_value == CV_value_alt) &amp;&amp; (CV_address == CV_address_alt) &amp;&amp; (command == command_alt)) &amp;&amp; puffern_CV))
{
decoderType = 255; // vorsichtshalber mal auf einen d&#228;mlichen Wert setzen, damit weiter unten nix passiert
 
Serial.print("Prg CV");
 
CV_address = ((Msg-&gt;Data[0] &amp; B00000011) * 256) + Msg-&gt;Data[1] + 1;
Serial.print(CV_address);
if (CV_address &lt; 1000) Serial.print(" ");
if (CV_address &lt; 100) Serial.print(" ");
if (CV_address &lt; 10) Serial.print(" ");
Serial.print(" ");
 
switch (Msg-&gt;Data[0] &amp; B00001100)
{
/* Die f&#252;r den Befehlstyp (xxxx-KKxx) im ersten Befehlsbyte festgelegten Werte sind:
KK = 00 &#8211; reserviert
KK = 01 &#8211; Byte &#220;berpr&#252;fen
KK = 11 &#8211; Byte Schreiben
KK = 10 &#8211; Bit Manipulation*/
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case B00000100: // Verify Byte
Serial.print(F("Lese CV"));
print_spaces(49);
break;
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case B00001100: // Write Byte
 
Serial.print(F("Schreibe CV ="));
if (Msg-&gt;Data[2] &lt; 100) Serial.print(" ");
if (Msg-&gt;Data[2] &lt; 10) Serial.print(" ");
Serial.print(" ");
Serial.print(Msg-&gt;Data[2]);
print_spaces(39);
break;
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case B00001000: // Bit Write
// 0111-10VV VVVV-VVVV 111K-DBBB EEEE-EEEE --&gt; im Programmiermodus f&#252;r Zugriffe auf einzelne Bits
// K = 1 &#8211; Bit Schreiben
// K = 0 &#8211; Bit &#220;berpr&#252;fen
if (Msg-&gt;Data[2] &amp; B00010000)
{
Serial.print("Schreibe Bit #");
Serial.print(Msg-&gt;Data[2] &amp; B00000111);
Serial.print(" = ");
Serial.print((Msg-&gt;Data[2] &amp; B00001000) &gt;&gt; 3);
print_spaces(36);
}
else
{
Serial.print("Lese Bit #");
Serial.print(Msg-&gt;Data[2] &amp; B00000111);
print_spaces(42);
}
break;
}
printPacket(Msg);
 
command_alt = command;
CV_address_alt = CV_address;
CV_value_alt = CV_value;
 
return;
}
}
else
{
//-------------------------------------------------------------------------------------------------------------------------------
// 0xxx-xxxx --&gt; bit7=0 -&gt; Lok Dekoder kurze Adresse
//-------------------------------------------------------------------------------------------------------------------------------
if (!bitRead(Msg-&gt;Data[0], 7))
{
decoderType = 0; // Lok
decoderAddress = Msg-&gt;Data[0]; // kurze Adresse
Befehls_Byte = Msg-&gt;Data[1];
 
// Aufteilung der gefundenen Bytes auf Befehle (Was soll der Dekoder tun?) und Funktionen (Wie soll er es tun?)
 
if ((Befehls_Byte &amp; B11100000) == B10000000)
{
Befehl = B00000100; // 100 = F0 - F4
Funktion = Befehls_Byte &amp; B00011111; // x-xxxx = F0 F4 - F1
z_lok_F0++;
}
 
else if ((Befehls_Byte &amp; B11110000) == B10110000)
{
Befehl = B00001011; // 1011 = F5 - F8
Funktion = Befehls_Byte &amp; B00001111; // xxxx = F8 - F5
z_lok_F5++;
}
 
else if ((Befehls_Byte &amp; B11110000) == B10100000)
{
Befehl = Befehls_Byte &gt;&gt; 4; // 1010 = F9 - F12
Funktion = Befehls_Byte &amp; B00001111; // xxxx = F12 - F9
z_lok_F9++;
}
 
else if (Befehls_Byte == B11011110)
{
Befehl = Befehls_Byte; // 1101-1110 = F13 - F20
Funktion = Msg-&gt;Data[2]; // xxxx-xxxx = F20 - F13
z_lok_F13++;
}
else if (Befehls_Byte == B11011111)
{
Befehl = Befehls_Byte; // 1101-1111 = F21 - F28
Funktion = Msg-&gt;Data[2]; // xxxx-xxxx = F28 - F21
z_lok_F21++;
}
else if (Befehls_Byte == B11011000)
{
Befehl = Befehls_Byte; // 1101-1000 = F29 - F36
Funktion = Msg-&gt;Data[2]; // xxxx-xxxx = F36 - F29
z_lok_F29++;
}
else if (((Befehls_Byte &amp; B11000000) == 0) &amp;&amp; (pktByteCount == 3))
{
Befehl = 0; // 00RSSSSS
Funktion = Befehls_Byte; // Speed 28 Stufen
z_lok_speed++;
 
}
else if (((Befehls_Byte &amp; B11000000) == 64) &amp;&amp; (pktByteCount == 4)) // Adr 10000 ???
{
Befehl = 0; // 00RSSSSS
Funktion = Befehls_Byte; // Speed 28 Stufen
z_lok_speed++;
}
 
else if ((Befehls_Byte == B00111111) &amp;&amp; (pktByteCount == 4))
{
Befehl = Befehls_Byte; // 00111111
Funktion = Msg-&gt;Data[2]; // RSSSSSSS Speed 127 Stufen
z_lok_speed++;
}
}
else
{
//-------------------------------------------------------------------------------------------------------------------------------
// 11xx-xxxx --&gt; bit7 = 1 AND bit6 = 1 -&gt; Lok Dekoder lange Adresse
//-------------------------------------------------------------------------------------------------------------------------------
if (bitRead(Msg-&gt;Data[0], 6))
{
// 11xx-xxxx
decoderAddress = 256 * (Msg-&gt;Data[0] &amp; B00111111) + Msg-&gt;Data[1];
Befehls_Byte = Msg-&gt;Data[2];
decoderType = 0;
 
// Aufteilung der gefundenen Bytes auf Befehle und Funktionen
 
if ((Befehls_Byte &amp; B11100000) == B10000000)
{
Befehl = B00000100; // 100 = F0 - F4
Funktion = Befehls_Byte &amp; B00011111; // x-xxxx = F0 F4 - F1
z_lok_F0++;
}
 
else if ((Befehls_Byte &amp; B11110000) == B10110000)
{
Befehl = B00001011; // 1011 = F5 - F8
Funktion = Befehls_Byte &amp; B00001111; // xxxx = F8 - F5
z_lok_F5++;
}
 
else if ((Befehls_Byte &amp; B11110000) == B10100000)
{
Befehl = B00001010; // 1010 = F9 - F12
Funktion = Befehls_Byte &amp; B00001111; // xxxx = F12 - F9
z_lok_F9++;
}
 
else if (Befehls_Byte == B11011110)
{
Befehl = Befehls_Byte; // 1101-1110 = F13 - F20
Funktion = Msg-&gt;Data[3]; // xxxx-xxxx = F20 - F13
z_lok_F13++;
}
else if (Befehls_Byte == B11011111)
{
Befehl = Befehls_Byte; // 1101-1111 = F21 - F28
Funktion = Msg-&gt;Data[3]; // xxxx-xxxx = F28 - F21
z_lok_F21++;
}
else if (Befehls_Byte == B11011000)
{
Befehl = Befehls_Byte; // 1101-1000 = F29 - F36
Funktion = Msg-&gt;Data[2]; // xxxx-xxxx = F36 - F29
z_lok_F29++;
}
else if (((Befehls_Byte &amp; B11000000) == 0) &amp;&amp; (pktByteCount == 4))
{
Befehl = 0; // 00RSSSSS
z_lok_speed++;
Funktion = Befehls_Byte; // Speed 28 Stufen
}
else if (((Befehls_Byte &amp; B11000000) == 64) &amp;&amp; (pktByteCount == 4)) // Adr 10000 ???
{
Befehl = 0; // 00RSSSSS
Funktion = Befehls_Byte; // Speed 28 Stufen
z_lok_speed++;
}
 
else if ((Befehls_Byte == B00111111) &amp;&amp; (pktByteCount == 5))
{
Befehl = Befehls_Byte; // 00111111
Funktion = Msg-&gt;Data[3]; // RSSSSSSS Speed 127 Stufen
z_lok_speed++;
}
}
//-------------------------------------------------------------------------------------------------------------------------------
else //bit7=1 AND bit6=0 -&gt; Accessory Decoder
{
// 10xx-xxxx
//-------------------------------------------------------------------------------------------------------------------------------
 
decoderAddress = Msg-&gt;Data[0] &amp; B00111111;
Befehls_Byte = Msg-&gt;Data[1];
decoderType = 1;
}
}
}
//-------------------------------------------------------------------------------------------------------------------------------
if (decoderType == 1) // Accessory Basic
{
if (Anzeige_Acc &amp;&amp; (Msg-&gt;Size != 6) )
{
z_acc++;
 
if ((Befehls_Byte &amp; B10000000) &amp;&amp; (Msg-&gt;Size == 3)) // Steuerbefehl f&#252;r Zubeh&#246;r Dekoder (Basic Accessory)
{
// die Zentrale sendet f&#252;r Magnetartikel (accessories) immer ein Paket bestehend aus Adresse (= Signal), Richtung (rot/gr&#252;n) und ein/aus (Spule).
// Zun&#228;chst wird eine Richtung eingeschaltet, dazu wird das DCC-Telegramm ggf. mehrfach wiederholt
// Bei der ECOS wird nach einer einstellbaren Zeit pro "Magnetartikel" ein Ausschaltbefehl (auch mehrfach) hinterhergeschickt
 
/* F&#252;r Zubeh&#246;r-/Weichendekoder sendet die DCC-Zentrale 3 Bytes:
Byte 1 Byte 2 Byte 3
__ __ __
1 0 A7 A6 A5 A4 A3 A2 : 1 AA A9 A8 P A1 A0 R : C7 C6 C5 C4 C3 C2 C1 C0
 
- AA..A0 sind die 11 Bit Adresse eines Zubeh&#246;rdekoders ("Addr")
- P = Power (0 = off, 1 = on) ("OutputPower"), bei Spulenantrieben von Weichen sind das Spule 1 und Spule 2
- R = Schaltrichtung (in welche Richtung "Direction" sich der Servo bewegt, 0 = rot, 1 = gr&#252;n)
- C7..C0 = Checkbyte (Byte_3 = Byte_1 XOR Byte_2)
 
- Das 1. Byte beginnt immer mit "10" --&gt; 10XX XXXX (Bit#7 = 1, Bit#6 = 0)
- Das 2. Byte beginnt immer mit "1" --&gt; 1XXX XXXX (Bit#7 = 1)
- Das 3. Byte dient der &#252;berpr&#252;fung der gesendeten Informationen: Byte_3 = Byte_1 XOR Byte_2
 
- Die 11 Bit Adresse des zu steuernden Spulenpaares entsteht aus den 11 Adress-Bits (AA ... A0). Dabei ist zu
beachten, dass die Bits AA, A9, A8 invertiert im urspr&#252;nglichen DCC-Paket abgebildet sind.
*/
 
decoderAddress = (((~Befehls_Byte)&amp;B01110000) &lt;&lt; 2) + decoderAddress;
Ausgang = (Befehls_Byte &amp; B00000110) &gt;&gt; 1;
Spule = (bitRead(Befehls_Byte, 3));
weichenadresse = (decoderAddress - 1) * 4 + Ausgang + 1;
 
if (puffern_Acc)
{
//-------------------------------------------------------------------------------------------------------------------------------
// alle Werte im Puffer ausgeben
// Schauen im Array, ob die gefundenen Bytes schon einmal ausgegeben wurden
if (Acc_counter &gt; 0)
{
for (byte j = 0; j &lt; Acc_counter; j++)
{
Paket_bekannt_A = 0;
 
if (Acc_received [j].ADR == weichenadresse)
{
Paket_bekannt_A++;
}
if (Acc_received [j].DIR == Ausgang)
{
Paket_bekannt_A++;
}
if (Acc_received [j].COIL == Spule)
{
Paket_bekannt_A++;
}
 
if (Paket_bekannt_A == 3)
{
return; // nix machen, keine Ausgabe im seriellen Monitor: war lediglich eine Wiederholung !
}
}
}
 
if (Acc_counter &gt; 0)
{
// Pufferzeilen mit der gleichen Adresse rausl&#246;schen
for (byte j = 0; j &lt; Acc_counter; j++)
{
if (Acc_received [j].ADR == weichenadresse)
{
// Befehl mit der gleichen Adresse aus der Puffertabelle l&#246;schen!
// dazu beginnend mit der Zeile j alle weiter hinten vorziehen, bis Pufferende oder mindestens bis Acc_counter
 
for (byte k = j; k &lt; min (Acc_counter, bufferSizeAcc - 1); k++)
{
Acc_received [k].ADR = Acc_received [k + 1].ADR;
Acc_received [k].DIR = Acc_received [k + 1].DIR;
Acc_received [k].COIL = Acc_received [k + 1].COIL;
}
 
// }
Acc_counter--; // ein Eintrag wurde gel&#246;scht
}
}
}
// eine Zeile im Acc_received mit neuem Paket bef&#252;llen
if (Acc_counter &lt; bufferSizeAcc)
{
Acc_received [Acc_counter].ADR = weichenadresse;
Acc_received [Acc_counter].DIR = Ausgang;
Acc_received [Acc_counter].COIL = Spule;
Acc_counter++;
}
else
{
// ersten &#228;ltesten Wert l&#246;schen und alle anderen Wertepaare nach links r&#252;cken
for (byte j = 0; j &lt; bufferSizeAcc - 1; j++)
{
Acc_received [j].ADR = Acc_received [j + 1].ADR;
Acc_received [j].DIR = Acc_received [j + 1].DIR;
Acc_received [j].COIL = Acc_received [j + 1].COIL;
 
}
// den letzten Eintrag nun dem neuen Paket bef&#252;llen
 
Acc_received [bufferSizeAcc - 1].ADR = weichenadresse;
Acc_received [bufferSizeAcc - 1].DIR = Ausgang;
Acc_received [bufferSizeAcc - 1].COIL = Spule;
 
Acc_counter = bufferSizeAcc;
}
}
//-------------------------------------------------------------------------------------------------------------------------------
// Zubeh&#246;r-Daten ausgeben
 
Serial.print(F("Weichen-Adresse "));
lcd.setCursor(0, 3);
lcd.write(" ");
lcd.setCursor(0, 3);
lcd.write("W ");
if ((decoderAddress - 1) * 4 + Ausgang + 1 &lt; 10) Serial.print(" ");
Serial.print((decoderAddress - 1) * 4 + Ausgang + 1);
lcd.print((decoderAddress - 1) * 4 + Ausgang + 1, DEC);
Serial.print(" (");
lcd.write(" (");
if (decoderAddress &lt; 10) Serial.print(" ");
Serial.print(decoderAddress);
lcd.print(decoderAddress, DEC);
Serial.print(" : ");
lcd.write(":");
Serial.print(Ausgang + 1);
lcd.print(Ausgang + 1, DEC);
Serial.print(")");
lcd.write(")");
if (bitRead(Befehls_Byte, 0)) {
Serial.print(" A");
lcd.write(" A");
}
else {
Serial.print(" B");
lcd.write(" B");
}
if (bitRead(Befehls_Byte, 3)) {
Serial.print(" On ");
lcd.write(" On ");
}
else {
Serial.print(" Off");
lcd.write(" Off");
}
print_spaces(36);
}
else // Accessory Extended NMRA --&gt; noch nicht getestet !!!
{
Serial.print("Acc Ext ");
decoderAddress = (decoderAddress &lt;&lt; 5) + ((Befehls_Byte &amp; B01110000) &gt;&gt; 2) + ((Befehls_Byte &amp; B00000110) &gt;&gt; 1);
Serial.print(decoderAddress);
Serial.print(" Asp ");
Serial.print(Msg-&gt;Data[2], BIN);
}
printPacket(Msg);
}
 
//----------------------------------------------------------------------------------------------------------------------------------------
// CV-Befehle f&#252;r Schaltdekoder POM
 
if (Anzeige_CV &amp;&amp; (Msg-&gt;Size == 6)) // 6 Bytes --&gt; d.h. CV-Befehle f&#252;r Schaltdekoder !
{
z_acc_cv++;
 
/* ECOS: POM-Schaltartikel POM-Adresse 12, CV 6, Wert 20 Schreiben: (6 Bytes ohne Pr&#228;ambel und Trennbits!)
Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5
10001100 11110000 11101100 -----101 ---10100 10000001
___ 3 MSB der Adresse sind invertiert !
10AAAAAA 1AAACDDD 1110CCVV VVVVVVVV DDDDDDDD EEEEEEEE
11 = Adresse 12
11 = Schreiben
10 = Lesen
V = CV + 1 --&gt; 5 + 1 = 6
20
Lesen:
10001100 11110000 11100100 -----101 -------0 10011101
 
Bas.Op.Mode.Prog [preamble]0[10AAAAAA]0[1AAACDDD]0[CVACCESS]0[EEEEEEEE]1
AAAAAA AAA1DDD = Output Address
AAAAAA AAA0000 = Decoder Address
CVACCESS = DCC Programming CMD
EEEEEEEE = Checksum
 
CVACCESS [1110CCVV]0[VVVVVVVV]0[DDDDDDDD]
CC = Command
CC = 01 Verify Byte
CC = 11 Write Byte
CC = 10 Bit Manipulation
VV VVVVVVVV = CV Number
DDDDDDDD = New Value
EEEEEEEE = Checksum
*/
 
decoderAddress = (((~Msg-&gt;Data[1]) &amp; B01110000) &lt;&lt; 2) + (Msg-&gt;Data[0] &amp; B00111111); // Adresse ist in 2 Bytes kodiert, MSB invertiert in Byte1 (Bit4-6) und der Rest in Byte0 (Bit 0-5)
command = Msg-&gt;Data[2] &amp; B00001100; // 2 Bits enthalten den Schreib-/ Verify-Befehl etc.
CV_address = ((Msg-&gt;Data[2] &amp; B00000011) * 256) + Msg-&gt;Data[3] + 1; // Nummer der CV
CV_value = Msg-&gt;Data[4]; // CV-Wert f&#252;r das Schreiben
 
if (!(((decoderAddress == decoderAddress_alt) &amp;&amp; (CV_address == CV_address_alt) &amp;&amp; (command == command_alt)) &amp;&amp; puffern_CV)) // immer ausgeben
{
switch (command)
{
case 12: //B1100 --&gt; 12 ==&gt; Schreiben
 
Serial.print(F("Acc " ));
Serial.print(decoderAddress);
if (decoderAddress &lt; 100) Serial.print(" ");
if (decoderAddress &lt; 10) Serial.print(" ");
 
Serial.print(" CV ");
Serial.print(CV_address); Serial.print(" ");
if (CV_address &lt; 100) Serial.print(" ");
if (CV_address &lt; 10) Serial.print(" ");
 
Serial.print(F("Schreibe CV ="));
if (CV_value &lt; 100) Serial.print(" ");
if (CV_value &lt; 10) Serial.print(" ");
Serial.print(" ");
Serial.print(CV_value);
print_spaces(33);
break;
 
case 4: //B0100 --&gt; 4 ==&gt; Lesen
 
Serial.print(F("Acc " ));
Serial.print(decoderAddress);
if (decoderAddress &lt; 100) Serial.print(" ");
if (decoderAddress &lt; 10) Serial.print(" ");
 
Serial.print(" CV ");
Serial.print(CV_address); Serial.print(" ");
if (CV_address &lt; 100) Serial.print(" ");
if (CV_address &lt; 10) Serial.print(" ");
Serial.print(F("Lese CV "));
print_spaces(42);
break;
 
case 8: //B1000 ==&gt; Bit-Gefummel !
 
// ... 111K-DBBB EEEE-EEEE --&gt; Zugriffe auf einzelne Bits
// K = 1 &#8211; Bit Schreiben
// K = 0 &#8211; Bit &#220;berpr&#252;fen
 
if (Msg-&gt;Data[pktByteCount - 2] &amp; B00010000)
{
Serial.print("Schreibe Bit #");
Serial.print(Msg-&gt;Data[pktByteCount - 2] &amp; B00000111);
Serial.print(" = ");
Serial.print((Msg-&gt;Data[pktByteCount - 2] &amp; B00001000) &gt;&gt; 3);
print_spaces(36);
}
else
{
Serial.print("Lese Bit #");
Serial.print(Msg-&gt;Data[2] &amp; B00000111);
print_spaces(41);
}
break;
 
}
printPacket(Msg);
 
decoderAddress_alt = decoderAddress;
CV_address_alt = CV_address;
command_alt = command;
}
return;
}
}
 
//-------------------------------------------------------------------------------------------------------------------------------
else if (decoderType == 0) // --&gt; Lok / Funktionsdekoder
{
/* Aufbau der Fahrbefehle:
Fahrbefehl, kurze Adressen
Byte 7 6 5 4 3 2 1 0
---------------------------------------------------------------------------
0 0 A A A A A A A Adresse 7 Bit
1 0 0 R S S S S S R = Fahrtrichtung, Sn = Geschwindigkeit 28 Stufen
2 XOR Pr&#252;fbyte
 
0 0 A A A A A A A Adresse 7 Bit
1 0 0 1 1 1 1 1 1 Befehlsbyte 0x3F
2 R S S S S S S S R = Fahrtrichtung, Sn = Geschwindigkeit 127 Stufen
3 XOR Pr&#252;fbyte
 
- Fahrbefehl 28 Stufen: unsigned char speed = ((Byte[1] &amp; 0x0F) &lt;&lt; 1) + ((Byte[1] &amp; 0x10) &gt;&gt; 4);
- Fahrbefehl 127 Stufen: unsigned char speed = Byte[2] &amp; 0x7F;
 
Fahrbefehl, lange Adressen
Byte 7 6 5 4 3 2 1 0
---------------------------------------------------------------------------
0 1 1 A A A A A A Adresse 6 Bit
1 A A A A A A A A Adresse 8 Bit
2 0 0 R S S S S S R = Fahrtrichtung, Sn = Geschwindigkeit 28 Stufen
3 XOR Pr&#252;fbyte
 
Byte 7 6 5 4 3 2 1 0
---------------------------------------------------------------------------
0 1 1 A A A A A A Adresse 6 Bit
1 A A A A A A A A Adresse 8 Bit
2 0 0 1 1 1 1 1 1 Befehlsbyte 0x3F
3 R S S S S S S S R = Fahrtrichtung, Sn = Geschwindigkeit 127 Stufen
4 XOR Pr&#252;fbyte
 
- Fahrbefehl 28 Stufen: unsigned char speed = ((Byte[2] &amp; 0x0F) &lt;&lt; 1) + ((Byte[2] &amp; 0x10) &gt;&gt; 4);
- Fahrbefehl 127 Stufen: unsigned char speed = Byte[3] &amp; 0x7F;
 
*/
if (Anzeige_Loks )
// zu Testzwecken filtern auf bestimmte Lok-Adresse
// if (Anzeige_Loks &amp;&amp; (decoderAddress == 42 || decoderAddress == 888))
// if (Anzeige_Loks &amp;&amp; (decoderAddress &lt; 25))
{
byte instructionType = Befehls_Byte &gt;&gt; 5;
 
/* Bits 7-6-5 sind relevant, ergibt 0 - 7 = 8 unterschiedliche Befehlstypen
0 = Control ??
1 = 0011-1111 128 Geschwindigkeitsstufen-Befehl, 0011-1110 Sonderbetriebsarten-Befehl
2 = 01xx-xxxx Basis Geschwindigkeits- und Richtungsbefehl r&#252;ckw&#228;rts 28 Stufen
3 = 01xx-xxxx Basis Geschwindigkeits- und Richtungsbefehl vorw&#228;rts 28 Stufen
4 = Lok Funktionen F0, F1 - F4
5 = Lok-Funktionen F5 - F12
6 = Lok-Funktionen F13 - F36
7 = CVs */
 
if (puffern_Lok)
{
// Schauen im Array, ob die gefundenen Bytes schon einmal ausgegeben wurden
if (Lok_counter &gt; 0)
{
for (byte j = 0; j &lt; Lok_counter; j++)
{
Paket_bekannt_L = 0;
if (Lok_received [j].ADR == decoderAddress)
{
Paket_bekannt_L++;
}
if (Lok_received [j].ORDER == Befehl)
{
Paket_bekannt_L++;
}
if (Lok_received [j].FUNC == Funktion)
{
Paket_bekannt_L++;
}
 
if (Paket_bekannt_L == 3)
{
return; // nix machen, keine Ausgabe im seriellen Monitor: war lediglich eine Wiederholung !
}
}
}
if (Lok_counter &gt; 0)
{
// Pufferzeilen mit der gleichen Adresse und dem gleichen Befehl rausl&#246;schen
for (byte j = 0; j &lt; Lok_counter; j++)
{
if (Lok_received [j].ADR == decoderAddress &amp;&amp; Lok_received [j].ORDER == Befehl) // &amp;&amp; Lok_received [j].FUNC == Funktion )
{
for (byte k = j; k &lt; min (Lok_counter, bufferSizeLok - 1); k++)
{
Lok_received [k].ADR = Lok_received [k + 1].ADR;
Lok_received [k].ORDER = Lok_received [k + 1].ORDER;
Lok_received [k].FUNC = Lok_received [k + 1].FUNC;
}
 
Lok_counter--; // ein Eintrag wurde gel&#246;scht
}
}
}
 
// eine Zeile im Acc_received mit neuem Paket bef&#252;llen
if (Lok_counter &lt; bufferSizeLok)
{
Lok_received [Lok_counter].ADR = decoderAddress;
Lok_received [Lok_counter].ORDER = Befehl;
Lok_received [Lok_counter].FUNC = Funktion;
Lok_counter++;
}
else
{
// ersten &#228;ltesten Wert l&#246;schen und alle anderen Wertepaare nach links r&#252;cken
for (byte j = 0; j &lt; bufferSizeLok - 1; j++)
{
Lok_received [j].ADR = Lok_received [j + 1].ADR;
Lok_received [j].ORDER = Lok_received [j + 1].ORDER;
Lok_received [j].FUNC = Lok_received [j + 1].FUNC;
 
}
// den letzten Eintrag nun mit dem neuen Paket bef&#252;llen
 
Lok_received [bufferSizeLok - 1].ADR = decoderAddress;
Lok_received [bufferSizeLok - 1].ORDER = Befehl;
Lok_received [bufferSizeLok - 1].FUNC = Funktion;
 
Lok_counter = bufferSizeLok;
}
}
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Serial.print("Lok ");
lcd.setCursor(0, 1);
lcd.write(" ");
lcd.setCursor(0, 2);
lcd.write(" ");
lcd.setCursor(0, 1);
lcd.write("L");
if (decoderAddress &lt; 10) {
Serial.print(" ");
lcd.print(" ");
}
else if (decoderAddress &lt; 100) {
Serial.print(" ");
lcd.print(" ");
}
else if (decoderAddress &lt; 1000) {
Serial.print(" ");
lcd.print(" ");
}
else if (decoderAddress &lt; 10000) {
Serial.print(" ");
lcd.print("");
}
Serial.print(decoderAddress); Serial.print(" "); Lokname(decoderAddress); Serial.print(" ");
lcd.print(decoderAddress, DEC);
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
switch (instructionType)
{
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case 0:
// 000x-xxxx
Serial.print(" Control ");
break;
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
case 1:
// Advanced Operations
// 001x-xxxx
 
if (Befehls_Byte == B00111111) //128 speed steps
{
//0011-1111 128 Geschwindigkeitsstufen-Befehl
 
// Richtung auswerten Bit 7 "R" im vorletzten Byte
if (bitRead(Msg-&gt;Data[pktByteCount - 2], 7))
{
Serial.print(" --&gt;&gt; ");
lcd.print(" --&gt;&gt; ");
}
else
{
Serial.print(" &lt;&lt;-- ");
lcd.print(" &lt;&lt;-- ");
}
 
// Geschwindigkeit Bit 6 - 0 vom vorletzten Byte
byte speed = Msg-&gt;Data[pktByteCount - 2] &amp; B01111111;
if (speed == 0)
{
Serial.print(" Stopp "); // wenn = 0, dann Stoppbefehl
lcd.print(" S"); // wenn = 0, dann Stoppbefehl
}
else if (speed == 1)
{
Serial.print(" Nothalt "); //


"Meine" Modellbahn:http://www.modelbaneeuropa.dk
Dänisches Bahnforum: http://www.baneforum.dk
PIKO C4 "Horror Gallery": http://moppe.dk/PIKOC4.html


 
moppe
ICE-Sprinter
Beiträge: 5.812
Registriert am: 07.08.2011
Ort: Norddeusche halbinsel
Gleise Roco, PECO, Märklin/Trix, PIKO,
Spurweite H0, N
Steuerung Z21, Lenz, MpC Gahler+Ringsmeier, Games on Track/Faller
Stromart AC, DC, Digital, Analog


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#10 von fbstr , 22.04.2020 20:27

Hallo Martin,

ich möchte gerne Deinen DCC-Monitor auf einem UNO laufen lassen und zwar mit Pin 8 statt 2 und A3 statt A5.
In Zeile 86 wird A3 definiert:

1
 
const byte DccAckPin        = A3;    // Arduino-Pin zur Erzeugung eines ACK-Signals
 



Und nur in Zeile 172 finde ich was zum anderen Pin:

1
 
Dcc.pin(0, 8, 1);                                 // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
 



Tut aber nur wenn ich doch Pin 2 nehme. Benötigt die NmraDcc fest den Pin2?


Gruss
Frank
---------------------------------------------------------------------------------------------------------------------
MobaLedLib Wiki
Projekt "Bahnpark Augsburg"
Stummitreff BB: normalerweise jeden 3. Freitag im Monat im Haus Sommerhof in Sindelfingen


 
fbstr
EuroCity (EC)
Beiträge: 1.345
Registriert am: 28.08.2016
Ort: Stuttgart
Gleise Peco Code 75, Trix C
Spurweite H0, H0e
Steuerung DR5000, Lenz LZV100, MLL
Stromart DC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#11 von Domapi , 22.04.2020 20:55

Das DCC-Signal wird über eine Interrupt-Routine ausgewertet.
Das ist beim Nano/Uno nur über PIN 2 oder 3 möglich.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#12 von ringstrecke , 23.04.2020 07:54

Hallo Martin,

tolles Projekt!!

Habe dazu natürlich ein Fragen.
Ich „spiele“ öfters mit einem STM32F1 Arduino.
Wo gibt es die Adapterplatine mit Schraubanschlüssen für den Arduino?
Ich habe auch bei arltt.de geschaut, habe das ACK-Schaltungsteil nicht gefunden.

Bezüglich des Display arbeite ich mit dem I2C-Bus, denke (hoffe) mal, dass ich das hinbekomme.

Viele Grüße

Martin


HO-Anlage im Aufbau, Lenz-DCC, 8 Booster Fahren, 1 Booster Schalten, PowerManagement für alle, WatchDog, Besetztmelder LDT, Weichendecoder LDT+Lenz, LDT Drehscheibendecoder, RS-Bus, Steuerung mit Railware
Als zweites "Standbein" Aufbau einer LGB Aussenanlage, Z21+WLAN


 
ringstrecke
RegionalExpress (RE)
Beiträge: 94
Registriert am: 03.04.2008
Gleise 550 m Roco Flex
Spurweite H0e
Steuerung Railware
Stromart AC / DC


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#13 von Domapi , 23.04.2020 08:39

Ich selbst nutze eine Lochrasterplatine; wo es Adapterplatinen gibt, weiß ich leider nicht.

Es ist aber keine rocket science, sich die paar Komponenten selbst zusammenzulöten.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#14 von fbstr , 23.04.2020 09:19

Zitat

Wo gibt es die Adapterplatine mit Schraubanschlüssen für den Arduino?
Ich habe auch bei arltt.de geschaut, habe das ACK-Schaltungsteil nicht gefunden.



Hallo Martin,
meinst Du die Testplatine mit meinem Nano drauf?
Die gibt's bei ebay, Amazon oder Ali. Auf die Schnelle habe ich dieses sündhaft teure Teil gefunden: Link (ebay.de)
Also ich bin der Meinung die gibt es in China für weniger als 1€. Ich hatte die mir damals wegen den Printschraubanschlüssen bestellt, die ich für Platinen von Bodo gebraucht hatte.

Die DCC-Platine ist von Thomas Arlitt (digi_thomas2003). Er hatte mir 2017 die Dateien gegeben und ich hatte damit meine ersten Platinen in China machen lassen. Frag ihn mal an ob er noch welche hat. Aber wie Martin (Domapi) schreibt, die Schaltung ist kein Hexenwerk.


Gruss
Frank
---------------------------------------------------------------------------------------------------------------------
MobaLedLib Wiki
Projekt "Bahnpark Augsburg"
Stummitreff BB: normalerweise jeden 3. Freitag im Monat im Haus Sommerhof in Sindelfingen

Mit diesem Beitrag wurden folgende Inhalte verknüpft:

 
fbstr
EuroCity (EC)
Beiträge: 1.345
Registriert am: 28.08.2016
Ort: Stuttgart
Gleise Peco Code 75, Trix C
Spurweite H0, H0e
Steuerung DR5000, Lenz LZV100, MLL
Stromart DC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#15 von ringstrecke , 23.04.2020 13:44

Hallo Frank,

danke für die Hinweise.
Hab leider keine passende gefunden, werde aber weiter suchen.
Ich benutze den STM32F103 - dieser hat 2x 20 Anschlüsse.

Wegen der Platine wende ich mich Thomas.

Gruß Martin
P.S. Hab heute ein Netzteil von Ali mit Kabel bekommen.
Nennt man so etwas klassich genullt ?


HO-Anlage im Aufbau, Lenz-DCC, 8 Booster Fahren, 1 Booster Schalten, PowerManagement für alle, WatchDog, Besetztmelder LDT, Weichendecoder LDT+Lenz, LDT Drehscheibendecoder, RS-Bus, Steuerung mit Railware
Als zweites "Standbein" Aufbau einer LGB Aussenanlage, Z21+WLAN


 
ringstrecke
RegionalExpress (RE)
Beiträge: 94
Registriert am: 03.04.2008
Gleise 550 m Roco Flex
Spurweite H0e
Steuerung Railware
Stromart AC / DC


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#16 von vikr , 23.04.2020 15:53

Hallo Martin,

Zitat


Hab leider keine passende gefunden, werde aber weiter suchen.
Ich benutze den STM32F103 - dieser hat 2x 20 Anschlüsse.




Du wählst hier aber nicht den einfachsten Weg.

Zitat
https://circuitdigest.com/microcontroller-projects/getting-started-with-stm32-development-board-stm32f103c8-using-arduino-ide


Programmieren des STM23F103 mit der Arduino IDE geht, bemötigt etwas Vorbereitung:

Zitat
http://dan.drown.org/stm32duino/package_STM32duino_index.json



Um Frust zu minimieren würde ich vielleicht doch mit einen Atmega 328p-Board anfangen, z.B. dem Arduino Nano ...

MfG

vk


vikr  
vikr
InterCityExpress (ICE)
Beiträge: 2.459
Registriert am: 23.10.2011
Spurweite H0, N


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#17 von Domapi , 23.04.2020 17:02

Kommen wir ˋmal wieder zum eigentlichen Thema zurück.

Hier meine Schaltskizze:



Und ein Bild der aufgebauten Schaltung:



Zwei Kabel mit Klemmen zum bequemen Gleisanschluß und eine zusätzliche LED (mit eingebautem Vorwiderstand) parallel zum R9 als Anzeige des ACK-Signals.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#18 von ringstrecke , 23.04.2020 19:01

Hallo vikr
mit dem STM32 komme ich gut zurecht (ist preisgünstig und für meine Zwecke ausreichend),
habe schon einige für die Kirmesbeleuchtung (WS2812) verbaut.

@Martin, vielen Dank für den Schaltplan, werde mich mal um die Teile kümmern.

Gruß Martin


HO-Anlage im Aufbau, Lenz-DCC, 8 Booster Fahren, 1 Booster Schalten, PowerManagement für alle, WatchDog, Besetztmelder LDT, Weichendecoder LDT+Lenz, LDT Drehscheibendecoder, RS-Bus, Steuerung mit Railware
Als zweites "Standbein" Aufbau einer LGB Aussenanlage, Z21+WLAN


 
ringstrecke
RegionalExpress (RE)
Beiträge: 94
Registriert am: 03.04.2008
Gleise 550 m Roco Flex
Spurweite H0e
Steuerung Railware
Stromart AC / DC


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#19 von Domapi , 09.11.2020 18:49

Heute gibt´s ein Update zu meinem DCC-Monitor, das einen voll krassen Fehler und ein paar andere Lappalien bereinigt. ops:

Offenbar nutzt keiner die Lokdressen 112 bis 127, sonst wäre der Fehler bestimmt schon jemandem aufgefallen. Entweder habt ihr armen Habenichtse <100 Loks im Bestand oder fahrt keine E-Loks, die in diesem Nummernband liegen

Folgende Probleme sind in der neuen Version gelöst:

    Bei den Zubehördekodern wurde die Schaltrichtung/Spule umgedreht und die Textausgabe passt jetzt z.B. zur Anzeige im ESU Lokprogrammer Führerstand Weichenstellpult
    - rote Taste = A
    - grüne Taste = B

    Bei Lokdekoder-Adressen von 112 - 127 wurden falsche DCC-Befehle ausgegeben, da diese vom Sketch fälschlicherweise als Programmierbefehle für das Programmiergleis interpretiert wurden. Nun wird eine zusätzliche Routine der NRMA-Library aufgerufen, die prüft, ob der DCC-Monitor vom Programmiergleis angesprochen wurde. In diesem Fall sendet die Zentrale diverse Befehlsketten, um den Dekoder bzw. Monitor in den Programmiermodus zu versetzen. Die Programmierbefehle fürs Programmiergleis und die Befehle für kurze Lokadressen ähneln sich dummerweise stark …

    Jetzt werden die Lokadressen von 112 - 127 und ihre Steuerbefehle sauber angezeigt. Auf dem Programmiergleis wird der Programmiermodus ein-/ausgeschaltet und im seriellen Monitor ausgegeben.



Wichtig war die Verwendung dieser Routine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
//-------------------------------------------------------------------------------------------------------
// Wird aufgerufen, wenn ein Programmierbefehl von der Zentrale gesendet wurde
// Brauchen wir, um nicht mit den Lok-Adressen 112 - 127 zu kollidieren ;-)
void notifyServiceMode(bool Prg_gleis_Mode)
//-------------------------------------------------------------------------------------------------------
{
Serial.print("Service-Mode/Programmiergleismodus: ");
if (Service_Mode == 0)
{
Serial.println("Ein");
}
else
{
Serial.println("Aus");
 
}
Service_Mode = Prg_gleis_Mode;
}
 



Die neueste Sketch-Version findet sich weiter unten im Thread.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#20 von Domapi , 16.11.2020 19:03

Am Wochenende habe ich mich mal über Layout-Software zur Erstellung von Schaltplänen und Platinen schlau gemacht und habe gleich ´mal mit KICAD einen g´scheiten Plan für den DCC-Monitor erstellt.

Ging nach ein wenig Einarbeitung wider Erwarten recht schnell. Da es mein Erstlingswert ist, fragt lieber vor der Verwendung des Schaltplans eure Eltern …





Insbesondere ist mir der Transistor unten aufgefallen, der wird fast komplett auf GND gezogen, wenn ein ACK-Signal ausgegeben wird.
Obwohl er an der Basis nur für 6ms angesteuert wird, erscheint mir das elegdrisch bedenklich. Bislang funktioniert es.
Evtl. könnte man sicherhalthalber einen 4,7 kOhm Widerstand zwischen Optokoppler Pin 5 und BC557 Basis einbauen.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#21 von Domapi , 03.12.2020 18:59

Ich habe mir spaßeshalber ein paar Platinen für den DCC-Monitor anfertigen lassen. Mein Erstlingswerk und funktioniert sogar

So sieht die Minimalbestückung aus:



Brückengleichrichter
Optokoppler 6N137
Widerstand 1,2 kOhm
Kondensator 100nF
Und natürlich ein Nano

Damit kann man die DCC-Signale schon auswerten.

Bestückt man die Platine komplett, dann lassen sich auch Acknowledgement-Befehle an die Zentrale senden. Dazu braucht man ein paar Bauteile mehr. Den R5 habe ich mit 470 Ohm verwendet, den R6 muss man in Abhängigkeit der verwendeten LED bestimmen. Ich habe eine LED mit eingebauten Vorwiderstand eingelötet und daher den Widerstand mit einem Draht gebrückt. Für normale LEDs sollte ein 470 Ohm eingebaut werden.



Hier der aktualisierte Schaltplan mit den neuen Widerständen R5 und R6:



Ich habe noch ein paar Platinen übrig, die ich günstig abgeben kann; bei Bedarf einfach per PN melden.


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#22 von MicroBahner , 04.12.2020 21:58

Hallo Martin,
ein sehr interessantes Projekt, dass sicher jeder DCC-ler gut gebrauchen kann.

Eine Anmerkung zu deiner Schaltung: Den R5 braucht es nicht, das war schon ok ohne Widerstand. Der Transistor soll ja als Schalter arbeiten und gut durchschalten ( obwohl man ihn in dieser Schaltung eh nicht in die Sättigung bekommt). Den Strom bestimmt R2.
Im Gegensatz dazu ist der 'optionale' Widerstand R6 essentiell, sonst betreibst Du die LED praktisch ohne Vorwiderstand. Sie wird zwar immer nur für 6ms eingeschaltet, aber auf Dauer dürfte ihr ( und auch dem Transistor ) das ohne Vorwiderstand nicht gut bekommen. Du schließt da praktisch über Transistor und LED die DCC-Spannung kurz.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.679
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Spurweite H0
Steuerung Eigenbau
Stromart Analog


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#23 von Domapi , 12.12.2020 18:42

Heute gibt es wieder ein kleines Update meines DCC-Monitors.

Hintergrund der Änderungen waren Tests mit dem ESU Lokprogrammer als "Zentrale". Der Lokprogrammer sendet nämlich ein paar seltsame Befehle aufs Gleis, die die Ausgabe durcheinander gebracht haben.

Es sind sogenannte Analogfunktionsgruppenbefehle. Diese sind von der DCC-Norm durchaus vorgesehen. Beim Lokprogrammer scheinen sie jedoch verwendet zu werden, um den Dekodern mitzuteilen, dass sie gerade vom ESU Lokprogrammer angesprochen werden. Folgende Befehle werden gesendet:

1
2
3
4
5
 
Lok     5   EP5 bayr. FLM      Analogfkt.gruppe Steuerkanal 151 = 128   0000-0101  0011-1101  1001-0111  1000-0000 
Lok 5 EP5 bayr. FLM Analogfkt.gruppe Steuerkanal 152 = 0 0000-0101 0011-1101 1001-1000 0000-0000
Lok 5 EP5 bayr. FLM Analogfkt.gruppe Steuerkanal 153 = 0 0000-0101 0011-1101 1001-1001 0000-0000
Lok 5 EP5 bayr. FLM Analogfkt.gruppe Steuerkanal 154 = 0 0000-0101 0011-1101 1001-1010 0000-0000
 
 



Die "151" erinnert schon stark an die ESU-Hersteller-ID, die normalerweise in der CV8 steht …

Irgendwann muss ich den Monitor mal an das Zimo MXULFA hängen; mal sehen, was da so alles gesendet wird.

Die Platinen sind mittlerweile alle weg; ich habe aber Nachschub in China bestellt, dieses Mal in schickem Rot


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#24 von sambaer1 , 14.12.2020 22:46

Hallo Martin,

erst mal herzlichen Dank für die Entwicklung des DCC Monitor. Der ist sicher für Viele sehr hilfreich.

Ich hab ihn nachgebaut und er funktioniert.

Ich hätte nur einen kleinen Wunsch bei der Ausgabe der Accessory Befehle:

Wenn ich eine Weiche das erste mal zum Beispiel auf Abzweig schalte, wird sie angezeigt. Wenn ich die gleiche Weiche wieder auf Gerade schalte wird sie nicht mehr angezeigt, obwohl der Zustand sich ja geändert hat.

Wenn ich mit "5 Nur neue Zubehör-Pakete anzeigen ein/aus = aus" schalte werden beide Richtungen angezeigt, aber auch alle Wiederholungen, was bei vielen Befehlen sehr unübersichtlich ist..

Es wäre schön, wenn (mit der Einstellung: "5 Nur neue Zubehör-Pakete anzeigen ein/aus = ein") beim Schalten einer Weiche genauso wie beim Schalten einer Lok Funktion jede Zustandsänderung angezeigt würde.

Zu meinem Testfeld: ich habe mit einer DCC++ Zentrale getestet.

Viele Grüße

Bernd


sambaer1  
sambaer1
Beiträge: 8
Registriert am: 14.02.2011
Spurweite H0
Stromart DC, Digital


RE: DCC-Monitor auf Arduino-Basis: --> N E U Version 1.4

#25 von Domapi , 15.12.2020 07:11

Hallo Bernd,

bei mir unter reinem DCC funktioniert das wunderbar. Standardmäßig ist im Sketch die Speicherung der Accessory-Befehle eingeschaltet, damit nur neue Befehle gezeigt werden. Bei mir sieht die Ausgabe beim Schalten der Weichen wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
NMRA DCC Monitor V 1.3
Sketch-Upload am: Dec 11 2020, 06:47:58
? = Zeige Tastaturbefehle f&#252;r den seriellen Arduino-Monitor
Prg Dekoder-Reset-Befehl 0000-0000 1111-1111
DCC-Adresse 21 ( 6 : 1) A On 1000-0110 1111-1000
DCC-Adresse 21 ( 6 : 1) A Off 1000-0110 1111-0000
DCC-Adresse 21 ( 6 : 1) B On 1000-0110 1111-1001
DCC-Adresse 21 ( 6 : 1) B Off 1000-0110 1111-0001
DCC-Adresse 22 ( 6 : 2) A On 1000-0110 1111-1010
DCC-Adresse 22 ( 6 : 2) A Off 1000-0110 1111-0010
DCC-Adresse 22 ( 6 : 2) B On 1000-0110 1111-1011
DCC-Adresse 22 ( 6 : 2) B Off 1000-0110 1111-0011
DCC-Adresse 23 ( 6 : 3) A On 1000-0110 1111-1100
DCC-Adresse 23 ( 6 : 3) A Off 1000-0110 1111-0100
DCC-Adresse 23 ( 6 : 3) B On 1000-0110 1111-1101
DCC-Adresse 23 ( 6 : 3) B Off 1000-0110 1111-0101
DCC-Adresse 24 ( 6 : 4) A On 1000-0110 1111-1110
DCC-Adresse 24 ( 6 : 4) A Off 1000-0110 1111-0110
DCC-Adresse 24 ( 6 : 4) B On 1000-0110 1111-1111
DCC-Adresse 24 ( 6 : 4) B Off 1000-0110 1111-0111
 
 



Zuerst kommt der "On"-Befehl für eine Adresse, der wird solange gesendet, wie man die Taste in der Zentrale drückt. Dann kommt der "Off"-Befehl.
Jeweils nur eine Ausgabe im seriellen Monitor, da ja "nur neue" eingestellt ist.

Evtl. liegt es an der Art und Menge der DCC++ Signale. Ich selbst kenne DCC++ nicht, aber ich vermute, dass die DCC++-Befehle stark von der DCC-Nomenklatur abweichen und daher mit meinem Monitor nicht ausgewertet werden können.

Eine Idee noch: Ganz am Anfang meines Sketches wird die Anzahl der gespeicherten Befehle festgelegt:

1
2
 
const byte bufferSizeAcc    = 5;     // Schaltartikelbefehle werden nicht andauernd wiederholt; hier reichen ein paar Pufferpl&#228;tze aus
 
 



Evtl. hilft bei DCC++ ein größerer Wert, z.B. 20 oder höher.

Alternativ bitte hier mal einen Teil der Ausgaben einstellen (mit Speicherung "aus"), dann kann man vll. erkennen, was DCC++ hier so alles treibt.

Ansonsten darfst Du den Sketch gerne erweitern!


Viele Grüße
Martin

Mein noch namenloser Trennungsbahnhof: viewtopic.php?f=64&t=152275


 
Domapi
EuroCity (EC)
Beiträge: 1.121
Registriert am: 22.09.2015
Ort: Nämberch
Gleise Ohne Pickel
Spurweite H0
Steuerung Mit Hirn und Verstand
Stromart AC, Digital


   


  • Ähnliche Themen
    Antworten
    Zugriffe
    Letzter Beitrag
disconnected Foren-Chat Mitglieder Online 46
Xobor Einfach ein eigenes Forum erstellen
Datenschutz