Flashing Three LED's

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
I'm trying to write general non blocking code logic for three LED, Not for specific uC and compiler. #There are 3 LED, numbered 1, 2 and 3.

Description of problem
  • Flash LED 1 once for 200 ms time period every 250 ms
  • Flash LED 2 once for 400 ms time period every 500 ms
  • Flash LED 3 once for 600 ms time period every 750 ms
Timer interrupt generates every 10 ms

Here is my planning with pseudocode. I'm stuck with LED flashing function logic and I don't have any idea how do it
C:
LED1
LED2
LED3

#define  True          1
#define  SET           1
#define  RESET         0
#define  OFF           0
#define  CLEAR         0

void main ()
{ // main start from here
    LED1 = OFF ;
    LED2 = OFF ;
    LED3 = OFF ;

    unit8_t Time_Flag = CLEAR;

    unit8_t LED1_Deadline_Time =  CLEAR ;
    unit8_t LED2_Deadline_Time =  CLEAR ;
    unit8_t LED3_Deadline_Time =  CLEAR ;

    while ( True )
    { // while Loop start from here
      if (Time_Flag == SET)
      {
        if ( LED1_Deadline_Time == 200 )  // Always check deadline time for LED1 if match
        {
            LED1_Flashing();
            LED1_Deadline_Time = RESET;
        }
   
        LED1_Deadline_Time++;
   
        if ( LED2_Deadline_Time == 400 )  // Always check deadline time for LED2 if match
        {
            LED2_Flashing();
            LED2_Deadline_Time = RESET;
        }
   
        LED2_Deadline_Time++;
   
        if ( LED3_Deadline_Time == 700 ) // Always check deadline time for LED1 if match
        {
            LED3_Flashing();
            LED3_Deadline_Time = RESET;
        }
   
        LED3_Deadline_Time++;
      }    
   
      Time_Flag = CLEAR ;
 
    } //while Loop End here

}// main End here

// interrupt every 10ms
void ISR_Timer_Interrupt ()
{
    if ( T1IF = SET )
    {
        Time_Flag = SET;
        T1IF = CLEAR;
    }
}
 
Last edited:

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
hi S45,
You have not stated which target MCU you are planning to use.?
I am planning for pic micro, But right now I am trying to solve the problem in plain C programming. I have provided my logic in previous post.

This link shows an Arduino method, it may suggest a solution.

E
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
I am not getting any idea from given link. Can you explain logic to solve my problem? Cause I'm stuck somewhere in the middle in my own logic so I'm looking for help
 

djsfantasi

Joined Apr 11, 2010
9,237
I am planning for pic micro, But right now I am trying to solve the problem in plain C programming. I have provided my logic in previous post.


I am not getting any idea from given link. Can you explain logic to solve my problem? Cause I'm stuck somewhere in the middle in my own logic so I'm looking for help
First, have you coded before?

Since you’re going to have to learn, reading other’s code is a good learning technique.

Use the aforementioned Arduino Reference site to learn what each statement does for any statement you haven’t seen before. Then, write out in English a description of how the program works. Concentrate on the main code… the rest will come later.
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
Use the aforementioned Arduino Reference site to learn what each statement does for any statement you haven’t seen before. Then, write out in English a description of how the program works. Concentrate on the main code… the rest will come later.
I have successfully written the code for the pic. I don't think it would be a good idea to work on multiple micros at same time.

I have already uploaded my logic in post #1. I am sure that my logic gives a basic idea to work on any microcontroller.

For now the problem is neither arduino nor pic nor complete code. i am just developing a program to solve the problem where i am stuck . may be someone help on this so it would be good to understand

summary : I need help developing the logic of the program
 
Last edited:

ericgibbs

Joined Jan 29, 2010
21,395
Here is my planning with pseudocode. I'm stuck with LED flashing function logic and I don't have any idea how do it
Hi,
How can you fully prove your Logic if you don't check it on the complete range of MCU's.?

You stated this as a specification:

