Go Down

Topic: Modular Stackable Microcontroller System (lots of pics) (Read 19657 times) previous topic - next topic


May 23, 2011, 12:21 am Last Edit: May 23, 2011, 12:24 am by WanaGo Reason: 1

I can't recall if you brought out the programming pins for each processor, but I can see that you probably need an easy way to update them without pulling the stack apart.

Forgot to reply to this.

Yes, each module with a processor has a ISCP programming header (the blue plug in the pictures), so each boards firmware can be changed without taking them out of the stack if required.

It will end up that once the firmware is written for each of the modules, in theory they wont need to be changed unless there is a new firmware revision released. All the coding for the system is done on the Processor Board.
It can be thought of that each module is basically a function that returns something. If you want information from the high speed board, you call its function (the function then request data from I2C etc) and the function returns the data. The data is constantly updating in the modules, but only accessed by the processor when required - seems to work a treat.


May 27, 2011, 12:20 am Last Edit: Aug 01, 2011, 07:03 am by WanaGo Reason: 1

I have been a bit busy lately, however had an evening this week which I did some 'first pass' design work on potential enclosures for each of the modules, in order to convert them into a backplane system, rather than a stackable system.

I send the CAD files to a couple of CNC places and Laser Cutting places, even a 3D printing place, to get price estimates to produce a few enclosures.
I have had a couple come back so far, and the cheapest so far is Laser Cutting of Acrylic (each made up of 6 pieces, 5 differernt pieces).

Anyway, here are a couple of renders of the laser cut and assembled enclosure. Note, laser cutting is 2D, so in order to get this to work and to work efficiently in terms of cutting, I designed it out of multiple pieces which slot and then screw together. Each module will be made of the same parts except the front, which can be varied to suit the plugs that come out the front.

Let me know what you think :)

They are just concepts, and need tweaking before a product is made.
The picture with the backplane has different plugs on it, which is most likely what I will use. The backplane is just the circuit board part too, which will be mounted on a laser cut piece of Acrylic too, which the module will bolt onto using the tabs above and below the module.

That is the concept anyway.



Busy laying out and fixing things on all of the 10 boards, here are some basic rendered pictures.

Change Relay Board from MCP23017 to ATMega328P due to ease of Addressing, and they are not far apart in price anyway.
Only board now with DIP Switches is the Analog Input Module, which has the MAX127 chip on it.
Changed the High Speed Module and Opto Input Module to have Zener and PTC IO for added protection, and tolerance to a range of input voltages.
Added PTC and Diode protection to each boards power supply, to protect against shorts etc.
Changed all boards to be printed at a board house like PCBCart, instead of my local printer. It is amazing how many Vias I could get rid of since my local printer couldnt do PTH's,
Changed to a backplane system completely.
Added RS485 onto the Processor Board, switchable via plug on jumper to change where uC gets RX data from - RS232 or RS485.

etc - you get the idea. All still in progress but getting there.

Only done a couple of the boards into the case assembly, and havent yet done the fronts to suit the few different variants, but again, should get the idea.

Comments welcome - spot anything wrong or silly or wonder why I did it a certain way?



Have you got a pin out for the backplane you could publish?

Also, have you considered using a length of ribbon cable with IDC plugs instead of a fixed backplane?


Hi TonyD

The pinout of the backplane? Sure I can release that if you want, however it isnt anything special... Its just made up to suit my boards. What would you like that for?
I have a 60 pin connector between the boards as that is what I found available and fitted the best, its a 2mm pitch plug from Samtec.

Ribbon Cable with IDC plugs - No I didnt consider it as I wanted a backplane system as the next step over the stacking system. You could use a Ribbon cable I suppose, however the standard IDC plugs are 2.54mm pitch which arent as ideal to fit in the spot. That is what I had to start with, however I only have a side with about 60mm of real-estate so a 2mm header suited better.
Is there any reason you suggested a ribbon cable though? If I had a system that required 20 modules, stringing them together with ribbon cable would be interesting, where as I could have 2 of these backplanes.
My plan is to attach an IDC type cable connector at the end of the backplane to allow connection to another backplane for expansion, as I can have up to 119 modules.



Few more modules added into Solidworks, 3 more PCB's to re-engineer into a backplane format and then 1 more to design from scratch.


