6:35 TIP: If your frequency is 16 Mhz then (1/f = T) it means that 1 cycle takes 1/16 000 000 = 62.5 ns and if you have 38 cycles. 38 * 62.5 ns = 2375 ns = 2.38 micro seconds.
@@Wokwi Not sure if it'll be interesting for everyone. But I was wondering if we could generate high frequency (~10--100 Khz) with PWM control using registers directly.
Super cool and interesting, the part with the delaymicroseconds not being accurate actually surprised me. And thanks a lot for the reference on the port manipulation video :)
It would be interesting to see how this could be adapted to work with the new Arduino UNO R4. It is not based on an ATmega chip therefore the registers are different and from what I could see also the execution of instruction is rather different. I tried to apply the same concept presented in this video using the General Purpose Timers but I could not obtain a working example. Maybe you are able to do it having more experience in the field.
So if we did 1000/microseconds we will get the frequency of the loop in Hz or as known as pulling rate? I am little bit confused about (sampling rate, frequency rate and pulling rate)? Also can this code be used with STM32? Thanks
Frequency (without "rate"), when measured in hertz units, is how many times per seconds something happens (e.g. if you clap your hands 3 times per seconds, then your clapping frequency is 3Hz. If you clap your hands once every 10 seconds, than your clapping frequency is 0.1Hz). Sampling rate is how often you are measuring (sampling) something. E.g. if you look at the watch once every two seconds, your sampling rate is 0.5 times per second. Not sure what's "pulling rate". STM32 - no, you'll have to use code specific for the STM32 timers. The principles are similar, but the code is completely different.
what if you use port manipulation, create an array like const byte leds [6] = { B00010000, B... the 1s is the address in the port D you want to turn on. so you call just the memory to PORTD = leds[number];
Sounds like it could work! Depending on how you use it, if you put a constant number in the array index, the compiler may even be smart enough to optimize it and just put the constant value in place...
Fantastic video. This video, this video and the optimize video are really explained very well and I learned a good bit in them. Hopefully we see more of these in the future! Btw WOKWI is a godsend and I am grateful everyday for it.
@@Wokwi I'm just jumping into the world of arudino's and microcontroller. My current project was a self watering potted plant that I can interact with via telegram. It was more or less a proof of concept for going s but larger scale and automation hanging planters and perhaps a garden in my yard.
You may want to check out this free Arduino/AVR internals course that goes deeper into these topics: th-cam.com/play/PLLomdjsHtJTz4st9xzb5qrqWAAatEzq-g.html
This is what I've been looking for. Experimenting with branchless Arduino programming and measuring its speed improvement has been problematic. I would be interested in your take on branchless Arduino programming.
Branchless programming is not really interesting on AVR-based Arduinos. The AVR has a very shallow pipeline with only two stages: fetch and execute. The branch penalty is then minimal: - an unconditional jump takes always two cycles - a conditional jump takes two cycles if the branch is taken, and one cycle if it's not.
It has some logic within to deal with PWM (for some pins) and map from Arduino pin numbers to port register and pin index. You can take a look at the source code and see everything that it does: github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/wiring_digital.c#L140
I do not understand half of the thing mentions here because I am a true n00b. But I learn that speaking near to machine language is the best. If we can code with pure 1 and 0 then we would achieve the fastest and most accurate timing.
One step at a time :) But if you understand half, that's already a good starting point! Actually, coding with Machine Language yourself will usually not get you the fastest timing. The C++ compiler can sometimes do optimizations that a human would usually overlook. But the ability to read the machine code that the compiler generates can be useful in those cases when you have a performance bottleneck in a specific point and you want to optimize it. Here's another example of using machine language within MicroPython (an embedded version of the Python language), to optimize a specific function that happened to be a bottleneck: urish.medium.com/embedded-python-cranking-performance-knob-up-to-eleven-df31a5940a63 What project(s) are you currently working on?
@@Wokwi Urgh! I might not have the flair for programming languages. Few successful programmers say that to be successful in programming one has to sit before their computers for hours on end. I tried and I was committed (No poking phone. No computer game. No shopping. No unnecessary distraction). I was genuinely interested in getting it (whatever project I was doing) done. But...oh well. I think the problem with me is I have high tendency to go to the most efficient way of doing things. Excellent example is this one - speak to ATmega's registers rather than human-readable-commands. Having said that, I THINK (only in my bloody tiny brain cell) that I would be more successful in messing about ATmega's language. Because it looks very simple and easy. Certainly looks can be deceiving! Ah ha! I do not know yet. I do not know yet because I have not obtained the board. I am waiting for that thing to arrive, so I am first doing theoretical research. Arduino is meant for idiots, I think I would do well. I think I would do well because I probably would be using zero brain cell because the project I am interested in at present is using Arduino as cheapo oscilloscope. I was understood that oscilloscope is a low-level project, it utilizes ATmega MCU capabilities directly, without the Arduino library. I just hope that I do not fry any I/O pins nor the chip! Ruggeduino has every safety feature possible, but I am not willing to fork out that money. Twisted positive thinking, justification, and rationalisation of my own inability to pay tell me that being in danger zone may train me be more analytical and careful rather than taking life for granted. Now, that is a little unfunny humor!
It's a good tendency to explore and learn how things works under the hood. You may be interested in this free AVR internals class: th-cam.com/video/WUNxaQGAJjU/w-d-xo.html
You would not want to program in machine language (the 1s and 0s). Assembly is just as fast (as it is translated word-for-word into machine language) and a lot easier to write. And as Wokwi said, C and C++ compilers at quite good at optimizing. Note that often humans can write more efficient assembly than the compiler, as they have one great advantage: they can run the compiler to see its output, then improve upon it. Yet, it is very unlikely you will ever need the performance of hand-written assembly and, if you ever need it, it will be for very specific time-critical code sections.
6:35 TIP: If your frequency is 16 Mhz then (1/f = T) it means that 1 cycle takes 1/16 000 000 = 62.5 ns and if you have 38 cycles. 38 * 62.5 ns = 2375 ns = 2.38 micro seconds.
is it really tip or is that extremely basic mathematical aptitude?
yes yes, I made a crude arduino clock a few months ago, you idea will help improve it. it won't be Casio accuracy but its good enough.
Man, I was looking for these type of videos where they explain the register level timing codes and their functions. Great video!
Happy to hear that! What would you like to see next?
@@Wokwi Not sure if it'll be interesting for everyone. But I was wondering if we could generate high frequency (~10--100 Khz) with PWM control using registers directly.
@@noon1117 Thanks! Yes, that'a good idea!
Thanks! Always knew digitalWrite takes a while, but never cared enough to measure how long precisely :)
Now you know :)
Super cool and interesting, the part with the delaymicroseconds not being accurate actually surprised me.
And thanks a lot for the reference on the port manipulation video :)
Very good video and explanation. Thank you
Mind blowing video. May god keep you happy and healthy.
Subscribed. Awsome content it makes my code more optimized.
Great video! Thanks. Subscribed.
Thank you!
Excelente vídeo. Obrigado pela aula
Keren om, penjelasannya sangat bagus👍
It would be interesting to see how this could be adapted to work with the new Arduino UNO R4. It is not based on an ATmega chip therefore the registers are different and from what I could see also the execution of instruction is rather different. I tried to apply the same concept presented in this video using the General Purpose Timers but I could not obtain a working example. Maybe you are able to do it having more experience in the field.
How u make this website to run code make video on it
Hi Nishat, the website is wokwi.com
You can learn how the Arduino simulator was created here: blog.wokwi.com/avr8js-simulate-arduino-in-javascript/
So if we did 1000/microseconds we will get the frequency of the loop in Hz or as known as pulling rate? I am little bit confused about (sampling rate, frequency rate and pulling rate)? Also can this code be used with STM32? Thanks
Frequency (without "rate"), when measured in hertz units, is how many times per seconds something happens (e.g. if you clap your hands 3 times per seconds, then your clapping frequency is 3Hz. If you clap your hands once every 10 seconds, than your clapping frequency is 0.1Hz).
Sampling rate is how often you are measuring (sampling) something. E.g. if you look at the watch once every two seconds, your sampling rate is 0.5 times per second.
Not sure what's "pulling rate".
STM32 - no, you'll have to use code specific for the STM32 timers. The principles are similar, but the code is completely different.
Excellent video! Thank you
what if you use port manipulation, create an array like const byte leds [6] = { B00010000, B... the 1s is the address in the port D you want to turn on.
so you call just the memory to PORTD = leds[number];
Sounds like it could work! Depending on how you use it, if you put a constant number in the array index, the compiler may even be smart enough to optimize it and just put the constant value in place...
Fantastic video. This video, this video and the optimize video are really explained very well and I learned a good bit in them. Hopefully we see more of these in the future!
Btw WOKWI is a godsend and I am grateful everyday for it.
Thank you! What project are you working on?
@@Wokwi I'm just jumping into the world of arudino's and microcontroller. My current project was a self watering potted plant that I can interact with via telegram. It was more or less a proof of concept for going s but larger scale and automation hanging planters and perhaps a garden in my yard.
@@ajciccone88 Sounds like a cool project. Enjoy your journey!
Any more advice on this topic?
You may want to check out this free Arduino/AVR internals course that goes deeper into these topics: th-cam.com/play/PLLomdjsHtJTz4st9xzb5qrqWAAatEzq-g.html
@@Wokwi thank you
Superb cool ; keep making videos....
Thank you :)
Excellent video!
Thank you very much!
I think if we are going to use thath is better use justo c to program
useful information, thanks
This is what I've been looking for. Experimenting with branchless Arduino programming and measuring its speed improvement has been problematic.
I would be interested in your take on branchless Arduino programming.
Branchless programming is not really interesting on AVR-based Arduinos. The AVR has a very shallow pipeline with only two stages: fetch and execute. The branch penalty is then minimal:
- an unconditional jump takes always two cycles
- a conditional jump takes two cycles if the branch is taken, and one cycle if it's not.
Well done ! 🙂
Very nice video
Really good. Thx
how you Know all this information :)
Thanks for share it.
Why is digitalWrite so slow?
It has some logic within to deal with PWM (for some pins) and map from Arduino pin numbers to port register and pin index. You can take a look at the source code and see everything that it does: github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/wiring_digital.c#L140
🤯👍🔥💥 useful 👌 👍 👏
This stuff is digital gold.
Very cool
Subtítulos spanish
Quieres agregarlos?
I do not understand half of the thing mentions here because I am a true n00b. But I learn that speaking near to machine language is the best. If we can code with pure 1 and 0 then we would achieve the fastest and most accurate timing.
One step at a time :) But if you understand half, that's already a good starting point!
Actually, coding with Machine Language yourself will usually not get you the fastest timing. The C++ compiler can sometimes do optimizations that a human would usually overlook. But the ability to read the machine code that the compiler generates can be useful in those cases when you have a performance bottleneck in a specific point and you want to optimize it.
Here's another example of using machine language within MicroPython (an embedded version of the Python language), to optimize a specific function that happened to be a bottleneck: urish.medium.com/embedded-python-cranking-performance-knob-up-to-eleven-df31a5940a63
What project(s) are you currently working on?
@@Wokwi Urgh! I might not have the flair for programming languages. Few successful programmers say that to be successful in programming one has to sit before their computers for hours on end. I tried and I was committed (No poking phone. No computer game. No shopping. No unnecessary distraction). I was genuinely interested in getting it (whatever project I was doing) done. But...oh well.
I think the problem with me is I have high tendency to go to the most efficient way of doing things. Excellent example is this one - speak to ATmega's registers rather than human-readable-commands.
Having said that, I THINK (only in my bloody tiny brain cell) that I would be more successful in messing about ATmega's language. Because it looks very simple and easy. Certainly looks can be deceiving! Ah ha! I do not know yet. I do not know yet because I have not obtained the board. I am waiting for that thing to arrive, so I am first doing theoretical research. Arduino is meant for idiots, I think I would do well.
I think I would do well because I probably would be using zero brain cell because the project I am interested in at present is using Arduino as cheapo oscilloscope. I was understood that oscilloscope is a low-level project, it utilizes ATmega MCU capabilities directly, without the Arduino library. I just hope that I do not fry any I/O pins nor the chip!
Ruggeduino has every safety feature possible, but I am not willing to fork out that money. Twisted positive thinking, justification, and rationalisation of my own inability to pay tell me that being in danger zone may train me be more analytical and careful rather than taking life for granted. Now, that is a little unfunny humor!
It's a good tendency to explore and learn how things works under the hood. You may be interested in this free AVR internals class: th-cam.com/video/WUNxaQGAJjU/w-d-xo.html
You would not want to program in machine language (the 1s and 0s). Assembly is just as fast (as it is translated word-for-word into machine language) and a lot easier to write. And as Wokwi said, C and C++ compilers at quite good at optimizing.
Note that often humans can write more efficient assembly than the compiler, as they have one great advantage: they can run the compiler to see its output, then improve upon it. Yet, it is very unlikely you will ever need the performance of hand-written assembly and, if you ever need it, it will be for very specific time-critical code sections.
Cool