![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
sweetie
Joined: 23 Feb 2011 Posts: 2
|
Need help on programming LPY510AL Gyro |
Posted: Thu Feb 24, 2011 12:06 am |
|
|
I am trying to integrate the voltages from this gyro and it seems like I am getting different angular rates in clockwise vs counter-clockwise rotation direction! When i start this code, it reads 0, when i rotate in one direction, the counts increase and decreases in the opposite direction. The problem is that when I return to the same physical position the count does not return to zero. It seems to get more negative each time I move it and return to the starting position. Any help or insight would be greatly appreciated. He is my code:
Code: | //CCS C Compiler
#include <18F252.h> //PIC Chip
#device ADC=8 *=16 //10 Bit A/D - 16 bit address
#use delay(clock=16000000,restart_wdt) //Running @ 16mhz
#use rs232(restart_wdt,baud=9600,bits=8,parity=n,xmit=PIN_C6,rcv=PIN_C7,stream=DSP) //Serial to LCD Display
#fuses HS,NOWDT,NOLVP,NOPROTECT,NOWRTD
#DEFINE YAW 1
signed int16 glYaw_Offset;
signed int16 giYaw = 0;
#int_TIMER1 //10ms timer interrupt
void TIMER1_isr()
{
set_adc_channel(YAW);
delay_us(10);
giYaw = giYaw + (long) read_adc() - glYaw_Offset;
set_timer1(-10000); //Set timer
}
void get_gyro_offset() //Calculate gyro offset once
{
int8 i;
int iNumAvgs = 100;
signed int16 iTemp;
set_adc_channel(YAW); //Yaw select channel
delay_us(15); //Settle time
iTemp = 0;
for (i=0;i<iNumAvgs;i++) //Average data
{
iTemp = iTemp + read_adc();
delay_us(15);
}
glYaw_Offset = (long) iTemp / iNumAvgs; //Get average from 100 readings
}
void main()
{
//*********************************** Setup Timer ***********************************
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
//********************** Initialize On-chip A/D *************************
//Gyro Ch1 = Yaw from Gyro chip Ch3 = 3.3v ref from Gyro Chip
setup_adc_ports(AN0_AN1_AN2_AN4_VSS_VREF); //Ch1 = Yaw Ch3 = 3.3V ref
setup_adc(ADC_CLOCK_DIV_32); //For 16-20Mhz Crystal - A/D Clock rate
delay_ms(250); //Wait to stabilize
get_gyro_offset(); //get offset to use in interrupt routine
enable_interrupts (INT_TIMER1); //Elapsed Timer1
enable_interrupts (GLOBAL); //Enable Interrupts
while(1)
{
fprintf(DSP,"%ld \r",giYaw);
delay_ms(100);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Thu Feb 24, 2011 7:13 am |
|
|
Hmmmm...
you've set your ADC to 8 bit mode
#device ADC=8 *=16 //10 Bit A/D - 16 bit address
needs to be
#device adc=10
...
So if your return to 'zero' and off by 1 bit, it won't take long to not be a 'zero'( 1 out of 256 vs. 1 out of 1024)
You'll have to redo the averages then, as you're now working with 10 bit readings..... |
|
![](templates/subSilver/images/spacer.gif) |
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Thu Feb 24, 2011 9:17 am |
|
|
Even when going to 10-bit numbers, integrator drift is the nature of the beast. You can make it better, maybe even much better, but its very unlikely that you'll make it go away.
Make sure you're not accumulating error when the device is at rest. You might also be having a problem if you're shifting the orientation of the device as you're rotating it, if you're doing it manually.
You might consider a first order integrator (trapezoidal rule) instead of a zero-order integrator (simple sum) if you need more precision. |
|
![](templates/subSilver/images/spacer.gif) |
sweetie
Joined: 23 Feb 2011 Posts: 2
|
|
Posted: Fri Feb 25, 2011 12:44 am |
|
|
Initially I tried using 10 bit A/D but it was a little noisy. 8 bit gave less noisy results and I am referencing the 3.3v from the gyro for the A/D on the PIC to get the full dynamic range of 256.
I think I wasn't clear on my observations, so let me try again.
When I start the app (with the board aligned parallel to the edge of my desk), I get a yaw reading of 0 which is great. No jitter in the data, just a solid zero. Now when I rotate the board slowly by just 20 or 30 degrees, I can see the integrated values increment to some value. When I stop the rotation, the value remains steady, again with no jitter. Now when I rotate in the opposite direction, I can see the values decrementing. However, when I reach the original starting position (parallel to the edge), the value I read is quite a bit negative but should be close to zero. Now when I do this whole procedure once again, the value I get at the original position becomes even more negative! This just is not right! I am moving very slowly as not to exceed the 100deg/sec rating of this gyro. Here is the doc for this unit.
http://www.pololu.com/catalog/product/1267
On the SparkFun web site there is some discussion on problems of this family of gyro with regards to output filter which I don't quite understand, but looking at the schematics of the Pololu unit, its seems to be bypassing the Hi-Pass filter.
http://forum.sparkfun.com/viewtopic.php?t=18247
Thanks again for all you inputs and suggestions! |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|