Control circuitry for a Cassette Deck

This was a Cassette Deck rebuild project.

The original Philips Servo mechanism for my FC562 failed, and a replacement was not available. The Cassette deck was too good to throw out (Dolby C NR, etc), so I planned a rebuild.

A suitable Solenoid mechanism was sourced (Akai unit) and modified to fit.

There are two solutions to control the deck. Discrete Logic chips, or a Microcontroller based circuit.

CMOS:

CMOS logic circuitry and MOSFET drive electronics were designed to control the Akai unit. Also, a digital up/down counter was designed and IR Remote control unit designed. The original Philips cassette deck now has full auto stop, IR control, and digital counter. The PCB was designed using Protel Easytrax for the Mac.

Front Panel view showing redesigned control panel using wafer switches

An early prototype of the Control and drive electronics board (Remote control underneath to the left)

 

 

 Vero-board version of the first Prototype. Use this along with the circuit diagrams as a guide if you want to make your own. The final PCB version is not much different.

download the pdf for the MOSFET used in this circuit.

Microcontroller:

The Microcontroller version of the circuit developed in two parts. Firstly, as an add on to the CMOS circuitry to enable remote control via a Mac or PC, then it seemed logical to just use the Micro to do the whole job.

Serial Interface: With a Stamp Microcontroller installed to receive commands via the serial port. Currently supports Rec, Rewind, Fast Forward, Play, and Stop. Future enhancments could include auto cue, indexing, end of track marking, etc.. The Deck can be controlled from a terminal emulator, such as Hyperterminal, or ClarisWorks Data Communictions, or by using my GUI interface. (Mac version - Windows to come soon).

The GUI Interface for Macintosh:

Mac requirements:

 

Circuit diagram of the Stamp Control circuit.

As you can see, the Stamp IC is on 5V TTL Levels (you can supply the Stamp with +12v on it's Vin Pin, but it will regulate it's self to +5V), so a simple level shifting circuit is provided to translate the +5V logic level to +12V for the existing circuitry.

The code to burn to the Microcontroller is here.

 

Full Micro control:

The original Logic circuit I designed has now been removed, and the Stamp Microcontroller is now the heart of the system. Simplfied circuit, and easily modified for future enhancements. Also, an annoying counter glitch (see the counter circuit diagram for the CMOS circuit) is gone.

The original logic circuit is now being put to good use by a friend...

The new control circuit's circuit diagram is below. This is the interface board, it plugs into a Basic Stamp OEM.

Circuit Diagram

 

 Overlay

 Installed Board

It works!...

Eagle CAD files: Board Schematic

Here is a version of the final code that provides basic functions, and displays the mode the deck is in on the display (Play, FFWD, etc). It also accepts commads from the serial port, using my GUI interface above (or a terminal emulator). Counter code is implemented, and auto stop. Also, this code reflects a modification made to my board, where I decided I don't need the EOT line, and it would be good to be able to drive the Motor with it's own line. EOT ("autostop") can be implemented easily anyway - if pulses stop coming from the counter, then the tape must have stopped. This will get you started, but it could do with a bit of optimising...

DIRS=%0100011111111111 'Set required ports (P14, P10 - P0) as OUTPUTS

'*********Declare Variables***************
command VAR BYTE
prev_count_state VAR BIT
counter_value VAR WORD
rewind VAR BIT

'Display messages
DATA 56,121,55,55,119,49,94,0 'LENNARD
DATA 121,56,121,57,120,49,63,55,6,57,109,0 'ELECTRONICS
_Stop DATA 109,120,63,115 'STOP
Play DATA 115,56,119,110 'PLAY
Rec DATA 49,121,57 'RECORD
RW DATA 113,64,124,119,57 'REWIND
FF DATA 113,64,113,63,49 'Fast Forward
_Pause DATA 115,119,62, 109, 121 'Pause 
_hello DATA 118,121,56,56,63  'Hello
counter DATA 63,6,91,79,102,109,125,7,127,111,128 'digits for the counter

'CONSTANTS
clock CON 5 'P5 = clock to 4094's pin 3
datapack CON 6 'P6 = Data to 4094's pin 2

