Go to Post DEKA is right next to the river, and when i got there this morning they wouldn't let us into the building, but apparently there is and standing water on the first floor. The ironic thing is that i work on the water project and we can't deal with a bit of water on the floor - Greg Needel [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
 
 
Thread Tools Rating: Thread Rating: 4 votes, 4.75 average. Display Modes
Prev Previous Post   Next Post Next
  #41   Spotlight this post!  
Unread 26-02-2007, 01:34
Dave K.'s Avatar
Dave K. Dave K. is offline
Engineer/Mentor
FRC #0930
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2005
Location: WI
Posts: 91
Dave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to beholdDave K. is a splendid one to behold
Re: Programming tricks (and former trade secrets)

Quote:
Originally Posted by Alan Anderson View Post
Anyone else feel like sharing?
Streamlined, non-directional Encoder Tach code and added a ring buffer. This is used with 100 counts per revolution encoders on each wheel and provides good low speed resolution while still allowing the PID loop to compute new values every 26ms.

Some will recognize Kevin's interrupt framework, but everything else is different.

Here's the relevant portion of the interrupt routine:

Code:
volatile unsigned int Tach_Count[NUM_TACH];
unsigned char Old_Port_B = 0xFF;

void InterruptHandlerLow () {

	unsigned char Port_B;
	unsigned char Port_B_Delta;

  // other interrupt handler code removed for clarity.

	else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) { // encoder 1 interrupt?
		INTCON3bits.INT2IF = 0; // clear the interrupt flag
		Tach_Count[0]++;
	}
	else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) { // encoder 2 interrupt?
		INTCON3bits.INT3IF = 0; // clear the interrupt flag
		Tach_Count[1]++;
	}
	else if (INTCONbits.RBIF && INTCONbits.RBIE) { // encoder 3-6 interrupt?
		Port_B = PORTB; // remove the "mismatch condition" by reading port b            
		INTCONbits.RBIF = 0; // clear the interrupt flag
		Port_B_Delta = Port_B ^ Old_Port_B; // determine which bits have changed
		Old_Port_B = Port_B; // save a copy of port b for next time around
	 
		if(Port_B_Delta & 0x10) { // did external interrupt 3 change state?
			if (Port_B & 0x10) {
				Tach_Count[2]++;
			}
		}
		if(Port_B_Delta & 0x20) { // did external interrupt 4 change state?
			if (Port_B & 0x20) {
				Tach_Count[3]++;
			}
		}
	}
}

Initialization:

Code:
unsigned char i, j;

	for(i=0;i<NUM_TACH;i++) {
		TachHead[i] = 0;
		for(j=0;j<TACHBUFSIZE;j++) {
			TachBuf[i][j] = 0;
		}	
	}
And here's the foreground tach code that runs in the 26ms loop:

Code:
#define NUM_TACH 4
#define TACHBUFSIZE 4

extern unsigned int Tach_Count[];  // interrupt routine edge counter
unsigned char i, j;
unsigned int TachBuf[NUM_TACH][TACHBUFSIZE];  // ring buffer
unsigned char TachHead[NUM_TACH];  // TachBuf head pointer
unsigned int Tach[NUM_TACH];  // Tach result register.


			// disable tach interrupts, grab current count, and reset counter

			INTCON3bits.INT2IE = 0;		// Disable INT2 for tach 1
			INTCON3bits.INT3IE = 0;		// Disable INT3 for tach 2
			INTCONbits.RBIE = 0;		// Disable Port B change interrupt for tach 3&4

			// get current tach values into local var, then reset the counter
			for (i=0;i<NUM_TACH;i++) {
				TachBuf[i][TachHead[i]] = Tach_Count[i];	// place current tach count into ring buffer & inc buffer
				Tach_Count[i] = 0;
			}

			INTCON3bits.INT2IE = 1;		// INT2 on
			INTCON3bits.INT3IE = 1;		// INT3 on
			INTCONbits.RBIE = 1;		// Port B change interrupt on


			// sum up the tach counts in ring buffer into Tach[]
			for (i=0;i<NUM_TACH;i++) {
				Tach[i] = 0;
				for(j=0;j<TACHBUFSIZE;j++) {
					Tach[i] += TachBuf[i][j];
				}
				if (++TachHead[i] >= TACHBUFSIZE) {
					TachHead[i] = 0;
				}
			}

                        // Tach[] now contains the unsigned wheel speeds
__________________
--Dave
 


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Former FIRST student and mentor dies in a tragic rocket attack in Iraq today. Munkaboo General Forum 48 19-04-2005 12:21
Off-season competetions and former teams Venkatesh Off-Season Events 5 10-12-2004 17:23
Harry Potter and the Chamber of Secrets Ryan Dognaux Chit-Chat 33 01-12-2002 19:57
scouting tips and tricks Rick Scouting 1 08-01-2002 00:52


All times are GMT -5. The time now is 18:06.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


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