Multiple microcontrollers for multiple tasks? - Page 1
Forum section: electronics / general

author: Brathahn
author_rank: Contributor
timestamp: August 04, 2019, 11:16:42 pm
content: Hello,this may be more of a meta question than an actual problem. I would like to hear how you would handle such a problem.I want to build an regulated AC power supply around a variac. So to do this, i thougt of controller like the atmega to handle all the tasks in such an application.wich would be the following:-measure AC-amps-measure AC-volts-move the variac with a geared dc motor-handle limit switches-handle some relays-calculate the regulation to move the motor to match the setpoints of amps/volts-display some values on an LCD or seven segment displays-read some buttons or quad-encoders with debouncingThis is quite the list as i see it.Including some tight timing with the display and motor control, continous analog read operations, some float operations and more.i am 100% sure some assembler wizards would shrug this off and do it in like 50 lines of codeFor me i thought of using multiple controllers.Maybe some attinys that connect over i2c to the main controller and feed it with already processed data.Or switch over to a more beefy controller like a stm32 (wich i dont have any experience in).So jeah.. how would you do it?Thanks for yor ideas.

author: Mr. Scram
author_rank: Super Contributor
timestamp: August 04, 2019, 11:39:25 pm
content: Adding controllers quickly ramps up the complexity and room for error. I'd definitely opt for a single chip solution. If the chip isn't quick enough either optimize or find a quicker chip. You'd be surprised what a reasonably programmed ATMega can do though.If you use Atmel Studio instead of the Arduino IDE things should be more efficient though I doubt it's even necessary. You could offload parts to hardware. Debouncing can be done in hardware and some of the other parts probably too.

author: Psi
author_rank: Super Contributor
timestamp: August 05, 2019, 12:15:27 am
content: I agree, an 8/16mhz ATMega should be able to do everything in your list at once without a problem.You will have to code any delays properly i.e. using timers to set flags, you wont be able to use any hard delays (loop delays).Yes, i also recommend avoiding the Arduino library for this reason.One thing i'm not sure about is how fast AC freq are you trying to measure current on.This will effect the speed required for sampling. (I'm assuming 50/60hz which is slow and totally doable on atmega)I very much agree that trying to have multiple MCUs in a system is a lot more complex than people expect. So only do this if you have no other choice.To build a multi-MCU system you need some sort of communication between the MCUs.Since there is delay in this comms, you can't just read a pin and get its value.eg, You can not goIf (input==low) DoStuff;Since getting the value "low" requires sending a message and waiting for it's response. (Or just waiting for the data if its being streamed constantly).This waiting locks up the CPU and interferes with other tasks you might be running.So, to make it work you must code a queue system and have the communication all be 'event driven' with timers and handlers.eg. You send a comms request for data, no result is returned at this point.Then, sometime later, a result arrives and it processed separably.-measure AC-amps-measure AC-voltsTimer and RMS calcCPU load = low-medium(Medium if heavy use of floats)One of my projects has a function with 3 trig functions on floats and gets around 200-400 hz on 8mhz Atmega. You only need like 5hz to drive your motor-move the variac with a geared dc motorSimple digital outputs to H bridge to drive motor direction.CPU load = Almost zero-handle limit switchesSimple digital inputs to trigger Boolean states.CPU load = Almost zero-handle some relaysSimple digital outputsCPU load = Almost zero-calculate the regulation to move the motor to match the setpoints of amps/voltsSome math, maybe some trig functionsCPU load = Low-display some values on an LCD or seven segment displaysSimple digital output based on lookup table to pick the required segmentsTiny bit of math to convert number variable into 3 digits 1,10,100 etc.CPU load = low-read some buttons or quad-encoders with debouncingSimple digital input and a little logic.CPU load = Low

author: rstofer
author_rank: Super Contributor
timestamp: August 05, 2019, 12:43:15 am
content: You are probably going to run out of pins on the smaller ATmega parts. Investigate "IO Expander" and see if adding a couple to a 4 wire SPI bus wouldn't solve your digital IO needs. I would avoid the I2C variants at every opportunity.https://www.microchip.com/wwwproducts/en/MCP23S17

