1
1
//
2
2
// FILE: GY521.cpp
3
3
// AUTHOR: Rob Tillaart
4
- // VERSION: 0.6.0
4
+ // VERSION: 0.6.1
5
5
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
6
6
// URL: https://github.com/RobTillaart/GY521
7
7
@@ -26,12 +26,11 @@ GY521::GY521(uint8_t address, TwoWire *wire)
26
26
_address = address;
27
27
_wire = wire;
28
28
29
- _ax = _ay = _az = 0 ;
30
- _aax = _aay = _aaz = 0 ;
31
- _gx = _gy = _gz = 0 ;
32
- _pitch = 0 ;
33
- _roll = 0 ;
34
- _yaw = 0 ;
29
+ // initialize errors
30
+ // don't do it in reset, as users might want to keep them
31
+ axe = aye = aze = 0 ;
32
+
33
+ reset ();
35
34
}
36
35
37
36
@@ -66,13 +65,14 @@ void GY521::reset()
66
65
_ax = _ay = _az = 0 ;
67
66
_aax = _aay = _aaz = 0 ;
68
67
_gx = _gy = _gz = 0 ;
68
+ _gax = _gay = _gaz = 0 ;
69
69
_pitch = 0 ;
70
70
_roll = 0 ;
71
71
_yaw = 0 ;
72
72
}
73
73
74
74
75
- void GY521::calibrate (uint16_t times)
75
+ bool GY521::calibrate (uint16_t times, float angleX, float angleY, bool inverted )
76
76
{
77
77
// disable throttling / caching of read values.
78
78
bool oldThrottle = _throttle;
@@ -89,29 +89,50 @@ void GY521::calibrate(uint16_t times)
89
89
// adjust times if zero.
90
90
if (times == 0 ) times = 1 ;
91
91
92
- // summarize (6x) the measurements.
92
+ // sum (6x) the measurements.
93
+ uint16_t samples = 0 ;
93
94
for (uint16_t i = 0 ; i < times; i++)
94
95
{
95
- read ();
96
- _axe -= getAccelX ();
97
- _aye -= getAccelY ();
98
- _aze -= getAccelZ ();
99
- _gxe -= getGyroX ();
100
- _gye -= getGyroY ();
101
- _gze -= getGyroZ ();
96
+ if (_readRaw () == GY521_OK)
97
+ {
98
+ _axe -= getAccelX ();
99
+ _aye -= getAccelY ();
100
+ _aze -= getAccelZ ();
101
+ _gxe -= getGyroX ();
102
+ _gye -= getGyroY ();
103
+ _gze -= getGyroZ ();
104
+ samples++;
105
+ }
102
106
}
103
107
104
- // adjust calibration errors so read() should get all zero's on average.
105
- float factor = 1.0 / times;
106
- axe = _axe * factor;
107
- aye = _aye * factor;
108
- aze = _aze * factor;
108
+ if (samples == 0 ) return false ;
109
+
110
+ // scale gyro calibration errors so read() should get all zero's on average.
111
+ float factor = _raw2dps / samples;
109
112
gxe = _gxe * factor;
110
113
gye = _gye * factor;
111
114
gze = _gze * factor;
112
115
116
+ // scale accelerometer calibration errors so read() should get all zero's on average.
117
+ factor = _raw2g / samples;
118
+ axe = _axe * factor;
119
+ aye = _aye * factor;
120
+ aze = _aze * factor;
121
+
122
+ // remove expected gravity from error
123
+ angleX *= GY521_DEGREES2RAD;
124
+ angleY *= GY521_DEGREES2RAD;
125
+ float _gravx = -sin (angleY) * cos (angleX);
126
+ float _gravy = sin (angleX);
127
+ float _gravz = cos (angleY) * cos (angleX);
128
+ axe -= _gravx;
129
+ aye -= _gravy;
130
+ aze += inverted ? -_gravz : _gravz;
131
+
113
132
// restore throttle state.
114
133
_throttle = oldThrottle;
134
+
135
+ return true ;
115
136
}
116
137
117
138
@@ -137,32 +158,11 @@ int16_t GY521::read()
137
158
}
138
159
_lastTime = now;
139
160
140
- // Connected ?
141
- _wire->beginTransmission (_address);
142
- _wire->write (GY521_ACCEL_XOUT_H);
143
- if (_wire->endTransmission () != 0 )
144
- {
145
- _error = GY521_ERROR_WRITE;
146
- return _error;
147
- }
148
-
149
- // Get the data
150
- int8_t n = _wire->requestFrom (_address, (uint8_t )14 );
151
- if (n != 14 )
161
+ int16_t rv = _readRaw ();
162
+ if (rv != GY521_OK)
152
163
{
153
- _error = GY521_ERROR_READ;
154
- return _error;
164
+ return rv;
155
165
}
156
- // ACCELEROMETER
157
- _ax = _WireRead2 (); // ACCEL_XOUT_H ACCEL_XOUT_L
158
- _ay = _WireRead2 (); // ACCEL_YOUT_H ACCEL_YOUT_L
159
- _az = _WireRead2 (); // ACCEL_ZOUT_H ACCEL_ZOUT_L
160
- // TEMPERATURE
161
- _temperature = _WireRead2 (); // TEMP_OUT_H TEMP_OUT_L
162
- // GYROSCOPE
163
- _gx = _WireRead2 (); // GYRO_XOUT_H GYRO_XOUT_L
164
- _gy = _WireRead2 (); // GYRO_YOUT_H GYRO_YOUT_L
165
- _gz = _WireRead2 (); // GYRO_ZOUT_H GYRO_ZOUT_L
166
166
167
167
// duration interval
168
168
now = micros ();
@@ -549,6 +549,43 @@ uint8_t GY521::getRegister(uint8_t reg)
549
549
}
550
550
551
551
552
+ // /////////////////////////////////////////////////////////////////
553
+ //
554
+ // PRIVATE
555
+ //
556
+ int16_t GY521::_readRaw ()
557
+ {
558
+ // Connected ?
559
+ _wire->beginTransmission (_address);
560
+ _wire->write (GY521_ACCEL_XOUT_H);
561
+ if (_wire->endTransmission () != 0 )
562
+ {
563
+ _error = GY521_ERROR_WRITE;
564
+ return _error;
565
+ }
566
+
567
+ // Get the data
568
+ int8_t n = _wire->requestFrom (_address, (uint8_t )14 );
569
+ if (n != 14 )
570
+ {
571
+ _error = GY521_ERROR_READ;
572
+ return _error;
573
+ }
574
+ // ACCELEROMETER
575
+ _ax = _WireRead2 (); // ACCEL_XOUT_H ACCEL_XOUT_L
576
+ _ay = _WireRead2 (); // ACCEL_YOUT_H ACCEL_YOUT_L
577
+ _az = _WireRead2 (); // ACCEL_ZOUT_H ACCEL_ZOUT_L
578
+ // TEMPERATURE
579
+ _temperature = _WireRead2 (); // TEMP_OUT_H TEMP_OUT_L
580
+ // GYROSCOPE
581
+ _gx = _WireRead2 (); // GYRO_XOUT_H GYRO_XOUT_L
582
+ _gy = _WireRead2 (); // GYRO_YOUT_H GYRO_YOUT_L
583
+ _gz = _WireRead2 (); // GYRO_ZOUT_H GYRO_ZOUT_L
584
+
585
+ return GY521_OK;
586
+ }
587
+
588
+
552
589
// to read register of 2 bytes.
553
590
int16_t GY521::_WireRead2 ()
554
591
{
0 commit comments