Skip Navigation.
Section 0

Windows Interface: FAQ

By Mark David [21030170+]


Who are you?

Hi. I am Mark David. I have a Rhodes Chroma serial #21030170, and a Chroma Expander serial #16330023 (needs repair). I also have an ARP 2600, which was my first synthesizer, and which I am now teaching my daughter and her 4th grade class to program.

The synths, and music in general, are only a hobby for me. At one time, I did play the ARP 2600 in a Boston punk band, named Daily Bodies. The band had a vocalist, two bass guitars, one drummer, and my synth, and was pretty painful to listen to (although that wasn't really very much of a liability at the time). Though short lived and with very few gigs to their credit, many long-time Bostonians claim to have heard of them. This is, I believe, due to an apparently indelible bit of graffiti placed strategically near Landsdowne Street early on in our career.

What is a Rhodes Chroma?

The Rhodes Chroma is a digitally-controlled analog synthesizer. My favorite site for more information is Chris Ryan's Rhodes Chroma site.

Why are you doing this?

There are (at least) three reasons why it would be fun and useful to hook up the Chroma to a computer. First, you can only play 2 instruments per Chroma/expander at a time using the manual interface; with a computer interface you can play 8. Second, the manual interface (one slider, one display, multiple programs/parameters) is a pain to use for someone who learned synths on an ARP 2600 and its more visually intuitive patching; a graphical programming interface would be a big improvement. Third, the computer can be used to "record" a performance on the Chroma; software could then be developed to edit, mix and playback these performances (on ANY Chroma).

The Chroma has a 25-pin port labelled "Computer Interface". It comes with a cable that works very well for hooking the Chroma to an expander and playing them both at the same time. Mine even came with a black box labelled "Chroma/Computer Interface", with a number of plugs and cables on or emerging from it and which I am informed probably was intended to plug into an Apple II card. I don't have an Apple II, however, and do not intend to get one. My first idea was to plug the Chroma's cable into my PC's parallel port, and see what happened; my thanks to the many people who kindly asked me not to do that. But by that time, I had already decided to solve this problem.

Hasn't someone else already done this?

Yes. Apparently at least four PC/Chroma interface boxes/cards exist. The most popular seems to be the Chroma Cult. But they all suffer from two shortcomings. First, they are MIDI interfaces to the Chroma's native programming protocol; I didn't want to use MIDI, for reasons I'll detail later. Second, they weren't built by me; I just wanted to do this myself, for the fun of it.

Overall Design

Why didn't you use MIDI?

Why did you use the PC serial port, instead of the parallel port?

At first I did try to use the parallel port, but ran into problems. I now know a lot more about how the serial port works than I do about the parallel, but here's my understanding of the issues.

Why did you do this as an external box, rather than an internal card?

Again, I wanted to use this on any computer, including my old laptop which can only be expanded with PCMCIA cards. I don't know any specifics about designing & building internal cards. It's got to be more complex. I'm terrible at building circuits. I was afraid of frying my entire computer.

Why did you implement the PC software as a client and server object library?

Because, though you are free to use my client interface, you may not like it as much as one you can design and build yourself. The server object library is intended to expose all the functionality of the Chroma in an API that anyone can use to create their own client.

Why can only one Chroma (#0) transmit performance info back to the computer?

I wanted to be able to receive commands from any number of Chromas, but I think it's currently beyond my circuit-designing skills. Factors that weighed into my decision include:

Why is the Chroma addressing command designed that way?

Well, I needed to find a way to specify which Chromas were the target of a given command. It would have been unwieldy to do it in the server by sending the same command multiple times with an address byte, and it would have resulted in timing errors (albeit small). There were unused numbers in the Chroma command space, so I'm using these and trusting in the Chroma's spec to ignore bad commands. (It works)

A more involved question is why use the least significant 4 bits as a bit map to control 4 Chromas, as opposed to an address controlling 16 Chromas (or add another byte to control 256 Chromas, or combine the two to control 4098 Chromas). First, this way only a single byte command is necessary to set the state of all the Chromas; were the bits used as an address, there would be need to be a defined ON command and a defined OFF command, and a separate command would need to be issued for each Chroma to change its ON/OFF state. Second, I don't have an immediate application for more than 4 Chromas. The most I've heard of so far in a single person's possession is 3. While it would be nice to imagine a concert with 4098 Chromas onstage playing simultaneously under a single PC's control, I'll do a re-design when such an event seems likely to occur.

Circuit Design

Why didn't you use a microprocessor?

I started out designing it that way. It seemed natural, since my strengths are in programming and not in circuit design. Gradually though, I realized that what this circuit was required to do was very easy - primarily just pass bytes back and forth. The only additional functionality required was the ability to address multiple Chromas; eventually I concluded that a microprocessor was overkill. The design strategy became: keep the circuit as simple and dumb as possible; implement all the smarts in the PC software. The circuit's cheaper this way, too.

Why didn't you use a more popular 8051/8052 family UART, instead of the CDP6402 style?

It seemed much simpler to me to have separate input and output buses on the UART, even though you have to add an external clock. The 8051/8052 style UARTs put the parallel transmit & receive on the same pins - I wasn't sure how to design around that, and what sort of power problems I'd have to guard against to keep from damaging the Chroma.

In retrospect, this may have been a mistake. During the testing of the circuit, I remembered everything I'd forgotten about 3-state outputs, so I think I could have handled an 8052's combination of the output & input buses onto the same pins. Furthermore, the CDP6402 has a couple of idiosyncracies that I didn't notice in the fine print that really complicated the design of the Chroma-->Computer communication; more about that below.

Why do you need all that logic to control the Chroma-->Computer communication?

It started out much simpler. I was going to use !XIFULL directly to lower !THRL on the UART, which loads the byte from the Chroma into the UART buffer. But, surprise: the load doesn't happen until the trailing edge of the pulse. So you lower it from the Chroma's !XIFULL and ... nothing happens. Furthermore, I intended to use THRE from the UART (which, when lowered, signals that its buffer is full) to pulse !XIACK to the Chroma and tell it that we'd received its byte. This actually works fine for the first byte or two; but for the remaining bytes in a multi-byte command, THRE can stay low for a relatively long time waiting for the previous byte to be sent serially to the computer. The Chroma apparently, when it has a new byte to send, gets ACK'ed immediately if !XIACK is still low, and you lose all the remaining bytes.

I tried combining logic with clock pulses (not reliable, as the clock is free running and asynchronous with the Chroma), having the computer do all the handshaking directly via otherwise unused Serial port pins (couldn't ACK fast enough, lost bytes), and using an LM556 chip to generate pulses (I forgot that this is great for making long pulses out of short ones, not vice versa). In the end, I've come up with the solution shown, which adds (much to my chagrin) 2 chips to the circuit. Basically, the logic feeds High bits into a shift register put together from 4 flip-flops. When it detects that it's OK to read from the Chroma and transmit it to the Computer, it feeds one Low bit into the register. The low pulse that eventually appears at the 2nd flip-flop is fed to !THRL to load the UART; the low pulse from the 4th flip-flop is fed to !XIACK on the Chroma. It is working very reliably.

How much does the circuit cost?

The following breakout is based on assumptions that basically reflect my construction methods, which were wire-wrap. I'm not including basic circuit testing and construction supplies like a breadboard & wires, power supply, solder gun, etc. I'm also not including the cables to connect the circuit to the Chroma and the computer, only because I already had them, and don't really know what they cost. Costs were what I paid (in USD); of course they'll vary somewhat according to source. I didn't include shipping, either.

For a single Chroma:

Part Price
CDP1854ACE UART $7.28
MAX233 dual RS-232 transciever $5.39
MC74HC4060AN counter $0.62
74HCT175 quad D-type flip-flop $1.19
74LS00 quad NAND gate $0.22
74LS02 quad NOR gate $0.20
2.4576 MHz crystal $2.13
(2) 16pF capacitors and a 10M resitor (~ $1)
DB-9 wire-wrap connector, male $6.00
DB-25 wire-wrap connector, male $7.60
40-pin (wide) DIP wire-wrap socket $2.79
20-pin DIP wire-wrap socket $1.44
(2) 16-pin DIP wire-wrap sockets $2.32
(2) 14-pin DIP wire-wrap sockets $2.04
TOTAL $38.09

For a second Chroma:

Part Price
74LS378 hex D-type flip-flop $0.46
74LS00 quad NAND gate $0.22
DB-25 wire-wrap connector, male $7.60
20-pin DIP wire-wrap socket $1.44
14-pin DIP wire-wrap socket $1.02
TOTAL (including first Chroma) $48.83

For each additional Chroma:

Part Price
74LS00 quad NAND gate $0.22
DB-25 wire-wrap connector, male $7.60
14-pin DIP wire-wrap socket $1.02
TOTAL (additional for each Chroma) $8.84

Any construction tips or notes?

YES! Most important, especially if you're not (as I am not) any good at this circuit stuff. Although the circuit draws its power from the Chroma, I highly recommend building and testing it entirely with another +5V power source. I learned this by accidentally shorting the +5V to ground briefly, which my Chroma very much did not like. Fortunately, it survived intact; but I wouldn't want to have that happen again. Build and test the circuit with another supply, and only connect pin 5 from Chroma 0 to the +5V bus when absolutely everything else is complete and working. Since I'm not very practiced at this, I also found that it took much less time altogether when I religiously retested the circuit, completely, very often - after every added/changed connection, if possible. I found that inevitably, after adding 5 wires at a shot without interim testing, I broke the circuit. I wrote a test server to run on the computer to do this - you will be able to use the Server Object Libray and my client to do this when they are finished.

Server Object Library

What is the Server Object Library?

It is a set of components (or DLL's, as we used to say) to help out programmers developing Windows applications that are going to interface with Chromas via the interface circuit that I designed. The first component is called ChromaServer, and handles (i.e., frees the programmer from having to deal with) the lower level communications with the Chroma and its proprietary command language. On the other hand, dealing with ChromaServer is still somewhat like dealing with a Chroma directly, with concepts (objects) like Program, Parameter and Instrument. The next component, called SynthServer will provide programmers with more musician-ly objects like Oscillator, Filter and Amplifier. It will call upon ChromaServer to get its work done.

Why aren't the cassette interface commands supported by ChromaServer?

I didn't add support for the cassette interface commands because I have never had nor used a cassette to store/load my programs. Thus, I not only don't have a way of testing whether my code that might support these would work, but (more selfishly) I don't need these commands. I was torn over whether to do these or not; the deciding factor was my design philosophy for the eventual application. I intend to treat the Chroma as a peripheral to which the computer will write Program information and playback of performances as needed, from information stored on the computer; the only necessary information received from the Chroma will be performance (Attack, Release, Lever1, etc.) commands. In this view, supporting a storage peripheral attached to the Chroma would be bizarre. Nonetheless, I've supplied the source code; if anyone feels like developing support for these commands, feel free.

Why aren't the Peek/Poke commands supported by ChromaServer?

Because I'm afraid of them, and have no need for them. Once again, feel free.

Why aren't the Identification, Information, ReadProgram or Status commands supported by ChromaServer?

Actually they are, but they are all subsumed under and performed by the Restore method of the Chroma class. It just didn't seem necessary to expose these querying commands when the data returned by the Chroma was otherwise available in the properties of the objects after the Restore method was run (and it's run for every Chroma as part of the Connect method of the ChromaController object). Perversely, the ReadParameter method is exposed at Parameter; I think there may have been a reason for this, but I can't remember what.

Why don't the ChromaServer Program/Parameter/PanelSetting values reflect what's stored in the Chroma?

For the first Chroma attached to the circuit (at address 0) they mostly do. However, as explained in the circuit design, this is the only Chroma that can send information to the computer. Because I'm viewing Program information on the Chroma as primarily write-only, that's OK with me - I'll just make sure I write Programs to those other Chromas before I play them. Any discrepancies between the first Chroma and ChromaServer's properties should be due to shortcomings in the Chroma's computer interface. At least one of these is the surprising failure of the Chroma to transmit Panel/Performance switch On/Off commands to the computer when the corresponding Set Split 16-19 functions are punched into the Chroma manually. Thus, the computer can't alwalys tell when these switches are flipped. I also am not getting good values from the Volume command when the Link balance is changed manually on the Chroma.

Can ChromaServer be used with any other interface circuits?

Good question. I've actually tried to keep the interface as general as possible to allow for other circuit designers' innovations. For anyone contemplating using the code with other circuits, here are at least some of the aspects of the server code that are specific to my circuit design: