Alternating Blinking LEDs : Building on the Basics with the CORE MCU Framework

Maybe that single blinking LED didn’t exactly turn heads at your last show-and-tell. But what if we took it a step further? Let’s add a second LED and make them blink in an alternating pattern. It might sound like a small upgrade, but if you’re a train enthusiast like me, you’ll start to see how these simple patterns can transform into something much more. Think about those classic railroad crossings with their alternating flashing lights—suddenly, this becomes more than just a blinking light. It’s the beginning of bringing your model train layout to life.

In this project, we’re going to set up alternating blinking LEDs using the PIC16F15313 and the CORE Framework. By building on what you’ve already learned, you’ll see how easy it is to expand a basic setup into something a bit more dynamic. This isn’t just about impressing anyone; it’s about taking control and creating something that sparks a little joy in the process.

Ready to see those LEDs dance? Let’s get started!

First Things First: Setting Up the Circuit

ledblink dual

We’ll begin by putting together a straightforward circuit using a PIC16F15313 microcontroller. It’s a simple setup, but each piece plays a key role in making those LEDs light up just the way we want.

  1. Powering the PIC16F15313: The PIC will be powered by a 5V DC supply. We’ll also add a 100nF capacitor for decoupling, which helps keep the power line smooth and steady, minimizing any unwanted fluctuations. Think of it as a little insurance policy that keeps things running consistently.
  2. Connecting the First LED: We’ll use PortA.0 on the PIC as our first output. It’s connected to a 300-ohm resistor, which then drives the first LED. That resistor is important because it limits the current flowing through the LED, protecting it from burning out while ensuring it glows just the way it should.
  3. Connecting the Second LED: Now we’ll do the same thing for the second LED. This time, we’ll use PortA.1. Again, we’ll place a 300-ohm resistor in line to keep the current in check and make sure the LED lights up safely.

When you put it all together, you have two LEDs connected to separate pins on the microcontroller, each ready to blink in sequence. Simple components, working together, showing just how easy it can be to create a tangible, visible result with just a few parts. And with a little code magic, we’ll bring them to life, creating a pattern that’s more than just lights—it’s the foundation of something much bigger!

Now, Let’s Dive into the Code

Here’s where the real magic happens—translating our simple circuit setup into a sequence of commands that brings it all to life. Below is the code that makes those LEDs alternate, using the PIC16F15313 along with the CORE MCU Framework. The framework handles the low-level configuration, so we can focus on the fun part: making things blink!

/****************************************************************************
* Title                 :    Dual Alternating LEDS
* Filename              :  alternating_leds.c
* Author                :   Jamie Starling
* Origin Date           :   2024/10/02
* Version               :   1.0.0
* Compiler              :   XC8 
* Target                :    
* Copyright             :   Jamie Starling
* All Rights Reserved
*
* THIS SOFTWARE IS PROVIDED BY JAMIE STARLING "AS IS" AND ANY EXPRESSED
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL JAMIE STARLING OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/

/******************************************************************************
*                     LICENSED FOR NON-COMMERCIAL USE
*                Visit https://jamiestarling.com/corelicense
*                           for details 
*******************************************************************************/

/******************************************************************************
* Includes
*******************************************************************************/
#include "core16F/core16F.h" //Include Core MCU Functions


/******************************************************************************
* Functions
*******************************************************************************/
void main(void)
{
  /*Setup*/
  /*Initialize for the Core8 System   */
  CORE.Initialize(); //
  
  GPIO.ModeSet(PORTA_0,OUTPUT);  /*Set PORTA.0 to Output*/
  GPIO.ModeSet(PORTA_1,OUTPUT);  /*Set PORTA.1 to Output*/
  
  /*Set the Initial Pattern*/
  GPIO.PinWrite(PORTA_0,ON);  /*LED on PORTA.0 ON*/
  GPIO.PinWrite(PORTA_1,OFF); /*LED on PORTA.1 OFF*/
  
  while(1) //Program loop
    {      
      CORE.Delay_MS(1000);    //One Second Delay
      GPIO.PinToggle(PORTA_0); //Toggles LED on PORTA_0
      GPIO.PinToggle(PORTA_1); //Toggles LED on PORTA_1      
    }
}




/*** End of File **************************************************************/

What’s Happening Here?

Let’s break down each part of the code and see what it’s doing:

  1. CORE Initialization: The CORE.Initialize() call sets up the internal configuration for the microcontroller. It’s like flipping the power switch and getting everything ready behind the scenes so we can start .
  2. Setting Up the Pins:
    • GPIO.ModeSet(PORTA_0, OUTPUT); configures PortA.0 as an output pin.
    • GPIO.ModeSet(PORTA_1, OUTPUT); does the same for PortA.1.
    This tells the microcontroller that we’ll be using these pins to send signals out—specifically, to control the LEDs.
  3. Establishing the Initial State:
    • GPIO.PinWrite(PORTA_0, ON); turns on the first LED connected to PortA.0.
    • GPIO.PinWrite(PORTA_1, OFF); makes sure the second LED (PortA.1) is off to start.
    Setting up an initial state is a good habit to get into. This way, you always know exactly what your program is doing from the very first moment.
  4. The Endless Loop: Inside the while(1) loop, the microcontroller keeps running the same sequence forever:
    • CORE.Delay_MS(1000); pauses for one second.
    • GPIO.PinToggle(PORTA_0); flips the state of the first LED—if it’s on, it turns off; if it’s off, it turns on.
    • GPIO.PinToggle(PORTA_1); does the same for the second LED.

What Does It All Look Like?

With the circuit set up and the code running, you’ll see the LEDs take turns blinking—one turning on while the other turns off, over and over. It’s a simple pattern, but with just a bit of code, you can already start to see how this could become a part of something bigger.

Think about those alternating red lights at a railroad crossing, or an emergency vehicle light bar. It’s these small building blocks that form the foundation of more complex patterns and effects.

Why Start Here?

You might wonder why we’re focusing on something as basic as blinking LEDs. The answer is simple: understanding the fundamentals is key. Once you grasp the core concepts, you can scale them up to more complex designs, chaining patterns together or incorporating inputs to control when and how these lights blink.

With each small project, you’re adding a new tool to your toolbox—building confidence in both your hardware and your coding skills. From here, you could easily start experimenting: What happens if you change the delay? Can you make one LED blink twice as fast as the other? Or add more LEDs and create a pattern that loops through each in turn?

Each tweak is a step toward mastering your craft, so take your time and enjoy the process!

A Dynamic Pattern Generator

With just a few lines of code, you’ve transformed a bare microcontroller into a dynamic pattern generator. The CORE MCU Framework makes it easy to get started, allowing you to focus on the fun parts—like seeing your ideas come to life, one blink at a time.

So whether it’s just for the joy of making something work or the first step toward a more complex project, take pride in these little wins. Because in the end, that’s what makes all the difference. Happy tinkering!

Core MCU Framework : Main Doc Page

Core MCU Framework Versions : Supported Devices


Have a Project or Idea!?

Seeking Bespoke Technology Solutions?

jamie@jamiestarling.com


Pin It on Pinterest

Share This