Friday, May 29, 2009

FreeRTOS has a PIC18 port!

Havn’t posted anything in a while, but working with FreeRTOS and the PIC18 port. Fully preemptive scheduling, small, fast, efficient and works with C18 compiler.

More on this once I have everything sorted out.

Monday, May 18, 2009

More thoughts on my token bus based RS485 protocol

It was suggested on the PICLIST that I list all possible errors that could happen with my protocol and write possible solutions. Let’s see how this goes.

In a perfect bus where there is no line disturbance, no random death of a node, and proper following of protocol by each node, we can assume that data will not get corrupted, the token will not get lost and the buss will never fail. However, in reality, there is noise and line disturbance, nodes may randomly go down or leave or get hung up, or nodes may fail to follow protocol for some other reason. Due to these issues, it is important that we try and list the possible problems that may occur on the bus and provide solutions if we can.

Possible problems:

  • The biggest problem in this type of protocol is when the token itself gets lost.
    • When the bus is in working order, it is always busy due to the token being passed around. If the token gets lost for some reason, no node on the bus will have voice and therefore, the bus goes idle.
    • The token may get lost due to several reasons such as line disturbance during passing of the token from node A to B, or if a node which owns the token goes down. In either case, the bus goes idle because no node has voice and therefore no node transmits.
    • Fortunately, we can use the silence on the bus to our advantage as an indicator that a new token must be assigned. A possible solution to this problem is that every node will detect a lost token when there is a silence on the bus for longer than (ID * 2) + 10 ms (for sake of example; better values need to be calculated during implementation). Therefore, the node with the lowest ID will detect the silence first. As soon as this node detects the silence, it has to assume ownership of the token and start transmitting something (before the next node detects silence).
    • Some things to consider: this method should work well. However, it assumes that all nodes give full priority to the network. If a node gets partially hung up doing a task for (let’s say) 50 milliseconds, it could cause the bus to issue a new token. The problem now is that two tokens are on the bus and this will effectively cripple the bus. However, this shouldn’t happen since part of the software stack design requires full priority be given to the bus.
  • Another problem arises during corruption of data.
    • When node A sends a normal data packet to node B, it expects that B receives the packet successfully. But what if B doesn’t get the packet due to data corruption? For a non critical packet, this may be acceptable. But when we actually need that packet to reach its destination, we need a way to make sure that it got there.
    • A possible solution to this (discussed in the original protocol description) is the ACK packet. How this works is that the sender node (node A) sends a packet and enables the ACK_REQ flag to signal that it wants an ACK from the target that it got the packet. When the target node (node B) receives the packet, it sees that the ACK_REQ flag is enabled and sends back an ACK  (or NACK) packet to the original sender (when it has voice, of course). If there is a problem where B does not get the packet at all, or the packet is too corrupted to identify the sender, A will trigger a timeout 100 ms after it sent the packet (again, these numbers are for example purposes only). This number, however, depends on the number of nodes present on the bus. If there is a large number of nodes on the bus, we must wait a long enough time for the token to get to node B for it to send back an ACK (or NACK). But it is safe to assume a large number like 100 ms or 250 ms for this since we don’t expect errors to occur very often. This leads us to our next problem:
  • What happens if the ACK (or NACK) packet gets corrupted?
    • So far, A has successfully sent a packet (with ACK_REQ) to B. B now sends an ACK (or NACK) back to A. Suddenly, something happens, causing the packet to get completely corrupted. What happens now? In this situation, B has received the packet but A is still waiting for an ACK and thinks that B didn’t get the packet at all.
    • For this situation, we can attach a sequence number to the packet. So even if the same packet (with the same sequence number) gets sent out multiple times, it wont get “used” more than once by the target.

2 more network protocols suggested on the PICLIST

http://yaspnet.sourceforge.net/

http://www.hth.com/snap/

These look really useful.

For embedded applications, CSMA/CD, token bus, and the polling system seem to be good choices.

Olin’s Old Network

Olin Lathrop:

