Loop time for OperatorControl function? Debug blows...

What is the loop time for OperatorControl function?

I wrote a program to figure this out myself, but then I couldn’t even figure that out because I remembered how difficult it was to even try and debug with these PIC controllers.

I don’t have a background in PIC or C programming. But I can program. I normally program controllers like PLCs and other controllers that support online programming, and allows me to pause the controller, and check variables. (Break Points) So I learned in this controller, you can’t do that. You have to debug using print statements to a terminal window. The problem I’VE ALWAYS HAD, is the print statements don’t seem to me they EVER MATCH what the ACTUAL VARIBLE IS IN THE CONTROLLER.

For example, back to my problem, I started off with no timer and setting a variable called count = count +1 in the OperatorControl function, then slapping a PrinttoScreen “count” variable. Last I remember this controller does a loop every 26.2ms. So I put an IF statement, if count >= to 38, then print another statement. I assumed I would see this print statement every 1 second in my terminal…I don’t…it’s faster than that….

So I decided to use the EasyC timer, it support milliseconds, so I set my If statement to if timer >= 1000, then print to screen…yah…it works…But now the same problem I have every single year with the printF or now print-to-screen, is that it doesn’t seem like the variable that is being printed is actually what my variable is inside the controller, or is it?

See ZIP attached. This simple timing program should capture and measure the loop time of OperatorControl function and print that information to screen for me, instead every time the print-to-screen prints the variable count to screen, it increments 1,2,3,4,5, hits about 16, then it jumps to 1568,1569,1570 to something like 1700, then finally enters the If statement, prints the count variable one final time, resets the timer, resets the count = 0, then starts all over.

Why, why, can’t I ever get the 2004, 2005, 2006 controllers to DEBUG right? Why does my count variable count from 1 to 16, then jump up to 1500? What is wrong with my code? Am I using the printF statement incorrectly?

Finally, since I can’t trust what print screen is telling me what my variable is, does anyone just know what the loop time of OperatorControl function loop time is? I think it’s FASTER than 26.2ms per loop. The reason I want to know, is because I wrote another velocity function that is going to be part of a PID function I need to know my sampling time to pull this off. And within that function, it looks like it was executing fast, but I will never know, because I can’t get the printF to work for me and stop lying about what the variables are in my program.

Can someone help set me straight?

test.zip (5.19 KB)


test.zip (5.19 KB)

I don’t know what file that is (EasyC format?), but for printf’s:

char byte;
int integer;
long longinteger;

printf(“Byte: %d Int: %d Long: %d %d”, (int)byte, (int)integer, (int)(longinteger >> 16), (int)(longinteger & 65535));

You can’t really print longs using the provided functions (unless they are small enough that they can be completely stored in an integer variable). If you really need access to your longs, then you can split them into two integers (as you see above), and then piece them back together offline.

I tried that to, in the HELP FILE it list the directives:

Using directives with Print to screen
Directive
Variable
PrintToScreen Output

%ld
long x = 2000000
2000000

%d
int x = -100
-100

%u
unsigned int x = 100
100

%x
int x = 255
ff

%X
int x = 255
FF

%lx
int x = 255
0ff

%b
int x = 100
1100100

I used:

