Thanks for clicking this video Today we will discuss,
how do I speed up Arduino code
by manipulating port registers.
It's start from writing the usual code like this
Then code the program like this one.
We will also read a lot about datasheet of atmega328p
as a guide in writing the code.
and testing using oscilloscope measuring devices.
follow my journey in revealing how fast
Arduino in executing the program
and how to optimize it.
A week ago when I learned about microcontrollers.
I suddenly thought
Is Arduino that we have been using really fast?
is it true that arduino is not so responsive?
Then I prepare everything to find out
how fast is arduino, specifically arduino uno
Rev 3, with atmega 328p microcontroller
atmega328p, in executing the program
which are written on the Arduino IDE
it turns out the program written on arduino IDE
uses a lot of functional features
that apparently have many lines of code
maybe you all know that arduino IDE
use C / C ++ language,
and it's true
However on the arduino IDE there are
functions that make it easier for us to write
programs on microcontrollers
But the easy one does not mean fast
and because at that time I was studying microcontrollers
I'm trying to learn the atmega328p datasheet
which one is found that
maybe if we can speed up some
arduino functions, by directly accessing the IO ports.
And today I will show you the comparison of
functions on Arduino.
with the code that directly accesses the port register
to show some functions on the Arduino IDE
requires many lines of code
you can open it on C drive
then select the arduino folder
in this case I'm using a Windows OS
so where the default install arduino IDE is in
Program Files(x86)
then follow the instructions on the video
this is the main folder in the arduino program
here are many programs, headers,
also C, C ++ files to perform
several functions on arduino
here I open the C file
because inside there are functions that I want to show.
in this digital wiring file you will find several functions
that are often used in Arduino programming.
for example here there is a pinmode function
that turns out to have a lot of lines of code.
here There are other functions, such as turnoffPWM,
In addition there are other important functions
such as digitalWrite
which also has many lines of code
Next I want to make an experiment that compares
programs written with the functions of arduino
with programs written with port manipulation.
this program will turn on the LED light using pin number 9 on the arduino board.
using pin number 9
on the arduino board
therefore we must read the datasheet from the atmega328p .
IO port and pin configuration sections
and also the schematic of Arduino Uno
and also the schematic of Arduino Uno
In the IO port section, you can see that there is a functional diagram of each general IO
In the IO port section, you can see that there is a functional diagram of each general IO
on each atmega328p pin
for each pin there are three registers which can be used
to define a particular pin as input or output.
to define a particular pin as input or output.
Or to set a certain pin to HIGH or LOW
and in the register description section, we can see several registers that we can use.
and in the register description section, we can see several registers that we can use.
Next we will look at the schematic of
Arduino Uno, to find out pin number 9 on the Arduino Uno board,
which part is connected to the atmega328p pin.
which part is connected to the atmega328p pin.
it turns out that the pin is connected to the PB1 pin on atmega328p
it turns out that the pin is connected to the PB1 pin on atmega328p
Then we want to make this pin become an output by setting the DDRB register DDB1 bit number to one.
Then we want to make this pin become an output by setting the DDRB register DDB1 bit number to one.
Then we want to make this pin become an output by setting the DDRB register DDB1 bit number to one.
We will open the Arduino IDE software,
We will open the Arduino IDE software,
then in the setup function, we will write it in several ways.
like for example like this.
this first method is not recommended
because it is inflexible and takes a long time to write.
the second one is like this.
here I use the left shift to set certain bits to become one just like this.
here I use the left shift to set certain bits to become one like this.
I will demonstrate this code using software Code Blocks,and here I use C language to demonstrate it
I will demonstrate this code using software Code Blocks,and here I use C language to demonstrate it
I will demonstrate this code using software Code Blocks,and here I use C language to demonstrate it
so this is the program. here there is the bin function
to display binary numbers at the output because printf does not support binary numbers.
to display binary numbers at the output because printf does not support binary numbers.
and here there is a reg variable, which we can equate to this reg variable with the DDRB register.
and here there is a reg variable, which we can equate to this reg variable with the DDRB register.
where in this register there are 8 bits with the first bit named DDB0
where in this register there are 8 bits with the first bit named DDB0
and the last bit named DDB7 and all bits have a starting value of zero.
and the last bit named DDB7 and all bits have a starting value of zero.
we want to change the DDB1 bit value to one,
in the program it means we want to change the bit at this position to value one.
in the program it means we want to change the bit at this position to value one.
and this is like the first way that I explained earlier.
here the bin (function) will display the output before and after the bit is set.
here the bin (function) will display the output before and after the bit is set.
and when executed, the result is like this
then there is another way, which use left shift operators.
then there is another way, which use left shift operators.
where here I will shift one bit one time.
where here I will shift one bit one time.
and when executed, the result is like this
if I replace zero instead of one
then bit one will occupy a position like this
then bit one will occupy a position like this
if I change it to five then bit one will occupy a position like this
if I change it to five then bit one will occupy a position like this
then for example, if we previously set other bits with certain values,
then for example, if we previously set other bits with certain values,
then we want to set the bits at position one to be one
we can modify this code just by adding the bitwise OR operator.
we can modify this code just by adding the bitwise OR operator.
so the bits in one position are worth one and the other bits are fixed
so the bits in one position are worth one and the other bits are fixed
Third, let's pause for a moment. Maybe you are confused why I directly wrote this program like this.
Third, let's pause for a moment. Maybe you are confused why I directly wrote this program like this.
Third, let's pause for a moment. Maybe you are confused why I directly wrote this program like this.
basically to be able to write the name of the port
on an Atmel microcontroller like Atmega328p we need to insert the Avr / io.h header file like this
on an Atmel microcontroller like Atmega328p we need to insert the Avr / io.h header file like this
on an Atmel microcontroller like Atmega328p we need to insert the Avr / io.h header file like this
on an Atmel microcontroller like Atmega328p we need to insert the Avr / io.h header file like this
but maybe you guys are wondering why I didn't write it in the program
but maybe you guys are wondering why I didn't write it in the program
the answer is: Arduino automatically puts the file header in the source code,
so we don't need to write it in the program
let me show you, here I open the Arduino IDE source on GitHub and I scroll down
let me show you, here I open the Arduino IDE source on GitHub and I scroll down
let me show you, here I open the Arduino IDE source on GitHub and I scroll down
and the credits can be seen that arduino is opensource a
and the credits can be seen that arduino is opensource
And here arduino uses several toolchain, one of which is called avrlibc
And here arduino uses several toolchain, one of which is called avrlibc
this will also answer why we can write programs
on microcontrollers with Avr microprocessors in C instead of using assembly language
on microcontrollers with Avr microprocessors in C instead of using assembly language
on microcontrollers with Avr microprocessors in C instead of using assembly language
when I click on avrlibc, we will be taken to avrlibc's homepage
when I click on avrlibc, we will be taken to avrlibc's homepage
when I click on avrlibc, we will be taken to avrlibc's homepage
here is a description that when we use this toolchain
together with other toolchains, we can
write programs on microcontroller atmel avr in C language.
write programs on microcontroller atmel avr in C language.
and I will also answer why here I use DDB1 and not number 1.
and I will also answer why here I use DDB1 and not number 1.
and I will also answer why here I use DDB1 and not number 1.
I will open the Avr / io.h header file.
In the program can be seen here,
if I define a certain series of atmel microcontrollers,
then certain header files will be inserted
accordance with the series microcontroller atmel.
accordance with the series microcontroller atmel.
and I'll scroll down to find the series: atmega328p
and I'll scroll down to find the series: atmega328p
here when we define this series, this header file will be inserted.
here when we define this series, this header file will be inserted.
here when we define this series, this header file will be inserted.
let's find what the contents of this header file are.
and actually I have opened it on github, iom328p file on atmega328p
and actually I have opened it on github, iom328p file on atmega328p
here there is a definition of a register along with its bit number,
it can be seen that DDB1 is 1.
it can be seen that DDB1 is 1.
That's why I wrote it like this in my Arduino source code.
Okay, let's go ahead with the explanation.
the third one that I like and recommend the most is to write it like this.
the third one that I like and recommend the most is to write it like this.
This syntax is similar to pinMode on Arduino only faster and smaller in size when compiled
This syntax is similar to pinMode on Arduino only faster and smaller in size when compiled
This syntax is similar to pinMode on Arduino only faster and smaller in size when compiled
Next, in the loop function
we will make the pin high and then low without any delay
we will make the pin high and then low without any delay
then after that there is a delay of 100 milliseconds
we can set the pin to high by setting the PORTB register, PB1 bit to 1.
we can set the pin to high by setting the PORTB register, PB1 bit to 1.
we can set the pin to high by setting the PORTB register, PB1 bit to 1.
to set the pin to low we can set the bit to zero
to set the pin to low we can set the bit to zero
and so the program turns on our LED using pin number 9 and manipulating the port register
and so the program turns on our LED using pin number 9 and manipulating the port register
and so the program turns on our LED using pin number 9 and manipulating the port register.
Next I will compare the program I have written with this program.
Next I will compare the program I have written with this program.
Next with the oscilloscope we will test how fast Arduino executes programs.
Next with the oscilloscope we will test how fast Arduino executes programs.
Next with the oscilloscope we will test how fast Arduino executes programs.
Okay, now we are in my private laboratory
so now we are in one of the laboratories on my campus,
here is a program that I want to test, still using functions on Arduino
here is a program that I want to test, still using functions on Arduino
I have uploaded and need 896 bytes of memory,
I have uploaded and need 896 bytes of memory,
and here the circuit, I have arranged everything, turned on the LED lights and measured using an oscilloscope.
and here the circuit, I have arranged everything, turned on the LED lights and measured using an oscilloscope.
here the probe is connected to the positive LED and the ground probe is connected to the ground on Arduino.
here the probe is connected to the positive LED and the ground probe is connected to the ground on Arduino.
here the probe is connected to the positive LED and the ground probe is connected to the ground on Arduino.
and on Arduino, I use pin number 9 and pin ground.
and on Arduino, I use pin number 9 and pin ground.
on the oscilloscope screen, It can be seen the detected signal,
here I use channel 1
here I am using channel 1 with the initial time / div setting of 50 microseconds,
here I use channel 1 with the initial time / here there is information that I need,
here is delta T, the time measured from cursor A to cursor B.
here is delta T, the time measured from cursor A to cursor B.
here I want to set this signal so that it's easier to see by changing the time / div
I set the time / div, so that it's clearer
I set the time / div, so that it's clearer
okay, here I use time / div of 200, sorry,
2.5 microseconds
then I move the cursor B and also the cursor A to measure
then I move the cursor B and also the cursor A to measure
delta T, how long is the transition from state high to state low
delta T, how long is the transition from state high to state low
and here I press this button to remove the menu on the oscilloscope
and here I press this button to remove the menu on the oscilloscope
and it turns out by using a 2.5 microsecond
time / div, it takes 4 microseconds,
time / div, it takes 4 microseconds,
measured from beginning of state high to state low.
I want to test the second program that I wrote
using the port register, but here there is a slight difference
with the program that I have explained.
can be seen in the void loop,
I put the delay before I set the pin to high or low
actually the same because what becomes our corcern is
to measure how much time is needed to transition from state high to state low
so it's the same.
then the second, in the second row of the void loop,
PORTB equals, one, in parentheses, left shift, PORTB1.
PORTB equals,one , in parentheses, left shift, PORTB1.
here I use the PORTB1 constant instead of PB1. It's actually the same and I'll show you why.
here I use the PORTB1 constant instead of PB1. It's actually the same and I'll show you why.
so like that and when I compiled it turned out to require 596 bytes of memory
so like that and when I compiled it turned out to require 596 bytes of memory
require 596 bytes of memory, This is a series that is still the same as the previous test.
require 596 bytes of memory, This is a series that is still the same as the previous test.
on the oscilloscope there is no signal yet because I have not run it.
and I want to upload this program to make sure it runs on atmega328p on arduino
and I want to upload this program to make sure it runs on atmega328p on arduino
and I want to upload this program to make sure it runs on atmega328p on arduino
I uploaded it. And it's still the same and here I run the oscilloscope
I uploaded it. And it's still the same and here I run the oscilloscope
I uploaded it. And it's still the same and here I run the oscilloscope
can be seen in the time / div settings, it is still the same as the previous program.
can be seen in the time / div settings, it is still the same as the previous program.
but the signal that emerge require much less time.
and here I want to change the time / div so that the signal are clearer
and here I want to change the time / div so that the signal are clearer
okay for this second program,
with a time / div of 100 ns, the transition from state high to low takes 124 ns.
with a time / div of 100 ns, the transition from state high to low takes 124 ns.
with a time / div of 100 ns, the transition from state high to low takes 124 ns.
it turns out that it takes much faster time than programs written with the functions of Arduino
it turns out that it takes much faster time than programs written with the functions of Arduino