Serial data to analog synthesizer..

I am currently working on a project that has given me a rough time.

I need to establish a serial connection to transmit from Arduino to and old Roland Juno-60 synthesizer. The problem is, that my serial data seems to match exactly the "DCB"-protocol specified by the synth manual (31250 baud, separate clock signal, 1 start bit, 8 data bits, LSB first, odd parity, 2 stop bits, logic HIGH=0v, LOW=5v), but it doesn't work. It is supposed to make the synth play some notes, but nothing is happening..

The sketch I've written is based on a timer interrupt to generate a 31250hz clock signal on dPin 3, and standard Serial.write() for the data transmission. The wierd thing is, that I have a previous sketch using a modified shiftOut()-function (to control the clock speed) that kinda works, even though the clock signal is quite unstable, oscillating between ~30k baud and 35k baud. This sketch actually triggers the synth, though the bytes recieved are by no means correct, and is quite impossible to control. However, it DOES trigger the synth, which I find a tad weird..

I've tried all sorts of workaraounds, but the only possible solution I can think of is, that the data signal from my tx-pin is perhaps not strong enough for TTL, when running it through a NOT-gate before it is send to the synth. In the "shiftOut"-sketch, the data signal is generated on dPins with digitalWrite() and is not inverted, and I figured that the solutions lies somewhere in this..

I'm not too bright in analogue electronics and the specifics of TTL, but could it be that the not gate (real basic made with two 10k resistors and an M2222 NPN) somehow make the data signal, voltage or current too weak?

NOT-gate diagram:

Please help..


By the way I have some LogicSniffer files and screendumps from both sketches, and from a readout from the synth (which shows the "real life" data stream, clock, etc.) that I could post if necessary..

Thought some code might help… :slight_smile:

The “full implementation” with steady clock and Serial.write():


 Firstly the timers are set up to bang out a clock signal of 31250HZ on pin 3.
 Followingly serial data is sent. Data bits must be inverted (LOW=5v, HIGH=0v) before sending them to DCB.
 Serial Data Stream for DCB:
 Using the SERIAL_8o2 parameter, the Arduino UART sends out the following:
 1 Start bit (LOW)
 8 Data bits (LSB first)
 1 Parity bit (Odd)
 2 Stop bits (HIGH)

// Timer reload value, globally available 
unsigned int tcnt2;

// Toggle HIGH or LOW digital write
int toggle1 = 0;

// Keep track of when each pin needs to be switched
int count1 = 0;

// Clock Output Pin
#define CLOCK_PIN 3
#define BUSY_PIN 4

void setup()
  //31250 Baud, Odd parity, 2 stop bits. (Juno accepts faulty parity bits)

  // First disable the timer overflow interrupt
  TIMSK2 &= ~(1<<TOIE2);

  // Configure timer2 in normal mode (no PWM)
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  TCCR2B &= ~(1<<WGM22);

  // Select clock source: internal I/O clock
  ASSR &= ~(1<<AS2);

  // Disable Compare Match A interrupt (only overflow)
  TIMSK2 &= ~(1<<OCIE2A);

  // Configure the prescaler to CPU clock divided by 128
  TCCR2B |= (1<<CS22)  | (1<<CS20); // Set bits
  TCCR2B &= ~(1<<CS21);             // Clear bit

  tcnt2 = 254; //31250Hz clock

  // Finally load end enable the timer
  TCNT2 = tcnt2;
  TIMSK2 |= (1<<TOIE2);

  //Configure I/O Pin Directions


ISR(TIMER2_OVF_vect) {
  // Reload the timer
  TCNT2 = tcnt2;


  if (count1 == 1)
    digitalWrite(CLOCK_PIN, toggle1 == 0 ? HIGH : LOW);
    toggle1 = ~toggle1;
    count1 = 0;

void loop()
    digitalWrite(BUSY_PIN,HIGH);  //  Busy/Latch
    Serial.write(0xFE);  //Start Code
    Serial.write(0xAF);  //Play F#
    Serial.write(0xAA);  //Play G
    Serial.write(0xAB);  //Play G#
    Serial.write(0xAC);  //Play A
    Serial.write(0xAD);  //Play A#
    Serial.write(0xAE);  //Play B

Next, the “fualty but working” version using shiftOut()

uint8_t dataPin = 8;
uint8_t clockPin = 3;
uint8_t latchPin = 4;

//Custom shiftOut-function

void shiftOutX(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, int val, uint8_t bits = 8)
  uint8_t i;
  for (i = 0; i < bits; i++)  {
    if (bitOrder == LSBFIRST)
      digitalWrite(dataPin, !!(val & (1 << i)));
      digitalWrite(dataPin, !!(val & (1 << ((bits - 1 - i)))));
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);

void setup() {


void loop() {
  // NB! Invert data bits






void dcbWrite(byte data){
  shiftOutX(dataPin,clockPin,LSBFIRST,0b1,1);    //Start
  shiftOutX(dataPin,clockPin,LSBFIRST,data,8);  //Data
  shiftOutX(dataPin,clockPin,LSBFIRST,0b1,1);    //Parity
  shiftOutX(dataPin,clockPin,LSBFIRST,0b0,10);    //Stop (rammer F# når den står til 10)


didn't the Hardware Serial not receive correctly on 31250 ?

This sounds like an early midi precursor. (The 31250 baud is a clue) Is it supposed to be optically isolated?

I also do not see how you can keep your clock and serial bytes in sync. You might need an Oscope to verify things are working as you plan.


@robtillaart No.. Something comes through, though but it's a line of chaotic notes, and definitly not the ones intended. I even got it to play random notes by just continously sending 0xFE, which is not supposed to trigger anything. My guess is that the clock signal of the hardware serial sketch is so unstable, that it triggers the data bits at more or less random times, and thereby sending out pseudo-random data, which is probably bound to trigger something..

Anyway, the question is not so much why the hardware serial is acting weird, but more why the software serial is not working..

@KeithRB Yeah, it's called DCB, and were used prorietarily by Roland in the early 80's just before MIDI was introduced. Well I checked the schematic of a JSQ-60 (DCB-sequencer) and it doesn't seem like it needs optocouling.

KeithRB: I also do not see how you can keep your clock and serial bytes in sync. You might need an Oscope to verify things are working as you plan.

I've been using OpenLogicSnigger to check the timing, and it should be in sync..

Software serial DCB output

Real DCB output (from a Juno 60)

Hardware serial DCB output

Could it be, that the "real" output sends a few additional 0's after the stop bits, and the software serial doesn't? And if so, is there any way to send 3-5, 0's on the tx pin, without start bits and parity? I tried a small delayMicroseconds(), but it also stops the clock signal..

I don’t know if anyone is still interested. But there was just a wrong thinking in the code. The Most significant bit in the 6 DCB Messages that are transmitting the Pitch of each Voice in the Juno 60 needs to be 1 if the Voice hast to be turned on and 0 if the voice has to stop to play. I wrote an example, where only one voice is playing one note for 250 ms and then is quiet for 250 ms. All other 5 Voices are turned off.

Cheers and thanks so much for your work. It helped me a lot!

JunoDcbOut.ino (1.84 KB)