I am running an atmega for a music playing application - with several loops in it - a 16khz audio playing loop and a control loop running similtaneously.
I would like to run the control loop as fast as possible. I understand the importance of leanness of code, and have found the control loop starts getting unreliable at 8khz or so, depending on what’s in it. However, I’d like to be able to tell a bit more accurately how close to it reaching it’s instability point it is - is there a way to find this? I.e maybe something that converts code to estimated clock cycles? This would allow me to quickly ID what the most hungry bits of the code are.
You can’t really have a “CPU usage” scale , at least on an 8-bit atmel , but that’s a couple of tricks I always use :
Use loop in a more smart way , if your code fits in an interrupt handler (atmegas have a limited code space for interrupts ) move the control loop there and use the interrupt of a timer to trigger it , leave the other loop on the main loop , in this way , the MCU will context switch between the interrupt and the main loop , avoiding timing issues and waste less time checking the statuses
This would affect the speed a little bit but you could pulse a pin high once per cycle and use a scope to measure how the period between pulses changes depending on how much code you have.
I don’t think you can get a deterministic behaviour , the busyness of the loops will change based of the status of the state machine , and that’s probably why he see the system “unstable”
Thanks - the interrupt handlers look super interesting! Unfortunately I don’t think I can fit the code in there though as control loop also features some capacitive sensing code, as well as a few ADC reads. But I will definitely consider it in future - definitely see what you mean by “in a more smart way”! Cheers
Yeah it’s not going to be accurate, it’s just a relative measurement and would need some averaging.
But really it sounds like your micro isn’t the right one for the job and/or the code isn’t very efficient.
I’ve used ATMEGA 328 series chips playing sound off an SD card with some basic button checking for control no issue but anything more than that tends to stretch them.
Not sure if you are writing using Atmel Studio or inside Arduinos IDE but if the later there are efficiencies to be gained switching some of the helper functions to “native” code and also…
You could also look at switching to a 32u4 like an Arduino Micro or Leonardo they seem to be much faster than 68/168/368 (Arduino Uno).
That is an excellent idea - and currently very similar what I’ve been doing - I just wondered if there was a faster/easier to use thing as currently having to program/then disconnect the board is taking a little bit of time as it’s in a fairly awkward form and I’d wondered if there was some kind of software that would give a ballpark. Thanks!
That is very interesting - yes I am using Arduino IDE but have been wondering about switching over to Atmel Studio - but find it all fairly puzzling.
I’d never considered that changing the compiler settings could change the efficiency of the code - I’d just assumed it was just about size not speed but that could make my week!
Oh yes and you are right on more powerful chips - the next iteration of this project (electronic bagpipes) will probably use the teensy chip - I have breadboarded it roughly but there is a lot of stuff there I don’t understand well like 4 layer board routing, I2S, but also potential for massive improvements in audio etc.
If you are up to share the code on GitHub I can have a look at it , I think that can be done using the atmegas in the right way , if you want to use a faster MCU , you can use the esp8266 (perhaps disabling WiFi) or take a look at mbed .
The NXP MK20DX256VLH7 in the Teensy 3.1 and 3.2 is a beast of an ARM microcontroller. It can easily handle loading data off SD card, sending I2S to an audio interface as well as servicing interrupts, ADCs and various comms ports all at once providing you’re sensible.
What you’re talking about here is a realtime system (presumably), i.e. there are certain deadlines which need to be met in order for the system to be operating correctly. If you can flip a pin when the deadline is set and when it is met (e.g. between playing one sample and the next), you can measure that signal to determine if it’s working optimally.
And lean-ness is only part of the story beware of things like digitalWrite and Read - whilst they might only look like one line of code, they’re far less efficient than using the native equivalents (DDR and PORT registers I imagine for an ATMEGA). Try to use bitwise operations where possible - for example, if you need to multiply an integer by 2, try shifting them one bit to the left e.g.
THING = THING << 1
Some optimizers will automatically do this for you at certain levels… but it doesn’t hurt to make their lives easier by doing it for them! Also, if you’re often setting direction bits on a register, you can set all the directions simultaneously with DDR register, rather than doing a loop over the pins and using pinMode on them each.
Having said that, if you’re looking to swap processors soon you might want to avoid optimising too much too early - and just do the minimum required to make the thing work!
Another thing to mention: technically, you’re processor is running at 100% utilisation all the time - it’s always executing your (user) code. The concept of CPU utilisation only really makes sense when you have an operating system that’s scheduling processes for you, and processes are not always in a state where they are running (usually because they’re blocked waiting for some I/O operation to complete).