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

  Рет қаралды 211,279

Wokwi

Wokwi

Күн бұрын

Пікірлер: 357
@edgarbonet1
@edgarbonet1 Жыл бұрын
For those who want still smaller, here is an assembly version that fits in 14 bytes: #include #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).
@emanuelh.a8492
@emanuelh.a8492 Жыл бұрын
NICE..!! Im learning assembler and I love it.. :3
@hapsti
@hapsti Жыл бұрын
@@emanuelh.a8492 :3
@mikoposter
@mikoposter Жыл бұрын
how is the c runtime so tiny only 28 bytes?
@edgarbonet1
@edgarbonet1 Жыл бұрын
@@mikoposter: * initialize some CPU registers (r1, SREG, SP): 12 bytes * call main: 4 bytes * jump to _exit: 4 bytes * implementation of __bad_interrupt: 4 bytes * implementation of _exit: 4 bytes That's 28 bytes total. If the program has a .bss section, add 16 bytes to zero that part of the RAM. If it has a .data section, add 22 bytes for copying it to RAM. This program doesn't use any RAM, but most non-trivial ones do have both a .bss and a .data section.
@asalvat-st6gg
@asalvat-st6gg Жыл бұрын
I had already try the same asm code and find that when substracting 0 with carry does not set the Z flag when r26 goes from 1 to 0. (At least in the Atmel Studio simulator). Instead I have to use: brnc delay , since the Carry flag is set when r26 goes from 0 to 0xFF,
@discopernicus
@discopernicus 4 жыл бұрын
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.
@Wokwi
@Wokwi 4 жыл бұрын
Thanks for the reply Denny! Agreed, when you have memory then definitely use it. In our opinion, optimizing is not all about the code size/execution speed, but first of all making good use of your time as a programmer, and saving headaches for people who come to maintain the code in the future (including yourself)
@CrispyCircuits
@CrispyCircuits Жыл бұрын
Some comments are saying to just go ahead and use the memory that you have. But then when the new PSI42-69 chip comes out next year, you may find yourself having to write a new version of the program that needs exactly that "unneeded" memory. KISS with clean and secure code.
@networkoperations
@networkoperations 11 ай бұрын
I mean, we're not talking C++ here. Most of this is very well translated 1:1 thru the interpreter. Not much will be saved hand writing the asm in this situation
@dmitrykh9183
@dmitrykh9183 10 ай бұрын
@@CrispyCircuits The best approach is a combination of both ;) Write with the technics which gives faster TTM/more structured and supportable code - and optimize/rewrite in the low level only the parts you really need to.
@coolfreaks68
@coolfreaks68 10 ай бұрын
@@Wokwi Memory is dirt cheap. Execution speed and Maintainability is what has more importance. Arduino is meant to be easy. We can always use STM32 and keep doing bare metal programming and never complete the project. Even if we somehow complete it, others are unable to reuse it.
@_a_x_s_
@_a_x_s_ 2 жыл бұрын
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”.
@turbogamerxd329
@turbogamerxd329 Ай бұрын
You can also set up a timer to directly manipulate an output pin. Thus you wouldn't need the core at all to keep the LED blinking. There's only one limit to that being which output pins can be used.
@alantong6121
@alantong6121 4 жыл бұрын
wow, main() will be my new skills that I can put on my resume!
@Wokwi
@Wokwi 4 жыл бұрын
My main() skill is optimizing 😉
@horacewonghy
@horacewonghy 3 жыл бұрын
and asm("");
@charly_a8654
@charly_a8654 Жыл бұрын
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.😉
@MrKANIOREX
@MrKANIOREX 10 ай бұрын
@charly_a8654: "There are thousands of ways to let a LED blink with a Microcontroller, but this in not the intended use of such a device" Meanwhile in my head: kzbin.info/www/bejne/o3XLf4SGqZ10pJI
@stephanc7192
@stephanc7192 5 ай бұрын
​@@MrKANIOREX 😂😂😂😂😂😂
@qdcs524gmail
@qdcs524gmail 4 жыл бұрын
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.
@Wokwi
@Wokwi 4 жыл бұрын
Thanks for the feedback Andre! Yes, totally, the accuracy of the "home-made" delay can be improved. This actually give me an idea for another video, stay tuned :-) Have you ever used assembly language in your projects? For which parts?
@rafa_dzto
@rafa_dzto 4 жыл бұрын
Hey ​@@Wokwi! Did you make that other video? :) (I'd be really interested in using efficient delays, for me, precise time intervals are really important, with using _delay_ms() for example)
@Wokwi
@Wokwi 4 жыл бұрын
@@rafa_dzto Yes, you can find it here: kzbin.info/www/bejne/qp_JloB5rrGNidE
@gabiold
@gabiold 3 жыл бұрын
@Andre Nixon Delgado Not completely true. While it is inaccurate with this cycle delay, it is not that much of a challenge to setup a timer for 1kHz frequency yourself (or any freq. which required in the project for other tasks), and make your own delay. It won't need half k of flash, and you might use that timer for several other timings. If you are not just blinking LED, but do some more advanced high-performance stuff, then interrupt handling, and utilizing that few timers that are in the core is a must. In a properly written automation code, there is not that much of use in a synchronous blocking delay function anyway as usually only the UI runs in the main thread and that usually waits for the user and updates the display, which is usually not quite wise to be delayed (for more than 10-50ms or so, it depends).
@bob-ny6kn
@bob-ny6kn 2 жыл бұрын
I agree with Angelo. Arduino API is for fast fun with electromech stuff. I coded for hardware users, giving them APIs built on APIs to get them (litterally) flying. Once they were aware of the environment, I showed them to the minutiae of the lower and lowest level code for tight control and timing. I am happy with Arduino's method. It makes coding widgets fun again.
@electron7373
@electron7373 Жыл бұрын
Really good optimization's without leaving the Arduino ide. Pretty neat!
@arsenic1987
@arsenic1987 2 жыл бұрын
3:53 - Woah woah.... woh!... How did you select and shift everything?.. I've never seen this before. Googling it revealed CTRL-SHIFT Up/Down... and it works. Many places..... I've just learned something awesome! :) Thanks.
@Wokwi
@Wokwi 2 жыл бұрын
Magic 🪄
@Fahnder99
@Fahnder99 2 жыл бұрын
replace delay with for loop is replacing ugly with catastrophy.
@zoltanszilvasy7057
@zoltanszilvasy7057 4 жыл бұрын
And what about compiling the "optimized" code to, for example, an STM32 Arduino-compatible board? Do you think, this is really a good way? I think this way is "good" only for dropping any portability and stucking into a very specific hardware. Moreover, if you want to write effective code to a particular hardware, than you can drop also C language and do it in the hardware's assembly. But, I think, Arduino's concept is rather the opposite of this and it better wants you to make code that can be portedto as many hardware environment as you can imagine for the task.
@Wokwi
@Wokwi 4 жыл бұрын
Hi Zoltan, thanks for your comment! Yea, this makes you appreciate the simplicity of Arduino, and portability, as well as the huge ecosystem of third-party libraries, code, and tutorials is what makes Arduino so powerful and amazing!
@michelobfedusenko8320
@michelobfedusenko8320 3 жыл бұрын
Arn’t cpu map libraries, such as in grbl and marlin, the answer to portability when using port addresses? Am I missing something?
@sharpfang
@sharpfang 2 жыл бұрын
Dropping C in favor of ASM made sense some 10-15 years ago. Nowadays it's very hard to write better ASM code than what the compiler will generate from C.
@jrstf
@jrstf Жыл бұрын
@@sharpfang - For me, writing C is torture because I don't know how to view the resulting assembler code, so I'm left to guess what my code does. That's only a problem in a small number of cases but they are very important. For instance, when I turn off interrupts for some critical code, I don't know enough to be sure the optimizer isn't going to relocate some of that critical code outside the uninterruptable section.
@edgarbonet1
@edgarbonet1 Жыл бұрын
@@jrstf You can use `objdump -C` to get an assembly listing of your compiled code, intermixed with the original C statements. This shows very clearly what the compiler does with your code. Not something I would do everyday, but it is handy for this small critical cases. Also, for critical sections on AVR, you have the avr-libc macro ATOMIC_BLOCK.
@williamheary1700
@williamheary1700 2 жыл бұрын
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!
@martinkuliza
@martinkuliza Жыл бұрын
if that's your problem why don't you just use ESP32 and all of a sudden you have more memory and delay doesn't block your program anymore
@nintendero65
@nintendero65 Жыл бұрын
@@martinkulizadelay still blocks the program actually, you need to use freertos task for that purpose actually... and its harder and less intuitive than using millis() or delay()
@martinkuliza
@martinkuliza Жыл бұрын
@@nintendero65 Actually delay doesn't block the program and Actually it's not harder that millis and Actually...... You seem to like the word "Actually" DO YOU UNDERSTAND WHAT THIS WORD MEANS ? It means if something ACTUALLY IS a certain way Example : The reply button here in you tube ACTUALLY IS BLUE, if i said it was Red, You could say ACTUALLY IT'S BLUE and that would be a true statement Now... in FreeRTOS and it is FreeRTOS not freertos, "delay()" DOES NOT .... ACTUALLY Block the entire program. where as in Arduino it does so... delay using ARDUINO IDE will block the program vTaskDelay() Used in FreeRTOS DOES NOT block the entire program and when you use delay() in FreeRTOS the compiler converts delay() to vTaskDelay() and therefore it does not block the entire program TRY IT create 2 tasks 1 that blinks a red LED 1 that blinks a blue LED have them both run at a freqeency of 300ms but put a delay on the blue led for 5000ms SEE IF THE RED ONE STOPS...... LOL.............. IT WON'T in Arduino it will when using FreeRTOS it will NOT Because using delay or vTaskDelay in FreeRTOS only delays that task, Not the entire program HERE READ THIS TASK STATES www.freertos.org/RTOS-task-states.html RE "you need to use freertos task for that purpose actually" What did you think i was talking about ? "and its harder and less intuitive than using millis() or delay()" The Entire Language of C++ IS NOT INTUITIVE THAT'S WHY THERE IS A 400 PAGE DOCUMENT ON IT if Arduino and C++ was intuitive - No one would need to watch a you tube video - No one would need to ask "How do i make this LED blink" or "I connected my board but the sketch is not uploading" or "I've done everything right but my code doesn't compile" WHAT'S INTUITIVE ABOUT C++ IN THE FIRST PLACE ? Also WHEN COMPARING vTaskDelay() or just delay() and you only need to enter the number in the parenthesis HOW IS THAT HARDER Than going through millis and putting all that code in No mate, delay() is a hell of a lot easier in FreeRTOS in FreeRTOS you don't really have a reason to use millis, millis was always a band aid solution anyway
@Dante-420
@Dante-420 10 ай бұрын
@@nintendero65 I think he meant that you avoid the delays when communicating between multiple MCUs if you have one MCU that's beefy enough to run your entire program.
@lastchance045
@lastchance045 2 жыл бұрын
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.
@Wokwi
@Wokwi 2 жыл бұрын
Good points, thanks for the feedback!
@mathiaspampus813
@mathiaspampus813 10 ай бұрын
Are you watching on a 4" 21:9 screen? If so, get a grip... if not, get a grip, your complaints are not valid. The trend of using overly large fonts "for people on mobile devices" has gone so far that I can't even watch some videos in fullscreen anymore, or have to move back like 10' to be able to read anything at all. Beside, how do you read the comments, horizontally scrolling because you have to zoom in so far? The video is utterly pointless anyway XD
@DavidRisnik
@DavidRisnik 2 жыл бұрын
liked it ! very enlightening, I will follow your videos. hugs from Brazil !
@Wokwi
@Wokwi 2 жыл бұрын
Thank you David!
@hk-four-sixteen
@hk-four-sixteen 10 ай бұрын
Optimizing code is good. However, premature optimization can waste a lot of time on something we really don't need or may not benefit from. Thus, the saying "Premature optimization is the root of evil, -Donald Knuth". So we build something that works first then examine it later to find out areas that need optimization. 😉 Anyways I've learnt something new from this video. I am from a web development background with php and c# and I'm new to arduino
@Wokwi
@Wokwi 10 ай бұрын
Yes!
@paulromsky9527
@paulromsky9527 2 жыл бұрын
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.
@Wokwi
@Wokwi 2 жыл бұрын
Awesome! Where do you teach?
@paulromsky9527
@paulromsky9527 2 жыл бұрын
@@Wokwi I am retired here in New Hampshire. I only take 6 students over the summer: 8 hours a day, 5 days a week, for 8 weeks. I interview all the parents and students together. I don't go by grades but by aptitude and eagerness to learn... and it's free! Except for the price of the project/kits which each student keeps. My angle is "Don't let your kids play video games all summer, get them a head start on being a scientist/engineer/technician and focus on STEM all summer". The parents love me because I stay away from all the "woke" nonsense they teach in public schools these days. I tell each parent/student that we ALL say the US Pledge of Allegence before we start class each day. This ourages the liberal troublemakers and thus I pass on selecting their child for my class. One parent tried to sue me because she claimed I was indoctrinating childen. I said no, the pledge is just a form of solidarity, if you want indoctrination, then go back to the public school system. My lawyer shut her down instantly. It's my house on private property, I set the rules and tell everyone what they are, you and your child have to agree to the rules which are legal, parents can tune in and watch/listen to the class at any time (I covered the On Air LEDs on the cameras with tape so I never know when parents are watching), and I do not charge a fee, the students just pay for the cost for their projects that they keep. Some parents want me to deprogram their children from the brainwashing their children get in public schools, some even offer a nice paycheck, but I tell them no, I will stick with just STEM. The pledge is just to weed out those with closed minds or demand EVERYTHING in the world is done their way. The parents that do just that get so annoyed that their child with straight A's and is a perfect bleeding heart spreading their adgenda was not selected. I once had a student that was here from Mexico on a visa. His parents said they were not comfortable with the US pledge because they are not US citizens. I told them, ok, your child will sit quietly while the rest of the class stands and recites the US pledge, then, the class will sit quietly while he stands and I say the Mexico plege WITH HIM in Spanish. The parents loved me, their son was a wonderful student.
@StormGod29
@StormGod29 10 ай бұрын
I always just use _delay_ms(1000) instead of delay(1000). The compiler knows exactly the for loop to jam into your code based on the frequency of your target board so timings remain accurate. And the compiled code is still tiny and readable without being bloated with Arduino stuff. This also compiles to 158 bytes and 0 bytes of DRAM int main(void) { DDRB = 0xff; // Set pins 8-13 to OUTPUT for(;;) { // Loop forever PINB = 0xff; // Toggle pins 8-13 _delay_ms(1000); // Do nothing for 1,000ms } }
@piano_arts_2007
@piano_arts_2007 10 ай бұрын
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.
@khatharrmalkavian3306
@khatharrmalkavian3306 11 ай бұрын
How do you move text up and down with the keyboard like that? I tried several combinations of ctrl, alt, shift and the arrow keys, but couldn't replicate the behavior in SciTE. Is it unique to Arduino IDE?
@Wokwi
@Wokwi 11 ай бұрын
Alt+Up or Alt+Down. This works in editors derived from VS Code, such as the editor Wokwi is using.
@khatharrmalkavian3306
@khatharrmalkavian3306 11 ай бұрын
@@WokwiAh. Thank you
@felixbaum2180
@felixbaum2180 2 жыл бұрын
You could use volatile long in your for loop, idk about asm() so don't know if that's more efficient
@Wokwi
@Wokwi 2 жыл бұрын
Good tip!
@DinhoPilot
@DinhoPilot 2 жыл бұрын
I never really used more than 50% mem on an Arduino program, but I don't doubt there are engineers/developers who will want to squeeze it as possible. Technically this video is very good
@DrakeOola
@DrakeOola 2 жыл бұрын
Your projects are really small and simple if you never reach the limit...
@DinhoPilot
@DinhoPilot 2 жыл бұрын
@@DrakeOola Personally if I needed more hardware I would use a Raspberry Pi, or another type of controller. Give me an example of any complex project?
@adammurphy5429
@adammurphy5429 Жыл бұрын
@@DrakeOola or libraries being used are very small
@larrybud
@larrybud Жыл бұрын
With today's microprocessors being so cheap, it makes no sense to spend time optimizing for memory when you can just buy a more capable cpu. But yes, it's an interesting video, and this is common with all higher level languages.
@bobvanwagner6099
@bobvanwagner6099 10 ай бұрын
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.
@paulalmquist5683
@paulalmquist5683 9 ай бұрын
Smaller but at what price? Readability, which directly effects maintainability! Part of the purpose of the Arduino IDE is to make programming easier, especially for the beginner. There are plenty of microcontrollers on the market so if you need more memory or more speed buy a different one. If one needs to minimize size then write the code in the assembly language for the target device and document it well but don't expect it to be easily understood by a wide audience.
@JohnHill-qo3hb
@JohnHill-qo3hb 2 жыл бұрын
In the book "Programming Arduino; Getting Started with Sketches" by Simon Monk, he mentions "main". I just unsuccessfully tried to find the page but that is all he does, mention it. Interesting video, subbed...
@Wokwi
@Wokwi 2 жыл бұрын
Thanks!
@ihsancicek4500
@ihsancicek4500 11 ай бұрын
I think you can create a delay function of your own, and use it whenever you need some delay. To protect the for loop getting pruned by the optimization process, you could have used volatile keyword for the function. It may yield a smaller footprint (I have not tried myself). The same volatile keyword approach can be used for interrupt service routine functions as well.
@brinza888
@brinza888 10 ай бұрын
In C you can not apply volatile keyword to functions
@raahimfareed
@raahimfareed 10 ай бұрын
@@brinza888 Arduino uses C++ I think, not C
@col8981
@col8981 Жыл бұрын
@1:29 PINB register should be read only, how about XOR PORTB with 0xFF i.e. PORTB ^= 0xff
@Wokwi
@Wokwi Жыл бұрын
You can actually write to PINB, as documented in the chip's datasheet. XORing PORTB with 0xff has the same effect, but it takes more instructions (read, xor, write), to it's a bit slower. Also, since the change isn't atomic, and interrupt may fire between these operation and possibly change the timing / result (unless you disable interrupts before running PORTB ^= 0xff).
@physicist137
@physicist137 Жыл бұрын
​@@Wokwi which MCU is that then? For the Atmega 328P PINB is Read Only, according to the data sheet.
@Wokwi
@Wokwi Жыл бұрын
​@@physicist137 Right, but then, if you check the section titled "Toggling the Pin", it says: > Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port
@physicist137
@physicist137 Жыл бұрын
​@@Wokwi O.o indeed! Thanks!
@serhiikuzmychov8784
@serhiikuzmychov8784 4 жыл бұрын
it is not 'optimization' it good explanation how Arduino framework works inside, he stripped out most of arduino )))
@Wokwi
@Wokwi 4 жыл бұрын
Good point, thanks!
@gabiold
@gabiold 3 жыл бұрын
Exactly. I won't call it optimization, I'd rather call it not using Arduino instead, but doing bare metal development. As someone who started embedded development before Arduino was a thing (or even born...), I like to write my own code, and know everything that will happen iside the device. I usually develop mostly interrupt-driven code and it is not that straightforward to write reentrant/multithreading code and it also not welcome that the framework wastes cycles and timers and so on while I could have utilized the whole core by myself. If someone at the point needing this kind of stuff, high performance code, etc. then it is better to leave the Arduino framework behind and start some serious embedded development. 😉
@lisandroiaffar4501
@lisandroiaffar4501 Жыл бұрын
Thank you so much for this great, high-quality tutorial :)
@voytechj
@voytechj 3 жыл бұрын
it is possible to reduce code by another ~128 bytes. First chunk of Flash memory is occupied by interrupt vector table and stack initialization. If we do not use interrupts then our code could start at address 0 without jump instruction to skip other interrupt vectors. A lot of instructions is wasted to make a delay, I have a suspicious that setting a timer and toggling pin in an interrupt function could lead to a much smaller code.
@Wokwi
@Wokwi 2 жыл бұрын
Thanks for the tip!
@Jobobaboss
@Jobobaboss 3 жыл бұрын
Wow I didn’t know that this was possible. Awesome!
@muhandiz6585
@muhandiz6585 10 ай бұрын
inside the for loop you can write ; which is an empty statement ,then the compiler would never ignore the for loop, or a better solution could be by moving the increment of i to the loop: for(long i=0;i
@owengrossman1414
@owengrossman1414 4 жыл бұрын
Would the percentage reduction be nearly as large if the program had started out to be 5000 bytes? It seems like you would reduce it by the same number of bytes when you eliminate setup() and loop().
@Wokwi
@Wokwi 4 жыл бұрын
That's right Owen!
@jakeowsley6552
@jakeowsley6552 8 ай бұрын
Hello, This was something I hadn't seen before. Writing PINB toggles all bits (i.e. 0xFF). That part wasn't clear from your narration, "totals the pins". PINx is considered a read only register in Atmel spec, with a caveat: "Three I/O memory address locations are allocated for each port, one each for the Data Register - PORTx, Data Direction Register - DDRx, and the Port Input Pins - PINx. The Port Input Pins I/O location is read only ... writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register."
@samj1012
@samj1012 2 жыл бұрын
Cannot thank you enough wokwi..this delay removal tool is easier than millis()...thumbs up for you
@Dragirek
@Dragirek 9 ай бұрын
How to convert a readable code into a nightmare
@pick_and_play
@pick_and_play 4 жыл бұрын
It's like going back to complex embedded coding from eaiser one. It negates the purpose of using Arduino :D. That's what I feel. A good solution would be to use a cheap, but well built Arduino hardware, remove the Arduino bootloader and use it as a regular AVR board.
@Wokwi
@Wokwi 4 жыл бұрын
Right, it helps you appreciate how much Arduino is making our lives simpler
@mlutteral
@mlutteral 10 ай бұрын
that is what libraries do: trade overhead for readability and easy of use. I don't think it worth to go quasi-assembly to save some hundreds bytes, but it is a nice exercice though
@weash33
@weash33 9 ай бұрын
I would really like to see an demonstration on how much of a speed gain we can achieve as a result of these kind of optimizations.
@JasonWGamingnProd
@JasonWGamingnProd 10 ай бұрын
basically, if you want your code to optimize, u write it at a lower level, like you are using the mcu directly. That's also what I ve learned when i stepped into the stm32 community.
@aisawaloki1571
@aisawaloki1571 10 ай бұрын
Very interesting, but I wonder if the idle loop would consume more power then delay function, as in many architectures delay or waiting is done by halt the cpu until woke up by the timer, is truly do nothing; while the "do nothing" loop are actually doing something to count the loop and branching back continuously.
@Wokwi
@Wokwi 10 ай бұрын
In the case of Arduino Uno, the delay() function doesn't halt the CPU (there's a discussion about this in another comment), so the power consumption would roughly be equivalent. But on other MCUs, it does halt the CPU (e.g. on the Raspberry Pi Pico).
@caunt.official
@caunt.official 11 ай бұрын
So you are using CPU up to 100% in for-loop to save a few hundred bytes of memory?
@Wokwi
@Wokwi 11 ай бұрын
Have you ever looked up how delay() is implemented on Uno? 😉
@caunt.official
@caunt.official 11 ай бұрын
@@Wokwi by physical timer chip I guess?
@Wokwi
@Wokwi 11 ай бұрын
@@caunt.official Busy loop that calls micros() repeatedly and compares the return value with a variable... github.com/arduino/ArduinoCore-avr/blob/63092126a406402022f943ac048fa195ed7e944b/cores/arduino/wiring.c#L106-L117
@caunt.official
@caunt.official 10 ай бұрын
@@Wokwi didn’t know, thank you. I am moving into microelectronics from desktop and backend development, and it’s a bad practice to delay something with for-loops in OS environments 😅
@Wokwi
@Wokwi 10 ай бұрын
@@caunt.official You're welcome. This is also true for embedded development - modern embedded OSes (like FreeRTOS) implement delay more efficiently. Delaying with a for loop consumes more power, so for battery operated devices, efficient delay is crucial.
@davitberishvili8062
@davitberishvili8062 4 жыл бұрын
using main() function how can be used drivers for different modules and EEPROM memory?
@Wokwi
@Wokwi 4 жыл бұрын
Some of them will work out of the box, and some will need some extra code that sets up the timers so that delay() works correctly. But as many people commented, we wouldn't go with our own main() in most cases. setup() and loop() do the trick well for most programs, and the idea of the video is to learn how things work behind the scenes, and also to learn to appreciate the convenience of the Arduino standard library, Wiring.
@davitberishvili8062
@davitberishvili8062 4 жыл бұрын
Thanks
@WistrelChianti
@WistrelChianti Жыл бұрын
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.
@monarch73
@monarch73 10 ай бұрын
The Arduino-Framework relies on the fact, that the loop()-function gives controll back to the caller from time to time. If you don't want that, don't use it at all. For Atmel- and Pico-Microcontrollers there are plenty of cross compilers available. BUT you have to keep in mind, you have to take care of all the hardware- and interrupt-handling-setup yourself! It makes binarys smaller and gets rid off a whole lot of stuff, that you probably don't need. But this is far from beeing trivial. You have to know about hardware-registers of the specific µcu, you are dealing with and manage them yourself. Like I said, far from beeing trivial.
@Calamity_Jack
@Calamity_Jack 10 ай бұрын
Back in the 70s, memory was expensive so we had to optimize byte usage by using inline assembly, bank switching, etc. I can't believe in 2024 where memory is cheap and plentiful we're still trying to save bytes!
@codewithdaniel-1
@codewithdaniel-1 2 жыл бұрын
Wokwi the best simulator for Arduino and esp32..I was surprised I was able to simulate freertos too 😯.
@Wokwi
@Wokwi 2 жыл бұрын
Great to hear Danny! What did you do with FreeRTOS?
@codewithdaniel-1
@codewithdaniel-1 2 жыл бұрын
@@Wokwi I was able simulate all freertos API's such as: queues, mailbox, semaphores(mutex binary and counting), task notifications, interrupts(with rtos),event groups ,timers ..and everything worked smoothly I chose esp32 for the simulations...thanks for the effort you put in place to make this possible ,, you have made prototyping easier.
@rizkitrimukti3827
@rizkitrimukti3827 7 ай бұрын
Can I2C Communication Components such as LCD 12C or Oled use this port manipulation?
@Astrabajt
@Astrabajt 8 ай бұрын
Im wondering why PINB can be assigned with the value. I thought it was read only ;)
@lutzmuller5703
@lutzmuller5703 10 ай бұрын
Hi, how can I insert a simple diode 1N4004 or transistor 2N3906.
@mazharkhaliq1971
@mazharkhaliq1971 10 ай бұрын
How it toggles PinB = 0xff; Means it should be high always, right?
@Wokwi
@Wokwi 10 ай бұрын
Writing to the PORTB register sets the value of the output pins in the PB group, and writing to the PINB register toggles them. So PORTB = 0xff; will always set the pins high, and PINB = 0xff; will toggle all the pins.
@jonayamaha3215
@jonayamaha3215 Жыл бұрын
i would like to learn how you edit your code, your copying and pasting, selecting, and editing text is very efficient. Greetings from Argentina.
@Wokwi
@Wokwi Жыл бұрын
You can find some of the keyboard shortcuts here: docs.wokwi.com/keyboard-shortcuts#power-editing-keys
@jonayamaha3215
@jonayamaha3215 Жыл бұрын
@@Wokwi thanks but i found that pressing F1 on the ide shows you everysingle shortcut and im playing with it, i hate using the mouse idk why, it doesnt feel right.
@Wokwi
@Wokwi Жыл бұрын
@@jonayamaha3215 Even better!
@tomekprzytarski9167
@tomekprzytarski9167 9 ай бұрын
What about incresing code? 924 bytes is preloaded arduino.h content, which will be used for building bigger code.
@adespade119
@adespade119 2 жыл бұрын
I can do that using 0 Bytes, Just buy a flashing LED off Amazon and throw away the Arduino. No really, this was a very good video for me, thanks.
@tommymairo8964
@tommymairo8964 10 ай бұрын
Shouldn't the compiler do the optimization during compile time? If there's no need for dynamic memory allocations.
@colleagueriley860
@colleagueriley860 5 ай бұрын
you trust your compiler to fix bad code?
@keshavharipersad2024
@keshavharipersad2024 10 ай бұрын
yes I have a question: (kinda more a request): how would you achieve individual pin control? and pwm?
@Wokwi
@Wokwi 10 ай бұрын
There are three registers that allow you to control individual pins: DDRx - set the direction of each pin (input / output), PINx - read the value of a pin (or toggle a pin), PORTx - set the output value of the pin (or enable the pull-up register). Replace x with the port name, so for the PBn pins, the register names would be DDRB, PINB, PORTB. PWM is a bit more involved - but look for documentation about the AVR timers (Timer 0 through Timer 2 for Arduino Uno).
@keshavharipersad2024
@keshavharipersad2024 10 ай бұрын
Okay, thanks. I'll dive into it. @@Wokwi
@NavyCuda
@NavyCuda 2 жыл бұрын
Does wokwi support adafruit boards? I have the adafruit feather nrf52832 with the m4f.
@Wokwi
@Wokwi 2 жыл бұрын
Hi! Wokwi does not simulate the nRF52 at this time, but feel free to open a feature request: github.com/wokwi/wokwi-features/issues/new/choose
@flinkiklug6666
@flinkiklug6666 2 жыл бұрын
Berry nice. I don't need it now. but it is good to know
@PeetHobby
@PeetHobby 11 ай бұрын
But if you start doing that, you may just be better off making the jump to Microchip Studio and leaving the Arduino IDE behind.
@syedabidaliabdi1273
@syedabidaliabdi1273 2 жыл бұрын
How can we add additional library in wokwi and components... Also let me know website to test raspberry pi 4 model B semulator online ?
@Wokwi
@Wokwi 2 жыл бұрын
For libraries, you can use the "Library Manager" tab. For components, there's a new "Custom CHIP API" that is being developed. Look out for documentation over the next few weeks. Raspberry Pi 4 Model B simulator - not something that you are likely to find online, as it's too demanding to simulate inside a web browser.
@lezbriddon
@lezbriddon Жыл бұрын
The overhead of the approx 800bytes and a few bytes of dynamic, is this a fixed overhead or does that overhead grow as the user sketch grows?
@Wokwi
@Wokwi 11 ай бұрын
It may grow when using additional library functions (such as the Serial library).
@laurentiucristian1
@laurentiucristian1 4 жыл бұрын
Premature optimization is the root of all evil :))) lol. Good video tho!
@UriShaked
@UriShaked 4 жыл бұрын
Thank! Yeah, I should have said that at the end :)
@surname_name
@surname_name 10 ай бұрын
How to open "Program running" window (with "Sketch uses ..." information)?
@regisrobart998
@regisrobart998 10 ай бұрын
Hello from France, really very interesting, is this applicable to attiny85? In the Arduino documentation there is nothing about these subtleties?
@Wokwi
@Wokwi 10 ай бұрын
Thanks! Yeah, the principles are the same. Arduino documentation tries to be broadly applicable to multiple boards, so they usually don't get into AVR-specific things. The datasheet is where you can find (almost) all the information, and there are also numerus blog posts and threads in forums such as AVR Freaks.
@regisrobart998
@regisrobart998 10 ай бұрын
thank's @@Wokwi
@mainaTheMaker
@mainaTheMaker 4 жыл бұрын
That's great I had a feeling there is a way to optimize code. How do I print lcd values and control stepper motor in same loop without causing delays to stepper motor
@Wokwi
@Wokwi 4 жыл бұрын
Thanks! Which library are you using for the Stepper motor?
@mainaTheMaker
@mainaTheMaker 4 жыл бұрын
@@Wokwi I was using a4988 module So I was creating a pwm signal using digitalwrite and delay function to implement it.
@Wokwi
@Wokwi 4 жыл бұрын
​@@mainaTheMaker check out the AccelStepper library, as it supports sending the PWM signal in a non-blocking fashion (so you can keep update the LCD while the PWM signal is being sent).
@kisoregupthaa2639
@kisoregupthaa2639 4 жыл бұрын
You can code by using LPC 2148 microcontroller method , it tells easy method without using any library function by perfectly knowing function of stepper motor
@ইভানেরবাকশো
@ইভানেরবাকশো 4 жыл бұрын
Hi mates! I have just started to learn arduinos, i have completely no idea what u r talking about, but i appreciaye it. 😅😅😂
@Ikurazo
@Ikurazo 3 жыл бұрын
Would this optimization interfere with UART communication protocols if I were planning to connect the Arduino to the Raspberry Pi and send data packets to and fro the 2 devices?
@Wokwi
@Wokwi 3 жыл бұрын
It would interfere with Arduino's Serial library, since it requires enabling interrupts. It can be mitigated by calling sei(): int main() { sei(); Serial.begin(115200); Serial.println("Hello World"); while(1); } But I wouldn't do this unless there's a really good reason to.
@armanlalani
@armanlalani 4 жыл бұрын
Does this optimizes only the memory utilized or also increases the speed of execution?
@morante1998
@morante1998 4 жыл бұрын
If memory utilization is optimized, speed of execution would also be optimize since there is no floating variables.
@Wokwi
@Wokwi 4 жыл бұрын
That's a great question! Next video will be about this exactly :-)
@tankumaat
@tankumaat Жыл бұрын
What about long push and looping menu system that jumps to different menu loop after long push.
@josealejandrosuarez4189
@josealejandrosuarez4189 4 жыл бұрын
Good tutorial! And good english! Slow and clear! Ideal for spanish people.
@Wokwi
@Wokwi 4 жыл бұрын
Muchas gracias Jose!
@stonered8760
@stonered8760 10 ай бұрын
Why would you develop MCUs with Arduino if you want to access the 'ugly' registers directly?
@painofakatsuki22
@painofakatsuki22 4 жыл бұрын
what will be the computation for the loop that replaces the delay?
@Wokwi
@Wokwi 4 жыл бұрын
The computation?
@painofakatsuki22
@painofakatsuki22 4 жыл бұрын
@@Wokwi in delay(1000) but in the optomization you use 5000 for loop is it by ratio ?
@Wokwi
@Wokwi 4 жыл бұрын
@@painofakatsuki22 Oh, I understand now... It is not accurate in this case, but it's possible to find the right value that will cause an accurate 1-second delay. If you are interested, let me know and I will try to explain how
@re.liable
@re.liable 2 жыл бұрын
I wonder where can I find the port registers reference now... the link in the description does not seem to work for me, and I can't seem to find it on Arduino's official references I mean, I sure could use one of the tutorials I've already seen in the internet, but the official documentation would be nice. I wonder why they removed it
@Wokwi
@Wokwi 2 жыл бұрын
Yes, they seem to have removed the reference page from their site. I updated the link in the video description to point to an archived version of that page.
@matejptacek8020
@matejptacek8020 8 ай бұрын
The active waiting saves space but definitely is not optimal in terms of energy consumption
@colleagueriley860
@colleagueriley860 5 ай бұрын
nor in terms of consistent timing
@Edmorbus
@Edmorbus 2 жыл бұрын
Good day, can you help me with the code for 4x 12v car battery voltage monitoring with ESP32 home
@mangostain
@mangostain 4 жыл бұрын
Hello, can you recommend a book which talk about this subject but deep? Thanks!
@Wokwi
@Wokwi 4 жыл бұрын
Unfortunately, I'm not aware of such book. If you find one, I'd love to know too!
@mangostain
@mangostain 4 жыл бұрын
@@Wokwi I just ordered "Avr Microcontroller and Embedded Systems The: Using Assembly and C", I think its the most related to the subject, what do you think?
@Wokwi
@Wokwi 4 жыл бұрын
@@mangostain Haven't read it, but it sounds relevant! If you are interested more in the electronics part, I did read Electronics Cookbook by Simon Monk which was pretty nice, and also heard good things about "The Art of Electronics", but haven't had a chance to read it yet
@FelipeValladares
@FelipeValladares 3 жыл бұрын
Hi! thanks for the video, it is very useful information! I have a question, the link you post about "Port registers" talks about ATmega8 and ATmega168 microcontrollers... Is "Port registers" possible to use with mega32u2??
@Wokwi
@Wokwi 3 жыл бұрын
Yes, the ATmega32u has even more port registers, going from PORTB to PORTF. You can find the complete information in the data sheet: ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf
@LexBarun
@LexBarun 4 жыл бұрын
The looong loop for nothing with cap 0-499.999 is not represent one second accurately, and will it be longer if the code is much complex?
@Wokwi
@Wokwi 4 жыл бұрын
That's true! To represent one second accurately, you could use the timers. If you want, we can post a demo for for that too.
@LexBarun
@LexBarun 4 жыл бұрын
@@Wokwi timer?
@Wokwi
@Wokwi 4 жыл бұрын
@@LexBarun yes, that's also how delay() works behind the scenes. Here is an example that uses Timer 1 to blink the LED every second: wokwi.com/share/GW8g3bgG5ooEcx2fWCH1? If you are interested, you can learn more about this in the following blog post, look for the section that says: "Blinking with Timers" blog.wokwi.com/5-ways-to-blink-an-led-with-arduino/?
@testingbeta7169
@testingbeta7169 10 ай бұрын
you missed the OBVIOUS point, arduino code was built for ease. if i or people like me saw this ddrb at start they may get turn off, that why arduinoc rules the diy space.
@deeepakkushwah2503
@deeepakkushwah2503 3 жыл бұрын
Can you please help me to make a code for dmx stapper motor with encoder
@Wokwi
@Wokwi 3 жыл бұрын
Sorry, I have no experience with DMX
@MarkHopewell
@MarkHopewell Жыл бұрын
The more you move away from the Arduino Wiring abstraction (bloat) the nearer you move towards its paired-back foundation, C.
@dopo8333
@dopo8333 11 ай бұрын
Nice insight. Still, complex code would be difficult from scratch.
@oscareriksson9414
@oscareriksson9414 11 ай бұрын
Some comments nag about micro controller independence etc 😂 well if you have a project and needed to optimize the chip and use all peripherals to control some product, let's say some robot. Well how is chip independant code going to matter? You are not going to swap chips all the time. You put the chip in there and it dies with the product. Especially if it is a commercial product. To the video maker, I like the low level stuffs thanks for the video!
@Wokwi
@Wokwi 11 ай бұрын
Thanks!
@seoness
@seoness 2 жыл бұрын
Can i run node js on Wokwi simulator and how paste code
@Wokwi
@Wokwi 2 жыл бұрын
Node.js does not run on any of the devices we currently simulate (Arduino, ESP32, Pi Pico, etc).
@FreddyBNL
@FreddyBNL 3 жыл бұрын
Don't you get the same result when you, instead of your asm statement, change the 'long i' into 'volatile long i'?
@Wokwi
@Wokwi 3 жыл бұрын
I think that would work too!
@gabiold
@gabiold 3 жыл бұрын
Or maybe use the nop() function is there is any. Some more sophisticated compiler might optimize out the empty assembly insert when sees no code. It won't doesn't optimize out NOPs, as this is an intentional instruction.
@prooffypro5834
@prooffypro5834 2 жыл бұрын
Thank you. I think that you have the deep programming knowledge. and you may help me solving my problem. I want to turn ON an LED for a definite time with a button, by using an ARDUINO UNO R3, even I hold the botton more than defined time. In short, I need one puls every time. I can do it a resistor and a cap at the input of ARDUINO, but I do not want to use any passive component. Could you help me? Thank you in advance...
@Wokwi
@Wokwi 2 жыл бұрын
You are invited to the discord chat at wokwi.com/discord. Ask the question in the #questions channel and we'll try to help!
@prooffypro5834
@prooffypro5834 2 жыл бұрын
@@Wokwi Thank you for the invitation.
@rZERO_game
@rZERO_game Жыл бұрын
this is great video for me: 1) I dont have to change Arduino IDE 2) I dont have to use setup,loop function. even i didnt know that setup and loop s are artificial function in arduino. say I want to use timer0,timer1 in different manner to generate 38khz pulse with 10ms on and 20 ms off format.then stup,loop style coding dont support timer0 to be used. it throws error that vector 11 already defined and i cant make ISR (TIMER0-OVF-vect) inturrupt. 3) i want to creat my own source code dont want to use library. 4) memory space effective use is possible if i dont use setup,loop function. Thanks . Please published video how to decode any header file,library which is built for arduino ide so that we can creat code for other AVR MCus which is not available in arduino IDE
@Новости-з3й
@Новости-з3й 2 жыл бұрын
Except for the description of the inner code of the Arduino, and how it works, the second part is useless. You do not want to replace all the Arduino timer with these bunch of loops. Beside, many library wont work anymore because they rely on delays...
@Wokwi
@Wokwi 2 жыл бұрын
That's true!
@ahmadmustafeen7532
@ahmadmustafeen7532 4 жыл бұрын
Hey. I have stuck in a problem.. is there a way to discount hc05 connection automatically after some time?
@Wokwi
@Wokwi 4 жыл бұрын
Hello Ahmad, you can try sending at "AT+DISC" command from the Arduino while the module is in AT command mode. Not sure this will work, but worth a try!
@gabrielcorrales8878
@gabrielcorrales8878 3 жыл бұрын
when you called that "for" function, how much time does it take to increase that i variable by one?
@Wokwi
@Wokwi 3 жыл бұрын
The "for" loop does more than that: it also checks the if the new value is less than 500000, and jumps back to the start of the loop. If you just want to measure how much time it takes to increment a "long" time variable by one, check out this video that explains how to measure it: kzbin.info/www/bejne/qp_JloB5rrGNidE And if you want to measure the time of one complete iteration of the "for" loop, you could count the time it takes for the entire loop to run (e.g. by logging the time returned by `micros()`), then divide by 500,000.
@dawidg1627
@dawidg1627 2 жыл бұрын
Thanks for sharing, exellent idea!
@helvacitaha
@helvacitaha 10 ай бұрын
amazing video, thanks
@TagFul19
@TagFul19 2 жыл бұрын
Thank you, very interesting analysis!
@Axeltreman
@Axeltreman Жыл бұрын
Any ideas how to faster analog read?
@MandoRick1978
@MandoRick1978 2 жыл бұрын
Machine code is very efficient. No nonsense. Also incredibly unreadable. I for one throw away the idea of saving space. If I run out of space, then I chose the wrong MCU from the start. My first MCU was the arduino Due. The setup and loop really comes into its own when doing dual core coding with setup1 and loop1. Is brilliant for beginners like myself.
@darklegend9868
@darklegend9868 4 ай бұрын
How to get the exact desired delay?
@misterAD88
@misterAD88 4 жыл бұрын
Very good i love arduino projects
@Wokwi
@Wokwi 4 жыл бұрын
We love them too!
@geoninja8971
@geoninja8971 3 жыл бұрын
Empty for loops was how we made pauses in BASIC programming on the old Amstrad CPC, back in the 1980's.... :) You didn't need 500000 loops for a second either!
@Wokwi
@Wokwi 3 жыл бұрын
Nostalgia!
@bob-ny6kn
@bob-ny6kn 2 жыл бұрын
110 GET "PRESS ANY KEY TO CONTINUE " x$
@NicksStuff
@NicksStuff 11 ай бұрын
Why not go further and do it with interrupts?
@Wokwi
@Wokwi 11 ай бұрын
Be our guest!
@Schroeder9999
@Schroeder9999 Жыл бұрын
PINB = 0xff toggles Port B?
@Wokwi
@Wokwi Жыл бұрын
Exactly
@Schroeder9999
@Schroeder9999 Жыл бұрын
@@Wokwi What happens when you do a PINB = 0x0f then?
@Wokwi
@Wokwi Жыл бұрын
@@Schroeder9999 Low 4 pins (PB0...PB3) will toggle, high 4 four pins (PB4...PB7) stay unchanged.
@Schroeder9999
@Schroeder9999 Жыл бұрын
@@Wokwi Cool! Thank you. Learned something new today ^u^
@_PathOfExile
@_PathOfExile 3 жыл бұрын
how about expanding the arduino program memory using hardware. in the other hand we keep the programming fun and easy.
@0124akash
@0124akash 10 ай бұрын
How to use millis function with register coding sir ? 1 single LED blink 2 LED on off through switch 3 two LED blink with different time. Can you make vdo related three topic. ?
@76Raby
@76Raby 10 ай бұрын
PINB should be read only. I do not understand how this line work.
@Wokwi
@Wokwi 10 ай бұрын
PINB has two functions: you can read it to get the current value (high / low) of the pins in the port, or you can write to it to toggle a pin. For instance, writing to 1 to the first bit would toggle the pin PB0
How Fast Does Your Arduino Code Run? ⏱
19:18
Wokwi
Рет қаралды 27 М.
Что-что Мурсдей говорит? 💭 #симбочка #симба #мурсдей
00:19
黑天使被操控了#short #angel #clown
00:40
Super Beauty team
Рет қаралды 61 МЛН
99.9% IMPOSSIBLE
00:24
STORROR
Рет қаралды 31 МЛН
Arduino OOP [40-Minute Crash Course]
42:12
Robotics Back-End
Рет қаралды 22 М.
Arduino Sketch with millis() instead of delay()
14:27
Programming Electronics Academy
Рет қаралды 233 М.
Level Up Your Arduino Code: Registers
21:09
SparkFun Electronics
Рет қаралды 187 М.
#BB11 Create an Arduino Library😨 - A Real World Example (Easy)
25:54
Bare-Metal MCU #1 - Intro to registers
13:10
Mitch Davis
Рет қаралды 79 М.
How to Use Arduino Interrupts The Easy Way
33:28
Rachel De Barros
Рет қаралды 94 М.
The Best 20 Arduino Projects of the year 2024!
14:59
ToP Projects Compilation
Рет қаралды 97 М.
Что-что Мурсдей говорит? 💭 #симбочка #симба #мурсдей
00:19