author: NiHaoMike
author_rank: Super Contributor
timestamp: August 05, 2019, 01:10:09 am
content: Quote from: Psi on August 05, 2019, 12:15:27 amYou'll want to use fixed point for that. A classmate tried to do AC power measurement with floating point on an Arduino and wondered why it was so slow...Of which, I would suggest using STM32. The cheaper ones only support fixed point, but at 32 bits, which gives a lot more room to implement DSP algorithms in.

author: brucehoult
author_rank: Super Contributor
timestamp: August 05, 2019, 01:37:40 am
content: Quote from: NiHaoMike on August 05, 2019, 01:10:09 amIt's not that bad. I see something around 100,000 FP mul/add/sub a second on a 16 MHz ATmega328. That's 20,000 FLOPS per AC cycle. Should be more than ample.The built-in ADC sample rate would be much more likely to limit you, I'd think.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: August 05, 2019, 01:47:45 am
content: Quote from: Brathahn on August 04, 2019, 11:16:42 pmThe choice for more than one controller can sometimes be physical/mechanical, as much as a work load one.Small MCUs these days, can easily cost less than the cost of running cable conductors.eg your display/buttons/quad encoders can all be user positioned, whilst the motor control part can be closer to the motor...I'd suggest you mock up some code on one controller first, and see how it fits for Speed and Size.

author: ledtester
author_rank: Super Contributor
timestamp: August 05, 2019, 01:50:29 am
content: Quote from: Brathahn on August 04, 2019, 11:16:42 pmYou might be interested in Atmel's own application note on implementing an AC power meter using an AVR (Atmel appnote AVR465):http://ww1.microchip.com/downloads/en/AppNotes/Atmel-2566-Single-Phase-Power-Energy-Meter-with-Tamper-Detection_Ap-Notes_AVR465.pdfLots of practical advice on how to go about accurately measuring AC amps and volts.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: August 05, 2019, 06:29:06 am
content: In general to perform multiple tasks on a single core, you need some sort of threading mechanism.That way you can program each task as a separate unit without it getting a unrecognizable ball of ...Each task needs some extra space to know where it is executing and what the state is of its variables.Before you jump to realtime-os-es that do preemptive threading (interrupting a running thread actively in order to switch to another thread), I have found a simple light-weight mechanism to work just as well: using cooperative multi tasking.This means that all tasks have to play nice in order for other tasks to run also.Using a set of macroseach task is basically a FSM but can be programmed as separate routines.Here are some examples from my Arduino template library to give an idea.Hope it helps

author: Brathahn
author_rank: Contributor
timestamp: August 05, 2019, 12:17:43 pm
content: Thanks to you all.I see, using a single controller has the advantage of instant input and data access without polling the slave-controllers first.Quote from: PCB.Wiz on August 05, 2019, 01:47:45 ami think i will do this and see how its coming together.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: August 05, 2019, 12:31:22 pm
content: It depends.... When you have reached the point where the amount of work you have to do per second is more than the number of cycles per second then you have to parallelise or find a faster processor.Multiple cores are very standard nowadays... e.g. a ESP32 has three cores (2 fast 1 small).That being said modern processors tend to clock fast so you may have enough headroom.