Ethernet/Bluetooth Board and Sensor Board modified and converted.


May 31, 2011, 09:39 am Last Edit: May 31, 2011, 09:50 am by WanaGo Reason: 1
Ok had a bit more time, got the 10th module modified.

Now onto the backplane to backplane connector, and the Quadrature Encode Input board.


The pinout of the backplane? Sure I can release that if you want, however it isnt anything special... Its just made up to suit my boards. What would you like that for?

Curiosity :) I was wondering why so many pins?


Oh right :)

I could have gone with a smaller connector and fewer pins etc, however I have 3 voltages (2 isolated 5V busses and 1 VIN which could be 24VDC), I2C, serial for debugging, spi to the ethernet board, grounds, 2 analogs going to the PSU board etc going down the bus and I just wanted to maximise the number of cores for each, especially the voltages as the draw could be up to 3A on each, especially if there is a max number of modules installed (probably will never happen though).

The rating of the plugs are 5A over 6 contacts at 20 degrees C, and I have 4 contacts for each voltage.

It fits nicely so I went with it, plus I could get free samples.



May 31, 2011, 07:13 pm Last Edit: May 31, 2011, 07:55 pm by FalconFour Reason: 1
Wow. I *really* like this setup!  :smiley-eek: Way out of my usefulness-range as more of the "arduino newbie" crowd (arguably not so newbie at this point, but I don't do anything professional with it, just silly electronics play/learning), but really amazing to look at.

I figure it might be useful to mention my initial thoughts when I read about using a backplane system... might be a little late in the design process, but I thought it'd be a *much* cheaper alternative to individual module cases and whatnot. At first, I visualized the backplane system as a "card-slot" system, where the backplane itself consisted of that same board you use now, itself also becoming, and enclosed in, a plastic case that makes up the size of the desired backplane unit. The plastic unit has slots that the modules - which would just be simple PCBs with edge connectors of some kind (maybe even card-edge and socket, to avoid pins?) that would slide into the backplane slots. Optionally, a faceplate could be attached to the installed module to hold it in place inside the backplane casing and give it its labeling, etc. It just seems like the current solution - pretty much the exact opposite with the backplane being the raw PCB - would have a lot more wasted plastic since most of the modules' plastic casing would be function-less when stacked against each other in usage.

At any rate it's an AMAZING project and I can really see it being useful for the industrial types. Can't wait to see what it turns into! :D

edit: I also got to thinking about a plug-n-play addressing system last night that could be very easily implemented in AVR C code. The general idea is to "throw all the addresses up in the air" (e.g. setting all i2c addresses to the same 119), then have each one "bounce" the i2c bus to request an address: "bounce", referring to "check immediately before sending". A module would check if the line is active, immediately send if it's clear, or immediately delay for a random amount of time before trying again. Random time could be accomplished by watching analogRead() on a floating analog pin and checking for the value to equal a specific number (e.g. "while (analogRead(0) != 450) ; // generate random delay"). Then, check again for the inactive line, and send. The latency between checking->sending should be small enough that two boards wouldn't consider it inactive at the same time. The addressing would, perhaps, occur on a processor interrupt attached to a "address request" pin that would be polled by the "bounce" code of the boards as well as the address-assignment-and-tracking function of the processor. And that address-assignment function (interrupt, etc) would track the IDs of installed boards, and pass that information off to the related functions for each board (e.g. Analog Output board functions would default to the first installed Analog Output board with no parameters automatically, by reading its board ID from the address generator). And because it's plug-and-play, assigned on each startup, it wouldn't need to be stored to (limited-write-cycle) EEPROM, and could be extended up to the full address range with extension backplanes. :D

editedit: Perhaps 4-position (16-selection) DIP switches could be used for >1 of the same module, so the code can reference which of the same type of board to refer to. That could be sent as part of the address request "packet" and the processor board would associate that in its assignment-table, so the code could also know what board is being referred to. It could still be assigned any given address, but the processor would know which DIP setting that address is set to (without it needing to be part of the assigned address).

editeditedit: Also, I've found that AVR controllers are available in a huge number of pin arrangements and prices, and one could easily be added to the module's design to act as either a full module itself, e.g. the 328p used on the Analog Out board* which could perform its own addressing as well as its function, or use something like a cheap, 8-pin ATTiny85-20PU as an I2C-to-module interface that could handle all the plug-n-play addressing as well as module-specific I/O translation (like controlling a UART-based module IC, and running it over the main I2C). I think it even can run on an internal oscillator that uses no external components; the Arduino's 328p and related family can run on an 8MHz internal clock if programmed to do so (sadly it seems to need external programming to enable that mode initially). And the 328p is in such high demand thanks to Arduino-related projects, that it might make the modules much more "sustainable" with alternative chips instead of the 328p's performing most modules' functions :)
* - BTW, are you using a lowpass filter on the analog outputs, such as in this Arduino digital sinewave generator (which I played around with, and sounds very much like a sine wave even without the filter!)... when you look at PWM output with an oscilloscope, it looks pretty frighteningly jagged... looks nice on a multimeter, but those do smoothing ;)


