Help with 9 bit serial on Uno Wifi Rev 2


I want to connect a bit of legacy hardware - an alarm control panel that uses a single wire to communicate to remote keypads. I can use a diode to connect the single bus wire to RX and TX (Pins 0 & 1) of the Uno WiFi Rev 2. I think.

I need to interface this to an Uno Wifi Rev 2 (which I understand is similar to an Uno R3 but with MEGA4809 + Wifi).

My challenge is that the protocol used by the alarm is 9 bits... 8 bits of data, a mark/space parity and 1 stop bit.

I'm stumped on how to get 9 bit to work on the Uno Wifi Rev 2. Everything I've looked at & tried has failed as it's invariably been done on a different kind of Arduino and so I'm struggling to learn from others (I'm new to all this!).

I've looked at the project by Luca Paolini (AccentaG4 | Virtual keypad for Honeywell Security Accenta G4 panel) who got the same alarm board hooked up to a Yun by the look of things - but I am struggling to get even the simplest of 9 bit test messages to work.

I've tried AltSoft and Alt9Soft libraries. I've tried using pins other than 0 & 1. I've tried hacking HardwareSerial (GitHub - nzin/xpressnet_arduino: A Xpressnet protocol implementation for Arduino Mega 2560).

I think I'm doing the right thing by interfacing my alarm to Serial1 on pins 0 & 1?
I think I don't need SoftSerial, SoftSerial9 or similar, as pins 0/1 are hardware ports?

But how do I configure pins 0 & 1 work with 9 bit messages?

Any pointers as to approach I should take/examples gratefully received!

I've tried SoftSerial9 (I can't get it to compile - it throws errors because the library was designed for avr architecture, but my board is megaavr, plus error about digital pins, interrupts and a bunch of stuff I only vaguely understand)

You say 9 bits, yet, you describe 10 bits. And you never count the start bit, which makes 11 bits. Isn't that right?


Hi, thanks for looking at my challenge!

Here’s what the guy who’s successfully integrated using a Yun said…

A quick analysis with the logic analyzer revealed a slightly unusual protocol: RS-232 [*** NOTE: I think it’s actually RS-485 ***] with 8 bits of data, mark/space parity and 1 stop bit or, if you prefer, 9 bit of data and 1 stop bit, which is the same. In fact, considering bits are sent LSB first (little-endian), the parity bit is just the 9th bit of data.
Messages consists of a single byte command, one or more bytes of data and a one-byte checksum of all the preceding bytes. Messages are not terminated.
Any message is sent over the bus with mark parity on the first byte and space parity on the remaining bytes.
In little-endian, 8-bit with parity and 9-bit without parity are equivalent.
In particular, 8-bit with mark parity is equivalent to 9-bit without parity when the 8-bit character is ORed with 0x100.
Having the 9th bit set exclusively for the 1st message in any sequence makes it easy to detect the head of the message sequence without any ambiguity.

So, I think what he’s saying is that the mark or space parity is the 9th bit and there’s not actually a stop bit per se as the bytes are of a fixed length?

His Yun implementation for this legacy device used SoftwareSerial9 (which wont compile on my board) plus I think that using “emulated” ports isn’t the right way to do it on my more up-to-date board…?

As an example, I need to receive a message constructed like below, to indicate that Key 1 has been pressed on a keypad…


The “K” character, being the first byte of the message, has mark parity.

“K” is 0x4b.
But in 9 bit, with mark parity this becomes 0x14b.

“1” in our example is 0x31.

I’m going to ignore for now!

And that’s all I’m trying to read over pins 0 & 1!

There’s only a 3 types of message to deal with, and once you read a “command” (which is indicated by bit 9 being set to 1) I think it will be fairly straightforward (ha!) to interpret the rest of the message in terms of its length and contents: