9 years ago.

Timer Issues

I have wrote the following program, and when y=1, x<1 and the times value is<4000ms the LED should turn on and it does. However after the 4000ms the LED will turn off, is there any way of keeping the LED lighting until y <1 again.

Thanks

int main() Main Code { while (1) { x=accelerator.read(); Read Accelerator Value y=brake.read(); Read Brake Value printf("Accelerator%.3f \n",x); Print accelerator value printf("Brake%.3f \n",y); Print brake value led = 1; Led-Off

if((x<1)&&(y<1)) If accelerator and brake depressed { printf("both off"); timer1.start(); Start Timer printf("timer starts \n"); } while((x<1)&&(y<1)){ While accelerator and brake depressed x=accelerator.read(); Read Accelerator Value y=brake.read();} Read Brake Value

if ((timer1.read_ms()<4000)&&(y==1)&&(x<1)) If Acc off, Brakes on & Timer under 4 Sec {task1();} Begin Task 1

else if (x==1) { Else if accelerator on task2(); Begin Task 2 } } } void task1(void){ Task 1 - Emergency Braking { led = 0;} LED On } void task2(void) Task 2 - Timer Reset { timer1.reset(); Reset Timer led=1; LED Off }

1 Answer

9 years ago.

Hi Owen,

Your problem come from the condition you set, not from the timer. Indeed, in your current code, the timer is useless as the main loop will run as long as your mbed is powered.

Having the timer.read_ms() < 4000 in your condition with a AND statement makes it turn off after 4 seconds as no all 3 statements are valid.

Here are some suggestions for you. (not tested, just reformated for easier reading. you migth want to us the < <code>>< </code>> brackets around your code next time. (remove the spaces I added to make it visible)

int main(void)
{
    timer1.start();
    timer1.reset();

    //no need to call lef = 1; 2 times in a loop. if you take out the while
    //(which freeze for some time) your lef will be triggered by your tasks.
    //led = 1;
    while (1) {
////////////////////////////problem 1////////////////////////////////////
//This function will hang your mbed until either x OR y are equal to 1.//
//Just remove the while loop and trust your other conditions/////////////
////////////////////////////problematic//////////////////////////////////
        //    while((x<1)&&(y<1)) {
        x=accelerator.read();
        y=brake.read();
        // }
        
        if((x<1)&&(y<1)) {
            printf("both off");
            timer1.start();
            printf("timer starts \n");
        }

////////////////////////////problem 2///////////////////////////////////////
//your condition says that once the timer_ms is over 4000ms, put led to 0.//
//This is where your real problem come from.////////////////////////////////
////////////////////////////problematic/////////////////////////////////////
        //  if ((timer1.read_ms()<4000)&&(y==1)&&(x<1)) {
        if( y == 1 && x < 1 ) {
            task1();
        } else if ( x == 1 ) {
            task2();
        }
    }
}

This should work, but your question was how to make it stop only when x == 1 again. As you seem to conflict a little bit with while loop, I'd suggest using a little "flag" to do what you want. here's what I mean:

bool flag = false; //put the flag to true when the led is enabled

void task1(void)
{
    led = 0;
    flag = false;
}

void task2(void)
{
    timer1.reset();
    led=1;
    flag = true;
}

int main(void)
{
    timer1.start();
    timer1.reset();

    //no need to call lef = 1; 2 times in a loop. if you take out the while
    //(which freeze for some time) your lef will be triggered by your tasks.
    //led = 1;
    while (1) {
        ////////////////////////////problem 1////////////////////////////////////
//This function will hang your mbed until either x OR y are equal to 1.//
//Just remove the while loop and trust your other conditions/////////////
////////////////////////////problematic//////////////////////////////////
        //    while((x<1)&&(y<1)) {
        x=accelerator.read();
        y=brake.read();
        // }

        if((x<1)&&(y<1)) {
            printf("both off");
            timer1.start();
            printf("timer starts \n");
        }

////////////////////////////problem 2///////////////////////////////////////
//your condition says that once the timer_ms is over 4000ms, put led to 0.//
//This is where your real problem come from.////////////////////////////////
////////////////////////////problematic/////////////////////////////////////
        //  if ((timer1.read_ms()<4000)&&(y==1)&&(x<1)) {
        if( flag ) { //if the flag is true, look for y value
        //add led disabling functions here
            if(y < 0) {
                task1();
            }
        } else { //if the flag is false, look for X in order to trigger the led.
        //add LED enabling functions here
            if ( x == 1 ) {
                task2();
            }
        }
    }
}

Flag can be useful. I maybe wrote too much code around it, but it's to show the way it works.

Timer are very usefull if you want to make an action during a certain time, but they are pointless when you wish to do this action until another condition (non-time related).

Hope this helps

Maxim

Hi Maxim,

Thanks for your help on this, the only problem is that I only want to turn on the LED when x <1 && Y=1 and the timer is less than 4 seconds. If this if statement is satisfied and the LED is turned on, I want it remain on until y< 1again. At present the LED will turn off after the 4 seconds.

Many Thanks

Owen

posted by Owen Doran 23 Apr 2015

Hi Owen,

Then it's just switching the conditions. The flag will handle if you have to verify in order to turn the led on or off.

With this code, the only thing that can turn off the LED is if y < 1 like you want it to. After this, you will have to make sure the timer is < 4000 and the variables are back as you wish if you want to repeat the operation.

bool flag = false; //put the flag to true when the led is enabled
 
void task1(void)
{
    led = 0;
    flag = false;
}
 
void task2(void)
{
    timer1.reset();
    led=1;
    flag = true;
}
 
int main(void)
{
    timer1.start();
    timer1.reset();
    while (1) {
        x=accelerator.read();
        y=brake.read();
        // }
 
        if((x<1)&&(y<1)) {
            timer1.reset();
        }
        //  if ((timer1.read_ms()<4000)&&(y==1)&&(x<1)) {
        if( flag == false ) {//flag is set by task1 and task2
            if(x < 1 && y == 1 && timer1.read_ms() < 4000  ) {
                task2();//turn on the led
            }
        } else { 
            if ( y < 1 ) {
                task1();
                //flag is set back to false here which let the other condition re-ligth it if needed.
            }
        }
    }
}

When you start programming, and even when you get used to it, try to put on a sheet of paper your conditions to see if they actually make sens between each other. It greatly helped me a couple years back.

Hope this was useful

Maxim

posted by maxim bolduc 23 Apr 2015