'VARIABLES
strobedigit VAR NIB 'a four bit variable used to determine which digit to update
character VAR BYTE 'the data to send to the display
a VAR BYTE
b VAR BYTE
boolean VAR BIT
startletter VAR BYTE
endletter VAR BYTE
spaces VAR NIB
disp_value VAR NIB
divider VAR WORD
auto_stop VAR BYTE

'*****MAIN PROGRAM*****
boolean = 0
LOW 7
LOW 8
LOW 9
LOW 10
LOW 14
counter_value = 0
auto_stop = 0
rewind = 0

'Display cute welcome message
GOSUB hello
GOSUB blankdisplay
startletter = 0
endletter = 0
spaces=0
FOR b = 1 TO 23
   FOR a = startletter TO endletter
      READ a, character
      strobedigit = spaces + endletter - a
      GOSUB loadregisters
   NEXT
   PAUSE 200
   endletter = endletter + 1
   IF endletter > 4 THEN incrementstartletter
   GOTO endofroutine
   incrementstartletter:
      IF endletter > 19 THEN endlettermax
      startletter=startletter + 1
      GOTO endofroutine
   endlettermax:
      endletter = 19
      spaces = spaces + 1
      startletter=startletter + 1
   endofroutine:
NEXT
' End of cute welcome message

GOSUB display_stop 'Just let the user know not much is happening...
_loop:  'now that cute welcome message is done with, let's play some music
   GOSUB checkcounter
   GOSUB checkbuttons 'has the user pressed a button?
   GOSUB CheckSerial  'check if a command from the serial port
GOTO _loop

blankdisplay:
SHIFTOUT datapack, clock, MSBFIRST, [0] 'blank display
FOR a = 0 TO 4
   PULSOUT a,1 'Strobe each digit
NEXT
RETURN

loadregisters:
   SHIFTOUT datapack, clock, MSBFIRST, [character] 'Send data to the display
   PULSOUT strobedigit,1 'Strobe required digit to display the data
RETURN

CheckSerial: 
'2400 baud 8N1 - fast enough...  Use a terminal emulator, or the Mac app on my website...
   SERIN 16, 396, 20, CheckButtons,[command]
   IF command = 82  THEN GOSUB checkforrecord 'R
   IF command = 112  THEN GOSUB checkforplay 'p
   IF command = 114  THEN GOSUB checkforrewind 'r
   IF command = 102  THEN GOSUB checkforfastforward 'f
   IF command = 115  THEN GOSUB checkforstop 's
   IF command = 80  THEN GOSUB checkforpause 'P
RETURN

checkbuttons:
   GOSUB checkcounter
  'Record Pressed?
   IF IN11 = 0 AND IN12 = 1 AND IN13 = 0 THEN GOSUB checkforrecord
   GOSUB checkcounter
   'Play Pressed?
   IF IN11 = 1 AND IN12 = 0 AND IN13 = 0 THEN GOSUB checkforplay
   GOSUB checkcounter
  'Stop Pressed?
   IF IN11 = 1 AND IN12 = 1 AND IN13 = 1 THEN GOSUB checkforstop
   GOSUB checkcounter
  'Pause Pressed?
   IF IN11 = 1 AND IN12 = 1 AND IN13 = 0 THEN GOSUB checkforpause
   GOSUB checkcounter
  'FF Pressed?   
   IF IN11 = 0 AND IN12 = 0 AND IN13 = 1 THEN GOSUB checkforfastforward
   GOSUB checkcounter
  'REW Pressed? 
   IF IN11 = 1 AND IN12 = 0 AND IN13 = 1 THEN GOSUB checkforrewind
   GOSUB checkcounter
   GOSUB checkautostop
RETURN

checkautostop:
   'Pulses from counter stopped?  Port 15
   auto_stop = auto_stop + 1
   IF auto_stop = 40 THEN 
      auto_stop = 0
      rewind = 0
      LOW 7
      LOW 8
      LOW 9
      LOW 10
      LOW 14
      GOSUB display_stop
   ENDIF
