Quote:
|
Originally Posted by teh_pwnerer795
how do i round? i remember doing it in java... not suer if its the same in C
|
What are you trying to round? If you're using int variables, there is no decimal part and all math operations will result in truncation of the decimal (i.e. 1/4 => 0, 5/2 => 2).
If you really needed the decimal part, you could use the float type instead of int. There are some problems with doing this
discussed here, and I wouldn't really recommend doing this on the RC.
EHaskins offered up some good suggestions, but there is a slight annoyance with it. What happens if you have a 10 step time based routine and you need to change the first duration to be a little longer or shorter? You have to change them all.
One way to fix it would be to use constants, and make them relative to each other.
Code:
#define AUTO_STEP1_END (10)
#define AUTO_STEP2_END (AUTO_DURATION_STEP1 + 5)
.....
if(i <= AUTO_STEP1_END)
{
....
}
else if(i <= AUTO_STEP2_END)
{
...
}
...
If you want to make things a little more advanced, you could do something like this.
Code:
#define NOT_DONE 0
#define DONE 1
...
#define MAX_AUTO_STEP 3
...
enum
{
PROG_STEP1,
PROG_STEP2,
PROG_STEP3,
PROG_STEP_LAST = PROG_STEP2,
};
...
static int prog_done = NOT_DONE;
static int prog_step = 0;
...
int ret;
if(prog_step < PROG_STEP_LAST)
{
switch prog_step
{
case PROG_STEP1:
ret = do_step1(); // These function names could be more specific
break;
case PROG_STEP2:
ret = do_step2(); // These function names could be more specific
break;
case PROG_STEP3:
ret = do_step3(); // These function names could be more specific
break;
default:
// Bad step number, exit now
prog_step = PROG_STEP_LAST;
break;
}
if(ret == DONE)
{
// Step is complete, move on
prog_step++;
}
}
else
{
// Set all pwms to 127 to terminate the run
}
....
// Then you would define your program step functions to do what you needed
int do_step1(void)
{
static int i = 0;
int status = NOT_DONE;
if(i >= 40)
{
// Set PWM values here
}
else
{
status = DONE;
}
return stats;
}
int do_step2(void)
{
static int i = 0;
int status = NOT_DONE;
if(i >= 30)
{
// Set PWM values here
}
else
{
status = DONE;
}
return stats;
}
int do_step3(void)
{
.....
}
The benefit to this is maintainability. Each step is a self-containted program of its own residing within a function called from your autonomous loop. This gives you the advantage of not relying on absolute time. Each step can know how many loops to run for and report that it's done.
Here's another perk. If you want to add a delay between step 2 and 3, you could change the enum to have PROG_STEP_2A between PROG_STEP_2 and 3. Then, in your switch, you could do something like
Code:
...
case PROG_STEP_2A:
ret = do_wait(100);
break;
...
int do_wait(int loops)
{
static int i = 0;
int ret = NOT_DONE;
if(i >= loops)
{
i = 0; // Leave the loop counter ready to go the next time.
ret = DONE;
}
else
{
// Turn PWMs off
i++;
}
return ret;
}
Now you have a nice reusable chunk of code that turns the motors off and waits for a certain number of loops before advancing. If all of a sudden you don't need that step anymore, you can simply comment you the function call and set ret to DONE. You burn a loop, but that shouldn't matter in most cases.
Code:
...
case PROG_STEP_2A:
ret = DONE;
// ret = do_wait(100);
break;
...