How to Glow an LED with C Language
Updated: Nov 9, 2020
Glowing and LED can be done several ways.
It can be done with only electrical components or with code flashed to a microcontroller chip.
The most common way to glow LEDs on and off is with the latter option and it involves the use of pulse width modulation.
Pulse Width Modulation (PWM) is the most important and critical skill to learn for beginners in robotics/electronics.
If you need to learn what it is, check out my tutorial right here.
In a nutshell, you set a frequency for electrical pulses to be sent out on one of the pins of your microcontroller at varying durations.
To glow and LED on you code your pin to send out electrical pulses for longer and longer durations each cycle in the loop section of your code.
The most common way is to create a variable, a placeholder, and set it to equal zero and increase that variable by 1 every loop cycle. The code has that variable value become the value of the duration for the PWM electrical pulses. Each loop, the variable increases in value so the pin is turned on longer and longer each time.
To glow an LED off you simply do the same but subtract from the variable each loop through.
If this is confusing at first, try to draw it out on paper. You WILL understand.
Here is our breadboard setup. You can see it is very simple.
We have our microcontroller with the first pin on the top left.
We have our ~5v of DC power and ground wires connected to our ATMEGA328p.
After that, we are going to use pin PB1 so let's connect the LED's positive (long leg) end to that pin's horizontal rail and connect the shorter negative leg of the LED to our ground.
The electricity can no come into the chip and go through pin PB1, through the LED and out to ground, just like water in a hose. It's as simple as that!
C Code to Glow the LED on ATMEGA328p
Writing code is not what tv and movies tell you.
It is easier to write in chunks.
Before you write the code you need to come up with a game plan, a basic overview of what you need done.
Our game plan: Use the internal clock in the chip that is always running and counting up 8 bits which is 256 steps which starts with 0 and ends in 255.
The ATMEGA328p chip runs at 8MHZ = 8,000,000 HZ = 8 million clock cycles per second which is too fast.
We want to divide this clock time to a lower frequency, we don't need it super fast.
We need a pin to send out electrical pulses at the end of each clock cycle at this speed (frequency).
Then we need to make the pin send out those pulses for longer and longer each time the code goes through the loop.
To glow off we reduce the time that the pin is sending out the electrical pulses at our frequency we chose.
I'm going to explain the code in the order I wrote it so it makes sense to you.
I learned everything I know from a really easy to read book full of all the info you need below! Check it out!
Let's see what that looks like in our code. Here is a snapshot of it. Don't copy paste. Keep reading!
You will see I have included the basic avr/io and util/delay header files. These are in almost every program I write in C.
Remember there are 3 blocks to code:
1. The Preamble and defines: Get all the reference files and create predefined terms with values used in Main and the Loop
2. Main: Call all actors to the stage and configure the chip for startup (timers, interrupts, predefined functions needed)
3. The Loop: The actual work to be performed over and over and over and over, forever
In the preamble, you can see I set up the timer we need for our frequency and electrical pulse configuration. I gave it the name timerSetup with no parameters needed which is why is says (void). See my pink notes.
All we are doing is flipping switches on inside the chip, we don't actually turn on Timer1 (the 16 bit resolution timer). We just look at the ATMEGA328p datasheet and go to Timer1 section and see which bits to flip on for FAST MODE and set its prescaler because the chip's clock is too fast. It is overkill so we flip the switch that divides it by 256.
The last part is to set the timer output at the frequency we chose to a pin. We can use pin PB1 which is associated with OCR1A which is a placeholder for whatever duration we set it to send out the pulses. See my pink notes.
Look at Main. You can see I need to call this timer to the stage by its name and the parentheses and a semicolon. Don't forget your semicolon when writing code in C.
I also go into the Data Direction Register B which is the street that our house pin PB1 is located on. Then we set PB1 to output.
We now have our timer with the frequency and the output pin for the electrical PWM pulses ready to go like a sprinter at the starting line.
Now we tell it how to sprint.
In the Loop remember we need to increase a number by +1 each time the loop cycles through. We then set this value which increased by +1 to be our new duration for the pulses that will be sent out on our pin PB1. Each loop the value grows so the time the LED is turned on grows longer. This creates our glowing effect.
We use a "for loop" as you can see in the code on lines 26-29.
In Main we create a placeholder for our number, I made an unsigned 8 bit variable and called it 'n'. You can call yours whatever you want and can even make it a signed variable which would let it be positive or negative but that takes up more memory in the chip and we don't need negative numbers in this code so fuggetaboutit.
Damn I am a good teacher!
The first "for loop" in our Loop section of the code on line 26 sets the 'n' variable to be zero, the condition is "as long as 'n' is less than 255" because the 8 bit chip we are using counts from 0-255, then it says to increment 'n' by +1 each time it loops through.
I included a pre-defined delay found in the preamble I called LED_DELAYA for 10 milliseconds.
Then on line 28 we set our output pin PB1's PWM value placeholder OCR1A to equal whatever 'n' is.