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.
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.
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.
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
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
After posting on the PICLIST and getting opinions about the protocol, I got the following responses:
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:
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.
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/