Description of problem
  • Flash LED 1 once for 200 ms time period every 250 ms
  • Flash LED 2 once for 400 ms time period every 500 ms
  • Flash LED 3 once for 600 ms time period every 750 ms
Timer interrupt generates every 10 ms

Most programmers could write Code using their preferred language and MCU, within a few minutes, that would carry out the above actions.

The reason you are stuck in finding a universal answer, is that you have not really defined the problem.

ie: I'm trying to write general non blocking code logic for three LED

E
 

click_here

Joined Sep 22, 2020
548
The easiest way to do this is to use 3 switch statements - Each switch handles a different LED

This is a great way for a beginner to implement multitasking for simple control programs :)

I've made a skeleton program that you can build on - Fair warning though, I've just typed this out on my phone, check for bugs!

Code:
#include <stdbool.h>
#include <stdio.h>

enum ledState
{
    LED_ON,
    LED_OFF      
};

enum ledList
{
    LED1,
    LED2,
    LED3
};
  
// Updated in interrupt;
volatile bool Tick;
  
// TODO - ISR 10mS that switches "Tick" to true 

// Turns LED outputs on/off    
void updateOutput(enum ledList ledNumber, enum ledState state)
{
    // TODO - Hardware specific code for outputs
}

int main(void) 
{
    // One tick = 10mS
    const unsigned int led1OnTicks = 20;
    const unsigned int led1OffTicks = 25;
    
    const unsigned int led2OnTicks = 40;
    const unsigned int led2OffTicks = 50;
    
    const unsigned int led3OnTicks = 60;
    const unsigned int led3OffTicks = 75;
    
    enum ledState led1 = LED_OFF, led2 = LED_OFF, led3 = LED_OFF;
    
    int led1Ticks = led1OffTicks, led2Ticks = led2OffTicks, led3Ticks = led1OffTicks;
    
    while(1)
    {
        // blocking can be changed to more LED states if needed 
        while(Tick == false)
        {
            continue;
        }
        
        Tick = false;
        
        switch(led1)
        {
            case LED_OFF:
            
                if(led1Ticks-- == 0)
                {
                    led1Ticks = led1OnTicks;
                    led1 = LED_ON;
            
                    updateOutput(LED1, LED_ON);
                }
                break;
            
            case LED_ON:
              
                if(led1Ticks-- == 0)
                {
                    led1Ticks = led1OffTicks;
                    led1 = LED_OFF;
            
                    updateOutput(LED1, LED_OFF);
                }
                break;
        }
        
        switch(led2)
        {
            case LED_OFF:
            
                if(led2Ticks-- == 0)
                {
                    led2Ticks = led2OnTicks;
                    led2 = LED_ON;
            
                    updateOutput(LED2, LED_ON);
                }
                break;
            
            case LED_ON:
              
                if(led2Ticks-- == 0)
                {
                    led2Ticks = led2OffTicks;
                    led2 = LED_OFF;
            
                    updateOutput(LED2, LED_OFF);
                }
                break;
        }
        
        switch(led3)
        {
            case LED_OFF:
            
                if(led3Ticks-- == 0)
                {
                    led3Ticks = led3OnTicks;
                    led3 = LED_ON;
            
                    updateOutput(LED3, LED_ON);
                }
                break;
            
            case LED_ON:
              
                if(led3Ticks-- == 0)
                {
                    led3Ticks = led3OffTicks;
                    led3 = LED_OFF;
            
                    updateOutput(LED3, LED_OFF);
                }
            
                break;
        }
    }
}
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
The easiest way to do this is to use 3 switch statements - Each switch handles a different LED

This is a great way for a beginner to implement multitasking for simple control programs
Thanks for understanding my problem. i am a beginner i use pseudocode before write the program to get idea. This program can be written in many ways like polling, interrupt, switch case statement.

I just want to use interrupt for now without switch case. Do you have any idea how to solve it with interrupt?
 

djsfantasi

Joined Apr 11, 2010
9,237
Thanks for understanding my problem. i am a beginner i use pseudocode before write the program to get idea. This program can be written in many ways like polling, interrupt, switch case statement.

