0:08
hello and welcome to controllers Tech
0:12
few months ago I made a video covering
0:15
ws2812 addressable LEDs
0:18
we used the timer pwm with dma to send
0:24
that video is still one of the most
0:26
appreciated videos I ever uploaded
0:29
while many of you made it work using
0:32
that method some of you still had
0:35
while for some the dma Callback wasn't
0:38
being called for others one or two LEDs
0:41
were behaving inappropriately
0:43
today we will cover yet another method
0:45
of interfacing these addressable LEDs
0:49
instead of pwm we will use the SBI
0:53
we can achieve High board rates with SBI
0:55
and therefore we can match the bit
0:57
timing required for the LEDs
1:00
here is the original article that I took
1:04
you can read this I will leave the link
1:09
here is the data sheet of the
1:12
ws2812 addressable LED driver
1:15
we will directly jumped to the timing
1:18
here are the big timings for zero and
1:22
to send a zero we need to keep the
1:24
signal high for 0.35 microseconds and
1:28
then low for 0.8 microseconds
1:31
and to Sender one we need to keep it
1:34
high for 0.7 microseconds and low for
1:40
the timing is flexible and an error of
1:43
150 nanoseconds is acceptable here
1:46
the total time for a pulse should be
1:48
around 1.25 microseconds with an error
1:54
we will use the SBI peripheral with the
1:57
board rate of 2.5 megabits per second
2:01
this means that each bit will be
2:03
transferred in 0.4 microseconds
2:08
if we want to transfer a zero we can
2:11
send a 1 followed by two zero bits
2:14
we know that each bit is equivalent to
2:16
0.4 microseconds so this bit sequence
2:20
will keep the signal high for 0.4
2:22
microseconds and then low for 0.8
2:29
this is exactly what the requirement is
2:34
ws2812 driver will see these three bits
2:39
similarly to Sender one we will send two
2:42
one bits followed by a zero bit
2:46
this will keep the signal high for 0.8
2:48
microseconds and then low for 0.4
2:53
this is not the exact but an acceptable
2:59
ws2812 driver will see these three bits
3:04
the period for the three bits is 1.2
3:07
microseconds which is as per the
3:09
requirement in the data sheet
3:15
we will discuss more things in this data
3:17
sheet later let's first open the IDE and
3:27
give some name to the project and click
3:31
let's start with the clock
3:34
bypass the clock as it is provided by
3:38
the board has 8 megahertz Crystal and I
3:41
am running it as the maximum possible
3:47
now go to the connectivity and enable
3:50
the SPI in half duplex mode
3:53
we only need to send the data so half
3:56
duplex mode is fine for us
3:58
let's keep the data size as 8 Bits as we
4:01
only need to send three bits
4:04
the data should be transferred as MSB
4:08
now we need to bring the board rate to
4:10
2.5 megabits per second
4:13
this setup doesn't allow me to do that
4:16
let me reduce the main clock to 160
4:21
all right here we have the 2.5 megabits
4:25
make sure the clock polarity is low and
4:28
the clock phase is one Edge
4:30
this is basically the SPI mode 0. two
4:35
pins got selected for the half duplex
4:38
we have the pin pa5 as the clock and the
4:41
pin pa7 as the data pin
4:44
we will connect the PIN pa7 to the LED
4:48
this is all the setup we need click save
4:51
to generate the project
4:53
we will create separate Library files
5:00
aws2812 header file in the include
5:02
directory and see file in the source
5:08
let's start writing the code in the
5:12
include the main file and the
5:15
ws2812 header file also
5:18
Define the number of LEDs being used
5:22
also Define an array to store the color
5:24
data here I am defining a matrix array
5:28
which will store the three colors for
5:32
let's write a function to set the colors
5:34
for the respective LED
5:36
the parameters of this function are the
5:39
LED number the red color code the green
5:42
code and the blue code
5:44
these color codes should be in the RGB
5:48
here we will store the LED number in the
5:51
first element of The Matrix
5:53
then store the green color in the second
5:55
element the red in the third and the
5:58
blue in the fourth I am storing the
6:01
green color first this is because as per
6:03
the datasheet the green color byte is
6:05
the most significant byte then we have
6:07
the red and at last the blue
6:10
therefore it will be easier to extract
6:12
the data later in the code
6:17
now let's write another function to send
6:19
the data through the SPI
6:22
the parameters are the color codes
6:25
here we will first combine the three
6:27
color bytes and make a single 24-bit
6:32
in the beginning we discussed that each
6:34
color bit will be equivalent of three
6:38
we will store these three SPI bits in a
6:43
since there are 24 color bits in total
6:46
let's create an array of 24 bytes
6:49
also Define an index variable to keep
6:52
track of how many bytes have been
6:54
occupied in the array
6:56
now we will assign the SBI bits for each
6:59
color bit and store them in the array
7:02
we have to send the MSB first therefore
7:05
the extraction should start from the
7:07
most significant position of the color
7:10
we will first shift the color data by 23
7:13
places to the right and extract the bit
7:17
if the bit is a 1 we will store 1 1 0 in
7:20
the first element of the array
7:23
otherwise if the bit is a zero we will
7:26
store 1 0 0 in the array
7:29
then the color data will be shifted by
7:31
22 places and we will extract the second
7:36
once all the bits from the color data
7:38
have been extracted we will send the
7:42
you can use interrupt dma or the normal
7:45
mode to send this data it should work
7:48
fine with all the methods
7:50
we need to define the SPI Handler as an
7:56
let's write one more function which we
7:59
will call from the main file to send the
8:03
here we will call the for loop as many
8:06
times as the number of LEDs we have and
8:09
each time we will send the data to the
8:13
the LED data array ensures that the
8:15
previous data for the LEDs is saved and
8:18
if a single LED is updated it doesn't
8:20
affect the rest of them
8:22
every time we update even a single LED
8:25
we have to send the data for all the
8:29
also note that unlike what we did during
8:31
the pwm tutorial here we are sending the
8:34
data for individual LEDs
8:37
this structure also reduces the memory
8:40
requirement for the data array and hence
8:42
the code can be used on the lower end
8:45
microcontrollers also
8:47
all right let's define these functions
8:53
we will Define the set LED function and
8:58
let's write the main file now
9:05
in the main function we will set all the
9:08
LEDs to zero to make sure they are off
9:21
in the while loop let's set all of them
9:24
to red and send the data to the LEDs
9:37
give a delay of one second
9:40
Now set all LEDs to green and send the
9:45
let's build and debug the code
10:00
here you can see all the LEDs showing
10:03
three colors after every one second
10:07
let me add a break point here
10:10
all right we have hit the break point
10:12
let's step over the send function
10:16
you can see all the leads are red
10:18
let's put breakpoints after every send
10:22
all the LEDs are green now
10:25
and now they are blue
10:28
so the code is working fine
10:31
I have already covered this topic where
10:34
we sent the data using the pwm
10:37
you can simply search for
10:39
ws2812 on the website and you can find
10:44
this code also has the brightness
10:46
feature which you can Implement in the
10:50
anyway I will include the brightness in
10:52
the final code before I upload it on the
10:56
one more thing we don't necessarily need
10:58
to set all the LEDs every time
11:01
but we do need to send the data for all
11:06
this is how the data gets shifted the
11:09
first 24 bits are used by the first led
11:12
then the rest of the data is shifted to
11:16
this process goes as long as there is
11:20
to indicate that the data is finished we
11:23
need to pull the data line low for more
11:25
than 50 microseconds
11:28
we haven't implemented this part yet
11:31
so after the data has been sent to all
11:33
the LEDs let's give a delay of one
11:45
to display some random color we can use
11:51
let me copy the RGB code of this color
11:54
and now I am setting the LED 0 with this
12:00
after setting the old send the data to
12:06
let's comment out this part
12:10
let's build and run this now
12:15
here you can see the LED shows the same
12:19
it might not be accurately visible in
12:22
here first we set all the LEDs to off
12:25
and then display single color on the LED
12:29
let's set another color now
12:31
I am setting this to the LED one
12:46
let's build and run this now
12:52
here you can see both the colors are
12:54
being shown on the LED zero and led1
12:58
so we were able to send the data to the
13:03
I hope you understood the process
13:06
I will add the brightness to the library
13:10
the details will be updated in the
13:14
this is it for today
13:16
you can download the code from the link
13:20
leave comments in case of any doubt
13:23
keep watching and have a nice day ahead