SUSI Soundmodule (z. B. von Uhlenbrock) werden von kompatiblen Decodern mit Digitalbefehlen angesteuert. Die Datenübertragung erfolgt seriell mit separaten Daten- und Taktleitungen. Wenn man die Steuerdaten mit einem kleinen Prozessor wie z.B. einem PICAXE erzeugt, so kann man das Soundmodul durch beliebige Auslöser ansteuern, also z. B. über Schalteingänge oder Spannungsmessung am PICAXE. Damit wird das Soundmodul viel breiter einsetzbar. Und genau das wollte ich ausprobieren!
Man nehme einen PICAXE 14M2 (oder einen anderen M2 Typ), spendiere ihm zwei externe Transistoren BC550 als OC Ausgänge, eine Tastaturmatrix zur Eingabe von 0-9 sowie ein Poti zur Einstellung der Geschwindigkeit. Das Programm weiter unten macht das deutlich.
Die SUSI-Steuerbefehle wurden frei publiziert und finden sich bei www.d-i-e-t-z.de oder auch bei normen.railcommunity.de. Dort ist auch die genaue Beschaltung der OC-Ausgänge beschrieben. Beide NPN-Transistoren liegen mit Emitter auf Masse und erhalten je einen Serienwiderstand 470 Ohm vom Collector zum Modul und einen Pullup von 22 K vom Collector nach Plus, die Basis wird jeweils über 1K2 angesteuert.
Das SUSI Soundmodul wird mit 15V Gleichspannung versorgt, der PICAXE mit 5V. Ich habe testweise ein Uhlenbrock 32300 mit T3-Sound angeschlossen und alle verfügbaren Sounds auf F1-F9 programmiert, F0 ist das Fahrgeräusch, das Poti gibt die Geschwindigkeit vor.
Das Bild zeigt die vom PICAXE erzeugten SUSI-Signale (für F9 on) auf DATA und CLOCK.
Definitions:
'Programm für PICAXE 14M2 mit 32 MHz und 3x4 Tastaturmatrix für F0-F9
'Copyright 2015 Matthias Eiermann
setfreq m32
'bytes 0-1 reserviert für bits 0-15 für SUSI Datenausgabe
symbol cmdbyte1=b0 : symbol cmdbyte2=b1 : symbol pulstime = b2
symbol sendbit=b3 : symbol keyinput=b4 : symbol analogin=b5
symbol counter=b6 : symbol countbyte=b7 : symbol funcval=b8
input B.1 'Analog In 0-5V für Geschwindigkeit
output B.2 '123 Tastaturmatrix
output B.3 '456 Tastaturmatrix
output B.4 '789 Tastaturmatrix
output B.5 '*0# Tastaturmatrix
output C.0 'data (invertiert für externen BC550 OC-Ausgang (via 22 K, 1K2 an +5V))
output C.1 'clock (invertiert für externen BC550 OC-Ausgang (via 22 K, 1K2 an +5V))
input C.2 '147* Tastaturmatrix
input C.3 '2580 Tastaturmatrix
input C.4 '369# Tastaturmatrix
high C.0 : high C.1 '=Low hinter externem NPN Transistorausgang
pulstime=64 '100 µs Clock-Puls
write 0, 0 'Status F0-F4
write 1, 0 'Status F5-F12
write 2, 0 'Status Vloco 7bit
'Initialisierung SUSI Modul
pause 100 'Warten auf SUSI Modul Initialisierung
cmdbyte1=%01100000 : cmdbyte2=%00000000 : gosub sendsusi : pause 100 'F 0-F 4 auf Null
cmdbyte1=%01100001 : cmdbyte2=%00000000 : gosub sendsusi : pause 100 'F 5-F12 auf Null
cmdbyte1=%01100010 : cmdbyte2=%00000000 : gosub sendsusi : pause 100 'F13-F20 auf Null
cmdbyte1=%01100011 : cmdbyte2=%00000000 : gosub sendsusi : pause 100 'F21-F28 auf Null
cmdbyte1=%00100100 : cmdbyte2=%00000000 : gosub sendsusi : pause 100 'Vloco auf Null
Main:
do
gosub keyboard
gosub keysend
loop
end
keyboard:
readadc B.1,analogin : analogin=analogin/2 : keyinput=0
for counter=1 to 4
select counter
case 1: high B.5
case 2: high B.4
case 3: high B.3
else : high B.2
endselect
if pinC.2 = 1 then : keyinput = counter*3-2 : endif
if pinC.3 = 1 then : keyinput = counter*3-1 : endif
if pinC.4 = 1 then : keyinput = counter*3-0 : endif
low B.2 : low B.3 : low B.4 : low B.5 : if keyinput=11 then : keyinput=10 : endif
next counter
return
keysend:
select keyinput
case 10
read 0,funcval : funcval=funcval xor %00010000 : write 0,funcval
cmdbyte1=%01100000 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 1
read 0,funcval : funcval=funcval xor %00000001 : write 0,funcval
cmdbyte1=%01100000 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 2
read 0,funcval : funcval=funcval xor %00000010 : write 0,funcval
cmdbyte1=%01100000 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 3
read 0,funcval : funcval=funcval xor %00000100 : write 0,funcval
cmdbyte1=%01100000 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 4
read 0,funcval : funcval=funcval xor %00001000 : write 0,funcval
cmdbyte1=%01100000 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 5
read 1,funcval : funcval=funcval xor %00000001 : write 1,funcval
cmdbyte1=%01100001 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 6
read 1,funcval : funcval=funcval xor %00000010 : write 1,funcval
cmdbyte1=%01100001 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 7
read 1,funcval : funcval=funcval xor %00000100 : write 1,funcval
cmdbyte1=%01100001 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 8
read 1,funcval : funcval=funcval xor %00001000 : write 1,funcval
cmdbyte1=%01100001 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
case 9
read 1,funcval : funcval=funcval xor %00010000 : write 1,funcval
cmdbyte1=%01100001 : cmdbyte2=funcval : gosub sendsusi
do : gosub keyboard : loop until keyinput=0
else
read 2,funcval : if analogin<>funcval then
funcval=analogin : write 2, funcval
cmdbyte1=%00100101 : cmdbyte2=funcval : gosub sendsusi
cmdbyte1=%00100100 : cmdbyte2=funcval : gosub sendsusi
endif
endselect
return
sendsusi:
'Umständliche Programmierung zur Erzielung kurzer Abwicklungszeiten
'Bits 0-15 stehen in Bytes b0 und b1 (Variablen cmdbyte1 und cmdbyte2)
high C.0
if bit0=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit1=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit2=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit3=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit4=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit5=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit6=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit7=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit8=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit9=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit10=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit11=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit12=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit13=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit14=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
if bit15=1 then : low C.1 : else high C.1 : endif
pulsout C.0, pulstime
high C.1
return