Memfault State of IoT Report

How to build a network of tiny micros?

Started by jmford94 2 years ago12 replieslatest reply 2 years ago171 views

Hi all.  

I am designing a system for controlling a multitude (150!) of
thermoelectric cooler units.  Each unit's current magnitude and
direction must be individually controlled.  I have a straw-man design
that should work, consisting of a DC/DC converter based LED driver to
provide a constant current source, commanded by a PWM signal.  Each
TEC will have one of these controllers.  A thermistor measurement is
desired at each TEC.  This might be dropped if it affects the cost of
the system.

Each of these 150 units must be controlled with a central computer
process that calculates the required heat injection/removal required
at each cooler, and sends the commanded current to the cooler

These are all mounted in an area of about 1 meter square.

This little controller should cost about $2 in large quantities, that
is, about 2000 unit batches.  I've looked at the ATtiny202 
microcontrollers, which are available in quantity for 0.50 or less.  I
also like the MSP430 series, which are pretty cheap as well.  My other
electronics for current control cost about 1.50 in quantity, so I'm in
the ballpark with a $2.00 BOM cost

On to the actual question:

I'm struggling with how to communicate with these controllers.  My
first thought was to use an I2C network.  Then I thought about a
half-duplex RS-485 multi drop arrangement.  In either case, one of the
problems is how to embed the address of the board in the
microcontroller.  I would like to have a simple way to program the
address without recompiling the code for each micro, and without
spending money on an external eprom to hold the address.  Is there a
way to easily patch the binary to change the address when programming
the board? I could have a routine in the device that will receive the
address and write it into internal eprom, with a default address that
would allow me to bring it up and write its address.  

I've never tried to design a system where every penny counts, so this 
is somewhat new territory for me.

Any suggestions for controllers or other ways to crack this nut?  Or
maybe I'm looking at the problem wrong?  Maybe one computer, or an
FPGA, to run the whole thing?  I'd need at least 300 digital I/O
points, and it seems that would lead to a nightmare of wiring.  That's
one thing that drove me to the current distributed design.  I also
prefer a distributed design to allow staged implementation of our

Thanks for any input!

[ - ]
Reply by mrfirmwareFebruary 8, 2022

I'd stick with the ARM Cortex-M0 class CPUs for better (free) tools. Check out the ST STM32G030. For that many units you might consider CAN. If not, then RS-485 is probably the way to go. You could use the CPUs device unique ID to enumerate and then program their bus addresses with some fancy broadcasts and rules for unprovisioned nodes.

[ - ]
Reply by CustomSargeFebruary 8, 2022

Self configuration at powerup is an option. I wrote for a 2-16 node system that you couldn't control the way the end user was going to connect the nodes. So the first node declares itself Master and each successive one is a slave incrementing its address. It allows for easy replacement of failed nodes since its all the same code.

At 150 nodes, latency could be an issue. You don't say how responsive the system has to be. It can also be broken up into multiple networks based on different criteria. It could be 5 networks of 30 with a central commanding the 5. Or a read only and a send only with a central coordinating both.

I wouldn't get caught up in physical details until the overall architecture and protocol is well in hand.

Big Project - Good Hunting  <<<)))

[ - ]
Reply by jmford94February 8, 2022

This is a good idea.  I'm fleshing out the protocol now, but it's affected by the physical implementation.  Agree that 150 slaves on the bus is a bad idea.

Latency shouldn't be a problem, but I do like the idea of 5 independent channels of control.  

[ - ]
Reply by DilbertoFebruary 8, 2022

HI, John!

   1. There is another cheap micro on the block, although its architecture is somewhat old. It's the EFM8BB10 from Silicon Labs. Sure I rather ARM, but when each penny counts, we have to "close an eye" to our preferences.

2. Adding another addressing schema to the others already mentioned, you can have two lines on each micro, data left and data right, and wire them in a 'daisy chain' schema.

Data left and data right are bidirectional comm lines.

This schema presupposes a single master/many slaves architecture.

Each micro would only answer to address 1.

When your protocol addresses micro 5, for instance, the first micro of the chain decreases the address in the message and passes it forward. The address in the message now will be 4.

