Inventing Networking Protocols For Dozens Of Arduinos

chain

When you don’t want to use I2C or SPI, and MIDI and DMX are old hat, [Scott] comes along and invents a very strange networking protocol that is just daisy chaining a few Arduinos together with serial connections.

Strange as it may seem, this networking protocol actually makes a whole lot of sense. [Scott] is working on an animatronic birdhouse in the vein of Disney’s Imagineers and needed to network a whole bunch of Arduinos without using up precious IO pins.

The networking stack [Scott] came up with capitalizes on the hardware UART in each Arduino by simply daisy-chaining several boards together. By adding an FTDI breakout at the beginning of the chain, [Scott] can control dozens of Arduinos straight from a terminal

[Scott] isn’t using off-the-shelf Arduinos for this project – a few months ago he found 100 Arduino-compatible stepper motor controllers while dumpster diving at his job, giving him more than enough nodes to come up with some pretty crazy networking protocols. It’s a great use of the hardware he has on hand, and a very clever solution to controlling dozens of microcontrollers at once.

Check out [Scott]’s demo after the break.

[youtube=http://www.youtube.com/watch?v=GFqzgdNSR4s&w=470]

35 thoughts on “Inventing Networking Protocols For Dozens Of Arduinos

  1. 1) It’s not going to be fault-tolerant, unless he adds something to bridge serial connections on an out-of-service board
    2) The latency is going to be hideous…
    These issues would be addressed (hoho) using a broadcast bus ala RS485

      1. Didn’t token ring and 10Base-T stop being used 20 years ago?

        1) wire all of the RX and TX lines into a single wire such that the Tx connections are all open drain (useful since UARTs idle @ 5V) so every device hears every other device including itself. Then add some software smarts to ignore your own echo and message formats that allow easy frame detection.

        Like 1-wire?

        1. Actually, FDDI is a token/ring network protocol.

          Ethernet won the home and business network markets for two reasons: 1) it’s easy to add and remove devices, 2) the actual traffic across such networks is only a fraction of the theoretical capacity. Collisions aren’t much of a problem when the wires are quiet 50% (or 90%) of the time. The tradeoff is that you have to segment your network once things start to get busy, and you have to accept the overhead of the collision-recovery protocol.

          Token rings are good when you know your network topology won’t change very often and you want high throughput. As the traffic across the network approaches 100%, devices just see an increase in Tx latency as they wait for the token to reach them again. You can set that to a predictable maximum by forcing each node to give up the token after a certain amount of time. The tradeoff is that you give up the freedom to add and remove nodes at will, and you have to maintain the network as a whole.

    1. come on man … were not working with FPGAs here duh there is going to be lag … when you cant use i2c with master and slave and when you cant just hook them up in parallel this is the best possible light-weight solution
      i think he did a great job with this and im seeing he is putting those pseudo-arduinos to good use!

  2. I did something similar in software (c++) a little over a decade ago when i was first learning to use winsock. One of my experimental projects was a series of 8 clients that established a connection to a server app. the addressing test (and purpose for the 8 clients as opposed to just 1 server and 1 or 2 clients) was having the first client take user input as a string, output the first word of the string to a broadcast as a client, communicate through the server ‘privately’ to the next client in the series and pass on the remainder of the string so that client 1 would say the first word, client 2 would say the second word, client 3 would say the third, client 4 would say the 4th word, client 5 would say the 5th word, client 6 would say the 6th, and so on until the entire string had been depleted. It’s a very basic approach to having several clients (or in this case controllers) work together to accomplish the same task- and while not the most efficient or fault tolerant method, it’s perhaps the quickest and easiest to implement from scratch. I have to admit though, i never foresaw any practical use for the concept (other than to test my skills and help me learn something new.) and after having read the first two posts regarding this collection of atmega’s I’ve got to say I’m looking forward to seeing the finished project, or at least another post on it’s progression in the near future.

    1. I’m actually working on two projects that use this technique right now. One is a battery string monitor and this daisy chain idea works well as I only have to isolate a single serial signal and there’s no addressing required no matter how many batteries in the string.

      The second is a monitoring and control network that does this in both directions (two UARTs) over RS-485, that makes it a redundant-ring topology which is more robust than a bus. As for latency, the worst case for 254 nodes is 45.3mS, and with a 20-node network the average latency is 3.2mS. Either is well acceptable for most applications.

    1. The two have nothing to do with each other. You can run the Arduino framework (or an identical clone anyways) on non-AVR cores and you can have AVR cores that can’t support the Arduino framework. Kind of like calling every CPU a “Linux” or every Linux install an “x86”.

    2. I wrote all of the software in the Arduino IDE, and each of the widgets uses an Arduino bootloader. Iit’s not shaped like the little blue board, but it is for all intents and purposes the same thing at this point. :)

        1. TO gently point out, *every* arduino (until recently) has an AVR chip from Atmel.

          I think what you are trying to say is every AVR system not specifically designed to be an Arduino or clone supports the IDE protocol.

          I have not tried, but I thing the Teensy 2.0 (++), if burned with the Arduino bootloader, will support the IDE. Their pinout card shows it configured to be an ardiono clone (in functionality of the pinout, not the formfactor).

          I just use the Teensy as a raw AVR – does a great job, BTW. Use the AVR Studio and the bootloader from Teensy – really slick.

  3. Two other low effort options come to mind that I’ve used in the past:
    1) wire all of the RX and TX lines into a single wire such that the Tx connections are all open drain (useful since UARTs idle @ 5V) so every device hears every other device including itself. Then add some software smarts to ignore your own echo and message formats that allow easy frame detection. Unfortunately there is no arbitration in this scheme so it works best if the concept of a master is token based and passed as needed.
    2) use multi-master I2C. I know several AVRs support this natively, not sure if the Arduino framework does or if you’d have to get fancy. Then everyone is a slave until they want to talk, when they reconfigure as a master.

  4. I2C is designed to be mostly on the same board or very close. According to the specs the line is very limited in terms of capacity, i remember in practice this only adds up to a few meters.
    I believe his implementation is very simple and good enough for some applications.
    But, if it were me, I would make it in some other way, so that if one node fails there wouldn’t be total failure.
    I suppose you can also implement a 1 wire sort of thing also, where the devices are connecting in parallel to that line.

    1. “so that if one node fails there wouldn’t be total failure.”
      That’s the beauty of a redundant ring, a single line fault has no affect on the network at all. Even a dead node has no affect on the rest of the network.

  5. Hey all. Thanks for the excellent feedback. I understand everything that you’re saying about using I2C, One-Wire, and the fault tolerance concerns. The plan is to use these little widgets, and they have even less connectivity than storebought arduino boards, or bare ATmega chips. The standard I2C pins aren’t even brought out to any headers, and if they were, I’d be using them for motor control or other outputs. There will likely be no more than a half dozen of these on the “network”. The main computer will be playing back music, and sending out the positioning information to the widgets. I doubt that there will be anything related to faults… and if there are, a bird might stop moving, i wiggle the wire, and it’ll be fine again.

    I understand the concerns, and I really thank you all for the input on it, but I’ve considered a lot wrt implementation, and this solution seems to be the best for my project… the lack of extra hardware or major software stacks, or loss of IO pins far outweighs (for this project) fault tolerance and such. :)

    Also, you can just call me “Scott” rather than “[Scott]”. That just looks weird. ;)

    1. Scott,
      If you are indeed using the TX and RX pins, why not simply connect all RX and all TX together? Each digital pin normally can drive quite a few others…
      You’ll have to make sure that there’s only one micro transmitting at the same time, the others have the TX set as input. (i do understand you don’t really need that).

      1. It’s a good idea, but I was afraid of one chip having enough power to send to all of the devices. They will be scattered throughout a room, the furthest one perhaps 100′ of wire away from the main host. No idea if this would be a real concern, and I don’t have the EE background to figure it out… I just know that what I have is good enough for my needs. :)

        And yeah, they wouldn’t really need to transmit anything at that point, but dealing with them transmitting simultaneously seems to be a difficult problem to deal with. (although yes, it was implemented/solved for 802.xx networking, I don’t really have the motivation, or enthusiasm to reimplement it for my stupid little network. :) This is a step on the way along a bigger path. I’m sure that there are different and better ways to do this, and I can explore those later… or others can… but I’ve got something that i’ve proven to myself works well enough for what I need it for. Time to shelve the results, and move forward with the rest of the project around it. :)

        1. Wiring them all in parallel is a really bad idea, because TX pin on a AVR isn’t current limited such that a collision wouldn’t damage the controllers in the long run (although they probably won’t die the first time it happens). You could use a series resistor on the TX output of each board, but that will seriously hurt the slew-rate, and thus the maximum bitrate of the whole system.

          Besides, it wouldn’t decrease the latency at all, assuming all boards need to be updated at the same frequency.

          I must say it’s a horrible solution for anything serious, but for this particular situation (entertainment only, re-using existing boards), it’s probably the best option available.

          1. Conditioning the signal to limit the current and voltage wouldn’t be THAT hard to do. However, with a common slave TX line, you now have to have software handshaking to ensure that you don’t get overlapping transmission. The cool thing about a ring network like this is that as long as the slaves are just acting like a fifo buffer, there is zero chance of collision.

            The custom packet format seems a bit odd though. It seems that a standard addressed packet would be better suited to the task. That way you could add, remove or reorder slaves at will and not have to alter your firmware.

      2. RS232 (TTL or level-shifted) over 100 feet is pretty bad after about 9600 baud. TTL-only is even shorter – best restricted to about 10 feet.

        A transmitter needs a receiver. The main reason for not tying the TX lines together is they are TTL, not open drain – the other TX lines would fight with the TX line that goes low. The receiver would become very confused, not to mention the damage to the TTL TX pins. (The MAX232 and the 485 level shifters are specifically designed to tolerate “fighting TX” connections.)

        [Scott]s – oops – Scott’s hack would work, just very fragile. A robust solution is to just make a small RS485 4-wire (duplex) board with ribbon cable between them. (two-wire is *very* confusing to get right unless you *only* have one master, N slaves, and *only* the master transmits.) 100 PCBs are really cheap to make – about $100 for the PCBs themselves, total under $300 (or so) for the rest of the parts, cables, etc.

        You can chew up a lot of time on a fragile token ring.

        Cool project in general!!

        1. Two-wire RS485 is the de-facto industry standard for CCTV control, can work over a very long distance and is cheap & robust. It can be confusing if there’s a lot of traffic to & from every node (much easier if it’s more “to” than “from” etc.) but it’s not hard to implement a few basic controls/timings to ensure everything works.

          I2C is really for on-board only, there’s plenty of better options for longer distances, from RSnnn to CanBUS, but being HaD it’s better to reinvent the wheel than do some research.

          1. I am assuming you are just stating general protocol info, because nothing in your post has anything to do with mine.

            The real issue with RS485 is multiple masters – possible but a real pain. same issue as any multi-master system because of the collisions.

            But – RS485 is great for robustness (high noise immunity) and long runs, ie 1000 feet. Full-duplex is a lot easier than half-duplex because TX and RX have their own pair, so you don’t have to switch RX to TX for the addressed slave (TX to RX for the master). Timing can be tricky and painful.

    1. It seems they are. Somewhere I’ve some old Clearway units that did something similar for dynamically linking vt100s to serial lines. All the serial data was sent round the ring by z80s.

      Those boxes had one neat trick which might be useful here: a changeover relay connected the incoming data to the outgoing data when it wasn’t energised. It was controlled by a digital output and when the software was up and working connected the units Tx to the outgoing data instead.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.