Timers and Such

I’ve forgotten most of the C that I learned a few years ago, and my mind has been clouded with the InteractiveC commands that we use in my robotics class (stupid LEGO RCX). I know about incrementing timers and doing, for example:

 timer1++;
if (timer1 < 200){
blah blah;
}

My question is does a C command exist that is the equivalent of InteractiveC’s “sleep()” function? We want to have a dead reckoning backup and it would be a lot easier for me to train newbies if we could do the following instead of the former, since they already know how to write those type of programs.


pwm13 = pwm14 = 167;
pwm14 = pwm15 = 87;
*sleep(2.0);* //drive forward for 2 seconds
pwm07 = 205;
*sleep(.5);* //raise arm
blah blah

Is that possible or am I just out of luck with doing things the easy way?

You have full control over the code that gets installed in the user processor. The good news is that you can do pretty much whatever you want. The bad news is, you can do pretty much whatever you want.

It appears that you are probably wanting to do this for autonomous mode, but the same thing will work for both.

Structure your code so that it is state driven and always exits. Whether in autonomous or teleoperated, setup your statemachine code to run every SPIData receive event (~38Hz).

You can then setup timer’s like this:



    if (TimerDrive) {  // if timer running
      if (!(--TimerDrive)) {  // decrement one tick, and when it hits zero
         // do whatever you need to do to advance to the next step in your state machine
     }

   }

   if (TimerSomethingElse) {  // if timer running
     if (!(TimerSomethingElse)) {  // decrement one tick, and when it hits zero
        // do something else
    }
  }
 

If you really do want to impliment a sleep function, and if this is for autonomous, keep in mind how the default autonomous mode software is structured, and make sure you’ll exit at the proper time… in other words, you’ll probably need to sprinkle tests at each step along the way.

That said, to impliment a sleep function, I’d suggest setting up one of the unused hardware timers to interrupt and reload at rate equal to whatever you need your timer resolution to be, say 100ms.

In the interrupt service routine, in addition to servicing the interrupt, do this:



   if (TimerSleep) {
     --TimerSleep;
   }


Then your sleep function can be setup like this:



volatile unsigned char TimerSleep;

void Sleep(unsigned char timer) {

   TimerSleep = timer;

   while (TimerSleep);

}


If you need more than 8 bits of dynamic range for your timer and move up to a 16 or 32 bit value, then you should disable interrupts, move the TimerSleep variable into a local temp, re-enable interrupts, test the local variable, and loop until it times out.

The protection is necessary because the interrupt routine would update one byte of the variable at a time, and it creates a critical region for your foreground test.

Okay, I believe I understand your coding, I just want to make sure. If I put in the last snippet of code somewhere in the program, will I be able to call the Sleep function the way I do in InteractiveC as seen in my second example?

If not, then do I put my actions inside the while (TimerSleep); ?

Overall, I’m recommending that you do not construct your code to use a sleep() type of programming approach because of the potential negative implications in doing so, but none the less provided the pointer on how to impliment it if you chose to go down that path. If you aren’t comfortable setting up a hardware timer and writing an interrupt service routine to handle timers in the background, then this probably isn’t a path you should pursue if this is something you need to have working in the next 24 hours.

I’m also not familar with InteractiveC nor was I able to find documentation that seemed to be directly relevant. A quick search of CD for ‘InteractiveC’ turned up one other post from 2002, so Im unclear on exactly what it is you are using.

One document I did find leads me to believe that it would have its own function libraries, and provides some level of multi-tasking. I saw a reference to a msleep() function which will sleep for the specified number of milli-seconds, but I’m not sure if what you are using also has this function included.

Whenever you have a multi-tasking in use, it is normal for any user written interrupt service routines to call O/S interrupt entry and exit functions to save additional registers or memory that the O/S may need to protect.

…anyway, if you can provide a URL pointer to the documentation I’d be glad to look at it and comment further, but right now I’m really hesitant to provide any advice because it may or may not be valid advice for your development environment.

You might want to investigate using WPILib. You can use a function like sleep() (except it’s called wait()) there because it handles things differently. See the bottom of page 50 of the manual (pdf). More information is available in the WPILib section of this forum.

For someone coming from a InteractiveC background it might be much more familiar.

That looks like a good suggestion.

I suppose the other thing that could be suggested here is that if a true stall of all code execution is really what is desired, and precison wasn’t a primary concern, that a simple FOR/NEXT loop could be setup to approximate the correct delay.



#define LOOPTIME  50   // emperically choose a number that provides the desired timer resultion

void Sleep(unsigned int timer) {

unsigned int i;

    while(timer--) {
        for (i=0;i<LOOPTIME;i++);
    }

}