Shop OBEX P1 Docs P2 Docs Learn Events
Working S-Link code (long) — Parallax Forums

Working S-Link code (long)

ArchiverArchiver Posts: 46,084
edited 2003-02-02 20:44 in General Discussion
I finally got an S-Link program working, to control my CD-changer. I
don't know if anyone would be interested in this, but here you go
anyway. By the way, this was written for the BS-2SX. For other models,
you'll have to adjust the timing to account for different processor
speeds. If you hooked your stamp to both a CD changer and your PC, you
could have a controller much like the Nirvis stereo system (but much
cheaper).

Background: S-link is a relatively slow protocol developed by Sony to
allow home theater units to communicate with each other through a mono
headphone jack. The signal is held high at 5V and a drop to 0V is
used to represent a 0 or 1. A drop in current for 600 microseconds is
a '0' and a drop for 1200 microseconds is a '1'. Each bit is delimited
by 5V for 600 microseconds. A command sequence must begin with a drop
to 0V for 2400 microseconds. The command sequence must be padded by 5V
at the end to make it 45 milliseconds long (but the padding rule is
apparently not very strict). Each command has an ID byte (identifying
the recipient of the command) and one or more command bytes. The
component that received the command will then issue a response
sequence back to the sender. My code issues every command twice, in
case the first time collided with an incoming response sequence from
my CD player. The id byte for 'CD Player #1' is decimal 144, or '1001
0000'. The command byte to 'play' is decimal 0, or '0000 0000'. The
following command would be the equivalent of pressing play on your cd:
'1001 0000 0000 0000'. The command to play 'disc#, track #' (which is
'0101 0000') takes an extra byte for disc# and one for track #.
Following are some commands I have verified to work on my Sony
CDP-CX200. Some, but not all, also work on my CDP-CX53:

1001 0000 0010 1110 - power on
1001 0000 0010 1111 - power off
1001 0000 0000 0000 - play
1001 0000 0000 0001 - stop
1001 0000 0000 1000 - track advance
1001 0000 0000 1001 - previous track
1001 0000 0000 0010 - pause on
1001 0000 0000 0011 - toggle pause
1001 0000 0001 0000 - scan forward (slow?)
1001 0000 0001 0001 - scan backwards (slow?)
1001 0000 0001 0010 - scan backwards (fast?)
1001 0000 0001 0011 - scan backwards (fast?)
1001 0000 0010 0000 - disable console, leaving s-link control only

To play a 'track#' on disc 1, start with: 1001 0000 0101 0000 0000
0001, then:
1) for tracks 1 thru 9, use your track number in binary
2) for tracks 10 and up, use 'track number plus + 6' in binary

For the hardware connection, get a MONO headphone cord from radio
shack with bare ends on one side. Connect the tip (the inner wire i
think?) to an output pin on your stamp (I used pin 8), and the ground
(outer wire?) to ground on your stamp.

Following is my code that works with the two Sony Cd players mentioned
above and my BS-2SX. Some or all of the commands should work with
other Sony cd players with the 'control A1' port on the back. Other
Sony devices with S-Link can be controlled as well (VCR's, DVD's,
etc., but I don't know their addresses/commands). If you're using a
different model Stamp, you can do what I did, which is to plug the
headphone jack into your sound card and record the signal with a
shareware WAV program (Ace Of Wave is a good one, recording at
16bits/mono/100Hz sampling). I ran a risk of blowing my soundcard by
doing this and you will too ;-) . Zoom up on the waveform you recorded
and you can verify the timings visually.

Code starts here:
''''''''''''''''''''
'{$STAMP BS2sx}
'sircs.bs2

DURATION con 6000
array var WORD(2)
array(0) = 500
array(1) = 1200
bytecode var byte
track_to_play var word
track_to_transmit var byte
track_to_play = 1

loop:

random track_to_play
track_to_transmit = (track_to_play / 3277) + 1
debug ? track_to_transmit
if track_to_transmit < 10 then skip_modification
track_to_transmit = track_to_transmit + 6
skip_modification:
gosub play_track
goto loop

play_track:
pulsout 8,2400
pulsout 7,2400
bytecode = 144
gosub bits
bytecode = 80
gosub bits
bytecode = 1
gosub bits
bytecode = track_to_transmit
gosub bits
pulsout 8,5000
'required command sequence padding
pause 500
pulsout 8,2400
pulsout 7,2400
bytecode = 144
gosub bits
bytecode = 80
gosub bits
bytecode = 1
gosub bits
bytecode = track_to_transmit
gosub bits
pulsout 8,5000
'required command sequence padding
pause DURATION

pulsout 8,2400
pulsout 7,2400
bytecode = 144
gosub bits
bytecode = 1
gosub bits
pulsout 8,5000
pause 500
pulsout 8,2400
pulsout 7,2400
bytecode = 144
gosub bits
bytecode = 1
gosub bits
pulsout 8,5000
return


bits:
pulsout 8,730
pulsout 7,array(bytecode.bit7)
pulsout 8,730
pulsout 7,array(bytecode.bit6)
pulsout 8,730
pulsout 7,array(bytecode.bit5)
pulsout 8,730
pulsout 7,array(bytecode.bit4)
pulsout 8,730
pulsout 7,array(bytecode.bit3)
pulsout 8,730
pulsout 7,array(bytecode.bit2)
pulsout 8,730
pulsout 7,array(bytecode.bit1)
pulsout 8,730
pulsout 7,array(bytecode.bit0)-499
return
'''''''''''''''''''''''''''''


This code randomly selects a track between 1 and 17 and plays the
first six seconds of it, displaying the track number in a debug
window. To change the delay durations for 0 and 1, change the values
of array(0) and array(1). The 'pulsout 7' I did is a dummy command,
just to get the stamp to sit there for a few microseconds and put out
5V. The '-499' at the end of the 'bits' subroutine is there to take
into account the time it takes for the stamp to execute the return
command at the end of 'bits'.


--Alex
Sign In or Register to comment.