Wow big reply
Thanks for taking the time.

Where to start....

The backplane system is based upon a PLC. I am an industrial automation engineer and all the PLC's we use at work are pretty much like this, and have used this sort of system for 20+ years. The only real difference is the PLC's at work hinge into position and are secured by 1 screw, rather than 1 screw top and bottom like mine are. That said, their connectors are much more sophistocated and allow for this type of insertion, whereas anthing I can find that is reasonably priced doesnt.

I had thought about a single case for the backplane and then the cards just slotting inside it, however it isnt the direction I wanted to take.

Here is a picture of one of the PLC's we use at work, found on google:

Addressing system. I am a little unsure what your suggestion is trying to achieve over and above the test method I have already implemented... Remember, you need to know the addresses of each of the modules, so self assigning at random wont be much help, as the main processor needs to know specifically which module is which so it can tell it to do the appropriate thing. No point having the processor turn on an output on the wrong module and start a grinder when really it should have turned on a fan.
The method I have is on a new module, it is address 119. With the bus powered up, plug each module in one by one, and the module gets assigned, and the module stores its assigned address in EEPROM. Next startup, it loads from EEPROM - job done...
Is there something I have missed with your proposal?

DIP switches, I wanted to get away from these entirely. What happens if you want 60 High Speed Counter modules... You would need 6 dips, and you would have to set each module individually. I dont want to go there.

AVR range - yes there is massive range. The only reason I went with the 328P is they are pretty cheap, and are natively supported by the Arduino platform. I am not using them to their full potential in most cases, and could probably swap them to be Tiny's in some cases, however I dont see the need at this point to be honest - they fit on the baords and its nicer to program all of the modules without having to chop and change the destination board type all the time.
I am a little confused with your example of the Tiny to do module specific IO translation.... what do you mean by this? Is it you mean having a module which can talk to other devices, like serial devices etc, which are not compatible with the I2C bus, but this does the talking to them and sends the info over the I2C bus? If so, then yes - something like that is already in the ideas basket, if not - can you elaborate please?

Analog Output - Low Pass. Correct, its just using the example given by Rugged Circuit on how to get the PWM to act as an Analog Output, and its then amplified through an opamp to give 0-10V. The PWM is set to use a clock prescale of 1, so the output is alot smoother than standard, which I think uses Clock/64. As I was seeing a big difference between what I was outputting and what I was reading in. I tied the Analog Output module to the Analog Input Module, and with the clock prescale of 1 set up, they read the same. I havent yet put it on the scope, but that is on the to-do list.

If I have misinterpreted what you said in any way, I appoligise and please repost.

I had done alot of thinking and am now up to the 4th iteration of this system, so hopefully I am getting there to be the final product soon.

Thanks for the reply



Here is the backplane as it currently stands. I need to add on the expansion plugs yet, but this may explain it a bit better if it is unclear.

The backplane PCB is just a simple single sided PCB with through hole plugs, and straigh interconnections down the length of the entire board.
It is fixed to the rear of a piece of plastic, with laser cut holes for the plugs to poke through. Top and bottom of this piece of plastic is a plastic standoff, which can be fixed to an eclosure, wall etc.

Side profile (PCB looks very thin, I have not set it correctly in Altium, but you get the idea).

That is the concept.



