Modular Stackable Microcontroller System (lots of pics)

Ok had a bit more time, got the 10th module modified.

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

WanaGo:
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 :slight_smile: I was wondering why so many pins?

Oh right :slight_smile:

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.
http://www.samtec.com/documents/webfiles/pdf/ls2.pdf

Cheers
James

Wow. I really like this setup! :astonished: 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! :smiley:

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. :smiley:

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 :slight_smile:

    • 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 :wink:

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

James

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.

Cheers
James

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 :slight_smile: 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 :slight_smile: Again, just figured it'd be better to spill the idea out instead of letting a possibly-useful idea pass by :slight_smile:

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) :smiley:

Thanks
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.

Cheers
James

You're right, I was a little hung up on the 119 addressing. I've used I2C a lot, at least in its SMBus implementation, for interfacing with laptop batteries, and spent hours looking at its timing and protocol... I've just only really dealt with one device at a time :stuck_out_tongue:

Really, the 119 address would no longer be a "broadcast", it'd be the processor sending commands to the board that's holding the address line high. Maybe this could be the sequence of events at the assigning-time (after one board has picked out that it's holding the address line this "round"):

  • all other devices are in "delay loop" mode while they see the address line is high, so they aren't listening
  • processor sends "hey, device 119, identify yourself" (start -> address 119 -> "read" -> read expected bits of information -> stop)
  • device sends "i'm a relay board, my programmed number is 32"
    -- if the response is garbled, perhaps 2 modules saw the line low at the same time; simply discard the data, send an error response, and the line should go low to get another request; those erroneous boards would just get re-queued within the next few milliseconds.
  • processor sends "hey, device 119, take address 2." (start -> address 119 -> "write" -> write its new address -> stop)
  • processor sends "hey, device 119, did you get that?" (start -> address 119 -> "read" -> read the new address -> stop)
  • processor remembers that a relay board is present with ID# 32, previously programmed to its EEPROM, and is on I2C address 2 now.
  • device goes to address 2 and releases address line
  • next device leaving delay loop sees that address line is free and begins the cycle again (and by holding high before the others come back from their delay, it effectively "queues" the boards to be addressed).

It should be able to address all the devices on the backplane within 1 second, even...

Thanks for the further clarification.
I understand now, and yes, by having the additional address line this sounds feasible.

It does mean having an additional line for addressing, each board would then have to isolate this line (as per my design), and it would have to be bi-directional isolation at that.

All signals going into the backbone need to be isolated, so no 1 board can blow up another board if something goes wrong.

Your proposal is a method to extract the serial number from each board while each is addressed the same on the I2C bus - which is great. Isolating this line on each board bidirectionally requires another chip on each board though.

I will have a think.

Thanks
James

Life got a bit busy however I have spent a bit more time on this and finally have everything to a point where I think its ready to get a few sets printed at PCBCart and get some cases made.

Here is a render of the system.
The modules which are not attached still need their PCB's updating, however the concept is right, and you cant really tell from the images. There is still 1 case I need to make a front for also, that is the Ethernet/Bluetooth module - but I dont have CAD images of the WIZNET 812MJ or the Sena Bluetooth module, so its a little harder to design a front for as I dont know their exact size.

Anyway, 2 renders attached - I havent included them to show on the forum as they are larger size.

Full Assembly
Processor Board

Cheers
James

Just made another Module in the last few hours, to fill a gap which I couldnt cover.

MOSFET Output Module :slight_smile:

This board has 8 MOSFETS which do High Side Switching, which are selectable in 2 groups of 4 outputs to select 5V switching or External Voltage switching. The 5V switching I have limited to 200mA shared between the outputs, however will be good for PWM'ing or switching high impedence inputs, such as Stepper Motor Drivers etc. The External Voltage switching is so you can provide it an external voltage, such as 24VDC, and the outputs will then output that voltage (minus the voltage drop), so you can therefore PWM 24V etc.
The MOSFETS I am using are IRLZ44N (http://www.irf.com/product-info/datasheets/data/irlz44npbf.pdf), which are Logic level.
I will probably limit the switching current to 1A or 2A, as I dont want to have to provide massive heatsinks, even though these things are capable of switching massive currents.

Still have checks to do to make sure I have done it right, but it could be a very handy module to have.

Today I went around to my mates place, who has a few projects for me, and we figured out the requirements of each project. Each of his projects will use 6 or 7 of the modules, so will be a good test of how they perform. 2 of the projects required this new module, hence me putting effort in this evening to make it.

Comments welcome, here is a picture.

Information was gained from this old post, so I will mention it - Thanks to those involved.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230677423

James

Changed my mind with the above board, after discussion with Graynomad.

Have modified it to use the L293 Half Bridge chip instead, which gives a push/pull arrangement.
It will do what I wanted the above to do, but will be able to pull to GND too.

Cheers
James

EY MAN!!! A GOOD OPTION IS THE EURO CARD CONECTOR AND THE EURO RACK. CHECK IT

EY MAN!!! A GOOD OPTION IS THE EURO CARD CONECTOR AND THE EURO RACK. CHECK IT

Gee talk about digging this up from the dead

Wow alot has happened since this....

ah the memories... :slight_smile:

patricio_flamini:
EY MAN!!! A GOOD OPTION IS THE EURO CARD CONECTOR AND THE EURO RACK. CHECK IT

Explain why this isn't spam.

WanaGo:

EY MAN!!! A GOOD OPTION IS THE EURO CARD CONECTOR AND THE EURO RACK. CHECK IT

Gee talk about digging this up from the dead

Wow alot has happened since this....

ah the memories... :slight_smile:

imagine digging the project back from the dead :wink:

WanaGo:
Gee talk about digging this up from the dead

Wow alot has happened since this....

ah the memories... :slight_smile:

I just read this thread!
This was some pretty cool work that you did on this topic.
Mind letting us know what else has happened since?
Did you make any new breakthrough's?

ARdentLogic:
I just read this thread!
This was some pretty cool work that you did on this topic.
Mind letting us know what else has happened since?
Did you make any new breakthrough's?

Was fun, yes.
Had all sorts of projects since this, but nothing really worth mentioning
Glad you enjoyed the read.