10

I have an existing, half complete, vending machine project running on an Atmel UTC, which I want to port to the Pi.

In order to talk to peripherals, such as coin acceptor, it has to support Multi-Drop Bus which has a 9-data bit serial port interface (plus start, stop and parity bits).

I learned the hard way with the Atmel board that hacks which one finds suggested on the net, which rely on using the parity bit as the 9th data bit can cause bad timing problems - difficult to detect and to correct (so, please don't refer me to this, or similar. Thanks).

Does anyone know if/where I can buy a true 9 bit serial port for the Pi (bonus points if it can somehow work with the Pi zero).

Is there, perhaps, a Hat available? Or could I easily (I have a s/w guy, with little knowledge of h/w) use another board to handle the 9 data bit UART and control that from a Pi?

Mawg
  • 433
  • 3
  • 8
  • 15

7 Answers7

7

My pigpio library supports reading and writing 9-bit serial data. It uses bit banging so you can use any available GPIO.

If I remember correctly any speeds of 19.2 kbps or slower were pretty stable.

What bits per second do you need?

Reading (C, Python) is slightly easier than writing (C, Python).

joan
  • 71,852
  • 5
  • 76
  • 108
3

I was assigned a project to run a snack vending machine that uses MDB protocol for payment and I have completed the project using Pi Zero (Orange).

I have tried 9 bit hardware serial and software serial libraries and had timing problems on Pi Zero. MDB's 9bit serial communication became a pain. MDB protocol says peripherals should have %5 tolerance for serial communication timing however different peripheral vendors have different tolerances, not compliant with MDB protocol. When you think that you have accomplished serial communication but try a different vendor's payment peripheral, it just don't work. So don't rely on MDB protocol datasheet. I got sick and tired of implementing MDB controller for buggy vendors. Also some peripherals can drain excessive amonts of current from uart pins during their internal boot process and might damage your serial communication layer. So, you better use an abstraction. Optocouplers are fine but still I wouldn't recommend handling MDB serial communication using Pi Zero. Better way is to use a middle layer approach using an AVR.

Rather using Uart on Pi Zero for MDB communication, I used an Atmega328 AVR for MDB handling, polling etc. Atmega328 controls the MDB peripherals using Software Serial library and sends human readable data to Pi Zero on hardware serial. All electronics scheme, sources and Pi Zero Armbian image, Python code for Vending operations are available here:

http://eliverse.com/content/vendiverse/

You can check the wiki page for further details on controlling motors, product delivery sensors, coolers and character LCD displays. It is a complete vending machine controller project and it is being used by couple of vending machine producers.

Eliverse
  • 31
  • 1
2

I also made complete demo for 9-bit UART emulation (based on even/odd parity). You can find it http://bohdan-danishevsky.blogspot.com/2016/10/9-bit-serial-communication-in-linux.html.

All sources available on git.

You can easily adapt it for your device. Hope you like it.

Kitty Hawk
  • 21
  • 1
1

All serial data is by definition, 1 bit. It is up to the interfaces reading and writing that data how to agree on how they interpret the bits to and from meaningful data.
If you want 9 bits of data, and a parity bit, and a stop and a start bit. Then it is up to you to convert your data into that format, and to interpret data you read in that format. The pigpio module mentioned in another answer will give you the hardware interfacing you need, or you can write your own. If you are developing in python, I suggest having a look at the bitString.py module by Scott Griffiths as a library that makes it fairly easy to manipulate bit based data.

Paul Smith
  • 127
  • 1
1

I definitely prefer hardware UART over software implementation like pigpio does.

You could use parity bit for 9-bit communication. There is one small issue: current kernel doesn't have CMSPAR support (space/mark parity).
But you could switch even/odd parity to get desired 9th bit value even with current kernel, example:

unsigned char check_parity(unsigned char v)
{
    v ^= v >> 4;
    v &= 0xf;
    return (0x6996 >> ((v ^ (v >> 4)) & 0xf)) & 1;
}

/* send 9 bits - 8 bits of byte + 1 bit of parity */
send_byte_with_parity(unsigned char byte, unsigned char parity)
{
    if (check_parity(byte) == parity) {
        options.c_cflag &= ~PARODD;
    } else {
        options.c_cflag |= PARODD;
    }
    tcsetattr(fd, 0, &options);
    write(fd, &byte, 1);
}


Better approach IMHO is to use small kernel patch for CMSPAR support:
http://marc.info/?l=linux-serial&m=145706834101241&w=2
It adds mark/space parity support, which allows code to be a bit simpler.

P.S. I implemented MDB over serial with this approach. It works on Pi flawlessly.
P.P.S. Patch has been approved and CMSPAR will work out of box starting with 4.6 kernel.

edo1
  • 576
  • 4
  • 7
1

You can't RELIABLE connect RPi serial directly to MDB bus due to 9-bit format and strict MDB timings. Messages between MDB peripheral and RPi need to be converted on-the-fly and in real-time. Check this link it will help: DIY MDB-UART converter

0

The accepted answer, which used an Atmel processor with true 9 bit data URT communicating with a Pi looks to have been either abandoned, or taken commerical.

So I am going with https://www.vendingtools.ro/en for Eur 70, and that will interface my Pi to the MDB 9 data bit bus.


[Update]

See also

https://www.qibixx.com/en/products/mdb-interface/

https://blog.abrantix.com/webshop/product/mdb-to-raspberry-pi/

Mawg
  • 433
  • 3
  • 8
  • 15