I just want to use interrupt for now without switch case. Do you have any idea how to solve it with interrupt?
?

@click_here ’s program does use interrupts. The switch|case structure is the code necessary to turn on/off the LEDs based on the timer interrupt.

It does NOT show what the ISR routine does, but that code depends on the specific MCU. As you asked for a solution that doesn’t depend on the MCU, that’s as complete a solution which can be provided given that constraint.

To complete the program, an ISR must be written for a specific MCU. Typically an ISR disables interrupts, sets a flag or executes some short non-blocking code and finally re-enables interrupts.

If I understand click_here’s code correctly, in the short non-blocking code, the value of TICK should be set to TRUE. The rest is MCU specific.
 
Last edited:

ronsimpson

Joined Oct 7, 2019
4,649
Description of problem
  • Flash LED 1 once for 200 ms time period every 250 ms
  • Flash LED 2 once for 400 ms time period every 500 ms
  • Flash LED 3 once for 600 ms time period every 750 ms
Timer interrupt generates every 10 ms
LED1 on for 10 interrupts out of 25.
LED2 on for 40 interrupts out of 50
LED3 on for 60 interrupts out of 75
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
LED1 on for 10 interrupts out of 25.
LED2 on for 40 interrupts out of 50
LED3 on for 60 interrupts out of 75
I don't know what your point is and why you have reduced the on off time of LED. I think your on off time is too short for a human to see the LED flashing. That's why I used timing 200ms, 400ms and 600ms in my example
 
Last edited:

MrChips

Joined Oct 2, 2009
34,629
What you have written is computer code, not pseudo code.
Pseudo code should be written in plain language.

I would solve the problem by creating three timers, one for each output.

Interrupt code:
increment timer1
increment timer2
increment timer3

Main code:
Start:
timer1 = 0
timer2 = 0
timer3 = 0
LED1 = ON
LED2 = ON
LED3 = ON

Loop:
if timer1 is equal to or greater than 20, LED1 = OFF
if timer1 is equal to or greater than 25, LED1 = ON, timer1 = 0

if timer2 is equal to or greater than 40, LED2 = OFF
if timer2 is equal to or greater than 50, LED2 = ON, timer2 = 0

if timer3 is equal to or greater than 60, LED3 = OFF
if timer3 is equal to or greater than 75, LED3 = ON, timer3 = 0

Go to Loop
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
I would solve the problem by creating three timers, one for each output.
Your description makes sense to me. I was using three timers like you

Does the below code match with your @MrChips description?

C:
LED1
LED2
LED3

#define  True          1
#define  SET           1
#define  RESET         0
#define  OFF           0
#define  CLEAR         0

void main ()
{ // main start from here
    LED1 = ON ;
    LED2 = ON ;
    LED3 = ON ;
   
   volatile    unit8_t Timer1 =  CLEAR ;
   volatile    unit8_t Timer2 =  CLEAR ;
   volatile    unit8_t Timer3 =  CLEAR ;
   
    Init_Port_Pins ();
    Set_Timer ();
   
    while ( True )
    {

        if (( Timer1 == 200 )|| ( Timer1 > 200 ))
        {
            LED = OFF ;
        }
       
        if (( Timer1 == 250 )|| ( Timer1 > 250 ))
        {
            LED1 = ON ;
            Timer1 = RESET;
        }
       
        if (( Timer2 == 400 )|| ( Timer1 > 400 ))
        {
            LED2 = OFF ;
        }
       
        if (( Timer1 == 250 )|| ( Timer1 > 250 ))
        {
            LED2 = ON ;
            Timer2 = RESET;
        }
       
        if (( Timer3 == 600 )|| ( Timer3 > 600 ))
        {
            LED3 = OFF ;
        }
       
        if (( Timer3 == 700 )|| ( Timer3 > 700 ))
        {
            LED3 = ON ;
            Timer3 = RESET;
        }
               
    }
   
}

