The CAN bus described yesterday keeps drawing my interest. It feels right on many levels…
Anyway, for a real CAN bus test, I’ve set up two nodes, to be able to see a full handshake:
That’s one node sending out a 0x101 packet, and another node responding to it with a 0x202 packet with the same payload. There are lots of interesting things going on here:
The CAN protocol requires any receiving node to send out an ACK bit the moment it has received a valid packet – this doesn’t tell the sender who got it – only that some node was listening and got it. The only thing you can conclude at this stage really, is that there is actual communication – it’s up to higher level layers to verify things.
The sender is a node connected to a 3.3V-based CAN transceiver, so the voltages it puts out on the bus are lower than the receiving / echoing node (which is an ARM-based LPCxpresso 11C24 board with a 5V transceiver, running a standard CAN example in the LPCxpresso IDE). As you can see, voltages are hopping a bit, but all that matters is the voltage difference between the two lines, so everything is fine.
There is no one listening to the reply, so the LPC11C24 doesn’t get a good ACK on that, and keeps re-sending the packet. It does this a number of times and will then give up.
The Hameg HMO2024 scope with its added serial decoding options is very effective in this setup – I made it trigger on a 0x202 packet, and it shows a nice list of the data it has captured. Since I’m using the analog channels, the levels are also clearly visible.
The bus is running at 500 KHz, so the basic bit timing is in multiples of 2 µs. Zooming in, I saw that the gap between each packet is 22 µs, which matches exactly the CAN bus specs requiring nodes to wait for at least 11 idle bits before they start. Speaking of which: the CAN names for “0” and 1″ are “dominant” and “recessive”, respectively – because a dominant bit always wins and forces the bus to a “0” (voltage applied).
The packet times here are ≈ 250 µs, so there’s some 10% of overhead for the gaps between packets, and the total “overhead” for getting 8 bytes of payload across (i.e. 128 µs) is about 100% – but that includes things like bit-stuffing, a message ID, a CRC check, and an ACK. Half the theoretical bit rate to be able to send real-time data with little latency, good reliability, and precisely tagged is actually very good.
Note that the CAN bus requires special transceiver chips. The level conversions are minimal (from “0” and “1” to pulling the two lines apart, in terms of voltage), but what they also add is a substantial amount of protection against common-mode signals, which is when both signals move up or down by the same voltage. This is extremely important in a car, where large currents can lead to huge spikes and voltage changes, but it really doesn’t hurt in other applications either: the CAN bus is a very nice way to tie pieces together – and when there is an issue with ground levels, the whole design even allows for opto-couplers to be used for complete isolation between nodes.
The “standard” way to hook up CAN nodes is through three pins (CAN-H, CAN-L, and GND), but it’s not uncommon to include a +5V supply pin, making this a neat 4-wire bus.