SUSI Soundmodule ohne Decoder ansteuern

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!

 

Schaltung

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.

Ergebnis

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.


Testprogramm


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