Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Robot Timing Code (http://www.chiefdelphi.com/forums/showthread.php?t=62031)

robotrobot2 19-01-2008 09:40

Robot Timing Code
 
2 Attachment(s)
Here's some timing code for a robot using the PIC processor. To use it link call() to the TMR0 overflow interrupt. Wait() delays the rest of the code for a number of seconds equal to the inputed float. Gettime() returns the current time in seconds since the robot started. Please post any comments!

Kevin Sevcik 19-01-2008 10:02

Re: Robot Timing Code
 
It's a nifty bit of code, but you can't use the wait() function on the IFI Robot Controller. Once you hit that spin loop to wait for anything over 50ms or so, you'll miss updating the master processor, the watchdog will time out, and your robot will be an impressive looking lump of aluminum and such sitting on the field.

robotrobot2 19-01-2008 10:57

Re: Robot Timing Code
 
The TMR0H and TMR0L bytes are built into the processor. They execute regardless of the code, as does the interrupt.

bronxbomber92 19-01-2008 11:36

Re: Robot Timing Code
 
Question: Why would you not use the OpenTimerx(), CloseTimerx(), WriteTimerx() and ReadTimerx() function provided with the c18 libraries?

robotrobot2 19-01-2008 11:52

Re: Robot Timing Code
 
The PIC processor on the robot doesn't include all of the registers used in C18, and it has a different processor speed.

Kevin Sevcik 19-01-2008 11:57

Re: Robot Timing Code
 
Quote:

Originally Posted by robotrobot2 (Post 681435)
The TMR0H and TMR0L bytes are built into the processor. They execute regardless of the code, as does the interrupt.

You misunderstand me. The timer and timing functions will work just fine. Using floats on these robots makes me cringe, but it will work. But your wait(inp) function will kill the robot as sure as pulling the battery. The master processor HAS to be updated by user processor periodically, if you don't the watchdog timer goes off and the master processor kills the robot. If you enter your while loop there you can to NOTHING but wait and can't update the master processor. So the watchdog times out and the master processor kills the robot.

I'm making a fuss about this because it's one of the most common mistakes made by rookie programmers and I really would rather there wasn't code out there that made killing your robot as simple as calling a function.

robotrobot2 19-01-2008 13:27

Re: Robot Timing Code
 
Is there any way to disable the watchdog timer?

dcbrown 19-01-2008 13:34

Re: Robot Timing Code
 
"It's a nifty bit of code, but you can't use the wait() function on the IFI Robot Controller. "

You really need to qualify that since it is not true in all cases.

You can call wait functions at user level (non-interrupt routine level) in EasyC, MPLAB/WPILIB, and other environments.

In these cases the get/put data routines are run at interrupt level off the system clock ISR. Doing this stuff in the background/at interrupt level means you don't have to worry about what you're doing at the non-interrupt level like doing wait() calls. As long as you don't disable interrupts or don't perform waits at interrupt level then it will work just fine.

Bud
PS the other nifty thing that easyc/wpilib does is the system clock notices when autonomous period ends and causes the processor to do a warm reset/reboot from interrupt level effectively exiting autonomous and when the main loops starts again, the operator call/loop is run. I'd done something similar, but did so by putting a call marker on the h/w stack and then at interrupt level when auto mode ended I popped stuff off the stack until I hit the marker and then did a return from interrupt level so in main it looked like the auto() routine had returned by itself. The warm reboot is easier/faster but that means you have to go through the c main startup/init code again.

dcbrown 19-01-2008 14:18

Re: Robot Timing Code
 
"is there a way to disable the watchdog timer?"

No. Also, I'm not even sure there is a WDT used in the user processor -- a check of the program memory map only showed a CLRWDT in the memory loop used to clear/initialize ram to zero at startup. But, its possible I missed something.

Its been a while since I looked at the default code on the user processor.

There are two PIC processors - a master processor and a user processor. First teams are programming the user processor. Default master code is loaded on the master processor.

The master processor is where all but PWM13-15 are connected. The master processor is designed to control all the motion of the robot such that if something goes wrong, it can detect the problem (like the user program on the user processor is whacked out) and stops all output. The OI comes into this processor too.

There is a data stream between the master and user processor over the SPI (serial) bus. This is a bi-directional serial 1-bit wide bus. The data stream is constant. The master is constantly sending the next rx data with OI information on the output stream and is simultaneously recieving the tx data from the user with the updated motor information.

On the user processor, the high priority interrupt routine services the SPI bus. It is constantly sending and recieving data into double buffered recieve and transmit data structures. It is filling up the 'A' rx buffer, while the 'B' rx buffer is sitting there for Getdata() to access. When this interrupt routine has recieved the last of the current 'A' rx data structure, it swaps buffers and sets a status flag indicating new rx data is available. It then starts filling up the 'B' rx buffer. A call to Getdata() will copy out the 'A' or 'B' buffer - whichever has the current completed rx data structure.

Calls to Putdata() place the tx data from the user into the send buffer not currently in use by the interrupt routine. You can repeatedly call Putdata() all you want, but until the high priority interrupt swaps buffers at a data structure boundary - the data doesn't won't go anywhere.

I don't recall if it is the lack of a Getdata() call or something else, but the end result is the master processor is able to detect that the user processor has flaked out and isn't consuming/updating data as it should. It asserts the !MCLR (master reset) on the user processor and holds it in the reset state giving you the red light of death. There is no way to prevent this from the user processor other than to do the Getdata/Putdata often enough to avoid the master processor killing your user processor.

I believe the IFI site has documentation that describes all this.


All times are GMT -5. The time now is 17:27.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi