diff --git a/GY521.cpp b/GY521.cpp index 2c8ea4f..eccd52a 100644 --- a/GY521.cpp +++ b/GY521.cpp @@ -1,7 +1,7 @@ // // FILE: GY521.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.3.1 +// VERSION: 0.3.2 // PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor // URL: https://github.com/RobTillaart/GY521 // @@ -11,14 +11,15 @@ // 0.1.2 2020-08-06 fix setAccelSensitivity + add getters // 0.1.3 2020-08-07 fix ESP support + pitch roll yaw demo // 0.1.4 2020-09-29 fix #5 missing ; -// 0.1.5 2020-09-29 fix #6 fix math for Teensy +// 0.1.5 2020-09-29 fix #6 fix maths for Teensy // 0.2.0 2020-11-03 improve error handling -// 0.2.1 2020-12-24 arduino-ci + unit tests -// 0.2.2 2021-01-24 add interface part to readme.md +// 0.2.1 2020-12-24 Arduino-CI + unit tests +// 0.2.2 2021-01-24 add interface part to readme.md // add GY521_registers.h // 0.2.3 2021-01-26 align version numbers (oops) // 0.3.0 2021-04-07 fix #18 acceleration error correction (kudo's to Merkxic) // 0.3.1 2021-06-13 added more unit test + some initialization +// 0.3.2 2021-07-05 fix #20 support multiWire #include "GY521.h" @@ -35,9 +36,10 @@ // // PUBLIC // -GY521::GY521(uint8_t address) +GY521::GY521(uint8_t address, TwoWire *wire) { _address = address; + _wire = wire; reset(); } @@ -45,7 +47,7 @@ GY521::GY521(uint8_t address) #if defined (ESP8266) || defined(ESP32) bool GY521::begin(uint8_t sda, uint8_t scl) { - Wire.begin(sda, scl); + _wire->begin(sda, scl); return isConnected(); } #endif @@ -53,15 +55,15 @@ bool GY521::begin(uint8_t sda, uint8_t scl) bool GY521::begin() { - Wire.begin(); + _wire->begin(); return isConnected(); } bool GY521::isConnected() { - Wire.beginTransmission(_address); - return (Wire.endTransmission() == 0); + _wire->beginTransmission(_address); + return (_wire->endTransmission() == 0); } void GY521::reset() @@ -79,10 +81,10 @@ void GY521::reset() bool GY521::wakeup() { - Wire.beginTransmission(_address); - Wire.write(GY521_PWR_MGMT_1); - Wire.write(GY521_WAKEUP); - return (Wire.endTransmission() == 0); + _wire->beginTransmission(_address); + _wire->write(GY521_PWR_MGMT_1); + _wire->write(GY521_WAKEUP); + return (_wire->endTransmission() == 0); } @@ -92,18 +94,27 @@ int16_t GY521::read() { if ((millis() - _lastTime) < _throttleTime) { + // not an error. return GY521_THROTTLED; } } // Connected ? - Wire.beginTransmission(_address); - Wire.write(GY521_ACCEL_XOUT_H); - if (Wire.endTransmission() != 0) return GY521_ERROR_WRITE; + _wire->beginTransmission(_address); + _wire->write(GY521_ACCEL_XOUT_H); + if (_wire->endTransmission() != 0) + { + _error = GY521_ERROR_WRITE; + return _error; + } // Get the data - int8_t n = Wire.requestFrom(_address, (uint8_t)14); - if (n != 14) return GY521_ERROR_READ; + int8_t n = _wire->requestFrom(_address, (uint8_t)14); + if (n != 14) + { + _error = GY521_ERROR_READ; + return _error; + } // ACCELEROMETER _ax = _WireRead2(); // ACCEL_XOUT_H ACCEL_XOUT_L _ay = _WireRead2(); // ACCEL_YOUT_H ACCEL_YOUT_L @@ -142,19 +153,19 @@ int16_t GY521::read() _gx *= _raw2dps; _gy *= _raw2dps; _gz *= _raw2dps; - + // Error correct raw gyro measurements. _gx += gxe; _gy += gye; _gz += gze; - + _gax += _gx * duration; _gay += _gy * duration; _gaz += _gz * duration; - _yaw = _gaz; + _yaw = _gaz; _pitch = 0.96 * _gay + 0.04 * _aay; - _roll = 0.96 * _gax + 0.04 * _aax; + _roll = 0.96 * _gax + 0.04 * _aax; return GY521_OK; } @@ -236,11 +247,11 @@ uint8_t GY521::getGyroSensitivity() uint8_t GY521::setRegister(uint8_t reg, uint8_t value) { - Wire.beginTransmission(_address); - Wire.write(reg); - Wire.write(value); + _wire->beginTransmission(_address); + _wire->write(reg); + _wire->write(value); // no need to do anything if not connected. - if (Wire.endTransmission() != 0) + if (_wire->endTransmission() != 0) { _error = GY521_ERROR_WRITE; return _error; @@ -251,20 +262,20 @@ uint8_t GY521::setRegister(uint8_t reg, uint8_t value) uint8_t GY521::getRegister(uint8_t reg) { - Wire.beginTransmission(_address); - Wire.write(reg); - if (Wire.endTransmission() != 0) + _wire->beginTransmission(_address); + _wire->write(reg); + if (_wire->endTransmission() != 0) { _error = GY521_ERROR_WRITE; return _error; } - uint8_t n = Wire.requestFrom(_address, (uint8_t) 1); - if (n != 1) + uint8_t n = _wire->requestFrom(_address, (uint8_t) 1); + if (n != 1) { _error = GY521_ERROR_READ; return _error; } - uint8_t val = Wire.read(); + uint8_t val = _wire->read(); return val; } @@ -272,10 +283,11 @@ uint8_t GY521::getRegister(uint8_t reg) // to read register of 2 bytes. int16_t GY521::_WireRead2() { - int16_t tmp = Wire.read(); + int16_t tmp = _wire->read(); tmp <<= 8; - tmp |= Wire.read(); + tmp |= _wire->read(); return tmp; } + // -- END OF FILE -- diff --git a/GY521.h b/GY521.h index 1b83573..b18ffe9 100644 --- a/GY521.h +++ b/GY521.h @@ -2,7 +2,7 @@ // // FILE: GY521.h // AUTHOR: Rob Tillaart -// VERSION: 0.3.1 +// VERSION: 0.3.2 // PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor // URL: https://github.com/RobTillaart/GY521 // @@ -15,7 +15,7 @@ #include "Wire.h" -#define GY521_LIB_VERSION (F("0.3.1")) +#define GY521_LIB_VERSION (F("0.3.2")) #ifndef GY521_THROTTLE_TIME @@ -34,7 +34,8 @@ class GY521 { public: - GY521(uint8_t address = 0x69); // 0x68 or 0x69 + GY521(uint8_t address = 0x69, TwoWire *wire = &Wire); // 0x68 or 0x69 + #if defined (ESP8266) || defined(ESP32) bool begin(uint8_t sda, uint8_t scl); @@ -43,14 +44,16 @@ class GY521 bool isConnected(); void reset(); + bool wakeup(); // throttle to force delay between reads. void setThrottle(bool throttle = true) { _throttle = throttle; }; bool getThrottle() { return _throttle; }; - // 0..65535 millis == roughly 1 minute. + // 0..65535 (max milliseconds == roughly 1 minute. void setThrottleTime(uint16_t ti ) { _throttleTime = ti; }; uint16_t getThrottleTime() { return _throttleTime; }; + // returns GY521_OK or one of the error codes above. int16_t read(); @@ -60,8 +63,8 @@ class GY521 uint8_t getAccelSensitivity(); // returns 0,1,2,3 // gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second bool setGyroSensitivity(uint8_t gs); - uint8_t getGyroSensitivity(); // returns 0,1,2,3 - + uint8_t getGyroSensitivity(); // returns 0,1,2,3 + // CALL AFTER READ float getAccelX() { return _ax; }; float getAccelY() { return _ay; }; @@ -77,16 +80,21 @@ class GY521 float getRoll() { return _roll; }; float getYaw() { return _yaw; }; + // last time sensor is actually read. uint32_t lastTime() { return _lastTime; }; + // generic worker to get access to all functionality uint8_t setRegister(uint8_t reg, uint8_t value); uint8_t getRegister(uint8_t reg); + + // get last error and reset error to OK. int16_t getError() { return _error; _error = GY521_OK; }; - // callibration errors + + // calibration errors float axe = 0, aye = 0, aze = 0; // accelerometer errors float gxe = 0, gye = 0, gze = 0; // gyro errors @@ -110,9 +118,12 @@ class GY521 float _pitch, _roll, _yaw; // used by user float _temperature = 0; - + // to read register of 2 bytes. int16_t _WireRead2(); + + TwoWire* _wire; }; + // -- END OF FILE -- diff --git a/GY521_registers.h b/GY521_registers.h index a503a62..88154d1 100644 --- a/GY521_registers.h +++ b/GY521_registers.h @@ -1,7 +1,7 @@ // // FILE: GY521_registers.h // AUTHOR: Rob Tillaart -// VERSION: 0.3.0 +// VERSION: 0.3.2 // PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor // URL: https://github.com/RobTillaart/GY521 // diff --git a/README.md b/README.md index 8d7b9f0..22880dc 100644 --- a/README.md +++ b/README.md @@ -12,20 +12,24 @@ Arduino library for I2C GY521 accelerometer-gyroscope sensor a.k.a. MCU-6050 Experimental library for GY521 a.k.a. MCU-6050 -Library is work in progress, in fact extracted and extended from an old project. +Library is work in progress, in fact it is extracted and extended from an old project. It needs to be tested a lot more. -It has three examples + +#### Examples + - calibration example to determine the offsets needed - example to read values. - test sketch to test get / set values. +- example to get pitch roll yaw. +- performance sketch. ## Breakout board -left to right +From left to right -| pin | pinname | description | +| pin | pinName | description | |:----:|:--------|:----------------| | 0 | VCC | +5V | | 1 | GND | ground | @@ -36,7 +40,9 @@ left to right | 6 | AD0 | address | | 7 | INT | interrupt | + #### Address + AD0 connected to GND => 0x68 AD0 connected to VCC => 0x69 @@ -54,25 +60,27 @@ AD0 connected to VCC => 0x69 ### Constructor -- **GY521(uint8_t address = 0x69)** Constructor with default address. 0x68 is also valid. -- **bool begin(uint8_t sda, uint8_t scl)** begin for ESP32 et al. -- **bool begin()** -- **bool isConnected()** device can be found on I2C bus. +- **GY521(uint8_t address = 0x69, , TwoWire \*wire = &Wire)** Constructor with default address. +0x68 is also a valid address. The wire argument is optional to select Wire1 Wire2 etc. on some boards. +- **bool begin(uint8_t sda, uint8_t scl)** begin for ESP32 et al. Returns true if address can be found on I2C bus. +- **bool begin()** Returns true if address can be found on I2C bus. +- **bool isConnected()** returns true if device can be found on I2C bus. - **void reset()** set all internal values to 0 and throttle time to 10 ms. - **bool wakeUp()** ### Throttle -- **void setThrottle(bool throttle = true)** throttle to force delay between reads. -- **bool getThrottle()** idem -- **void setThrottleTime(uint16_t ti )** milliseconds, max = 65535 = 1++ minute -- **uint16_t getThrottleTime()** idem +- **void setThrottle(bool throttle = true)** throttle to force "delay" between reads. +- **bool getThrottle()** returns true if throttle mode is set. +- **void setThrottleTime(uint16_t ti )** throttle time in milliseconds, max = 65535 = 1++ minute +- **uint16_t getThrottleTime()** returns throttle time set. -### Read +### READ + +#### Set before read -#### SET BEFORE READ // as = 0,1,2,3 ==> 2g 4g 8g 16g - **bool setAccelSensitivity(uint8_t as)** as = 0, 1, 2, 3 ==> 2g 4g 8g 16g - **uint8_t getAccelSensitivity()** returns 0, 1, 2, 3 @@ -83,11 +91,13 @@ AD0 connected to VCC => 0x69 #### Actual read - **int16_t read()** returns ... -- **uint32_t lastTime()** last time sensor is actually read. In millis(). +- **uint32_t lastTime()** last time sensor is actually read. In milliseconds. #### Call after read +Note that multiple calls will return the same value. One must explicitly call **read()** to get new values. + - **float getAccelX()** idem - **float getAccelY()** idem - **float getAccelZ()** idem @@ -105,7 +115,7 @@ AD0 connected to VCC => 0x69 ### Register access -Read the register PDF for the specific +Read the register PDF for the specific value and meaning of registers. - **uint8_t setRegister(uint8_t reg, uint8_t value)** - **uint8_t getRegister(uint8_t reg)** @@ -116,13 +126,14 @@ Read the register PDF for the specific **Should** - test test and test ...(ESP too) - improve documentation -- look for math optimizations (atan, hypot, performance) -- multi Wire interface (e.g Wire1, Wire2 etc) +- look for maths optimizations (atan, hypot, performance) + **Could** - calibrate function in the lib ? (think not as lib might grow?) - calibrate sketch could print code snippet to include... - +- option to read only Accel? +- option to read only Gyro? ## documents diff --git a/examples/GY521_performance/GY521_performance.ino b/examples/GY521_performance/GY521_performance.ino new file mode 100644 index 0000000..f3388c1 --- /dev/null +++ b/examples/GY521_performance/GY521_performance.ino @@ -0,0 +1,47 @@ +// +// FILE: GY521_performance.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: minimal demo +// DATE: 2021-06-13 + + +#include "GY521.h" + + +GY521 sensor(0x69); + +uint32_t counter = 0; + + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + Wire.begin(); + + delay(100); + while (sensor.wakeup() == false) + { + Serial.print(millis()); + Serial.println("\tCould not connect to GY521"); + delay(1000); + } +} + +void loop() +{ + uint32_t start = micros(); + int16_t x = sensor.read(); + uint32_t duration = micros() - start; + + Serial.print(x); + Serial.print('\t'); + Serial.print(duration); + Serial.println(); + + delay(1000); +} + +// -- END OF FILE -- \ No newline at end of file diff --git a/library.json b/library.json index 2dcc777..1c98f83 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/GY521.git" }, - "version": "0.3.1", + "version": "0.3.2", "license": "MIT", "frameworks": "arduino", "platforms": "*" diff --git a/library.properties b/library.properties index 99ca66f..40676e8 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=GY521 -version=0.3.1 +version=0.3.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for GY521 angle measurement