Using CAN bus tranceivers with custom data link layer

We needed a noise immune, low cost, multidrop, multi master (realtime and distributed) protocol and there is only CAN bus seems to meet with these requirements.

Since there are no can controllers (data link layer hardware) for very low cost MCU's (such as STM32F0) and no easy-to-use API we could find to get started we can not consider CAN bus as a default communication stack of our projects.

So I think I can implement a really tiny layer that will allow implementing any protocol (like Modbus) over UART over CAN physical layer while taking advantage of data collision detection by using 1 starting byte as a bait.

Additionally, I suppose any I2C or 1-Wire hardware can directly use a CAN transmitter for its bus protocol with a simple diode-resistor hack, similar to 1-wire <-> uart diode-resistor hack.

I suspect I'm missing something since this approach is both bringing many advantages with a relatively small effort although there is no implementation I could find for this purpose.

Are there any hidden consequences on this survey?

Edit

1-Wire (with UART hack) is not working over MCP2551 CAN transceiver, since the transceiver starts feeding itself with zero (dominant) at the end point (the 1-Wire side) which prevents any device from writing "1" on the bus till the transceiver's "permanent TXD detection" function takes over the control. So, it's useless from the point of view of "simple 1-wire range extender". Which means a CAN bus transceiver's RXD/TXD pins can not be converted to an open drain line with a simple 1-wire/uart converter hack, so it will not work either with an I2C bus.

Edit-2

Using 1 byte as a bait is not performant since we have to use only 1 bit as zero, which means we have to use 100 bit just for addressing if we plan to connect 100 device on the same bus because although we could detect someone else is talking at the same time but we can not detect the priority (eg. if node#0b101 and node#0b011 talks at the same time, we will read 0b001 which is just the same response when node#0b011 and node#0b001 talks. So node#011 will never know if it has the priority or not.) So this is impossible if we don't use a bit banging technique and read the RX port bit by bit. Which makes no sense because it's reinventing CAN bus as mentioned.

• Have you looked at Local Interconnect Network (LIN bus)? – Dave Tweed Apr 10 '16 at 14:01
• Linbus is not twisted pair, thus not noise immune. Since it's not a multimaster protocol, it can not be used in a distributed control system. Also it seems more complicated to implement on a product because it's way less widespread, thus it seems it's a real pain to find a library for LIN bus. Thank you for considering though. – ceremcem Apr 10 '16 at 16:28

1. Many small and cheap microcontroller have CAN built in. Look at some of the PIC 18 with "8" in their part number. You only need to add the physical CAN transceiver, like a MCP2551.
2. If you just want a differential signal, then you can use a number of differential line drivers/receivers. There is nothing wrong with using CAN transceivers for this, RS-485 or others are options too.

Overall, I'd use CAN all the way. You will need a line drivers/receivers one way or another. CAN transceivers are as good as any, but then it's easier to use the rest of CAN. The main difference with CAN is that the lower levels of the protocol have been well thought out and are available at low cost integrated directly in many microcontrollers. RS-485 throws you a electrical spec, then you're on your own.

It's a lot more difficult to get all the details of a multi-drop bus right and robust than most people realize. Use CAN. It's all been worked out and done for you. You send whole packets at the firmware level. The hardware takes care of collision detection, retry, and CRC checksum generation and validation. These are all things you want, and with CAN you get them practially for free.

• I think recently some vendors have been working on some more power-sensitive transceivers as well, which could be beneficial in OP's application vs. conventional CAN transceivers from many years ago. – Krunal Desai Apr 10 '16 at 17:10

There are discrete controllers (MCP2515) that require SPI and few other GPIOs.

• Clearly this approach should be used as a last resort, right before reinventing something with CAN bus transceivers :) – ceremcem Apr 11 '16 at 17:23

It's not true that CAN is not available on small Cortex m0 parts. Look at LPC11C22; it has a built-in CAN transceiver. Or the STM32F042. NXP is 3$in quantity, STM32 about 2$ but requires an external transceiver which adds cost.

If the additional cost for a part with CAN controller does not fit in your project, I assume you must be charging a very large design fee to invent your own software-CAN system and be able to break-even. Building test cases and proving that your own data bus system is reliable, noise immune, bit-error 'free', collision detection, bus arbiter, etc. is not easy.

I did exactly this one time. I don't know if it still compiles(I'm using wireless now), but it works very well if you get everything right.

Microchip used to have a CAN chip that failed a lot if there was too much common mode voltage or something like that. AC adapters could trigger the failure mode with their leaky AC crap IIRC. Then they came out with a new version. I forgot the part number, but do your research.

I2C needs a more complicated hack though. The transciever usually can't work both ways without a smarter chip telling it which direction is in use(Those actually do exist, though). MCU UART doesn't have that problem because the microcontroller is aware of the separate TX and RX pins of the transciever, I2C uses bidirectional wires.

https://github.com/EternityForest/WBTV