There are other ways to guarantee this.  I think the vast majority of RS-485 networks use a bus master system.  This simplifies a lot of stuff.  I did one a while back where the master addressed each slave in turn.  If the slave had nothing to send, it responded with a NACK so that the master would know to go on to the next slave. In my system, the configuration wasn't known up front, but the maximum number of slaves was limited to 15.  The bus master kept track of which slave addresses were in use to avoid the timeout for the unused ones each time thru the list of slaves.  If a slave timed out three times in a row, it got crossed off the list.  Once per loop, the master would try one unused address.  If a slave responded, it would be added to the active list.  This allowed hot-swapping and powering slaves up and down, which was important for this particular system. This was done 10 years ago on hardware that was designed before that.  The biggest bestest PIC at the time was the 16F877.  CAN hardware wasn't that readily available yet.  A few years later and I definitely would have argued for using CAN instead. This project is long dead, so I can give more details on it.  I have attached the protocol document. As I have said consistantly though, I still think you're better off using CAN and a 18F4580 or similar.

Sunday, May 17, 2009

My RS485 Network Protocol

After hours of research, I was unable to find a suitable real-time, multi-master/peer-to-peer network protocol for RS485. So I made my own. Please evaluate it and comment on it.

The protocol is designed to work over RS485, using an RS485 transceiver hooked up to a PIC's UART pins. 8 bit, no parity, 1 stop bit. Maximum length of data segment of packet is 0xFF bytes long, but since most midrange controllers don't have that much, I'll stick with 26 bytes. The protocol has a token bus type topology (or at least that's what I think it's called), so it's deterministic, collision free and real time.

The packet looks like this:

<preamble> <destination> <source> <flags> <length of following data> <data> ... <data> <checksum>


<preamble>: 1 byte. Start of packet. 0xAA.


<destination>, <source>: 1 byte each. 0x01 - 0xFE. 0x00 represents the bus owner, configuration node or hub (unimplemented for now). 0xFF is broadcast, for all nodes.

<flags>: 1 byte <0, 1, 2, 3, 4, 5, 6, 7>
0 - ACK - acknowledge
1 - NACK - no acknowledge (could not use the packet, for some reason)
2 - ACK_REQ - when sending, request an acknowledgement from target node
3 - ID_REQ - request identification information from the target node
4 - TYPE - is the data segment a special command type or a normal data type?
5 - TOKEN - this packet is a token and contains data of zero length; all other flag bits must be zero
6 - not used/application specific
7 - not used/application specific


<length>: the length (in bytes) of the data segment that follows


<data>: the data (or command) segment itself


<checksum>: the 8 bit polynomial checksum

Notes:


The lowest ID on the bus has voice (starts with token). If it has a message to send, it can send up to 4 packets. Then it MUST give up its voice and give the token to the next node. -> The 5th (or less if it has less or even no data to send) packet must be a token that it passes to the next node.

If the node has no data to send, it will pass the token to the next node in the bus, which is it's own ID + 1.

IDs are static on the bus and are assigned incrementally (I want to make them dynamic, though).

When a byte is received, it is buffered in memory in the "interrupt on RX" function. After the last byte (checksum) has been received, the packet is checked, validated and used. It is discarded if the packet does not belong to the node.

The packets shall be examined as CPU time permits. One question to you all though: since this type of network requires the constant examining of packets, I assume it takes a lot of CPU time.

The token bus type network guarantees that a node will be able to transmit every x units of time. However, for small, embedded applications, two other types of networks are also very possible: CSMA/CD and Polling. All the different types of networks are discussed on this page: http://www.ece.cmu.edu/~koopman/protsrvy/protsrvy.html

 

Further:

 

