Interesting Microprocessor Info

Today, I had a little time to spare with a frequency counter and a VEX micro. (I am using the MPLAB C programming environment.)

I re-wrote the user code to only execute my code fragments and nothing else (no reading of the receiver channels and no assigning values to pwm outputs - it just runs my code chunks.) My first experiment was to set IO15 to an output and toggle it. Here is the code chunk called from user_routines.c


void TestRoutine(void)
{
  // Simply toggle the output between 1 and 0

  rc_dig_out15 = !rc_dig_out15;
}

The frequency counter showed about a 37 millisecond period. Since user routines runs twice per cycle on IO15, that means the cycle time is 18.5 milliseconds. This timing became synchronized when I turned on the transmitter. Thus, the VEX micro seems to synch up to the transmitter packet rate. This may seem trivial to most of you but the next code segments are more interesting:


void TestRoutine(void)
{
  // Simply toggle the output between 1 and 0

  rc_dig_out15 = !rc_dig_out15;
  printf("variable %2x\n",(int)rc_dig_out15);
  printf("this is a big honkn' super duper long printf statement to the terminal\n");
  printf("this is another big honkn' super duper long printf statement to the terminal\n");

}

The 160 ASCII characters in the printf statements do not alter the repetition rate of the user_routines.c! The period gets longer when I add a copy of the last printf line. Two conclusions can be made. 1) Too much text slows the user_routines repetition rate. 2) One would have to write a lot of code to get an equivalent slowdown. Thus user_routines.c is a very safe bet for consistent timing.

Next, I moved the test code to user_routines_fast.c. Things get more interesting here.


void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */
  rc_dig_out15 = !rc_dig_out15;
}

Setting the freq. counter to frequency (instead of period), I get about 455KHz. The interesting part is that the frequency dips occasionally. This must be due to other processes. Simply adding one more line of code to increment a variable slows the frequency down to 350KHz or so (I don’t remember exactly.) The more code I add, the slower it gets. The random dips in frequency are still there.

Conclusions: 1)The user_routines_fast.c is blazingly fast compared to the regular user_routines. 2)It appears that the repetition rate varies “randomly”. 3)This random variation may make digital PID or filters difficult as the integration and differentiation components are repetition rate dependent - necessitating some other means of getting an accurate timebase. 4)The repetition rate is greatly affected by the amount of code you have running in the user_routines_fast.c. 5)Getting data into and out of IO15 was completely independent of user_routines.c or the transmitter on/off.

The last conclusion is way cool because, with the speed of user_routines_fast.c, I can easily handle all my optical sensors through regular IO ports without using interrupts!!!:slight_smile: What is better is that the IO ports function with or without the transmitter on.

Now that I don’t have to mess with interrupts for the optical sensors, life just got a whole lot simpler.

This may be duh info for some folks but I hope it simplifies life for some others like it has for me.

EJ

P.S. Since the motor pwm outputs have a pattern repetition rate of 18.5 milliseconds, updating pwm values in user_routines_fast.c would make no sense (updates ocuring too fast for the motor pattern). Still keep the updates in the regular user_routines.c

interesting thoughts :cool:

i have done a little of mplab myself, but not much. i do know that for FRC, the user_routines.c runs almost twice as slow as user_routines_fast.c, so it isnt very surprising that vex is the same.

i dont know if you know this but u_r_fast.c (abbreviated) is the autonomous code, so it shouldnt need the transmitter. and u_r.c is teh remote control part, so it does need the transmitter.

To all intents and purposes, the VEXtroller and the previous generation IFI controllers are the same, with differing numbers of I/Os (in my experience)

The distincition between user_routines_fast and user routines is not directly related to whether you are in autonomous or not.

As ElectronJohn pointed out, fast runs as often as possible, while reglar runs on a synchronized 18.5 us cycle.

If you looked at the first teams, many round this to “~ 20 us” and use it for a simple clock (just increment a variable somewhere in user_routines).

If you want to find a place which will really slow things down / generate buffer errors, try doing a big printf from inside user_routines_fast.c = bad news

~ Christopher