Aug 15

A command from the master to a slave will (in most cases) consume more than one byte. This will require some sort of protocol making things very fast complex. The goal is to keep it as simple as possible to minimize the chances of errors in the software which will result in ‘strange’ errors when the applications become more complex.

All ATMEL AVR controllers can handle 9 bit serial communication. The extra 9th bit can be used to indicate the start of a new command making it easy to re-synchronize communications when data is corrupted or a slave missed a byte (for whatever reason). In most cases the master will be some sort of embedded controller but during development a PC will be used. Most PC’s can not handle the 9th bit, since I do not know what embedded platform will be used I’m not sure it can handle the 9th bit as well.

On the PC side there are other ways to ‘create’ the 9th bit by using the parity bit. This is typically set to none but it can be programmed to be “1”, “0”, “even” or “odd”. By setting the parity bit to “1” before sending the first byte en than setting it to “0” before sending the rest there are in fact 9 bits send over the serial bus. On the slave side we can not use the parity bit since that will only enable the parity bit checker module of the AVR controller and generate parity errors in case it does not match. But the idea is to set the AVR to 9 bit communication mode and receive the extra parity bit send by the PC as the 9th bit. Worst case the 9th bit is added to the wrong side of the byte but that could be corrected in the AVR by moving the incoming bits around.

I wrote a very simple Windows app in Delphi that sets/clears the parity bit and than sends a fixed value trough the serial port. An ATMEGA32 receives the serial data and by setting a breakpoint we can evaluate the data received. The results are good: the data is received as send and the parity bit is stored in the 9th bit register, so no modification is needed!

The slave will only respond with data after the master has send a command. This should at least be 1 byte so that the master knows the slave has received the data. Since the parity on the PC side is at that moment set to “0” the AVR needs to set the 9th bit to “0” before sending data. This also prevents that other AVR’s on the bus think a new command has started, so perfect. I extended to code in not application to make sure this works, and indeed, it does.

There will be times that a slave wants the attention of the master, for example, when a leg hits an object it can decide to stop moving but the master needs to know it hit something to tell the other legs to stop moving as well. This can be implemented by adding an “interrupt” line to the master, by pulling it low the master knows the slave wants attention and can than respond by send a “GetStatus” command. When more than one slave is connected the number of interrupt lines grow rapidly and so does the amount of wires in the communication cable. Since I want to daisy chain the slaves that is not the way to go, a better option is to connect all slaves to the same interrupt line and allow all of them to pull it low, even at the same time. The master than will not know who generated the interrupt, but by sending a “GetStatus” command to all connected slaves one after another it can find out who (or more than one) generated the interrupt.

The maximum speed of a PC serial port is 128000 bits per second. Using 1 start, 1 stop, 1 parity and 8 databits this means 11600 bytes per second. Assume a 2 byte command and 1 byte status reply this means 3800 slaves can be checked in 1 second. Fast enough since there will never be so many slaves and the slave should keep itself “safe”, so in case of a conflict it should stop what it is doing and then report this to the master.

This requires an input on the PC side. A serial port has 2 extra inputs (Data Set Ready and Clear To Send) and also two extra outputs (Request To Send and Data Terminal Ready). These signals are driven by the serial port automatically if hardware control is switched on, if switched off they are not used and can be set or cleared manually independent of the transmission flow. I guess these signals are also available on most embedded controller platforms, otherwise an IO pin can be used as well.

Each command will exists of minimal:

  • The command
  • The address of the slave
  • The amount of data bytes send as part of the command
  • The data (if any)

That means a minimum of 3 bytes will be send for each command. However, there will never be 256 slaves connected or 256 different commands or even 256 data bytes. So this seams a bit of a waste which can easily be solved by packing this in two bytes were the first 6 bits are the command, the next 6 bits the slave address and the last 4 bits the amount of data. When a command is received it needs to reply with at least 1 data byte. This byte should contain:

  • The interrupt status
  • The amount of data that will follow

This can also be packed in 1 byte, the first bit for the interrupt and the last 4 bits for the amount of data leaving 3 bits to spare for future extensions.

 

 

 

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.