Optimizing Arduino Code: no setup(), no loop() ⛔

preview_player
Показать описание
When you write Arduino code, you usually split your code into two parts: the setup() function that runs once, at the beginning of the program, and the loop() function that runs repeatedly. But did you know that it doesn't always have to be this way?

In this video you will learn how to write Arduino code without setup() and loop(), and see some of the benefits that come with it (such as reduced code size), as well as some solutions to common challenges with this method.

Arduino Port Registers Reference:

Arduino main() function source code:

The code from the video:

The Arduino Blink Playground:
Рекомендации по теме
Комментарии
Автор

For those who want still smaller, here is an assembly version that fits in 14 bytes:

#include <avr/io.h>
#define io(reg) _SFR_IO_ADDR(reg)

sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
ldi r26, 49 ; delay for 49 * 2^16 * 5 cycles
delay:
sbiw r24, 1
sbci r26, 0
brne delay
rjmp loop

Build it with `-nostdlib` in order to prevent the linker from adding the interrupt vector table (104 bytes) and the C runtime (28 bytes).

edgarbonet
Автор

If you want for further memory saving. Try use assembly language and keep in mind that it will really give you headaches as you need to know the register memory address for every pin and interupt that the microcontroller had. So in real life situation, what is the benefit from this memory saving? Is it make the code run faster? Made it work more reliable? More stable? Well, my motto is, memory is there to be use and make your life easier. So use it as what it intended to be.

discopernicus
Автор

Using internal timer interrupts is more efficient and accurate for blinking an LED. Especially when you try to do something else aside of the blinking, which can make the LED blinking a bit slower as more instructions are executed after the blinking lines.
Or for more efficient for some more tasks and the ease of use, FreeRTOS can be used. You just need to create the task, using the internal task delay method that is similar to the delay method although it might not be so optimised if you are trying to implement some simple applications like “blink”.

_a_x_s_
Автор

Really good optimization's without leaving the Arduino ide. Pretty neat!

electron
Автор

wow, main() will be my new skills that I can put on my resume!

alantong
Автор

Thank you so much for this great, high-quality tutorial :)

lisandroiaffar
Автор

Wow I didn’t know that this was possible. Awesome!

Jobobaboss
Автор

Mind blown!! Here I was thinking that for more complex projects I'd have to do something crazy like break out sections of the code to multiple arduino units for the sake of storage and memory, but your video has shown me that I need to be more versed in my computer languages. Thank you for this!

williamheary
Автор

Arduino was invented as a platform for beginners on a microcontroller. And so everything complicated was hidden in the library. The great advantage is, you can start programming without reading datasheets and understanding the inner structure of a device. Because for beginners, this can be rather frustrating.
The arduino-platform is ok for smaller projects.
But if i want to use the full periphery of the controller and have to optimize for speed or memory-usage, i prefere the Atmel-Studio and coding in Ansi-C or even in assembler. The advantage is a much better use of the resources, but i loose the independence of processortype and i need much experience in debugging, especialy when using many nested interrupts.

So, both approaches have their raison d'etre😊
There are thousands of ways to let a LED blink with a Microcontroller, but this in not the intended use of such a device.😉

charly_a
Автор

liked it ! very enlightening, I will follow your videos. hugs from Brazil !

DavidRisnik
Автор

Thank you, very interesting analysis!

TagFul
Автор

Great video. I use those low level registers to control WS2812 LEDs with my own code rather than the libraries.
I figured out a while ago I could use main() like we normally use in C/C++, but the delay and other functions didn't work. Your video shows why. Thanks!

So, if I write my own main() and then add in init(); initVariant(); and USBDevice.attach(); up front in it, I can then use it with any Arduino function [ like delay() ] just like we do with setup() and loop().

This is great! I teach Summer STEM and I want to show my students the normal main() entry point for a more general C/C++ expectations with most compliers.

paulromsky
Автор

Great simple descriptive video.

If ever redone in.a newer video: The sizing comments should include a description of what the mods were, and the operating result. Also would be nice to know what the empty loop time elapsed is, measured. You can use a stopwatch and and outer loop to lengthen the time to that which your fingers can operate the stopwatch to some good accuracy.

bobvanwagner
Автор

This is like using C code but without the Arduino "runtime" (if it can be considered as a programing runtime) and the same if you make some an aplication for windows but without the C runtime.
Really cool.

piano_arts_
Автор

Cannot thank you enough wokwi..this delay removal tool is easier than millis()...thumbs up for you

samj
Автор

The comment section shows great interest in this video. The point of the video is "Optimizing" .
I suggest that you optimize the use of the screen space (width) Roughly 30% is wasted in two black voids. Further the width of the info block on the left could be reduced by half and still maintain its purpose.
These changes would allow a much wider area for the code block and a larger font would make reading the screen possible. I enjoyed the video but gave up trying to read the text because of the illegibly small letters. Oddly the least important text in the info block is more legible as it has a larger font size. Thank you for not using any distracting music.

lastchance
Автор

One of the purposes of setup() and loop() is ease in programming for new coders. And function delay() offers accurate time delay. Your code is mix of low-level register access, and inaccurate delay using simple loop. If I want a 200ms delay, your coding would be inaccurate.
If you want optimization I think you go for assembly language coding.

qdcsgmail
Автор

Berry nice. I don't need it now. but it is good to know

flinkiklug
Автор

Usefull to know... I did once hit the space constraints of an uno but have since jumped to a controller with built in wifi and more room so the problem went away. Might come in handy though if I ever go back to using the uno with the ethernet shield for something else.

WistrelChianti
Автор

What about long push and looping menu system that jumps to different menu loop after long push.

tankumaat