// interrupt every 10ms
void ISR_Timer_Interrupt ()
{
    if ( T1IF = SET )
    {
      Timer1++ ;
      Timer2++ ;
      Timer3++ ;
     
      T1IF = CLEAR;
    }
}
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,237
I don't know what your point is and why you have reduced the on off time of LED. I think your on off time is too short for a human to see the LED flashing. That's why I used timing 200ms, 400ms and 600ms in my example
He is explaining how to use the timer interrupts. Note he doesn’t say 10ms, he says 10 interrupts.

If an interrupt occurs every 10ms, how long will 10 interrupts take?

His explanation takes that into account. If you multiply each quantity of interrupts by 10 ms/interrupt, you’ll see his table of events implement the same times in ms that you’re trying to achieve.
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
He is explaining how to use the timer interrupts. Note he doesn’t say 10ms, he says 10 interrupts.

If an interrupt occurs every 10ms, how long will 10 interrupts take?
one interrupt takes 10 milliseconds so 10 interrupt will takes 100 milliseconds

LED1 on for 10 interrupts out of 25.
I was only confused by abov line. 10 interrupt will takes 100 milliseconds. while actual requirement was of 20 interrupts Look at post #1

I understand what he had to say
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
To save me from trouble, I have created a table of the whole process with new timings values. I will write code to achieve the goal mentioned in the table

interrupt occurs every 10ms

LED 1 change state every 100ms
LED 2 change state every 200ms
LED 3 change state every 300ms

C:
starting LED1 = ON, LED2 = ON, LED3 = ON
1 ---- >
2 ---- >
3 ---- >
4 ---- >
5 ---- >
6 ---- >
7 ---- >
8 ---- >
9 ---- >
10---- > LED1 = OFF
11---- >
12---- >
13---- >
14---- >
15---- >
16---- >
17---- >
18---- >
19---- >
20---- > LED1 = ON, LED2 = OFF,
21---- >
22---- >
23---- >
24---- >
25---- >
26---- >
27---- >
28---- >
29---- >
30---- > LED1 = OFF, LED3 = OFF
31---- >
32---- >
33---- >
34---- >
35---- >
36---- >
37---- >
38---- >
39---- >
40---- > LED1 = ON, LED2 = ON
41---- >
42---- >
43---- >
44---- >
45---- >
46---- >
47---- >
48---- >
49---- >
50---- > LED1 = OFF
51---- >
52---- >
53---- >
54---- >
55---- >
56---- >
57---- >
58---- >
59---- >
60---- > LED1 = ON, LED2 = OFF, LED3 = ON
61---- >
62---- >
63---- >
64---- >
65---- >
66---- >
67---- >
68---- >
69---- >
70---- > LED1 = OFF
continue
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
This is my possible plan that should work for Table
C:
LED1
LED2
LED3

#define  True          1
#define  SET           1
#define  RESET         0
#define  OFF           0
#define  CLEAR         0

void main ()
{ // main start from here
    LED1 = ON ;
    LED2 = ON ;
    LED3 = ON ;
    
   volatile  unit8_t Timer1 =  0 ;
   volatile  unit8_t Timer2 =  0 ;
   volatile  unit8_t Timer3 =  0 ;
    
    
    while ( True )
    {

        if ( Timer1 == 100 )
        {
            LED1 = OFF ;
            Timer1 = 0;
        }
        
        if ( Timer1 > 200 )
        {
            LED2 = ON ;
            
        }
        
        if ( Timer2 == 200 )
        {
            LED = OFF ;
            Timer2 = 0;
        }
        
        if ( Timer2 > 200 )
        {
            LED2 = ON ;
        }
        
        if ( Timer3 == 300 )
        {
            LED3 = OFF ;
            Timer3 = 0;
        }
        
        if ( Timer3 > 300 )
        {
            LED3 = ON ;       
        }

    }
    
}

// interrupt every 10ms
void ISR_Timer_Interrupt ()
{
    if ( T1IF = SET )
    {
      Timer1++ ;
      Timer2++ ;
      Timer3++ ;
      
      T1IF = CLEAR;
    }
}
 
Top