author: AndyC_772
author_rank: Super Contributor
timestamp: August 05, 2019, 12:46:41 pm
content: If the output of your device is limited by the speed of a geared down motor, then I suggest it's highly unlikely that CPU speed will be an issue, whatever CPU you may choose to use.Do pick a CPU that has considerably more memory than you think you'll need. Experience has a habit of increasing memory requirements; I often find I end up adding history and moving-average tables as a project progresses.It might be worth considering a separate CPU to implement any safety or sanity checking features. For example, you might have one whose only job is to measure the required set voltage output, and to keep a relay enabled provided the output doesn't exceed it by more than <some>%. This could guarantee that, even if the main CPU crashes or does something wildly inappropriate, the output protection will still work. Keeping the protection code simple makes it easier to keep reliable.

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 05, 2019, 01:00:55 pm
content: Well given your requirements (it's not that complex either), I would definitely go for a single-chip solution. If your MCU can't handle it because it's not powerful/fast enough, select a beefier one instead of sticking to one that is underpowered and will make you system much more complex (think of all the communication between MCUs required to make all this work, potential synchronization issues, etc.) It will also be a lot more expensive (several MCUs and anything needed around each, larger PCB, more complex layout...) Power draw would also dramatically increase for no good reason.Aside from performance considerations, using multiple MCUs/CPUs is sometimes done in safety-critical designs to isolate critical tasks so that a software bug in one would have no direct influence on the others (except of course you'd still have to handle and consider communication between them if it applies, which in itself can bring other kinds of bugs...)

author: Psi
author_rank: Super Contributor
timestamp: August 05, 2019, 02:01:50 pm
content: There are some situations where having multiple mcus is a good idea.Or at least situations where it doesn't add much more complexity and takes a lot of loading off the MCUFor example, i used 5x STM32F4 micros in an LED sign project.Four of the mcu's had 4x RGB LED arrays (32x32) on them for a total screen size of 8x2 panels or 256x64 pixels.The LED modules didn't do any color mixing themselves, just Red Green Blue on or off.So each slave mcus read 16 bit pixel color data streaming out a 16bit bus on the master stm32.It then did all the PWM mixing and color correction needed to drive it's 4 panels.This was a good division between mcus because they really didn't need to talk to each other at all. Just read the pixel data bus and update their own led panels.This left the 5th 'master' MCU free to read SD cards, decode gifs and draw images in 16bit color without having to also do PWM mixing fast enough to keep the display flicker free.Of course an even better way to do that is a FPGA but if i had tried to learn FPGA and build that project at the same time i would never have finished it.

author: Mr. Scram
author_rank: Super Contributor
timestamp: August 05, 2019, 02:26:18 pm
content: Quote from: rstofer on August 05, 2019, 12:43:15 amUseful advice, though here too it often pays to simply upgrade to a bigger part. Especially when budget isn't a key consideration. Sooner or later you'll run out though and that's when expanders can come in handy.

author: rstofer
author_rank: Super Contributor
timestamp: August 05, 2019, 04:19:52 pm
content: Absolutely! Get a part with more pins. I like the ATmega128 for that very reason.While at it, consider a faster CPU. These days we have ARM cores running at hundreds of MHz. You really can't beat a combination of speed and pins. But sometimes, more pins just aren't available (unless you are using an FPGA) so having many switch inputs still works better with an IO Expander.Did I mention avoiding I2C? When available, I always use the SPI bus. It takes more pins (1 per Expander plus 3 others that are common) but writing the code is a lot simpler.

author: ledtester
author_rank: Super Contributor
timestamp: August 05, 2019, 06:44:07 pm
content: Quote from: rstofer on August 05, 2019, 04:19:52 pmYes, do your prototyping and design work with a platform that's convenient to use and has plenty of memory, peripherals and IO pins. Once you've got things working you can work on fitting it into a smaller device.