RETURN

checkforrecord:
   'RECORD pressed?
   rewind = 0
   boolean = 1
   HIGH 7
   HIGH 8
   LOW 9
   LOW 10
   HIGH 14
   GOSUB display_record
RETURN

checkforplay:
   'PLAY  pressed?
   rewind = 0
   boolean = 0
   LOW 7
   HIGH 8
   LOW 9
   LOW 10
   HIGH 14
   GOSUB display_play
RETURN

checkforrewind:
   'REWIND  pressed?
   rewind = 1
   LOW 7
   LOW 8
   HIGH 9
   LOW 10
   HIGH 14
   GOSUB display_rewind
RETURN

checkforfastforward:
   'FASTFORWARD  pressed?
   rewind = 0
   LOW 7
   LOW 8
   LOW 9
   HIGH 10
   HIGH 14
   GOSUB display_fastforward
RETURN

checkforpause:
   'PAUSE pressed?
   IF boolean = 0 THEN 'record mode?
      LOW 7
      ELSEIF boolean = 1 THEN 'if record mode, keep 7 high while paused
         HIGH 7 'so the audio input can still be monitored while paused
   ENDIF
   LOW 8
   LOW 9
   LOW 10
   HIGH 14
   GOSUB display_pause
RETURN

checkforstop:
   'STOP pressed?
   rewind = 0
   LOW 7
   LOW 8
   LOW 9
   LOW 10
   LOW 14
   GOSUB display_stop
RETURN

display_stop:
   GOSUB blankdisplay   
   FOR a = 0 TO 3
      READ _Stop + a, character
      strobedigit = 3 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

display_play:
   GOSUB blankdisplay   
   FOR a = 0 TO 3
      READ Play + a, character
      strobedigit = 3 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

display_record:
   GOSUB blankdisplay   
   FOR a = 0 TO 2
      READ Rec + a, character
      strobedigit = 2 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

display_fastforward:
   GOSUB blankdisplay   
   FOR a = 0 TO 4
      READ FF + a, character
      strobedigit = 4 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

display_rewind:
   GOSUB blankdisplay   
   FOR a = 0 TO 4
      READ RW + a, character
      strobedigit = 4 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

display_pause:
   GOSUB blankdisplay   
   FOR a = 0 TO 4
      READ _Pause + a, character
      strobedigit = 4 - a
      GOSUB loadregisters
   NEXT
   PAUSE 1000
RETURN

hello:
   GOSUB blankdisplay   
   FOR a = 0 TO 4
      READ _hello + a, character
      strobedigit = 4 - a
      GOSUB loadregisters
   NEXT
   PAUSE 3000
RETURN

checkcounter:
   IF IN15 = 1 AND prev_count_state = 0 THEN
      prev_count_state = 1
      IF rewind = 1 THEN
         counter_value = counter_value - 1
         ELSE
         counter_value = counter_value + 1
      ENDIF
   auto_stop = 0 'reset auto stop count
   ENDIF
   IF IN15 = 0 AND prev_count_state = 1 THEN
      prev_count_state = 0
   ENDIF

   'Figure out 10000 unit
   disp_value = counter_value/10000   
   strobedigit = 4
   READ counter + disp_value, character
   GOSUB loadregisters

   'Figure out 1000 unit
   divider = disp_value * 10000    
   divider = counter_value - divider 
   disp_value = divider/1000  
   strobedigit = 3
   READ counter + disp_value, character
   GOSUB loadregisters

   'Figure out 100 unit
   divider = divider - (disp_value * 1000)  
   disp_value = divider/100   
   strobedigit = 2
   READ counter + disp_value, character
   GOSUB loadregisters
   
   'Figure out 10 unit
   divider = divider - (disp_value * 100)  
   disp_value = divider/10   
   strobedigit = 1
   READ counter + disp_value, character
   GOSUB loadregisters

   'Figure out 1 unit
   divider = divider - (disp_value * 10)  
   disp_value = divider  
   strobedigit = 0
   READ counter + disp_value, character
   GOSUB loadregisters
RETURN