PrintToScreen ( "Loop Count = %ld
" , (long)count ) ;

Shouldn’t that work? It doesn’t seem to work for me…
The reason I changed it to:

PrintToScreen ( "Loop Count = %d
" , (int)count ) ;

Was because I seen a tutorial or sample code of the EasyC, they used a long varible, then used a %d and an INT to print it to screen, so I followed suit but no matter which way, the printing of my count varible to screen is wacky…I can’t possiblily debug like this…why or why don’t these PICs support online debugging?

Yes, that is EASYC code. I printed the operatorcontrol function to PDF in the zip file.

Ok, so you are using EasyC. I’ve never used it, so I don’t know how to help you with it… but in MPLab (compiling to mcc18) %ld isn’t functional. You’d have to seperate longs greater than 65535 as I have shown above. If the long is between 0 and 65535 you can cast it to an integer, and it will print alright.

The error you see may come from wraparound… that is, the upper 2 bytes of the long are both cutoff when you cast to int. So, for example:

long test = 19203238; // 00000001 00100101 00000100 10100110

printf(“botched-long: %d”, (int)test); // botched-long: 1190 (00000000 00000000 00000100 10100110)

You see that the lower 2 bytes (the length of an int) are the same in both numbers, but in the cast version the upper two are cleared out. You probably already know this, but, eh, I already said it.

The PICs themselves support online debugging, but I’m guessing that IFI’s setup has made this feature unavailable. They have a Dynamic Debug Tool (I 've never used it), so maybe that would be something you could look into?

I figured something like this was happing in the PrintF statement. Seems “weird” to me that you have to be a printF expert just to get your varible out. I see what you mean now. I know my bits and btyes and binary.

I wonder if EasyC supports the “%ld” directive. Why would they put it in the help file if it doesn’t?

%ld
long x = 2000000
200000

I’ll play around with my print-to-screen function, (thank you Joel)m but back to my main question…does anyone know the loop time of the operatorcontrol function block in EasyC?

I guess I’ll find out soon enough myself if I ever get my varible out and formatted correctly to a terminal window…sigh…

I did look at the online debugger last year, I never got it to work. Since I don’t use PICs everyday, outside my normal job, I just didn’t get how to make it work in MPLAB. I found myself in the same frustrating boat last year with terminal debugging with varibles that don’t seem right being printed to screen…

I’ll look into that issue tomorrow. I’ll let you know.
The values your robot prints to screen should be current as of the last
time the variables were updated in the program loop.

Example of Current Loop:
X = X - Y;
printf("PrintX: %d ",X);

Example Loop Behind:
printf("PrintX: %d ",X);
X = X - Y;

You do have to take into account the fact there is a 26ms delay between loops.

If the change is large and quick alot can happen in a loop. If you have a 200 line encoder and your wheel is spinning at 300RPM there will be jumps in the
numbers of ticks between loops.

Here’s the problem… and this may not have been documented as well as it could have been. I noticed that your OperatorControl function just does a few statements, then exits.

When a program starts up the Initialize function is called first, then depending on the field controls (or dongle in the competition port) either the Autonomous function or OperatorControl function is called. When the OperatorControl function exits, the system just runs it again. It does this in case a program accidentally exits.

It is the intent (here’s the part not documented well) that the programmer write an infinite loop in the OperatorControl function that never exits. So your program was running, getting the timer value and ending. Then the system restarted it.

So to write a program for the controller with EasyC you should put a loop into the OperatorControl function so it doesn’t exit - and just keep reading the OI values, doing your stuff, and setting motor values.

The 26ms loop time that is a characteristic of the default code is changed quite a bit in EasyC. What happens is that EasyC will automatically get values from the OI and send motor every 26ms behind the scenes. So when you do a SetPWM repeatedly, the last value you set when the 26ms time comes up will be sent to the motors, even if you set it 100 times during that 26ms period.

The sensors (digital and analog IO) happens as fast as you can read/write data to those ports. There is no 26ms interval when reading or writing those.

If you want to write a PID loop and get the loop time for your integral term, a good way to do that is with a timer. It will count in 1ms increments and you can factor the time each time through the loop into your calculations. Another was is to only do the calculations at longer intervals - again a timer will help with that.

This may be confusing, especially after using the default code. If you have any other questions, I’ll be happy to try to answer them.

Also, the PrintToScreen function calls the Microchip printf function which is pretty standard - you could look at the user guide that Microchip has. It should correctly print long variables, as you said, using the %ld directive.

You can also call printf yourself by putting it inside of an User Code block from the EasyC palette.

Brad,

Thank you so much for your insight. I just posted a question about this very thing (not using a While Loop in our code) in this post:

Dummy Link Here

So what your saying above, is that EasyC excute different than FRC Default code last year? We can poll the I/O faster than the 26ms? In other words, if we have an encoder (quadature), we should be able to get a decent velocity measurement from the inputs correct?

We did start to use the timer in our test.zip file above. Basically setting up a timer, then sending our code into “poll the encoder and get velocity reading” function (get_right_velocity) function.

Makes sense now that you’ve said something about the while loop.

I think maybe if Intellitek updated their software to version 2.1, they should make a change to the “Competition Template” and just add a blank While Loop in the OperatorControl function. This would eliminate some of our guess work, and now maybe the timers won’t reset on their own.

I hope your right about those dumb printF statements. I would be nice to actually see a long varible come out to a terminal session like that and ACTUALLY BE what the varible is inside the controller.

Of course, what would be even NEATER is if Intellitek could make an online debugger or step/break logic in the PIC. You could hover your mouse over a varible and see what the varible is or even access to a VARIBLE TABLE…every varible created would go to a varible table, then you just open the table and view your varibles like a watch window instead of having to do all the printF statements. But I suppose that amounts to controller OVER-HEAD and then everyone would be complaining about that…I wouldn’t complain at all…anything to make debugging a PIC controller easier…

I said it many times before and I’ll say it again…I dunno how you PIC programmers stand it, you don’t know what your missing compared to other CPUs, such as IAI Robot, PLCs, Servo Motor Platforms. They all support some sort of online debugger, make life tons easier…I do have one servo motor that I program that works the same way as a PIC, it’s called a Smart Motor by Animatics. Not so “smart” to me when you have to debug it through a terminal window…

We would like to think that the end result for every team, whether they run easyC or MPlab, will be a similar success story, but easyC does away with the concept of fast and slow loops made famous by the default code.

The program will automatically poll the I/O, and send motor commands every 26 ms.

Absolutely, the remainder of your program will run as fast as it is able. The results from your encoder will depend more on the type of encoder you are using than anything else.

It was our intent / expectation that the user add the while loop themselves. Permanently adding this loop to the template seems an unnecessary restriction, however it is certainly something to consider.

Thank you for your suggestions. We are always interested in hearing constructive feedback about the software.

Chris G

Don’t get us wrong. We think EasyC rocks! I don’t think allot of people take it for a test drive then make a judgment too fast. Post I read on CD are really “sad to read”.

It really is easy…mind blowing compared to all the hardship of interfacing we encountered last year trying to get our quad-encoders working and camera system. So far it seems flexible “enough” to do some pretty basic things, even PIDs. We don’t feel at all limited. It makes coding tons faster, you don’t have to remember your dumb variable names, or even mis-spelling them because if they aren’t in the pull down list, then it’s either not in the same scope “global/local” or we need to read the HELP file because we grabbed the wrong variable type to do that assignment. BTY, the help is awesome, kudos to the engineer that did the help files, love the videos inside the helps file and everything else about the help files. You guys did an awesome job with that.

more constructive…
One thing we like to do is “state” programming using Case Selects. Of course I don’t see that in your command library. But, all we are going to do is track a state logic then do an If state = 1, then do this, If state = 2, then do this…pretty much the same as case selects…I dunno why people use case selects to do state logic, unless it complies smaller. But with 4X more memory who cares right??? knock on wood…

We also like to do our own PIDs. But our PID is nothing like a normal one, so it wouldn’t matter if a PID function block as added to the default library or not. We will keep you posted if we get our PID wrote and converted into EasyC. Actually, we will probably post it in th FIRST Software Repository, later on in the season.

problems…
The only problem we’ve had is loosing the re-draw on the screen. I don’t know if that is computer related or not at this point, but the graphics in EasyC seem to disappear onscreen. We have to shut it down and restart it to get the graphicals to reappear. It’s like a chunk of it will be missing. I’ll try and remember to do a screen shot the next time it happens.

Other than this, I’ll let our programming team know about this post, and try to get the print-to-screen thing to behave. And we should be all set.

Here is a screen shot of that re-draw problem.

I am using a DELL D800 with an ATI graphic card when this happens.

Pretty much have to save, then restart the application to get the icons / “graphics” to come back.

[quote=“chakorules”]

problems…
The only problem we’ve had is loosing the re-draw on the screen. I don’t know if that is computer related or not at this point, but the graphics in EasyC seem to disappear onscreen. We have to shut it down and restart it to get the graphicals to reappear. It’s like a chunk of it will be missing. I’ll try and remember to do a screen shot the next time it happens.
[/quote]

redraw.jpg


redraw.jpg