MDB Protocol (vending) - help ?

Anyone familiar with implementing the MDB protocol on the Arduino? I don't think the HWSerial Library will work for this function ....

MDB Infomation

Serial Bit Format:

1 Start Bit 8 Data Bits 1 Mode Bit 1 Stop Bit

11 Bits Total

Mode Bit: Master-to-Peripheral

The mode bit differentiates between ADDRESS bytes and DATA bytes. ADDRESS bytes must be read by all peripherals, DATA bytes are only read by the peripheral that has been addressed.

The mode bit is set (logic one) to indicate an ADDRESS byte, and not set (logic zero) to indicate a DATA byte.

Mode Bit: Peripheral-to-Master

The mode bit must be set on the last byte sent when data is sent from a Slave to the Master.

Section 18.5 of the 1284 datasheet:

"18.5 Frame Formats A serial frame is defined to be one character of data bits with synchronization bits (start and stop bits), and optionally a parity bit for error checking. The USART accepts all 30 combinations of the following as valid frame formats: • 1 start bit • 5, 6, 7, 8, or 9 data bits • no, even or odd parity bit • 1 or 2 stop bits A frame starts with the start bit followed by the least significant data bit. Then the next data bits, up to a total of nine, are succeeding, ending with the most significant bit. If enabled, the parity bit is inserted after the data bits, before the stop bits. When a complete frame is transmitted, it can be directly followed by a new frame, or the communication line can be set to an idle (high) state. Figure 18-4 on page 177 illustrates the possible combinations of the frame formats. Bits inside brackets are optional."

So 9-N-1 would seem to be whats needed here.


Anyone familiar with implementing the MDB protocol on the Arduino?

I'm not, but from what you describe it sounds petty simple. Set the UART up as Crossroads indicated and start sending bytes. Mind you I don't know how you read/write the 9th bit, it must be in the docs.

Do you have a spec for the protocol?


The datasheet has several code examples:

The following simple USART initialization code examples show one assembly and one C function
that are equal in functionality. The examples assume asynchronous operation using polling
(no interrupts enabled) and a fixed frame format. The baud rate is given as a function parameter.
For the assembly code, the baud rate parameter is assumed to be stored in the r17:r16

C Code Example(1)

void USART_Init( unsigned int baud )
/* Set baud rate */
UBRRHn = (unsigned char)(baud>>8);
UBRRLn = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRnB = (1<<RXENn)|(1<<TXENn);
/* Set frame format: 8data, 2stop bit */
UCSRnC = (1<<USBSn)|(3<<UCSZn0);

Sending Frames with 9 Data Bit
If 9-bit characters are used (UCSZn = 7), the ninth bit must be written to the TXB8 bit in
UCSRnB before the low byte of the character is written to UDRn. The following code examples
show a transmit function that handles 9-bit characters. For the assembly code, the data to be
sent is assumed to be stored in registers R17:R16.

C Code Example(1)(2)

void USART_Transmit( unsigned int data )
/* Wait for empty transmit buffer */
while ( !( UCSRnA & (1<<UDREn))) )
/* Copy 9th bit to TXB8 */
UCSRnB &= ~(1<<TXB8);
if ( data & 0x0100 )
UCSRnB |= (1<<TXB8);
/* Put data into buffer, sends the data */
UDRn = data;

Receiving Frames with 9 Data Bits
If 9-bit characters are used (UCSZn=7) the ninth bit must be read from the RXB8n bit in
UCSRnB before reading the low bits from the UDRn. This rule applies to the FEn, DORn and
UPEn Status Flags as well. Read status from UCSRnA, then data from UDRn. Reading the
UDRn I/O location will change the state of the receive buffer FIFO and consequently the TXB8n,
FEn, DORn and UPEn bits, which all are stored in the FIFO, will change.
The following code example shows a simple USART receive function that handles both nine bit
characters and the status bits.

C Code Example(1)

unsigned int USART_Receive( void )
unsigned char status, resh, resl;
/* Wait for data to be received */
while ( !(UCSRnA & (1<<RXCn)) )
/* Get status and 9th bit, then data */
/* from buffer */
status = UCSRnA;
resh = UCSRnB;
resl = UDRn;
/* If error, return -1 */
if ( status & (1<<FEn)|(1<<DORn)|(1<<UPEn) )
return -1;
/* Filter the 9th bit, then return */
resh = (resh >> 1) & 0x01;
return ((resh << 8) | resl);
and there's some other stuff about checking flags ...


Here is the MDB spec document. The voltages and data rate of MDB isn't anything obscure, maybe your issue is with timing?

Is there a library for 9 bit serial? That's what is needed.

Hi, you could use a interface for MDB protocol, I could recommend to you interface EasyMDB RS232-TTL!interfaces-mdb-english/cojy