Wednesday, February 17, 2021

An ATTiny85 as DCC function decoder

Why?


Back in the starting days of our model railroad I bought some used passenger cars from GDR-based manufacturer BTTB. I wanted to install some lights into these cars now and since we're already using DCC, I had the idea to use a function decoder to switch lights on and off. There also is a small empty space in the base of each car that could contain the parts of the decoder, so let's go ahead. Since proper function decoders are still quite expensive, especially if you compare that to the price of the used cars, I decided to look out for a DIY solution.
Besides the Arduino Nano clones (which are rather bulky due to the micro USB connector) a nice and small contender was the Digispark USB board (when using the chinese clones, they are affordable too).  
The Digispark boards use an Attiny85 micro controller with one interrupt connected input (so you get a callback function call when the input value changes, rather than having to poll for the value in your code) and 4 to 5 outputs, which I will not use completely anyway (I only need 1 output for the internal light and 2 outputs for the front and rear end lights).

Design

As a base I used the following circuitry:




On the left side we can see the full bridge rectifier; contrary to the image above I used a SMD S40 rectifier. Additionally you can spot the input diode at the bottom, together with a voltage divider [^1] that is connected to pin 2 of the digispark board (pin 2 is the interrupt pin). To the left of the digispark board, I used 7805 voltage regulator [^2] which delivers a constant 5V voltage from the rectified 14-16V voltage of the DCC signal. You can also see that I used an electrolytic capacitor for storing some energy in case of loss of connection. The BC547 transistor with series resistor R3 is used to switch the LED with its series resistor. Obviously, this last part needs to be repeated for each LED channel (lighting, front & rear), but for simplicity this was left out of the sketch.

[^1]: Later on, I increased the resistor values of the voltage divider circuit to 2kOhm and 8kOhm to reduce the current going through that path.
[^2]: The 7805 is slightly inefficient and gets at least warm due to excess heat is has to radiate - later on I decided to use one of the smallest electronic buck converters I could find, which were similar in size while having a far far lower heat dissipation.

The Software Side

You can now transfer the required program to the digispark with the source code from the following repository:
 

nagf2rpi-functiondecoder.ino

This code uses the library nmradcc, which you can either download directly from that github page or using the Arduino IDE's library manager. The code is based on an example from the nmradcc library, but some changes needed to be made. The function digitalPinToInterrupt doesn't exist for the ATTiny85, so another initialization routine had to be called as well.

The result on my test track can be seen in this video:


youtube video of testing

And Now?

After I came this far, I decided to not use the Attiny85 for the rest of the cars. The disadvantages were simply to high:

- The electric power consumption of the digispark board alone is rather high, I once measured above 30mA (without LEDs and after the voltage regulator). Keeping the LEDs on all the time would have had a far lower impact. This also reduces the usability of the capacitor(400mF) to zero. The solution came in the form of some Arduino Pro Mini clones I could buy for roughly the same price, which only use 1-2mA at a voltage of 3.3V.
- The Attiny85/Digispark has a standard kernel which needs to check for a USB connection too. That's why it will have a down time of a few seconds after each restart (and a restart happens every time the car loses contact to the tracks). One could replace this kernel, but this brings other problems too.
- The price of each Digispark board is rather high, around 3-4€ per piece and the Arduino pro mini modules are comparable..
- I extracted grey smoke from several of the Digisparks I originally bought (happens when you mix up the cabling...), so I'd have to buy new ones anyway.

I hope this helps, maybe I'll make the planned video about DIY DCC decoders in the future.

Monday, February 15, 2021

Ein ATTiny85 als Funktionsdecoder

Warum?

In den Anfangszeiten unserer Anlage habe ich ein paar alte BTTB Personenwagen gekauft, die ich jetzt einmal mit einer Beleuchtung ausstatten wollte. Da wir ja bereits digital fahren, wurde nach einigem hin und her die Idee geboren, vor die LED-Beleuchtung auch noch einen (Funktions-)Decoder zu setzen, der zwischen Wagenbogen und Boden der Inneneinrichtung passen könnte. Da einfache Funktionsdecoder vergleichsweise teuer sind und den Preis pro Wagen weit übersteigen würden, habe ich mich nach einer Selbstbaualternative umgeschaut.
Neben den doch eher großen Arduino-Nano-Verschnitten kam dafür ein Digispark-Board in Frage, welches zumindest in der Variante als chinesischer Nachbau vertretbar ist.
Der Digispark besitzt einen einzigen Eingang mit Interrupt (als Eingang für das DCC-Signal; ein Interrupt wird benötigt, damit nicht immer der Status des Eingangs gelesen werden muss, sondern bei Veränderung des Eingangs automatisch eine Funktion aufgerufen werden kann) und 4 oder 5 Ausgänge (die ich aber erstmal einmal nicht alle brauche - ich will maximal 3 Ausgänge für die Innenbeleuchtung und die Wagenschlussbeleuchtung in beide Richtungen).

