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.