I made this exact same mistake when I first started FRC Programming. What you need to realize is that the architecture of PC Terminal-style programming (When you write a program in C that runs in a black DOS-style window) and the architecture of microcontroller programming is inherently different.
When you write a program in C to run in a DOS-style terminal window, everything executes linearly. The program starts at main() and when it gets to the end, the program terminates. This fact doesn’t change, but there’s a lot more going onin the RC that just what you write. In reality, 90% of what the RC is actually doing is being done in the background, and you don’t ever have to deal with it.
You may not have programmed it, but you know how the OI and the RC communicate through the Radio modems, and how you can program the copper pins on the RC through the PWM and Digial IO and Analog Input variables in the code? All of that stuff is being controlled within the code, primarily by the Getdata() and Putdata() routines which you may have seen and been warned not to mess with.
It probably seems to you like the code variables represent what’s going on in the hardware at the exact moment you look at them, and that when you change one of these variables, the hardware immediately changes what it’s doing. But it only seems that way because Getdata() and Putdata() are being called roughly 38 times per second. Take a look at the main.c file. The program starts at main(), yes, but if you look within that function, you’ll see an infinite loop (while(1)). As a programmer, you know that this loop will never end. Well, this is completely intentional. Within the loop, you’ll see the routine Process_Data_From_Master_uP(), which is called within an if() statement (the NEW_SPI_DATA flag is set automatically when the microprocessor has new data that needs to be processed. This is where the 38 times per second comes in). The function Process_Data_From_Master_uP() basically just calls Getdata(), calls Default_Routine(), calls Putdata(), and ends. Default Routine is probably where you do all of your stuff, like reading the josytick values and setting pwms accordingly to drive the robot, etc. The autonomous routine doesn’t actually call Process_Data_From_Master_uP(), but the Getdata(), do something, Putdata() structure is the same.
Here’s the main point. When you write your own code, you need to realize that the microprocessor is running through the entire thing 38 times per second. Not just that, it NEEDS to run through the entire thing 38 times per second. If you hold everything up in a while loop, then Getdata() and Putdata() don’t get called, and the RC stops communicating with itself and with the OI. The code you posted is actually fine, but the problem is that it only takes a fraction of a second for it to count to 900. From what you say, it seems like the counting to 900, even though it takes under a second, it taking a little bit too long and it throws off Getdata() and Putdata(), or maybe it’s just overtaxing the processor.
The solution to this problem would be to use a timer that increments once during each overall program loop, and check the timer once during each loop to see if it’s time to stop. Like so.
void Auto_Drive(void)
{
// The static keyword is required because this function is being called and
// terminated 38 times per second. Thus a non-static timer would loose its
// value every time the function terminated. A static variable remains even
// after the function terminates and retains its value. Also, it is set to 0 only
// when it is first defined.
static unsigned int timer = 0;
// Let's drive forward for 5 seconds.
if(timer < 190)
{
// Drive straight forward at full speed.
Main_Drive(127 /*X Joystick Value*/, 255 /*Y Joystick Value*/);
++timer;
}
else if(timer == 190)
{
//Stop moving
Main_Drive(127 /*X Joystick Value*/, 127 /*Y Joystick Value*/);
}
}
I used 190, because the Getdata()/Putdata() combo takes about 26.2milliseconds to execute. So, if one increment of the timer takes .0262seconds, and we want to drive forward for 5 seconds…
1 program loop
5 seconds X ------per------
.0262 seconds
The seconds cancel each other out, and we’re left with 190.8 program loops. Thus, we increment timer 190 times.
Hope you’ve learned something.