Jun 01, 2011, 12:57 am Last Edit: Jun 01, 2011, 01:01 am by FalconFour Reason: 1
Ooh, I see the point of the casings now. I figured it was a little late to be suggesting that, but I thought it would be better to mention my thought than to just pass it by :) I'd never seen industrial PLC equipment before, so that makes sense.

OK, about the addressing, I think I might not've been entirely clear on that, I was sorta thinking half it up as I was writing. The controller would definitely know the address of each of the modules (and each of 60 of the same as well), but its internal addressing would be plug-n-play on each startup (and as a result, modules could be plugged/unplugged without resetting the whole bus/addressing either, just request an address). It'd work like this:
- system powers on
- all modules start with an address 119.
- all modules wait a random amount of time using the analog-input method or other "true random" (so they don't all pull the same random number from their algorithms, etc).
- the first module coming back from the random delay (becomes "first" when it) checks the "address request" line, and if low, it immediately brings it high and contacts the processor via I2C for an address (now other devices waiting at "random" will "bounce" and start another random delay while this line is high)
-- in the request, the module would specify its classification (analog-in, relay-out, etc) and any user-assigned ID in any method (perhaps using the ATTiny's EEPROM to store a user-defined "module ID" that's used in the code and stored when the processor assigns its ID).
- processor responds with an address
- module confirms the address and sets itself
- processor remembers "this device is given ID XX and is numbered YY"
- module releases the address request line to go low and be picked up by another device coming back from the delay, loop continues until devices are no longer requesting addresses

That has a number of advantages:
- no IDs to set manually unless they need to be (more than 1 of the same module), and even in that case, the processor could have a special exception/error message/routine to handle when two devices have the same "external ID", e.g. automatically assign a new ID, notify the user, etc. A populated backplane could be added by just plugging it in while the device is already running, and the modules would just pick up new PnP IDs.
- no serial numbers to assign
- even if 2 devices end up with the same "external ID", the auto-assigning process would allow it to be reprogrammed with zero issues, no need to unplug all modules to reprogram one's ID
- only one pin needed to manage the whole ID-request chain, since addressing would be done over I2C itself

Admittedly, I didn't really hash through the whole newly-revised addressing system posted earlier in the thread, as me writing-up my addressing idea was sort of an afterthought... so if you've got a better system then of course use whatever works :) Again, just figured it'd be better to spill the idea out instead of letting a possibly-useful idea pass by :)

BTW: the 3d renderings look freaking _awesome_! If just a bit big for my 1366x768 screen (they're all cut-off here on the forum, I have to right-click, "view image in new tab" to see it in all its glory) :D


The 3D renders, you are right, they are probably a bit big for alot of people.... I have a big screen so didnt even think twice about it...

Addressing. I understand, but again I am struggling to see how to put this into practice.
Have you used I2C before?

If all modules are 119 to start with, the master cannot say to one, have this address. They would all pick that up and they would all set themselves to the new address...
From then on I am struggling to see how it will work. With the method I have already, by plugging them in 1 by 1, only 1 module is ever 119 at any given time, so the master can address it individually. If they are all 119, then they would all be listening and its basically a broadcast then and they would all react.
By have a serial number on each device loaded in, it enables the main processor to destinguish between two modules that have the same address. If you have 2 modules at 119, then if you do an I2C scan, it will show there is a deivce on 119 but it doesnt know which one it is. If you know that 1 device is serial 12345, and one device is serial 54321, then you can say to address 119 "if you are serial 12345 then set your address to be 100", for example. Without that, if you said, address 119 change your address to be 100, then you will have 2 devices at address 100 and you will be no better off.

Again, If I havent interpreted you correctly, then let me know.

I did some testing with addresses being the same, as I do a I2C scan of the bus and request serial and model numbers of the boards that respond. If I get 2 boards on a single address, then the serial number and model that are returned are all junk as two devices are talking at the same time - so it seems. I can still assign them addresses if I do it via serial number, as I have code in each module which states their serial number and if they are a serial number when a request comes in, they know if they are being told to change or not.

So in effect, if I keep the serial number method, plug all in at once, then I could get the main processor to assign each with an address, it will have to know serial numbers though. So we are no better off...

Let me know if I have missed the mark with your proposal again.


Go Up