Posted inRaspberry Pi

Raspberry Qt – Part 10

You need a communications protocol

But isn’t RS-232 our communications protocol? Well, it is the communications transport layer. If you read through the code you will see I set the baud rate to 9600 using a data/character protocol of 8 data bits No parity bits and 1 stop bits commonly labeled as 8-N-1.

So isn’t our protocol 8-N-1? No. That is the data transmission protocol for the transport layer it is not a communications protocol. If you are looking at this blog on-line then you are somewhat familiar with TCP/IP. At least you’ve heard of the name. In its simplest terms, skipping over all of the OSI network layers discussion, TCP/IP provides a packet communications protocol. This allows the Internet to operate both for people surfing the Web and those downloading movies and music. (Hopefully you are doing that last part legally.)

With serial communications either the device you are communicating with or your application must define the boundary markers for a data packet and, in many cases, the content of said packet. Unlike the world of TCP/IP, there are no predefined universal packets out there. Why? Because serial communications, in particular the bulk of RS-232, has its roots in device control before we had computers. It is defined by current on pins which is why the connectors on first generation computers were 25-pin. It wasn’t until much later when computer makers started “dumbing down” serial communications that connectors shrunk to DB9 followed by 3 and 4-pin connectors as we have with our TTL converter. The logic of communication got pushed out to the devices as computers became both better and cheaper.

A “packet,” as far as our transport layer is concerned, is a single entity made up of 8 data bits, no parity bit, and 1 stop bit. The definition of a packet is at the core of this discussion. You see, the QSerialPort class is derived from QIODevice. This device class is set up for block and/or packet IO. A UART considers a packet to be a single group of bits.

Back in the days of DOS we had a rather awesome serial communications library from Greenleaf Software Inc. It was called CommLib. It created a double ring buffer and allowed you to set triggers by ending character(s), bytes in buffer, etc. Been decades since I worked with it but I “think” you could even have a trigger set for when both a start and stop byte were in the buffer. You could also scan/peek into the ring pulling out just what you wanted. This was very handy when developing systems which communicated with truck scales. It has been 2 decades since I wrote a truck scale ticket creation system, but, I will wager all outdoor truck scales still use serial communications. Wifi is both too new and too unreliable in an industrial setting. Besides, a “packet” for a scale reading is generally under 20 bytes. The scale can easily transmit several times per second over serial.

Many truck scales would send a start of packet byte, 1-N characters for the weight, an end of packet byte and a checksum byte. A number of scales would send a fixed number of bytes for the weight. The checksum was generated using various algorithms. It was meant to ensure no noise corrupted one or more bytes in the packet. The checksum was also a source of constant trouble in the early days. Why? A simple checksum algorithm had the potential to collide with either the start of packet or end of packet character hosing up your logic for finding a packet.

Take a look at this ASCII table for a moment. Most device level serial communication will bound their packets with STX and ETX. These have ASCII values of 1 and 2 respectively. It doesn’t take much imagination to realize the checksum or CRC ending up as one of those 2 values.

Our application is not going to use STX, ETX or a checksum of any kind. Our only packet bounding character will be the newline ‘\n.’ If you are trying to write a cross platform solution, which I am not, you cannot use ‘\n.’ For some systems such as Linux that is a Line Feed character, for others it is a Carriage Return and some systems use both characters. Be that as it may, we still need to have a class packet buffer to assemble our text message because the QIODevice class emits the readyRead() signal when the device thinks a packet is available. In the case of QSerialPort that is when the first byte is in the internal buffer. The QSerialPort class has not been enhanced to understand more complex packet definitions.

Time for a bit of warning about the phrase “Carriage Return Line Feed.” People say this. Some people even believe this is the sequence all systems use. In truth, the noobs at Microsoft creating DOS went down this very path and luggied up most of IT doing it. Back in the day when serial communication reigned supreme most systems sent a Line Feed followed by a Carriage Return. This industry standard came about out of necessity. Paper terminals and printers didn’t have much in the way of smarts. Many didn’t even have multiple fonts.

Take a look at the Underwood mechanical typewriter. That lever on the left was how you created your Line Feed Carriage Return combination. As you first pressed it the platen rolled the paper however many notches in the gear you had line spacing set to. Further/continued pressure pushed the platen back to the home position. Some electric typewriters kept the platen in place choosing to move a golf ball like print head. At some point printers and paper terminals diverged from typewriter technology choosing to use a dot matrix print head.

Early dot matrix printers produced horrible print. It was good enough for IT workers, but you wouldn’t want to send invoices and correspondence printed like that. These terminals also had a timing problem. The print head traveled to home very slowly. Communication to these printers had to send Carriage Return followed by the Line Feed to buy enough time for the print head to actually make it to the “home” (far left) position. If you did not do that the left margin would swim down the page as the print head started printing the next character from where ever it happened to be.

Despite all of the claims spouted in the late 80s, dot matrix printing has not been replaced. Yes, you may all own ink jet or laser printers, but, any business involved in the transport of goods will still be using dot matrix printers. Why? Multi-part forms such as truck weigh bills are required by law. No, you cannot print N copies of the same thing. It has to be a single numbered form and that requires impact technology. The golf ball print head can produce high quality print, but, the dot matrix prints with greater speed. Over the years the letter quality has gotten better as well.

Why have I chosen to tell you all of this? Because you will encounter it if you are planning to do embedded systems or semi-embedded systems development. While today’s dot matrix printers have larger print buffers and network connections, you will encounter devices with the same limitations as yesteryear. Be it a milling machine or a materials rolling belt, there will be situations where you have to “buy time” with your communications to allow the device to position itself. Yes, some of these devices have gotten better at having position sensors, but few can communicate their exact position like a mouse driver does to an application.