After posting on the PICLIST and getting opinions about the protocol, I got the following responses:

  • What happens when the token gets lost? For example, when the node which has the token goes down. Tokens get lost.
    • My possible solution: I don’t expect a node which owns the token to go down. Note that when sending tokens, the receiving node must always acknowledge that it got the token. If it does not send an ACK, the sender still owns the token and must try again a few times until the receiving node gets the token. If there are a few unsuccessful tries (4 or 5), the token owner broadcasts (to 0xFF) that the target node is probably down and sends the token to the next node (n + 0x02). Now, to solve the problem of recovering from a lost node which has the token, we could probably add another node to the bus known as the bus owner with an address of 0x00. The owner takes place in passing the token around and keeps track of who is on the bus and who is not. If the token gets lost, the bus owner then polls each of the nodes to see which node went down. After that, the bus owner then either reassigns the IDs so that they are all consecutive or broadcasts to all nodes saying which node went down so the nodes do not pass the token to that node. Basically, the bus owner makes sure that the bus is in working order.
  • Look at the DMX 256 protocol.
  • Look at uLan - http://ulan.sourceforge.net/
  • What happens when an ACK is not received?
    • In this situation, the first packet (with an ACK_REQ) is successfully transmitted, but there is an error when the target node sends an ACK. In effect, the ACK does not get sent back to the original sender. The sender would probably then send the packet again. This could be a problem especially when node A passes the token to node B. B then needs to ACK to A that it got the token. If A does not get the ACK, A will then send the token again. But what might happen here is that B will start talking on the network since it has voice (it got the token). A collision occurs. This might be a very improbable situation, but if it does happen, it will disrupt the bus.
    • A possible solution to this is that:
      • A token –> B
      • B ACK –> A
      • A ACK –> B
    • What happens here is that A sends a token to B and waits for an ACK.
      • If B did not get the token at all, it obviously will not send an ACK. In this case, A still has the token. A will wait for a while and then trigger a timeout in which case it will retry sending the token to A.
      • If B got the token:
    • B sends an ACK to A.
      • If there is a problem sending the first ACK, B will retry sending the ACK until it gets a response. If it doesn’t get a response, B drops the token and it is assumed that A still has the token due to an unsuccessful transfer.
      • If A got the ACK:
    • A sends an ACK to B.
      • If there is a problem sending the ACK to B, B will drop the token. Now no one has the token. The bus owner sees this as the token has not been circulating for a while. The bus owner then resets the bus by giving the token to a certain node.
      • If it B got the ACK, B now has the token.
    • As you can see, this gets very complicated really quickly. Maybe CSMA/CD isn’t so bad after all.

Sunday, May 10, 2009

I2C for chip-to-chip communication

If you have several PIC microcontrollers and other I2C devices on the same PCB, the best bus to use would probably be the I2C bus. It’s a synchronous multi-master bus so the PICs can talk to each other while controlling the slave devices as well.

Here are some interesting sites on the I2C bus:

http://www.robot-electronics.co.uk/htm/using_the_i2c_bus.htm

http://www.i2c-bus.org/i2c-primer/

http://en.wikipedia.org/wiki/I%C2%B2C

http://www.esacademy.com/faq/i2c/

Sunday, May 3, 2009

CAN – It’s Awesome!

After further research, I learned more about the CAN bus (controller area network). It only requires three wires (high, low, ground) and terminating resistors (typically 110 ohms for CAT5 cable) and a CAN transceiver. Unlike RS485, the CAN bus specifications specify the physical layer as well as the protocol layer. The bus allows for multi master communication over long distances (1000 m) and sufficient data rates (1 Mbit/s). The details such as collision avoidance/detection error checking and so on are all taken care of at the chip level.

Maxim IC has some CAN transceivers and I just sampled them. I’m planning to use them over CAT3 or CAT5 cable (twisted pair). Let’s see how this goes.

More on this once I get the system up and running.

Saturday, May 2, 2009

Microcontrollers & Communication

I recently started a project which required several microcontrollers (placed around the house) to be able to communicate with each other. The difficult part is choosing a communications method and protocol. After doing some research, I found the following to be suitable options for inter-microcontroller communications.

The most interesting and suitable option I found was was the RS485 bus. This bus allows for communications over potentially long distances (greater than 1.3 km), tolerates high speed, allows for many protocol designs, is asynchronous and easy to use. Several protocols allow for multiple bus masters with collision detection. Overall, the bus should be pretty reliable. Further research suggested that either CAT3 (phone cable) can be used with 6 contact RJ11 type connectors. This allows for full duplex communication over 4 lines and one ground line. CAT 5 ethernet cable with RJ45 type connectors could also be used if desired. However, twisted pair cable is strongly recommended (such as CAT3 or CAT5).

Another option is using ethernet. The Microchip ENC26J60 transceiver can be used. However, I’m not sure how ethernet can be used as a bus (without a hub/switch). More on this later.

If wires prove to be too cumbersome to implement, one may chose to take the wireless route. Futurlec sells SPI radio transceiver modules at a low cost. Implement your own protocol.

Other busses such as CAN, LIN and USB are further discussed on the following site: http://www.ucpros.com/