Der Bauplan

Als Grundlage habe ich also folgenden Bauplan gewählt:



Auf der linken Seite können wir den Gleichrichter sehen; im Gegensatz zur Skizze habe ich da einen S40 SMD Gleichrichter benutzt. Weiterhin kann man an der Unterseite der Skizze die Eingangsdiode erkennen, die zusammen mit der Spannungsteilerschaltung[1] R1/R2 auf Pin 2 des Digispark gelegt wurde (Pin 2 ist der Pin auf dem der Interrupt liegt). Links vom Digispark kann man den 7805 Spannungsregler[2] erkennen, der aus der Gleichspannung von ungefähr 14-16V die 5V Versorgungsspannung für den Digispark erzeugt. Direkt rechts neben dem Gleichrichter ist nun beispielhaft sowohl der Stützkondensator (C1) zu sehen, als auch ein BC547 Transistor mit Vorwiderstand R3 und die zu schaltende LED mit Vorwiderstand. Dieser letzte Teil würde für jede zu schaltende LED (Beleuchtung, Schluss- und Frontbeleuchtung) wiederholt, ich habe dies aber der Einfachheit halber weggelassen.

[1] Die Spannungsteilerschaltung habe ich später jedoch mit höheren Widerständen mit 2kOhm und 8kOhm verbessert um den Stromfluss zu verringern.
[2] Der 7805 ist relativ ineffizient und wird relativ schnell warm - deshalb habe ich ihn später durch einen Buck-Converter ersetzt - die kleinsten Buck-Converter die ich finden konnte waren in vergleichbarer Größe aber mit einem vielfach verringerten Stromverbrauch.

Die Software

Der Digispark wird nun mit der Arduino IDE mit dem source code aus diesem repo bespielt:

https://github.com/sengels/nagf2rpi-functiondecoder/blob/master/nagf2rpi-functiondecoder.ino

Dieser Code benutzt die Bibliothek nmradcc, die entweder direkt von github oder aus der Arduino-Bibliotheksübersicht benutzt werden kann.
Ein paar Änderungen müssen hierbei gemacht werden, die Funktion digitalPinToInterrupt existiert nicht für den Attiny85, deshalb muss dann auch eine andere Initialisierungsroutine aufgerufen werden als in dem ursprünglichen Beispiel.

Auf meinem Testgleis sieht das ganze nun folgendermaßen aus:

Test

Und nun?

Nachdem ich soweit war, habe ich mich nun doch entschlossen, nicht weiter mit dem Attiny85 zu arbeiten, die Nachteile sind nämlich relativ hoch:
  • Der Stromverbrauch des Digispark boards ist ziemlich hoch, ich habe im laufenden Betrieb deutlich über 30mA gemessen. Die LEDs für die Beleuchtung benötigen nur einen Bruchteil. Bei diesem hohen Stromverbrauch ist auch der Stützkondensator keine Hilfe mehr. Außerdem hatte ich zwischenzeitlich einen Arduino pro mini clone bestellt und diesen bei 3,3V mit ungefähr 2mA betreiben können.
  • Der Attiny/Digispark muss deutlich aufwendiger bespielt werden, der Standard-Kernel hat eine 6-sekündige Einschaltdauer, die halt bei jedem Kontaktverlust an der Schiene auftreten würden.
  • Der Preis für einen digispark ist immer noch sehr hoch und unterscheidet sich nicht von einem arduino pro mini (ungefähr 3-4€ pro Stück)
  • Ich habe leider mehrere Digisparks in Rauch aufgehen lassen (wenn man beim decoder halt die Anschlüsse vertauscht), werde aber keine weiteren Digisparks mehr kaufen.

Ich hoffe, diese Ausführungen helfen jemandem, vielleicht mache ich tatsächlich noch einmal ein youtube-Video dazu.