It has been a bit quieter than usual on this blog recently. It isn’t that we haven’t been up to much. Quite the contrary, it has been very busy.
But much of the business (busy-ness) has been either at work. And the land work has mostly just been putting finishing touches on projects that have already been posted up here. (I figured you wouldn’t be interested.)
But another project that has been consuming a lot of my time is trying to write the microcontroller firmware for the walkway lights. We’ve received the prototyped PCBs we sent out for fabrication and built a few prototype lights. Here is a picture of 3 of them on my desk awaiting firmwares:
These are just the “heads” of the light posts upside down on the table. The circuit boards you can see on the top will go down into the light posts and everything will screw together. This will allow for easy maintenance when one of them is faulty in the field and needs to be brought back inside for diagnosis and repairs.
So each light post is actually a little computer (Atmel ATmega328p microcontroller) running at 8MHz. It sits on an RS485 communications bus that runs about 150m from BaanMae to BaanRimNaam. Each microcontroller drives one 7W LEDs that is mounted inside of the light post head.
WARNING: The rest of this post is a bit nerdy in a network communications kind of way. If you aren’t interesting in learning about RS485 and basic networking concepts like “master-slave” and “peer-to-peer” and what the differences are, you are welcome to stop reading here. I promise I won’t be offended. Consider yourself warned.
Most of my early experience with RS485 communication has come from communicating with the Robotis Dynamixels that Praew uses on her robots. Since then, we have built quite a few robots using RS485 communication between microcontrollers and Dynamixels, or even just between microcontrollers and microcontrollers. We’ve even built some security systems that use RS485 to communicate between devices.
Trivia break: RS485 can transmit data between more than 32 devices that can be over 1km apart.
In effect, the walkways on the land will have “robotic lights”. Not in the sense that they can get up and walk around, but in the sense that they will have their own localized intelligence and the ability to communicate intelligently with other devices on the land. (Think “Internet Of Things”.)
But this has led me to revisit the communications protocols that I’ve been using on the RS485 projects over the years. Most of my network communications experience over the past 30 years has been things like custom encrypted file transfer protocols over TCP or UDP over Ethernet (or even WiFi). And there are a number of things one takes for granted on Ethernet that isn’t there for you on RS485. In effect, RS485 is “bare metal”. On RS485, one sends bits down a pair of wires according to the following rules:
- if the voltages between the wires is within 200mV of zero, no data is being sent
- if the voltage is less than -200mV, then a 0 bit is being transmitted (by someone)
- if it is greater than 200mV, then a 1 bit is being transmitted (by someone)
Now the hard part is that since there is only one bus of 2 wires, there may be dozens of devices on the bus. How do all these devices communicate without all of them trying to talk at the same time and scrambling each other’s messages?
In comes basic master-slave type communications. This is what the Dynamixel uses, and it is the simplest way of controlling the bus and preventing data collisions. Basically, one device is designated as a “master” and all other devices are “slaves”. The slaves can never talk unless responding to a request from the master. By this mechanism, the master has full control over the bus, and by talking to one slave at a time, can guarantee no more than one device is ever transmitting at a time.
The analogy I like to use for this is a meeting of people. There is a chairwoman running the meeting, and she asks each person if they wish to speak, and only then can that person respond. But no one is allowed to speak until called upon.
The problem with master-slave communication is exactly the problem you can imagine in this meeting. Since no one is allowed to ask a question, or follow-up on what someone else said, most of the time is taken up with the chairwoman asking each person one-by-one “do you have something to say?”, “what about you?”. This becomes very tedious in a real meeting, and it basically consumes the RS485 network in master-slave communications. Imagine that you have a network of sensors, any one of which may measure something that is of importance to you (like each one measuring the voltage of its own batteries to tell you when the batteries are getting too low), the master must constantly poll each device saying “do you have anything to say?”, “what about you?”. Since the master device has no way of knowing when one of these devices will have something to communicate, it must constantly and repeatedly ask them. So 99.9% of the time, the master is asking the slave “do you have anything to say?” and the slave is responding “no I don’t”.
This brings us to peer-to-peer communications. While almost all Ethernet and other Internet communications are peer-to-peer, I’ve always used standard socket libraries to program them. These libraries (and the hardware that they control) insulate the programmer from having to do things like figure out when data can be transmitted down the wire without colliding with someone else’s data. (It might be worth mentioning at this point that modern Ethernet switches don’t have a bus since they are single-point to single-point connections with a switch, with the switch intelligently routing data between devices, but the Ethernet standard was originally built on a bus design, and I suspect that it can still work that way if you could scrounge up some old hubs.)
I’ve been thinking about using RS485 in a peer-to-peer way a lot recently, and I came up with an approach for building a simple peer-to-peer protocol library for my ATmega devices. My goal is to come up with something that does its best to avoid collisions and is still robust enough to handle them properly when they do occur.
I’ll probably post about this in more detail once I have a proof of concept test running, but for now I’ll throw out some of the background thoughts going around in my head.
One of the original network protocols that did this is called ALOHAnet from the University of Hawaii in the late 1960’s and early 1970’s. Their approach was quite simple:
- If you have data to send, just send it
- If a collision occurs, wait some amount of time and try again