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?

  • 1
    There's a serial interface on the GPIO - on Raspbian etc images it has been set to provide output from the Pi so you have to disable that first, but you will still have a issue with the bits are not in the standard range. This post on the forums may help as well. – Wilf Nov 27 '15 at 11:31
  • 1
    Can you add hardware to the project? A shield with a UART wouldn't be too hard to make one of, and would give you exactly what you need, though it might use up more I/O than it's worth. A really low-end PIC CPU could probably be quickly programmed to translate between 8 and 9 bit serial without costing too much or being an excessive amount of work for you. – Michael Kohne Nov 27 '15 at 18:13
  • Do you knwo where I could buy one? – Mawg Sep 8 '16 at 12:30
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).

  • 1
    Are you 100* sure? When I first started developing, I was warned off of such "hacks" and told that there would be timing problems. Do you know if anyone tried it with a vending machine? en.wikipedia.org/wiki/Multidrop_bus and coin-acceptor.com.cn/Upload/EditorFiles/technicalfile/… (sorry, I can't give a sectoin number as I am behind a company firewall) – Mawg Nov 27 '15 at 11:26
  • 3
    The only experience I have is using the library between the Pi and a laptop with a USB serial dongle. The tests I did are documented in raspberrypi.stackexchange.com/questions/27488/…. My software only uses RX/TX and ground so if you do something fancy with the other serial signals you may have problems. – joan Nov 27 '15 at 11:37
  • Sounds good. :Let me check the spec & get back to you – Mawg Nov 27 '15 at 11:39
  • 2
    @Mawg: you have accepted this. Does it mean that the proposed solution worked reliably? – Thomas Weller Sep 8 '16 at 13:12
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.

  • This is a fantastic answer, especially as it is a first answer. I have previously had success with an Atmel board with a true 9-bit UART and had hoped to save money by using a Raspberry Pi, but your solution is so comprehensive that I would be a fool not to use it. Alas, I am a software only guy, so for a prototype I would strongly prefer a no-soldering required solution. Can you recommend a COTS board? – Mawg Oct 22 '17 at 11:49
  • This page of your web site says "If you have completed steps in Making a Vendiverse VMC Board or if you have obtained a Vendiverse VMC board" . Can I purchase one from you? How much would it cost? Also, if you recommend any particular MDB peripherals, could you add that to your site? Thanks – Mawg Oct 22 '17 at 12:12
  • It looks like my emails are getting stuck in your spam. Can you get in touch with me? You have my email address, and I am still in Bremen – Mawg Feb 25 '18 at 17:49
  • Now it looks like the page is dead, and the project abandoned :-( – Mawg Jan 22 at 20:23
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.

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.

  • 5
    The problem with transmitting serial data is in the timing. The data is not self clocking and the only guaranteed level transition is in the stop/start bits. Both ends have to maintain tight, uninteruppted timing to work out where the bits are. That is why dedicated hardware is generally used to transmit and receive the data. There is little timing leeway. – joan Nov 27 '15 at 19:52
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/

-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.

  • Without the patch or at least a link, and more complete details this is not an answer, nor is it even a helpful comment - other than it says it is theoretically possible. – Steve Robillard Mar 4 '16 at 3:12
  • It still leaves more questions than answers: How do I implement MDB, how do i apply the kernel patch, will this work on all Pi's or only some of them? What else might this break? How can I undo this if needed? Is this patch safe? Remember you know this because you implemented it the OP has not. – Steve Robillard Mar 4 '16 at 8:12
  • 1
    I have undeleted your answer, as you admit your answer could be better. I hope you will take the opportunity to improve it. – Steve Robillard Mar 11 '16 at 19:55
  • What else need I add? MDB implementation? I didn't get permission to open-source it from my employer. – edo1 Mar 11 '16 at 20:32
  • See my previous comment and remember that the end user does not know all that you do. – Steve Robillard Mar 11 '16 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.