author: splin
author_rank: Frequent Contributor
timestamp: August 07, 2019, 03:01:47 am
content: As already said, using multiple micros can add a lot more complexity than a superficial look would reveal; in particular you have to consider the multiplication in failure modes arising from the independant operation of the various subsystems and all the code required to handle them. Of course, in trivial applications it may not be an issue - if something goes wrong with your waste basket automatic lid opener you may well be amused by the random opening and closing of the lid. When you get bored you remove and replace the batteries to restore order.With a home automation system, failures, both software and hardware may not be a direct safety concern - ie. a gas boiler won't operate unsafely even if the heating controls try to tell it to do so, but they could be economically damaging by operating the boiler at full output (controlled only by its internal overheat sensors) for extended periods. Worse, at the same time the air conditioning may be set to full. Or the burglar alarm may get silently disabled.With distributed processing you have to deal with the fact that one or more subsystems might not respond at all to query or command messages, or perhaps worse, respond either earlier or later than expected. On a single processor, in general, if it is running then all functions will be running, and all at the same speed. If the processor fails to run for some reason then all functions stop.In the distributed case, inter-device communication protocols have to allow for getting no response to a message meaning timeouts and retry mechanisms are required. But how long for the timeout? Typically you'll estimate the time required, allowing for a reasonable number of retries, and add a bit of margin. Mostly it's not critical and a large margin can be used, but not always without seriously compromising the performance or functionality - fast polling of remote devices may be required for a responsive UI but if a non critical remote sensor is unplugged a 10 second timeout could seriously slow down the system - unless a more complex scheme of parallel polling is implemented with the increased risk of software errors.So you implement it and get it all running and because you are concientious you test that all your timeouts are appropriate by measuring the response time for every type of message that can be sent - all work that is generally unecessary in a single processor solution. It all works fine - until it doesn't because you hadn't measured the worst case response time. It may be that processor A request some data from processor B and usually it has the data and responds immediately; very occasionally it has to get the data from processor C because something changed - eg. a limit switch being activated indicating that a motion sensor had lost sync and needed recalibration. The response from B to A is now much longer than usual and the timeout may have expired.Processor A decides that the message has failed for some reason so repeats its request. Shortly after, the delayed response to its first request arrives from B but unknown to A because the messaging protocol didn't include sequencing data, with the wrong data related to the first request and not the later and possibly slightly different 2nd request. To make matters worse the response to the second request then arrives from B - if you are lucky A rejects it because it wasn't expecting it but worse it might be sat in an input queue which only gets read when A expects the response to its next request. A hasn't implemented a 'too fast response' timeout error check so now gets permanently out of sync with B.Then there is the issue of different startup times for each device; usually simple to deal with by waiting long enough before messaging other devices to be certain they are all running but it gets harder as the allowed time gets reduced to the minimum possible, required for a "responsive" system. Especially if the devices are programmed by different people or teams. It all worked brilliantly until one decides to add a comprehensive hardware selftest on startup which means it is almost always ready to receive the first message from a master device but very ocasionally isn't.And so on and on. Many scenarios have to be considered which arise purely from the decision to distribute the functionallity. Maintenance is made more difficult because of the timing dependencies and lots more documentation may be required to be generated and maintained.

author: guenthert
author_rank: Frequent Contributor
timestamp: August 07, 2019, 05:03:33 pm
content: If there are multiple quasi-simultaneous tasks and multi-threading seems too cumbersome (and multi-mcu most certainly will then), Parallax' Propeller might be a reasonable choice. That chip has some drawbacks (one of them is that an external EEPROM is required, but there are more), but it does make multi tasking with deterministic timing pretty easy.For more complex (i.e. in need of more memory or speed) applications, TI Sitara MCUs (as used on e.g. Beagle Bone Black) with their PRUs comes to mind, but those will be overkill for what you have in mind.

author: Nosmo
author_rank: Newbie
timestamp: August 07, 2019, 11:24:31 pm
content: Or the Atmega2560. Almost the same price. More memory. 16Mhz max rather than 20.

author: edigi
author_rank: Regular Contributor
timestamp: August 09, 2019, 06:30:04 am
content: Quote from: NivagSwerdna on August 05, 2019, 12:31:22 pmI guess under small core you mean the ULP co-processor and the 2 real cores are the the PRO and APP core. Using the PRO core for app code is not necessarily a good idea and the ULP programming (as far as I could judge) is quite tricky (+ ESP32 has only a small number of pins).Thus the benefits of the multiple cores are not necessarily that big (also ESP32 has huge interrupt latency that worth cross checking).On the positive side is though that it has FPU.As for what the OP has asked, MCU + CPLD could be one way, CPLDs requiring minimal extra components and can do autonomously some simple (but fast) logic where MCU would control it and handle the more complex logic (where heavier calculations are required). The advantage of the CPLD that it provides full flexibility of the logic synthesized and huge pin flexibility as well (can help PCB design).