SoftwareSerial oddity when talking to a Sun keyboard

Hi Guys,

So I've set myself a small challenge as an introduction to Arduino. I have an old Sun keyboard which I'm going to convert to USB.

The interesting thing about the keyboard is that its native protocol is serial-based - According to the documentation:

"The keyboard communicates with the system using asynchronous serial protocol with negative logic. The communication is full duplex at 1200 baud. The data has 1 start bit, 8 data bits, 1 stop bit and no parity."

So I wired everything up to my Arduino micro and did a little test:

//Software serial for Sun KBD
SoftwareSerial sunSerial(10, 11, true);

void setup() {
  //Normal serial port init for monitoring
  Serial.begin(1200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  sunSerial.begin(1200);
}

void loop() {
  char c = sunSerial.read();
  //not sure why we're getting this spamming out so let's filter for now (inverse of 0 i guess)
  if (c != 0xFFFFFFFF) {
    Serial.println(c, HEX);
  }
}

Press and hold a button and voila we have output.... BUT the output is doing some odd things.

According to the document if I press then release the space bar I should see the following hex values received

0x79 (space pressed) 0xF9 (space released) 0x7F (idle - sent to say no keys are depressed on keyboard)

So pressing and releasing space should just loop those 3 values for each press/release

Instead this is what I get when pressing and releasing 8 times

79 FFFFFFF9 7F FFFFFFF9 FFFFFFF9 7F 7F 79 7F 79 FFFFFFF9 79 FFFFFFF9 79 7F 79 FFFFFFF9

So initially it did the 0x79 and the second value does end in F9 and was followed by 7F - but it looks like something very odd is going on. if I alternate between 2 keys (space as above and 'm' (0x6A pressed, 0xEA released) you'd expect a loop of

0x79 (space pressed) 0xF9 (space released) 0x7F (idle - sent to say no keys are depressed on keyboard) 0x6A (m pressed) 0xEA (m released) 0x7F (idle)

instead we get:

79 FFFFFFF9 7F FFFFFFEB 7F FFFFFFF9 7F 6A FFFFFFEA FFFFFFF9 FFFFFFEA FFFFFFFE 7F FFFFFFF9 7F 6A FFFFFFEA 7F FFFFFFF9 6A FFFFFFEA

I'm not sure what the problem here is - Initially I thought it might be to do with the number of bits being processed (so things end up getting shifted) but i'm not sure now.

Does anyone have any ideas what could be going on, or suggest something that might help me debug this? (note I don't have access to an oscilloscope etc).

Thanks in advance for any help provided

Tim

The fact you get FFFFFF9 is probably because the char is converted to an int and that the "sign’ bit is extended resulting in preceding FFFFF’s

are the cables soldered or breadboard?

code beneath is similar to your code, prints a bit more, please give it a try

void loop() 
{
  if (sunSerial.available() > 0)
  {
    int c = sunSerial.read();  // read returns an int not a char
    Serial.print(c, DEC); 
    Serial.print('\t');
    Serial.println(c, HEX); 
  }
}

Hi Rob

I tried your code - still shows the issue - some responses appear missing, others appear to be not the expected value…

249 F9
249 F9
255 FF
106 6A
250 FA
127 7F
249 F9
249 F9
127 7F
254 FE
234 EA
255 FF
127 7F
249 F9
255 FF
234 EA
254 FE
127 7F
249 F9
249 F9
127 7F
107 6B
239 EF
127 7F

(this was cycling followed by ‘m’ keys)

It still seems to me like the bits being received may not be getting correctly interpreted… I guess I could modify the SoftwareSerial.c file - maybe look at all the bits in the ring buffer it uses and try to see if something obvious pops up.

FYI it’s on a breadboard

Thanks

Tim

At least the hex dump is now not extended, improved readability

FYI it's on a breadboard so loose wires could happen...?

next step, try to see the char pressed/releases too

void loop() 
{
  if (sunSerial.available() > 0)
  {
    int c = sunSerial.read();  // read returns an int not a char
    Serial.print(c, DEC); 
    Serial.print('\t');
    Serial.print(c, HEX); 
    Serial.print('\t');
    switch(c)
    {
    case 0x6A: Serial.println("m pressed"); break;
    case 0xEA: Serial.println("m released"); break;
    // extend these cases
    default: Serial.println("?"); break;
    }
  }
}