Why LED is not turning OFF - 8051 Timers

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
My intention is to show to you practical approach from setting goal (toggling led with each button press with debouncing), drawing flowchart, writing code and testing it. Next goal will be non-blocking debounce routine with remembering different states which has more practical for real time systems. But before we must reach this first goal. If you want to learn how embedded systems work, you must be more consistent. Your code in #152 is not LED toggling routine, it is led blinking on trigger routine.
@trebla I have understood how the LED will toggle at the each press of a push button. My program is working but it has a problem that there is too much denounce time. I am working on simulator to get 20ms - 30 ms debounc time.

I'll post the code when I have the exact debounc time
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Working code on hardware
C:
#include<reg51.h>

sbit LED = P1^0;
sbit Button = P0^7;

void Wait (long unsigned  int DelayTime)    /* Function to generate delay time */
{
    unsigned long int Count = 0;

    for (Count = 0; Count < DelayTime; Count++)
    {
        /* Do nothing */
    }
}

void main (void)
{
      P0 =0x80;
    P3 =0x00;
    P1 =0x00;
    P2 =0x00;
    

  while(1) //infinite loop
  {
    if(Button == 0) //If Button pressed
    {
             LED =~ LED;
            
       Wait(450); //debounce 24ms
            
         if(Button == 0) //If Button pressed
            {         
               Wait(450); //debounce 24ms

            }     
     }
  }
}
I am not confirmed that I am getting 24ms of debounce time but it seems I am getting 24ms

1599753215548.png
 

trebla

Joined Jun 29, 2019
542
Look at flowchart and compare your code against it:

Check if button pressed = code line 26
Toggle LED = code line 28
Delay for press debounce = code line 30

Looks good so far but:
Check if button released - if not, check again tasks are not working as we want because:
Mistake 1: you check if button pressed, but if button is hold down, then LED is toggled again after last delay (line 34) and first button check (line 26)
Mistake 2: if you change it to button released checking, but button is still pressed then delay in line 34 is not executed and LED is toggled again in line 26.

I asked you about using while() loop for checking button release, but you are trying do this with if() statement which is for this type debounce routine somewhat harder and demands adding state flag variables. We will do it later but now is simpler solution to use :

line 26: while(Button == Pressed); // wait until button released
next line: Wait(450); // button release debounce delay

Try it and see how it works.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Look at flowchart and compare your code against it:
code for flow chart
C:
#include<reg51.h>

sbit LED = P1^0;
sbit Button = P0^7;

void Wait (long unsigned  int DelayTime)    /* Function to generate delay time */
{
    unsigned long int Count = 0;

    for (Count = 0; Count < DelayTime; Count++)
    {
        /* Do nothing */
    }
}

void main (void)
{
      P0 =0x80;
    P3 =0x00;
    P1 =0x00;
    P2 =0x00;
  

  while(1) //infinite loop
  {
    while(Button == 0); //If Button pressed

        LED =~ LED;
          
    Wait(450); //debounce 24ms
          
    while(Button == 0); //If Button pressed
  
    Wait(450); //debounce 24ms

  }
}
When I run the code if button is hold down, then LED is toggled and When I press the button then LED is toggled for few ms

Edit: correction checking for 0
 
Last edited:

trebla

Joined Jun 29, 2019
542
In line 26 you want to wait until button is first time pressed, this means that you dont want to toggle LED until button is not pressed and you must write in line 26:

while(Button != 0); // wait until button pressed
 

trebla

Joined Jun 29, 2019
542
while() loop runs until equation in parentheses remains true and exits loop when false. If equation in parentheses returns a nonzero value then in C it means true condition, if returned value is 0 then it means false condition.

For example you can use while(1) loop for keep your program loop run forever because 1 represents allways true condition and nothing except some memory error can change it. If you write while(0) loop to anything inside this loop will be never executed.
And because this is while(check condition); empty-body loop very useful to put program wait until this "check condition" goes false and program can continue.

This method has of course absolutely blocking nature and can be used only when we must absolutely wait some conditions passed until program can continue, for example in hardware initialization/startup sequence.
 

djsfantasi

Joined Apr 11, 2010
9,156
BTW, you have several data points for the input to your wait() function and the resultant delay in ms. You should be able to derive a linear equation for any input value and the resultant delay. Either you can use this equation to calculate the input value for any given delay... Or modify your function to input a delay in ms and calculate the number of iterations for your loop to obtain that delay.

I’d provide that function, but you can code it yourself since it’s my bedtime and I’m half-asleep.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
In line 26 you want to wait until button is first time pressed, this means that you dont want to toggle LED until button is not pressed and you must write in line 26:

