The MCUs would just attach via a standard interface (1wire, 2wire, modbus, etc) and by default sit with all pins in a high impedance mode until being told what to do. With the end product essentially being a controllable ADC or GPIO interface for something else.
I guess my thinking is more along the lines of how industrial control systems work. But instead of using RSLogix and PanelViews (HMIs) you're using something like C# or other high level object oriented language.
How should that "telling what to do" work? If you want to write C# code you could either try to interpret it on the node (not very fast at all), or you would need a compiler (is there a C# one available for AVR for example?) and than flash the image to the device via some sort of bootloader.
Or was you intention just to "abuse" the MCUs as port/io extenders?
Did you think of a system distributed throughout a larger area or rather of a rack-mount variant with backplanes and plugable modules?
No the base programming on the AVR is just listening for instructions. You would not be compiling anything on the PC side. Instructions in this sense are not code.
Here's a mockup of a way the PC side might work.
For (int X=1; X <16; X++)
{
Controller1.DigitalPin[X] = OutputState.High;
}
Controller1.ApplyIOState(255); // 255 means apply to all pins in one instruction passed to the controller.
When ApplyIOState used. It looks in the array and converts it into an equivalent PORT status and passes it to the device.
The device gets the data packet sets the ports accordingly. PORTB = X;
If for some reason you wanted to set the states individually, you could put the Controller1.ApplyIOState inside the loop
For (int X=1; X <16; X++)
{
Controller1.DigitalPin[X] = OutputState.High;
Controller1.ApplyIOState(X); // Apply IOState to pin(X)
}
This would be a most costly way of doing it. Since the idea would be packetizing instructions (or units of work).
The idea would be you get your states ready and then send them all at once.
Or logically, you build a job for that device and then apply it. There would be a need to interrupt it also.
There might even be a master device that lives in the power block (if you choose) that has an eeprom or flash that takes the system state and applies it at power up to all the devices. It could take care of trying to poll what is out there. Each device perhaps will not allow IO passthrough until it is configured. So at power up, the device broadcasts "I am not assigned an ID, I am an ATMEGA32P" and the master says "You are device ID 1" and the device says "I am Device 1 and an ATMEGA328P" and then it opens up the passthrough. The next device says "I am not assigned an ID, I am an ATMEGA128" then the Master replies back and says "You are device 2" and so on.
Newly configured devices that have the base firmware loaded might generate a random ID code, like a MAC address and write it to the very end of Progmem.
When it stops getting broadcasts for unconfigured devices. The master replies back to the PC and says "This is my layout" If the layout matches what is set up on the PC. Then the work is sent out to the devices.
Another software configuration might be a streaming mode. This would be for things like controlling Christmas lights, the PC is constantly streaming instructions for different parts. Streaming mode would more be focused on holding a state until an instruction arrives. In streaming mode the module would not really be suitable for fast changes in IO because it would be spending most of its time waiting for instructions.
As for layout, I thought of some different scenarios. One way would be just ever expanding side modules. Each module would have a small pin header on each side for power and IO. Hopefully an optocoupler to isolate the IO. These modules could have a DIN mount on the back and just slide together.
Another idea would be devices that are spread out and connected via some cable in a star or bus configuration. If it was a star configuration, I'd have to decide if the star was physical or logical. Meaning it looks topologically as a star but is really a bus or ring with in and out.
I've always been interested in cheap fiber optics as well, ever since I've seen those kids toys with a flashlight (torch) inside that you can fluff up and let spread out the fibers. So I might want to look into an inexpensive bulk fiber that could be used for interconnecting rather than glass strand. TOSLink cables might be a first choice for some kind of standardized connector but if I could avoid that with some kind of LED mount with a pin hole on it, that would be neat also. Perhaps using 5 or 3 mm LEDS, tap a tiny hole in the top to push the fiber into.
I understand that as the complexities increase so does the potential for lack of memory or cost. Cost is a primary concern of course. So any time where the lack of memory becomes a problem I'd be willing to reconsider the design if it doesn't add much to the cost. Maybe an external SPI flash might be a better way or some extremely cheap MCU (ATTiny) to handle the IO. If we keep the instructions high level we could integrate other types of MCU with different capabilities.
Some goals:
Cost: Implement each module with the least cost. Offload as much work to the PC or master module. Each module should be as close to being MCU + passives as possible. The idea is for the modules to be cheaper than standalone MCU boards because power regulation, USB, etc are not there. I've seen some things like AVR based PLCs but the cost always seems to be higher than what I would expect.
Expandability: Be able to add modules up until the limit of the bus protocol allows. Move other parts to other modules. If you need to drive a load, the mosfets and/or relays would be in a different module.
Again, I like exploring these topics. I like to think I might actually follow through on them, but well, I don't know if I will.