Revised based upon more accurate information for Vex people.
I bought a Vex Gyro at Worlds and decided to try it out with RobotC.
The gyro chip is a MEMS ST LY3100ALH 1000 deg/sec max rate gyro. The Vex people amplified the output by a factor of 1.511 so that the nominal 3 V max is 4.533 v. Don’t know why they didn’t amplify it to 5v … but it results in a gyro scale factor of 600 deg/s/volt. The cortex equation that converts A2D to dps can be derived as follows:
Vgyro = (dps*.0011 + 1.5) * 1.511 = dps* .00166 + 2.267 volts
A2D = Vgyro*2/3*4095/3.3 = Vgyro*827.27 counts
or A2D = (dps*.00166 + 2.267)*827.27
or A2D = 1.374 * dps + 1874
The inverse gives
dps = (A2D-1874)*.7277
Setting the Gyro Deadzone:
The noise density is .016 deg/s/√(HZ) and the bandwidth is 140 hz so the noise output = .016*√140 = .19 dps rms. The A/D sampling resolution is 1 bit from above is .728 dps. The standard deviation of the sampling noise is typically about .289 LSB or .21 dps. RSS of these two sources is .283 dps. Typically we set the deadzone at the 2 sigma level of the total noise sources or .57 deg/s. This is less than 1 count on the A/D output so the dz should be placed at 1 counts to keep the gyro integration from drifting. I use 2 counts to add some margin. Without this deadzone you would expect to see a random walk drift on the integration of the gyro angle when sitting still.
3.2.2013 RobotC 3.08 revisions
“Fix drift in gyro value calculation. Make “nGyroJitterRange” and “bHasSensorBiasSettings” #define parameters in “loadBuildOptions.h”. Change bias setting for gyro from 130 to 131. Fix some small bugs in gyro bias calculation. Introduce a “gyro jitter range” setting that ignores very small changes for gyro steady state position. Suppose gyro bias in 1840; they the ‘ignore jitter’ would treat values in 1837 to 1843 as if they were the steady state value.”
Ok..so it looks like the 3.08 RobotC dead zone is +-3 counts…. or about +-2.2 deg/sec. My 3.58 RobotC now shows the dead zone at 4 counts now or 2.8 deg/sec.
Recent testing of programming robot have shown drift rates of .6 deg/min even with the jitter range that RobotC claims to use.
When constantly turning with rates that exceed the deadzone, the rms rate noise contributes about
sqrt(Time*dt) *.283 degs rms
angle drift where dt is the gyro integration step period. If one updates at 100 hz then the rms drift is sqrt(Time)*.0283 So with a 1 minute programming challenge time we would expect around .22 deg rms of drift. Which is not too bad.
Bias Calibration Time
How long should we average the bias before starting the integration to get angle. Using an average to estimate of the bias sees the standard error drop by 1/√N where N is the number of samples. We want enough samples to drive the standard error down to where it doesn’t contribute significantly to the total drift rate after 60 second programming challenge. If we pick a 10% increase in the total drift error then we can tolerate 1 deg error/60 sec. From this we can calculate N
1/60 = 1/√N *.283
so N = 288
So we can generally sample at 1 per ms so a 1 second averaging time should be sufficient.
Vex Pendulum Robot:
I wanted to use this with the accelerometer to reconstruct the Vex bbot inverse pendulum robot… however it will be still noisy in tilt angle due to the low resolution of the gyro. My last bbot used a 400 dps max with a 10 bit A/D so with the Cortex 12 bit A/D and 1000 deg/sec max we would not see any improvement. I was hoping for a variable scaling gyro that would allow me to use 100 to 200 deg/s maximum for this application.
The RobotC version 2.32 gyro type did not work with this gyro yet. I wrote a RobotC gyro test software that used the A/D to measure the voltage and then process it with my own task process_gyro(). Running this process calculates an unbiased rate gyro output and gyro angle from integrated rate. The gyro worked pretty well with a 500 hz integration rate and a 1 second initialization time. Typically a rotation to 180 deg and back was within 5 degs. There is noticable cross axis sensitivity and also sensitivity to EMI noise so you don’t want to mount this on your processor.
For those interested here is the program:
#pragma config(Sensor, in1, gyro, sensorPotentiometer)
//*!!Code automatically generated by ‘ROBOTC’ configuration wizard !!*//
//Program author: Chris Siegert
//Mentor Vex Team 599 and 1508a
//The gyro board scales the 3 volt chip to 4.533v with gain factor 1.511
//this gives 600 dps/volt scale at board
const int gyro_init_time_ms = 1000; //ms
const float sf_gyro = 600.*5./4095.; //units dps_per_cnt = 600 dps/volt*5volt/4095cnts
const int gyro_dz = 2 ;// dead zone in a/d counts (approx .67 deg_per_sec per count)
const int gyro_int_step_size = 2; // integer ms step size 500 hz nominal
//Chip Vdd = 3v and Nominal gyro voltage output = 1.5 v -> 4095*/3.3*2/3*1.5*1.511. = 1874 cnts
int gyro_bias = 1874; //nominally 1874 cnts
int gyro_angle = 0; //gyro angle degs 1 deg resolution
int rate_cnts=0; //unbiased gyro rate a/d counts
int gyro_rate_x10 = 0;//unbiased gyro rate deg/sec*10
float cum = 0;
//………………. initialize gyro …………………………….
int count = 0;
wait1Msec(1);// this gives about 1 count per ms to average
cum = cum + (float)(SensorValue[gyro]);
gyro_bias = cum/count;
cum = 0;
//………………. integrate gyro……………………………….
int dt = time1[T1];
rate_cnts = SensorValue[gyro]-gyro_bias;
float error = SensorValue[gyro]-gyro_bias;
if(error>gyro_dz || error< -gyro_dz)
cum = cum + dt*error*sf_gyro/1000.; //integrate if |error| > dz
ClearTimer(T1); //reset timer after use rate pulse
gyro_angle= cum;//scale to 1 deg/sec resolution