The second micro does the same, and so on until micro number 5 receives the message with address 1. It doesn't pass the message anymore and answers it, with address 1 in a reverse way, this time toward the master.

The following micro toward the master increases the address in the message and passes it forward ( toward the master ), and the process continues until the master receives the answer with address 5.

This approach has the benefits of no need to set an addressing device for each micro, no EEPROM needed, and no signal degradation.

On the minus side, it's very slow, mainly for the last micros of the chain.

I hope to have helped.

[ - ]
Reply by jmford94February 8, 2022

Very cool idea.  I have never seen this before!  I'll have to look into the EFM8BB10.  I noticed the 8051 architecture is alive and well in this bargain-basement arena...

[ - ]
Reply by dnjFebruary 8, 2022

This is essentially how the long strings of individually programmed RGB LEDs work. Great way to do this. I was able to get a string to follow music even with hundreds of FFT calculations per displayed sequence. Since you are dealing with temperatures that don't fluctuate madly, 10 messages per second is not going to be an unreasonable frequency

[ - ]
Reply by DilbertoFebruary 8, 2022

Hi, dnj!

The method I depicted is somewhat different from the way long strings of individually programmed RGB LEDs work.

IIRC, with individually programmable LED strings, if you want to change the data to the nth LED in the string, you should send n messages, as the first message will be caught by the first LED, the second by the second, and so on.

The "addressing change method" requires that the master just send the message to the node it wants to communicate with.

But OK, if the communication has to be done ever with all nodes, there will be little, if any, difference.

[ - ]
Reply by MatthewEshlemanFebruary 8, 2022

Those RGB LED strips are great, and a good example here.

I played around with those here:


Modeling the LEDs like a frame buffer worked nicely.


[ - ]
Reply by jimfredFebruary 8, 2022

Create a virtual dipswitch location in flash and tell the compiler/linker "hands-off". Reading the flash location from code is easy - similar to reading a special function register, but how to set the value of that location in flash? Use whatever tool downloads the firmware to flash by writing to the special location manually. Different manufacturers and tools do this differently. 

I use a tool like this https://github.com/jimfred/PyCubeProgrammer_API to create automated python utilities, not only download code, but to write 'dip switch' or calibration values to flash and to create simple diagnostic GUIs to read/control aspects of firmware.

[ - ]
Reply by jmford94February 8, 2022

The ATTiny202 has a piece of memory that the debugger/programmer writes into that is not affected by a chiperase command.  That seems like a nice place to store the address and any calibration info.  Thanks for the idea.

[ - ]
Reply by MatthewEshlemanFebruary 8, 2022

Many years ago, actually my first professional firmware effort, involved a 9bit serial multidrop bus communication design.

It was nice, because the first byte would always represent the address (9th bit high), and if the microcontroller supports it (ours did), you can configure the UART to only interrupt on a matching address, then grab the packet, then configure the UART back to interrupting only on the expected address, dramatically reducing the unnecessary interrupts on the micro. Given the number of micros here, that might be important to consider.

Setting the address was done with PIO lines. But we only had a dozen or so micros on our bus. For 150, that would require 8 PIO pins for each micro, each set uniquely via hardware. That sounds a bit tedious too, but maybe there is a clever idea in here somewhere?

Idea: chain a SPI bus between all the micros. That could be used for the initial setting of addresses. The first micro claims address 1, the second claims address 2, etc. The SPI bus would perhaps only be used for the initial address configuration process, then the system would switch to the multidrop serial bus. If the latency of sending a command to the 150th micro isn't a show-stopper, then perhaps just use a chained SPI bus for the entire system. I've seen this done for a few dozen micros on a single PCB, but not sure of the HW/EE/system impacts with 150+...

Good luck, let us know what ends up working!

Best regards,



[ - ]
Reply by jmford94February 8, 2022

Yeah, I worry about the electrical performance of SPI with that many daisy-chained items.  But maybe it's better to daisy chain than multi-drop that many slaves.  

The system is very slow, with commands issued once a second at the max, so a slow serial shift register bus might be an idea.  It would regenerate itself electrically at each drop.

This would play with dilberto's idea!

Memfault State of IoT Report