In Software on Mar 28, 2009 at 00:01
Here’s a little “muxview” front-end for the MuxShield:
(it’s not very exciting since all slaves are returning the same text)
This little application recovers the individual streams from the multiplexed data coming in over USB. Screens 1..5 show what is coming from each slave channel. Screen 6 displays what came in before the multiplexer was started.
Here’s a more interesting example with 5 RFM12B receivers (you won’t be able to read the text because I had to reduce the screenshot to fit this blog). The antennas are way too short, to force weak transmissions and bad reception. As you can probably glimpse, each of the slaves has trouble with the data, but in very different ways:
This application is written in Tcl/Tk, the script is available here. I’ll tweak it further over time to fit my needs.
In AVR, Software on Mar 27, 2009 at 00:01
It’s nice when things come together. The MuxShield is now able to re-program up to 5 attached slaves and then act as multiplexer for serial output from each of them.
Here’s how it works in practice:
- Connect the MuxShield and plug a few slaves into it.
- Make sure the switch is set to “PROG”.
- Program a sample sketch for the slaves into it, e.g.:
- Connect to the MuxShield with a terminal:
(that’s 3x two lines of output, every 3 seconds)
- Sample output with the switch set to “RUN”:
- In the “RUN” position, programming changes the MuxShield code of the ATmega328 itself.
I often forgot to put the switch in the right position while developing the MuxShield code, but once that is done it should no longer be an issue. Since the slave code is for an ATmega168, sending it to the MuxShield with the switch set to “RUN” will fail (the 328 bootstrap rejects the 168 re-programming request).
Note that the MuxShield also makes a fine stand-alone re-flash unit: just connect a slave and press reset with the switch set to “PROG”. Here’s a MuxShield with 5 slaves, all trying to say “Hi!” at the same time:
Source code of the MuxShield sketch is available here.
Onwards – I now have the perfect tool to develop and test multiple JeeNodes!
In AVR, Software on Mar 26, 2009 at 00:01
I’ve made good progress on the MuxShield – only some minor changes to the bootstrap were needed, here is a diff:
These extensions still fit in the current 2K boot loader area, but only just!
To summarize: the bootstrap watches the switch connected to pin 7. If it is high (which is also the case if the MuxShield is not connected), then nothing changes. But if it’s low, the following happens:
- Change the bootstrap baudrate back to 19200.
- Respond as if this is an ATmega168 (different signature bytes).
- Store all incoming flash data at an offset of 0x3800.
The end effect is really, really simple: if the switch is in the RUN position, nothing changes and the Arduino behaves just like an ordinary ATmega328 board. If the switch is in the PROG position, the board looks like an ATmega168 board while programming. After that, it resumes its ATmega328 program as before.
One more step is needed to make this truly plug-and-play for re-flashing up to 5 connected FTDI slave boards: on startup, the MuxShield code must check if the switch is in the PROG position. If so, it must program each of the slaves with the data loaded in flash memory starting at offset 0x3800. Then finish off by starting the serial multiplexing logic.
Anyway – 2 out of 3 steps are done, this is going a lot smoother than expected!
In AVR, Software on Mar 25, 2009 at 00:01
Here is an extract of the code to multiplex 5 serial ports in software on an Arduino Duemilanove:
It’s a big bag of tricks, really. There is a timer running at 3x the baudrate, which detects start bits and then picks out data bits every three ticks. The crucial issue for the receivers is that the work is done in parallel for 5 input streams, but that these events are not happening at the same time. There are in fact 5 little state machine, each with their own independent state.
For the output, it’s slightly simpler: a buffer with all the 5 transmit bit states is scanned and sent out. The trick here is to fill that buffer with the proper bit patterns. When nothing is sent on a channel, its corresponding bit remains high in all values in the buffer. The transmit buffer has 30 entries, 3 per bit plus the start and stop bits. A simplification here is that all bytes are sent at the same time, i.e. start and stop bits occur at the same time on all active transmit channels.
The idea of multiplexing is that all received data is collected and sent out to the main (hardware) serial port, running at 57600 baud. Extra character codes 0x01 .. 0x05 are inserted into the multiplexed data stream to identify from which channel the data is coming. On the transmit / de-multiplexing side, the character codes 0x01 .. 0x05 are filtered out and used to indicate to which channel to send out the next characters.
If you connect two of these multiplexing shields back-to-back, you can send 5 independent bi-directional serial streams over a single 3-wire cable. Come to think of it, the following setup would make a great test for these multiplexing shields:
The full source code for the multiplexing sketch can be found here. It has been tested at 9600 baud (all receivers must run at the same speed). It probably works at higher speeds even, but this hasn’t been tested. At some point, the Atmega chip is going to get swamped while handling the barrage of timer 1 interrupts. I haven’t really tested the transmit part yet, i.e. the de-multiplexing side of things.
In AVR, Hardware on Mar 24, 2009 at 00:01
One of these days, I’d like to push the RFM12B radios a bit further, to see how they behave in high-traffic and high-noise situations. What I need really, is a convenient way to re-flash and monitor multiple JeeNodes. Here’s what I’ve come up with:
It’s an Arduino Duemilanove with a proto shield, containing 5 FTDI sockets for connecting slave boards. I’d like this new “MuxShield” to perform two tasks:
- A serial line multiplexer which can send out commands to any connected board, as well as receive and report incoming data from all connected boards, at the same time.
- A boot flash repeater which can reprogram the flash memory of each board, using the standard FTDI serial protocol.
The multiplexer makes it possible to collect data while running a multi-board send-receive test, while the repeater simplifies the development cycle when frequently altering the software. With the combination of both, I won’t need to constantly unplug boards or adjust IDE settings.
The idea for the repeater is to use a larger ATmega328 on the Duemilanove, and to reserve half its flash memory for the data which needs to be programmed into the slave boards (which for now will remain ATmega168’s).
A few more hardware details: 4 of the 5 FTDI connectors are jumpered to supply either +5V or +3.3V from an on-board regulator. And there’s a small slide switch (visible in the picture above) which determines whether the incoming flash program is intended for the Arduino or for the slave boards. I’ll add two status LEDs later, to make it easier to see what’s going on.
This setup is not limited to JeeNodes or to testing wireless radios, it works with other FTDI-based Arduino’ish systems such as the RBBB by Modern Devices or the DC Boarduino by Adafruit – there are no doubt several more.
Anyway, on the software side it’s going to be a challenge to make all of this work. And I’ll need to customize the Arduino bootstrap code.