Thread: 2008 Gyro Code
View Single Post
  #5   Spotlight this post!  
Unread 09-02-2008, 11:32
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,567
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: 2008 Gyro Code

Quote:
Originally Posted by FireJet View Post
I tried running Process_Gyro_Data in the _Spin functions, but it still won't help. To make sure that it wasn't my code that was broken, I also added a bit of debug output to Kevin's gyro.c code, in Process_Gyro_Data, so that it now looks like this:

Code:
void Process_Gyro_Data(void)
{
	int temp_gyro_rate;

	// fresh ADC data available?
	if(Get_ADC_Result(GYRO_CHANNEL))
	{	
		// should the completed sample set be used to calculate the gyro bias?
		if(calc_gyro_bias == 1)
		{
			// put the ADC reading on the circular queue
			Gyro_Queue[Gyro_Queue_Index] = Get_ADC_Result(GYRO_CHANNEL);
		
			// increment the write pointer
			Gyro_Queue_Index++;
		
			// is the circular queue now full?
			if(Gyro_Queue_Index == GYRO_QUEUE_SIZE-1)
			{ 
				// update the gyro bias status
				Gyro_Bias_Status = GYRO_BIAS_BUFFER_FULL;
			}

			// If the index pointer overflowed, cut-off the high-order bit. Doing this
			// every time is quicker than checking for overflow every time with an if()
			// statement and only then occasionally setting it back to zero. For this 
			// to work, the queue size must be a power of 2 (e.g., 16,32,64,128).
			Gyro_Queue_Index &= GYRO_QUEUE_INDEX_MASK;
		}
		else
		{
			// get the latest measured gyro rate
			temp_gyro_rate = (int)Get_ADC_Result(GYRO_CHANNEL) - gyro_bias;
	
			// update reported gyro rate and angle only if 
			// measured gyro rate lies outside the deadband
			if(temp_gyro_rate < -GYRO_DEADBAND || temp_gyro_rate > GYRO_DEADBAND)
			{
				// update the gyro rate
				gyro_rate = temp_gyro_rate;
	
				// integrate the gyro rate to derive the heading 
				gyro_angle += (long)temp_gyro_rate;
			}
			else
			{
				gyro_rate = 0;
			}
		}

		Reset_ADC_Result_Count();
	}
	else
	{
		printf("NO NEW ADC DATA.\n\r");
	}
}
Every time Process_Gyro_Data gets called, I get "NO NEW ADC DATA." output. So, I don't believe there's a problem with my code.
Did you enable the ADC and timer? Read adc_readme.txt (and gyro_readme.txt).


Quote:
Originally Posted by FireJet View Post
As well, I've tried replacing that hard-timed loop with this:

Code:
while (Get_Gyro_Bias_Status() != GYRO_BIAS_BUFFER_FULL)
{
    printf("Calculating gyro bias.\n\r");
}
But that seems to cause the controller to run out of RAM (it locks up and shows a code error).
The user processor has to communicate with master processor regularly. You can't have a loop that runs for a long time (ideally, it should never run longer then 26.2ms)*. If it's hung up for too long, it will cause a code error. Because of this, you should not use while loops that are waiting for any type of outside input. You want to make sure the telop function runs very quickly. In almost all cases, replacing your while with an if works, because telop will be called many times.


*WPILIB/EasyC works around this by doing the communication in the background, but you have to deal with it in IFI and Kevin's code.