while(Button != 0); // wait until button pressed
I would like to apologize for being too late because I had some family issues due to which I could not come back but I'm ready now to move forward

C:
#include<reg51.h>

sbit LED = P1^0;
sbit Button = P0^7;

void Wait (long unsigned  int DelayTime)    /* Function to generate delay time */
{
    unsigned long int Count = 0;

    for (Count = 0; Count < DelayTime; Count++)
    {
        /* Do nothing */
    }
}

void main (void)
{
    P0 =0x80;
    P3 =0x00;
    P1 =0x00;
    P2 =0x00;
 

  while(1) //infinite loop
  {
    while(Button != 0); // wait until button pressed

    LED =~ LED;
          
    Wait(450); //debounce 24ms
          
    while(Button == 0); //If Button pressed
 
    Wait(450); //debounce 24ms

  }
}
When I hold button down continuously , LED doesn't change state that's what we want
 

trebla

Joined Jun 29, 2019
542
Ok, now we want the button debounce routine that is not blocking because in real time systems we have multiple processes who need to be checked too. In ideal case we want to be waste processor time for checking state changes only and not waiting after some event happening.

In the above code (#163) we are waiting and blocking another code to run:
1.until button pressed
2.after button press in debounce delay
3.until button released
4.after button release in debounce delay

The first waiting task can be eliminated with wrapping this debounce routine to if() statement body as you did at the beginning this tread but we cannot eliminate another blocking components (2, 3 and 4) in debounce routine this way.

If we want make non-blocking debounce routine, we must make these componets independently checkable, this means we must remember in which current state our button debounce routine is. Button has two states but button checking/debouncing routine has more states.

You can try to figure out these states.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Ok, now we want the button debounce routine that is not blocking because in real time systems we have multiple processes who need to be checked too. In ideal case we want to be waste processor time for checking state changes only and not waiting after some event happening.

You can try to figure out these states.
In this routine I am checking the status of button
C:
 int Button_Check()
{
     int status = Button_Not_Pressed;
    
     if(Button == 0 ) //If Button pressed
    {
       Wait(450); //debounce 40ms
            
         if(Button == 0) //If Button pressed again
            {       
              return Button_Pressed;
            }   
     }
        return Button_Not_Pressed;
 }
 

jpanhalt

Joined Jan 18, 2008
11,087
A push button SPST switch, resistor, and LED will so the same thing. No microcontroller required -- in reference to your new thread on sensors.
 

trebla

Joined Jun 29, 2019
542
If you start writing code without correct program flow or state diagram you ended up with big mess. Try to draw state diagram for debounce routines point of view.
 

trebla

Joined Jun 29, 2019
542
Try to imagine MCUs perception for outside events. You are sitting in the dark and count your heartbeats. Suddenly you see light on one port, you mark this event, toggle predetermined output pin and set goal for next count. Light flashes rapidly at the beginning (your perception rate is million times per second) and then later stays steady on for a while. But you are doing other things now, until noticed the counting goal is reached, marked this event and checked is the light still on, if yes, then you do again some other things, if not then you mark this event and set goal for next count. You are doing other things again and meanwhile noticed the counting goal is reached (again), marked light event to be cleared until you see it again.

For our debounce routine, these 'light' events are possible system states and for handling button debounce we need remember the current state. Try to draw state diagram with all the above mentioned states.
 

trebla

Joined Jun 29, 2019
542
Your state diagram represents two system states, one for LED not toggling if button not pressed and second for LED toggling continuosly if button pressed and waiting button to pressed same time, which can never happen in same time. This state diagram presents fully blocking routine which has no output.

We need real time processing system without any waiting states. We have input events caused by the outside world and we need process them, LED toggling is an output for debounce routine, instead LED we can set signal for another process input. Just think in which state is our debounce routine before button press and during debounce processing. Hint: i see at least 5 states.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
We need real time processing system without any waiting states. We have input events caused by the outside world and we need process them, LED toggling is an output for debounce routine, instead LED we can set signal for another process input. Just think in which state is our debounce routine before button press and during debounce processing. Hint: i see at least 5 states.
Ok here is my new state diagram with button state
 

Attachments

trebla

Joined Jun 29, 2019
542
You focus on the button, button has only two states but for reading this button without errors we need debounce routine and this routine has at least 5 states. LED toggling is a different process or signal to another routine. You can derive these states from the flowchart you posted in #83. Focus on the debounce routine states and take the button as the input signal for this routine.
 
Top