Full Me 3-Axis Accelerometer and Gyro Library


#1

I needed to access the acceleration data from the MPU-6050 chip on the MeGyro, but the default Makeblock libraries only exposed the angle data.

I have written a library which exposes all of the functions of the MPU-6050 chip as well as provides the code to produce reporter and command blocks for the chip. The available functions are:

  •   Reporter Blocks:
    
  •          double MeAccelGyro::getAngle(uint8_t index)          
                    [angle in degrees, 1=x-axis, 2=y-axis, 3=z-axis]
    
  •          double MeAccelGyro::getAccel(uint8_t index)          
                    [acceleration in g's, 1=x-axis, 2=y-axis, 3=z-axis]
    
  •          double MeAccelGyro::getSIAccel(uint8_t index)        
                    [acceleration in m/s^2, 1=x-axis, 2=y-axis, 3=z-axis]
    
  •          double MeAccelGyro::getTemp(uint8_t index)           
                    [chip temperature, 1=deg C, 2=deg F, 3= deg K]
    
  •   Command Blocks:
    
  •          void MeAccelGyro::setDLPFfreq(uint8_t index)            
                  [Digital Low=Pass Filter frequency, 1=260Hz, 2=84Hz, 3=94Hz, 4=44Hz, 5=21Hz, 6=10Hz, 7=5Hz)
    
  •          void MeAccelGyro::setGyroSensitivity(uint8_t index)
                    [Gyro full scale sensitivity, 1=250deg/s, 2=500 deg/s, 3=1000 deg/s, 4=2000 deg/s ]
    
  •          void MeAccelGyro::setAccelSensitivity(uint8_t index)
                    [Accelerometer full scale sensitivity, 1=2g, 2=4g, 3=8g, 4=16g
    

I’ve tested the library in Arduino with the Ultimate 2.0 robot.

I’m more than wiling to make the library available here to anyone who wants it, but I would like to ask Makeblock to substitute this library for the restricted version in mBlock5 that only reports the angle. I have tried to make an extension using the Extension Builder, but so far, I don’t see any way to actually output the data to a block. There doesn’t seem to be any documentation to do this (you need to send an ArduinoC variable to the Javascript of the block) . If Makeblock can do this, that’d be great, though.

I’m an engineering physics professor, and I’m developing a new curriculum for our lower-division engineering students that uses Makeblock robots. It’s critical for their labs that they have access to the accelerometer data.

Any help anyone could provide would be gratefully accepted! As I mentioned, I’d be happy to make an extension if someone can show me how to send the value of an ArduinoC variable to a reporter block – that’s literally all that I’m missing.

Many thanks,
Dr. K

Dr. Keith “Kilo” Watt
Engineering Physics
Department of Physical Sciences
Glendale College, Arizona


#2

Here is the library in case anyone wants to try it

MeAccelGyro.h

/**
 * \par Copyright (C), 2012-2016, MakeBlock
 * \class   MeAccelGyro
 * \brief   Driver for Me 3-Axis Accelerometer and Gyro module.
 * @file    MeAccelGyro.h
 * @author  Dr. Keith "Kilo" Watt
 * @version V1.0.0
 * @date    2022/04/30
 * @brief   Header for MeAccelGyro.cpp module.
 *
 * \par Copyright
 * This software is Copyright (C), 2012-2016, MakeBlock. Use is subject to license \n
 * conditions. The main licensing options available are GPL V2 or Commercial: \n
 *
 * \par Open Source Licensing GPL V2
 * This is the appropriate option if you want to share the source code of your \n
 * application with everyone you distribute it to, and you also want to give them \n
 * the right to share who uses it. If you wish to use this software under Open \n
 * Source Licensing, you must contribute all your source code to the open source \n
 * community in accordance with the GPL Version 2 when your application is \n
 * distributed. See http://www.gnu.org/copyleft/gpl.html
 *
 * \par Description
 * This file is a driver for Me 3-Axis Accelerometer module, It supports 3-Axis Accelerometer V1.0 device provided
 * by MakeBlock. This driver is an extension of MeGyro to expose the accelerometer data.
 *
 * \par Method List:
 *
 * ** NOTE: The following methods should be exposed to user with a block for each:
 *       Reporter Blocks:
 *              double MeAccelGyro::getAngle(uint8_t index)
 *              double MeAccelGyro::getAccel(uint8_t index)
 *              double MeAccelGyro::getSIAccel(uint8_t index)
 *              double MeAccelGyro::getTemp(uint8_t index)
 *
 *       Command Blocks:
 *              void MeAccelGyro::setDLPFfreq(uint8_t index)
 *              void MeAccelGyro::setGyroSensitivity(uint8_t index)
 *              void MeAccelGyro::setAccelSensitivity(uint8_t index)
 *
 *
 *    1. void MeAccelGyro::setpin(uint8_t AD0, uint8_t INT)
 *    2. void MeAccelGyro::begin(void)
 *    3. void MeAccelGyro::update(void)
 *    4. double MeAccelGyro::getAngle(uint8_t index)
 *    5. double MeAccelGyro::getAccel(uint8_t index)
 *    6. double MeAccelGyro::getSIAccel(uint8_t index)
 *    7. double MeAccelGyro::getTemp(uint8_t index)
 *    8. void MeAccelGyro::setDLPFfreq(uint8_t index)
 *    9. void MeAccelGyro::setGyroSensitivity(uint8_t index)
 *    10. void MeAccelGyro::setAccelSensitivity(uint8_t index)
 *    11. void MeAccelGyro::fast_update(void)
 *    12. uint8_t MeAccelGyro::getDevAddr(void)
 *    13. double MeAccelGyro::getRawTemp(void)
 *    14. double MeAccelGyro::getCTemp(void)
 *    15. double MeAccelGyro::getKTemp(void)
 *    16. double MeAccelGyro::getFTemp(void)
 *    17. double MeAccelGyro::getAngleX(void)
 *    18. double MeAccelGyro::getAngleY(void)
 *    19. double MeAccelGyro::getAngleZ(void)
 *    20. double MeAccelGyro::getGyroX(void)
 *    21. double MeAccelGyro::getGyroY(void)
 *    22. double MeAccelGyro::getAccelX(void)
 *    23. double MeAccelGyro::getAccelY(void)
 *    24. double MeAccelGyro::getAccelZ(void)
 *    25. double MeAccelGyro::getSIAccelX(void)
 *    26. double MeAccelGyro::getSIAccelY(void)
 *    27. double MeAccelGyro::getSIAccelZ(void)
 *    28. double MeAccelGyro::getRawAccelX(void)
 *    29. double MeAccelGyro::getRawAccelY(void)
 *    30. double MeAccelGyro::getRawAccelZ(void)
 *    31. void MeAccelGyro::setDLPFfreq260(void)
 *    32. void MeAccelGyro::setDLPFfreq184(void)
 *    33. void MeAccelGyro::setDLPFfreq94(void)
 *    34. void MeAccelGyro::setDLPFfreq44(void)
 *    35. void MeAccelGyro::setDLPFfreq21(void)
 *    36. void MeAccelGyro::setDLPFfreq10(void)
 *    37. void MeAccelGyro::setDLPFfreq05(void)
 *    38. void MeAccelGyro::setGyroSensitivity250(void)
 *    39. void MeAccelGyro::setGyroSensitivity500(void)
 *    40. void MeAccelGyro::setGyroSensitivity1000(void)
 *    41. void MeAccelGyro::setGyroSensitivity2000(void)
 *    42. void MeAccelGyro::setAccelSensitivity2G(void)
 *    43. void MeAccelGyro::setAccelSensitivity4G(void)
 *    44. void MeAccelGyro::setAccelSensitivity8G(void)
 *    45. void MeAccelGyro::setAccelSensitivity16G(void)
 *
 * \par History:
 * <pre>
 * `<Author>`         `<Time>`        `<Version>`        `<Descr>`   
 *  Kilo Watt		 2022/04/30          1.0.0			  Initial extension of MeGyro to expose acceleration and temperature data
 * </pre>
 *
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef MeAccelGyro_H
#define MeAccelGyro_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <Arduino.h>
#include "MeConfig.h"
#ifdef ME_PORT_DEFINED
#include "MePort.h"
#endif // ME_PORT_DEFINED

/* Exported macro ------------------------------------------------------------*/
#define I2C_ERROR                  (-1)
#define GYRO_DEFAULT_ADDRESS       (0x68)

/**
 * Class: MeAccelGyro
 * \par Description
 * Declaration of Class MeAccelGyro
 */
#ifndef ME_PORT_DEFINED
class MeAccelGyro
#else // !ME_PORT_DEFINED
class MeAccelGyro : public MePort
#endif // !ME_PORT_DEFINED
{
public:
#ifdef ME_PORT_DEFINED
/**
 * Alternate Constructor which can call your own function to map the MeCompass to arduino port,
 * no pins are used or initialized here
 */
	MeAccelGyro(void);

/**
 * Alternate Constructor which can call your own function to map the MeCompass to arduino port,
 * no pins are used or initialized here, but PWM frequency set to 976 Hz
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 */
	MeAccelGyro(uint8_t port);

/**
 * Alternate Constructor which can call your own function to map the MeCompass to arduino port
 * and change the i2c device address
 * no pins are used or initialized here, but PWM frequency set to 976 Hz
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 * \param[in]
 *   address - the i2c address you want to set
 */
	MeAccelGyro(uint8_t port, uint8_t address);
#else
/**
 * Alternate Constructor which can call your own function to map the _AD0 and _INT to arduino port,
 * no pins are used or initialized here
 * \param[in]
 *   _AD0 - arduino gpio number
 * \param[in]
 *   _INT - arduino gpio number
 */
	MeAccelGyro(uint8_t AD0, uint8_t INT);

/**
 * Alternate Constructor which can call your own function to map the _AD0 and _INT to arduino port
 * and change the i2c device address, no pins are used or initialized here
 * \param[in]
 *   _AD0 - arduino gpio number
 * \param[in]
 *   _INT - arduino gpio number
 * \param[in]
 *   address - the i2c address you want to set
 */
	MeAccelGyro(uint8_t AD0, uint8_t INT, uint8_t address);
#endif  //  ME_PORT_DEFINED
/**
 * \par Function
 *   setpin
 * \par Description
 *   Set the PIN of the button module.
 * \param[in]
 *   AD0 - pin mapping for arduino
 * \param[in]
 *   INT - pin mapping for arduino
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   Set global variable _AD0, _INT, s1 and s2
 */
  void setpin(uint8_t AD0, uint8_t INT);


//***********************************************************************
// Setup Functions

/**
 * \par Function
 *   begin
 * \par Description
 *   Initialize the MeAccelGyro.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   You can check the MPU6050 datasheet for the registor address.
 */
  void begin();


//***********************************************************************
// _Loop Functions

/**
 * \par Function
 *   update
 * \par Description
 *   Update some calculated angle values to the variable.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   The angle values are calculated by complementary filter.
 *   The time constant of filter is set to 0.5 second, but period dt is not a constant, 
 *   so the filter coefficient will be calculated dynamically.
 */
  void update(void);

/**
 * \par Function
 *   fast_update
 * \par Description
 *   Fast update some calculated angle values to the variable.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   The angle values are calculated by complementary filter.
 *   The time constant of filter is set to 0.5 second, but period dt is not a constant, 
 *   so the filter coefficient will be calculated dynamically.
 */
  void fast_update(void);

/**
 * \par Function
 *   getDevAddr
 * \par Description
 *   Get the device address of Gyro.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The device address of Gyro
 * \par Others
 *   None
 */
  uint8_t getDevAddr(void);

//************************************************************
// User-facing functions for blocks

//************************************************************
// Reporter Blocks

/**
 * \par Function
 *   getAngle
 * \par Description
 *   Get the angle value of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The angle value of setting axis
 * \par Others
 *   Z-axis angle value is integral of Z-axis angular velocity.
 */
  double getAngle(uint8_t index);

  /**
 * \par Function
 *   getAccel
 * \par Description
 *   Get the acceleration value in g's of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The acceleration value in g's of setting axis
 * \par Others
 *   None
 */
  double getAccel(uint8_t index);

/**
 * \par Function
 *   getSIAccel
 * \par Description
 *   Get the acceleration value in SI units (m/s^2) of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The acceleration value in SI units (m/s^2) of setting axis
 * \par Others
 *   None
 */
  double getSIAccel(uint8_t index);

 /**
 * \par Function
 *   getTemp
 * \par Description
 *   Gets the ambient temperature of the MPU6050 chip in various units
 * \param[in]
 *   index - temperature units(1:Celsius, 2:Fahrenheit, 3:Kelvin)
 * \par Output
 *   None
 * \return
 *   The chip temperature in the selected units
 * \par Others
 *   Note that the dropdown in the command block should have Celsius,1; Fahrenheit,2; Kelvin,3
 */
  double getTemp(uint8_t index);


  //************************************************************
// Command Blocks

/**
 * \par Function
 *   setDLPFfreq
 * \par Description
 *   Sets the frequency of the digital low-pass filter
 * \param[in]
 *   index - Freq settings in Hz(1:260, 2:184, 3:94, 4:44, 5:21, 6:10, 7:5)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 260Hz,1; 184Hz,2; 94Hz,3; 44Hz,4; 21Hz,5; 10Hz,6; 5Hz,7
 */
  void setDLPFfreq(uint8_t index);

/**
 * \par Function
 *   setGyroSensitivity
 * \par Description
 *   Sets the sensitivity of the gyro in deg/sec
 * \param[in]
 *   index - Sensitivity settings in deg/sec(1:250, 2:500, 3:1000, 4:2000)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 250 deg/s,1; 500 deg/s,2; 1000 deg/s,3; 2000 deg/s,4
 */
  void setGyroSensitivity(uint8_t index);

/**
 * \par Function
 *   setAccelSensitivity
 * \par Description
 *   Sets the full scale sensitivity of the accelerometer in g's
 * \param[in]
 *   index - Sensitivity settings in g's(1:2, 2:4, 3:8, 4:16)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 2g,1; 4g,2; 8g,3; 16,4
 */
  void setAccelSensitivity(uint8_t index);


// ***********************************************************************
// * Functions used by the library (could be exposed to user if desired)

 /**
 * \par Function
 *   getRawTemp
 * \par Description
 *   Get the raw (Least Significant Bit) temperature of the sensor
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of temperature
 * \par Others
 *   None
 */
  double getRawTemp(void) ;

/**
* \par Function
*   getCTemp
* \par Description
*   Get the temperature of the sensor in degrees C
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees C
* \par Others
*   None
*/
  double getCTemp(void) ;

/**
* \par Function
*   getKTemp
* \par Description
*   Get the temperature of the sensor in degrees K
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees K
* \par Others
*   None
*/
  double getKTemp(void) ;

/**
* \par Function
*   getFTemp
* \par Description
*   Get the temperature of the sensor in degrees F
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees F
* \par Others
*   None
*/
  double getFTemp(void) ;

  /**
 * \par Function
 *   getAccelX
 * \par Description
 *   Get the acceleration value of X-axis converted to g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
  double getAccelX(void) ;

  /**
 * \par Function
 *   getAccelY
 * \par Description
 *   Get the acceleration value of Y-axis in g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
  double getAccelY(void) ;

  /**
 * \par Function
 *   getAccelZ
 * \par Description
 *   Get the acceleration value of Z-axis in g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of Z-axis
 * \par Others
 *   Z-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
  double getAccelZ(void) ;

  /**
* \par Function
*   getSIAccelX
* \par Description
*   Get the acceleration value of X-axis converted to SI units (m/s^2).
* \param[in]
*   None
* \par Output
*   None
* \return
*   The SI acceleration value of X-axis
* \par Others
*   X-axis angle value is calculated by complementary filter.
*   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
*   This implies that 9.81m/s^2 = 16384 LSB => 1 m/s^2 = 1670.1
*/
  double getSIAccelX(void) ;

  /**
 * \par Function
 *   getAccelY
 * \par Description
 *   Get the acceleration value of Y-axis in SI units (m/s^2).
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The SI acceleration value of X-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 9.81 m/s^2 = 16384 LSB => 1 m/s^2 = 1670.1
 */
  double getSIAccelY(void) ;

  /**
 * \par Function
 *   getAccelZ
 * \par Description
 *   Get the acceleration value of Z-axis in SI units (m/s^2).
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The SI acceleration value of Z-axis
 * \par Others
 *   Z-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 9.81 m/s^2 = 16384 LSB => 1 m/s^2 = 1670.1
 */
  double getSIAccelZ(void) ;

 /**
 * \par Function
 *   getRawAccelX
 * \par Description
 *   Get the raw (Least Significant Bit) acceleration value of X-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 */
  double getRawAccelX(void) ;

  /**
  * \par Function
  *   getRawAccelY
  * \par Description
  *   Get the raw (Least Significant Bit) acceleration value of Y-axis.
  * \param[in]
  *   None
  * \par Output
  *   None
  * \return
  *   The LSB acceleration value of X-axis
  * \par Others
  *   Y-axis angle value is calculated by complementary filter.
  */
  double getRawAccelY(void) ;

  /**
  * \par Function
  *   getRawAccelZ
  * \par Description
  *   Get the raw (Least Significant Bit) acceleration value of Z-axis.
  * \param[in]
  *   None
  * \par Output
  *   None
  * \return
  *   The LSB acceleration value of Z-axis
  * \par Others
  *   Z-axis angle value is calculated by complementary filter.
  */
  double getRawAccelZ(void) ;

/**
 * \par Function
 *   getAngleX
 * \par Description
 *   Get the angle value of X-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 */
  double getAngleX(void) ;

/**
 * \par Function
 *   getAngleY
 * \par Description
 *   Get the angle value of Y-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of Y-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 */
  double getAngleY(void) ;

/**
 * \par Function
 *   getAngleZ
 * \par Description
 *   Get the angle value of Z-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of Z-axis
 * \par Others
 *   Z-axis angle value is integral of Z-axis angular velocity.
 */
  double getAngleZ(void) ;

/**
 * \par Function
 *   getGyroX
 * \par Description
 *   Get the data of gyroXrate.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The data of gyroXrate
 * \par Others
 *   None
 */
  double getGyroX(void) ;

/**
 * \par Function
 *   getGyroY
 * \par Description
 *   Get the data of gyroYrate.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The data of gyroYrate
 * \par Others
 *   None
 */
  double getGyroY(void) ;

  /**
 * \par Function
 *   setDLPFfreq260
 * \par Description
 *   Sets the Digital Low-Pass Filter to 260Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
  void setDLPFfreq260(void) ;

 /**
 * \par Function
 *   setDLPFfreq184
 * \par Description
 *   Sets the Digital Low-Pass Filter to 184Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
  void setDLPFfreq184(void) ;

 /**
 * \par Function
 *   setDLPFfreq94
 * \par Description
 *   Sets the Digital Low-Pass Filter to 184Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
  void setDLPFfreq94(void) ;

 /**
 * \par Function
 *   setDLPFfreq44
 * \par Description
 *   Sets the Digital Low-Pass Filter to 44Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
  void setDLPFfreq44(void) ;

 /**
 * \par Function
 *   setDLPFfreq21
 * \par Description
 *   Sets the Digital Low-Pass Filter to 21Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
	  void setDLPFfreq21(void) ;

 /**
 * \par Function
 *   setDLPFfreq10
 * \par Description
 *   Sets the Digital Low-Pass Filter to 10Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
  void setDLPFfreq10(void) ;

/**
* \par Function
*   setDLPFfreq05
* \par Description
*   Sets the Digital Low-Pass Filter to 5Hz
* \param[in]
*   None
* \par Output
*   None
* \return
*   None.
* \par Others
*   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
*/
void setDLPFfreq05(void) ;

 /**
 * \par Function
 *   setGyroSensitivity250
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 250 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
  void setGyroSensitivity250(void) ;


 /**
 * \par Function
 *   setGyroSensitivityy500
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 500 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
  void setGyroSensitivity500(void) ;

 /**
 * \par Function
 *   setGyroSensitivity1000
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 1000 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
  void setGyroSensitivity1000(void) ;

 /**
 * \par Function
 *   setGyroSensitivity2000
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 2000 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
  void setGyroSensitivity2000(void) ;

  /**
 * \par Function
 *   setAccelSensitivity2G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 2g (default at power-up)
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
  void setAccelSensitivity2G(void) ;

 /**
 * \par Function
 *   setAccelSensitivity4G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 4g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
  void setAccelSensitivity4G(void) ;

 /**
 * \par Function
 *   setAccelSensitivity8G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 8g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
  void setAccelSensitivity8G(void) ;

 /**
 * \par Function
 *   setAccelSensitivity16G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 16g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
  void setAccelSensitivity16G(void);


// Full Scale constants for gyroSensitivity
#define         DEGS_250   131.0;
#define         DEGS_500    65.5;
#define         DEGS_1000   32.8;
#define         DEGS_2000   16.4;

// Full Scale constants for accelSensitivity
#define			ACCEL_2G	16384.0;
#define			ACCEL_4G	8192.0;
#define			ACCEL_8G	4096.0;
#define			ACCEL_16G	2048.0;

private:
  volatile uint8_t  _AD0;
  volatile uint8_t  _INT;
  mutable double gyroSensitivity; /* LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14*/
  double  gx, gy, gz;
  double  gyrX, gyrY, gyrZ;
  int16_t accX, accY, accZ;
  double  gyrXoffs, gyrYoffs, gyrZoffs;
  uint8_t i2cData[14]; // Used to read IMU data
  uint8_t i2cData2[2]; // Used to read temperature data
  uint8_t Device_Address;
  int16_t rawTemp;  // For on-board temperature sensor
  mutable double accelSensitivity; // LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.29
  
/**
 * \par Function
 *   deviceCalibration
 * \par Description
 *   Calibration function for the MeAccelGyro. 
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   The calibration function will be called in initial process, please keep the 
 *   device in a rest status at that time.
 */
  void deviceCalibration(void);

/**
 * \par Function
 *   writeReg
 * \par Description
 *   Write the registor of i2c device.
 * \param[in]
 *   reg - the address of registor.
 * \param[in]
 *   data - the data that will be written to the registor.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   To set the registor for initializing.
 */
  int8_t writeReg(int16_t reg, uint8_t data);

/**
 * \par Function
 *   readData
 * \par Description
 *   Write the data to i2c device.
 * \param[in]
 *   start - the address which will write the data to.
 * \param[in]
 *   pData - the head address of data array.
 * \param[in]
 *   size - set the number of data will be written to the devide.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   Calling the official i2c library to read data.
 */
  int8_t readData(uint8_t start, uint8_t *buffer, uint8_t size);

/**
 * \par Function
 *   writeData
 * \par Description
 *   Write the data to i2c device.
 * \param[in]
 *   start - the address which will write the data to.
 * \param[in]
 *   pData - the head address of data array.
 * \param[in]
 *   size - set the number of data will be written to the devide.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   Calling the official i2c library to write data.
 */
  //int8_t writeData(uint8_t start, const uint8_t *pData, uint8_t size);
  int8_t writeData(uint8_t start, uint8_t* pData, uint8_t size);
};
#endif //  MeAccelGyro_H

#3

Part 1 of MeAccelGyro.cpp

/**
 * \par Copyright (C), 2012-2016, MakeBlock
 * \class   MeAccelGyro
 * \brief   Driver for Me 3-Axis Accelerometer and Gyro module.
 * @file    MeAccelGyro.cpp
 * @author  Dr. Keith "Kilo" Watt
 * @version V1.0.0
 * @date    2022/04/30
 * @brief   Driver for MeAccelGyro module.
 *
 * \par Copyright
 * This software is Copyright (C), 2012-2016, MakeBlock. Use is subject to license \n
 * conditions. The main licensing options available are GPL V2 or Commercial: \n
 *
 * \par Open Source Licensing GPL V2
 * This is the appropriate option if you want to share the source code of your \n
 * application with everyone you distribute it to, and you also want to give them \n
 * the right to share who uses it. If you wish to use this software under Open \n
 * Source Licensing, you must contribute all your source code to the open source \n
 * community in accordance with the GPL Version 2 when your application is \n
 * distributed. See http://www.gnu.org/copyleft/gpl.html
 *
 * \par Description
 * This file is a driver for Me 3-Axis Accelerometer module, It supports 3-Axis Accelerometer V1.0 device provided
 * by MakeBlock. This driver is an extension of MeGyro to expose the accelerometer data.
 *
 * \par Method List:
 * 
 * ** NOTE: The following methods should be exposed to user with a block for each:
 *       Reporter Blocks:
 *              double MeAccelGyro::getAngle(uint8_t index)
 *              double MeAccelGyro::getAccel(uint8_t index)
 *              double MeAccelGyro::getSIAccel(uint8_t index)
 *              double MeAccelGyro::getTemp(uint8_t index)
 * 
 *       Command Blocks:
 *              void MeAccelGyro::setDLPFfreq(uint8_t index)
 *              void MeAccelGyro::setGyroSensitivity(uint8_t index)
 *              void MeAccelGyro::setAccelSensitivity(uint8_t index)
 *              
 * 
 *    1. void MeAccelGyro::setpin(uint8_t AD0, uint8_t INT)
 *    2. void MeAccelGyro::begin(void)
 *    3. void MeAccelGyro::update(void)
 *    4. double MeAccelGyro::getAngle(uint8_t index)
 *    5. double MeAccelGyro::getAccel(uint8_t index)
 *    6. double MeAccelGyro::getSIAccel(uint8_t index)
 *    7. double MeAccelGyro::getTemp(uint8_t index)
 *    8. void MeAccelGyro::setDLPFfreq(uint8_t index)
 *    9. void MeAccelGyro::setGyroSensitivity(uint8_t index)
 *    10. void MeAccelGyro::setAccelSensitivity(uint8_t index)
 *    11. void MeAccelGyro::fast_update(void)
 *    12. uint8_t MeAccelGyro::getDevAddr(void)
 *    13. double MeAccelGyro::getRawTemp(void)
 *    14. double MeAccelGyro::getCTemp(void)
 *    15. double MeAccelGyro::getKTemp(void)
 *    16. double MeAccelGyro::getFTemp(void)
 *    17. double MeAccelGyro::getAngleX(void)
 *    18. double MeAccelGyro::getAngleY(void)
 *    19. double MeAccelGyro::getAngleZ(void)
 *    20. double MeAccelGyro::getGyroX(void)
 *    21. double MeAccelGyro::getGyroY(void)
 *    22. double MeAccelGyro::getAccelX(void)
 *    23. double MeAccelGyro::getAccelY(void)
 *    24. double MeAccelGyro::getAccelZ(void)
 *    25. double MeAccelGyro::getSIAccelX(void)
 *    26. double MeAccelGyro::getSIAccelY(void)
 *    27. double MeAccelGyro::getSIAccelZ(void)
 *    28. double MeAccelGyro::getRawAccelX(void)
 *    29. double MeAccelGyro::getRawAccelY(void)
 *    30. double MeAccelGyro::getRawAccelZ(void)
 *    31. void MeAccelGyro::setDLPFfreq260(void)
 *    32. void MeAccelGyro::setDLPFfreq184(void)
 *    33. void MeAccelGyro::setDLPFfreq94(void)
 *    34. void MeAccelGyro::setDLPFfreq44(void)
 *    35. void MeAccelGyro::setDLPFfreq21(void)
 *    36. void MeAccelGyro::setDLPFfreq10(void)
 *    37. void MeAccelGyro::setDLPFfreq05(void)
 *    38. void MeAccelGyro::setGyroSensitivity250(void)
 *    39. void MeAccelGyro::setGyroSensitivity500(void)
 *    40. void MeAccelGyro::setGyroSensitivity1000(void)
 *    41. void MeAccelGyro::setGyroSensitivity2000(void)
 *    42. void MeAccelGyro::setAccelSensitivity2G(void)
 *    43. void MeAccelGyro::setAccelSensitivity4G(void)
 *    44. void MeAccelGyro::setAccelSensitivity8G(void)
 *    45. void MeAccelGyro::setAccelSensitivity16G(void)
 *
 * \par History:
 * <pre>
 * `<Author>`         `<Time>`        `<Version>`        `<Descr>`
 *  Kilo Watt         2022/04/26         1.0.0         Initial extension of MeGyro to expose acceleration and temperature data
 * </pre>
 *
 * @example MeAccelGyroTest.ino
 */

/* Includes ------------------------------------------------------------------*/
#include "MeAccelGyro.h"

/* Private functions ---------------------------------------------------------*/
#ifdef ME_PORT_DEFINED
/**
 * Alternate Constructor which can call your own function to map the MeGyro to arduino port,
 * no pins are used or initialized here
 */
MeAccelGyro::MeAccelGyro(void) : MePort(0)
{
  Device_Address = GYRO_DEFAULT_ADDRESS;
}

/**
 * Alternate Constructor which can call your own function to map the MeGyro to arduino port,
 * no pins are used or initialized here, but PWM frequency set to 976 Hz
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 */
MeAccelGyro::MeAccelGyro(uint8_t port) : MePort(port)
{
  Device_Address = GYRO_DEFAULT_ADDRESS;
}

/**
 * Alternate Constructor which can call your own function to map the MeGyro to arduino port
 * and change the i2c device address
 * no pins are used or initialized here, but PWM frequency set to 976 Hz
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 * \param[in]
 *   address - the i2c address you want to set
 */
MeAccelGyro::MeAccelGyro(uint8_t port, uint8_t address) : MePort(port)
{
  Device_Address = address;
}
#else  // ME_PORT_DEFINED
/**
 * Alternate Constructor which can call your own function to map the _AD0 and _INT to arduino port,
 * no pins are used or initialized here
 * \param[in]
 *   _AD0 - arduino gpio number
 * \param[in]
 *   _INT - arduino gpio number
 */
MeAccelGyro::MeAccelGyro(uint8_t AD0, uint8_t INT)
{
  Device_Address = GYRO_DEFAULT_ADDRESS;
  _AD0 = AD0;
  _INT = INT;
}

/**
 * Alternate Constructor which can call your own function to map the _AD0 and _INT to arduino port
 * and change the i2c device address, no pins are used or initialized here
 * \param[in]
 *   _AD0 - arduino gpio number
 * \param[in]
 *   _INT - arduino gpio number
 * \param[in]
 *   address - the i2c address you want to set
 */
MeAccelGyro::MeAccelGyro(uint8_t AD0, uint8_t INT, uint8_t address)
{
  Device_Address = address;
  _AD0 = AD0;
  _INT = INT;
}
#endif // ME_PORT_DEFINED

/**
 * \par Function
 *   setpin
 * \par Description
 *   Set the PIN of the button module.
 * \param[in]
 *   AD0 - pin mapping for arduino
 * \param[in]
 *   INT - pin mapping for arduino
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   Set global variable _AD0, _INT, s1 and s2
 */
void MeAccelGyro::setpin(uint8_t AD0, uint8_t INT) 
{
  _AD0 = AD0;
  _INT = INT;
#ifdef ME_PORT_DEFINED
  s1 = AD0;
  s2 = INT;
#endif // ME_PORT_DEFINED
}

#4

Part 2 of MeAccelGyro.cpp

//***********************************************************************
// Setup Functions

/**
 * \par Function
 *   begin
 * \par Description
 *   Initialize the MeAccelGyro.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   You can check the MPU6050 datasheet for the registor address.
 */
void MeAccelGyro::begin(void) 
{
  /* Default power-up state for the MeAccelGyro:
        Gyro at 250 degrees second
        Acceleration at 2g
        Clock source at internal 8MHz
        The device is in sleep mode.
  */

  rawTemp = 0.;
  gx = 0;
  gy = 0;
  gz = 0;
  gyrX = 0;
  gyrY = 0;
  gyrZ = 0;
  accX = 0;
  accY = 0;
  accZ = 0;
  gyrXoffs = 0;
  gyrYoffs = 0;
  gyrZoffs = 0;
  Wire.begin();
  delay(200);
  writeReg(0x6b, 0x00);//close the sleep mode (wake the device), 0x06 is power management register
  delay(100);
  //writeReg(0x1a, 0x01);//configurate the digital low pass filter
  setDLPFfreq184();        // set the digital low-pass filter to 184Hz 
  setGyroSensitivity500(); // set the gyro scale to 500 deg/s
  setAccelSensitivity2G(); // set the accelerometer to +/-2g 

  delay(100);
  deviceCalibration();
}

//***********************************************************************
// _Loop Functions

/**
 * \par Function
 *   update
 * \par Description
 *   Update some calculated angle values, accelerations, and temperatures to the variables.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   The angle values are calculated by complementary filter.
 *   The time constant of filter is set to 0.5 second, but period dt is not a constant, 
 *   so the filter coefficient will be calculated dynamically.
 */
void MeAccelGyro::update(void) 
{
  static unsigned long	last_time = 0;
  int8_t return_value;
  double dt, filter_coefficient;
  /* read imu data */
  return_value = readData(0x3b, i2cData, 14);
  if(return_value != 0)
  {
    return;
  }

  // Read the raw temperature data
  int8_t temp_return_value;
  /* read temperature data */
  temp_return_value = readData(0x41, i2cData2, 2);
  if (temp_return_value != 0)
  {
      return;
  }
  /* assemble the temperature sensor data*/
  rawTemp = ((i2cData2[0] << 8) | i2cData2[1]);
  // End raw temperature read

  double ax, ay;
  /* assemble 16 bit sensor data */
  accX = ( (i2cData[0] << 8) | i2cData[1] );
  accY = ( (i2cData[2] << 8) | i2cData[3] );
  accZ = ( (i2cData[4] << 8) | i2cData[5] );  
  gyrX = ( ( (i2cData[8] << 8) | i2cData[9] ) - gyrXoffs) / gyroSensitivity;
  gyrY = ( ( (i2cData[10] << 8) | i2cData[11] ) - gyrYoffs) / gyroSensitivity;
  gyrZ = ( ( (i2cData[12] << 8) | i2cData[13] ) - gyrZoffs) / gyroSensitivity;  
  ax = atan2(accX, sqrt( pow(accY, 2) + pow(accZ, 2) ) ) * 180 / 3.1415926;
  ay = atan2(accY, sqrt( pow(accX, 2) + pow(accZ, 2) ) ) * 180 / 3.1415926;  

  dt = (double)(millis() - last_time) / 1000;
  last_time = millis();

  if(accZ > 0)
  {
    gx = gx - gyrY * dt;
    gy = gy + gyrX * dt;
  }
  else
  {
    gx = gx + gyrY * dt;
    gy = gy - gyrX * dt;
  }
  gz += gyrZ * dt;
  gz = gz - 360 * floor(gz / 360);
  if(gz > 180)
  {
    gz = gz - 360;
  }

  /*
     complementary filter
     set 0.5sec = tau = dt * A / (1 - A)
     so A = tau / (tau + dt)
  */
  filter_coefficient = 0.5 / (0.5 + dt);
  gx = gx * filter_coefficient + ax * (1 - filter_coefficient);
  gy = gy * filter_coefficient + ay * (1 - filter_coefficient);   
}

/**
 * \par Function
 *   fast_update
 * \par Description
 *   Fast update some calculated angle values to the variable.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   The angle values are calculated by complementary filter.
 *   The time constant of filter is set to 0.5 second, but period dt is not a constant, 
 *   so the filter coefficient will be calculated dynamically.
 */
void MeAccelGyro::fast_update(void) 
{
  static unsigned long	last_time = 0;
  int8_t return_value;
  double dt;

  dt = (double)(millis() - last_time) / 1000.0;
  last_time = millis();

  // Read the raw temperature data
  int8_t temp_return_value;
  /* read temperature data */
  temp_return_value = readData(0x41, i2cData, 2);
  if (temp_return_value != 0)
  {
      return;
  }
  /* assemble the temperature sensor data*/
  rawTemp = ((i2cData[0] << 8) | i2cData[1]);
  // End raw temperature read

  /* read imu data */
  return_value = readData(0x3b, i2cData, 14);
  if(return_value != 0)
  {
    return;
  }

  double ax, ay;
  /* assemble 16 bit sensor data */
  accX = ( (i2cData[0] << 8) | i2cData[1] );
  accY = ( (i2cData[2] << 8) | i2cData[3] );
  accZ = ( (i2cData[4] << 8) | i2cData[5] );  
  gyrX = ( ( (i2cData[8] << 8) | i2cData[9] ) - gyrXoffs) / gyroSensitivity;
  gyrY = ( ( (i2cData[10] << 8) | i2cData[11] ) - gyrYoffs) / gyroSensitivity;
  gyrZ = ( ( (i2cData[12] << 8) | i2cData[13] ) - gyrZoffs) / gyroSensitivity;  
  ax = atan2(accX, sqrt( pow(accY, 2) + pow(accZ, 2) ) ) * 180 / 3.1415926;
  ay = atan2(accY, sqrt( pow(accX, 2) + pow(accZ, 2) ) ) * 180 / 3.1415926;  

  if(accZ > 0)
  {
    gx = gx - gyrY * dt;
    gy = gy + gyrX * dt;
  }
  else
  {
    gx = gx + gyrY * dt;
    gy = gy - gyrX * dt;
  }
  gz += gyrZ * dt;
  
  gz = gz - 360 * floor(gz / 360);
  if(gz > 180)
  {
    gz = gz - 360;
  }

  gy = 0.98 * gy + 0.02 * ay;
  gx = 0.98 * gx + 0.02 * ax; 
}

/**
 * \par Function
 *   getDevAddr
 * \par Description
 *   Get the device address of Gyro.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The device address of Gyro
 * \par Others
 *   None
 */
uint8_t MeAccelGyro::getDevAddr(void) 
{
  return Device_Address;
}

#5

Part 3 of MeAccelGyro.cpp

//************************************************************
// User-facing functions for blocks

//************************************************************
// Reporter Blocks

/**
 * \par Function
 *   getAngle
 * \par Description
 *   Get the angle value of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The angle value of setting axis
 * \par Others
 *   Z-axis angle value is integral of Z-axis angular velocity.
 */
double MeAccelGyro::getAngle(uint8_t index)
{
    if (index == 1)
    {
        return getAngleX();
    }
    else if (index == 2)
    {
        return getAngleY();
    }
    else if (index == 3)
    {
        return getAngleZ();
    }
}

/**
 * \par Function
 *   getAccel
 * \par Description
 *   Get the acceleration value in g's of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The acceleration value in g's of setting axis
 * \par Others
 *   None
 */
double MeAccelGyro::getAccel(uint8_t index)
{
    if (index == 1)
    {
        return getAccelX();
    }
    else if (index == 2)
    {
        return getAccelY();
    }
    else if (index == 3)
    {
        return getAccelZ();
    }
}

/**
 * \par Function
 *   getSIAccel
 * \par Description
 *   Get the acceleration value in SI units (m/s^2) of setting axis.
 * \param[in]
 *   index - Axis settings(1:X-axis, 2:Y-axis, 3:Z-axis)
 * \par Output
 *   None
 * \return
 *   The acceleration value in SI units (m/s^2) of setting axis
 * \par Others
 *   None
 */
double MeAccelGyro::getSIAccel(uint8_t index)
{
    if (index == 1)
    {
        return getSIAccelX();
    }
    else if (index == 2)
    {
        return getSIAccelY();
    }
    else if (index == 3)
    {
        return getSIAccelZ();
    }
}

/**
 * \par Function
 *   getTemp
 * \par Description
 *   Gets the ambient temperature of the MPU6050 chip in various units
 * \param[in]
 *   index - temperature units(1:Celsius, 2:Fahrenheit, 3:Kelvin)
 * \par Output
 *   None
 * \return
 *   The chip temperature in the selected units
 * \par Others
 *   Note that the dropdown in the command block should have Celsius,1; Fahrenheit,2; Kelvin,3
 */
double MeAccelGyro::getTemp(uint8_t index)
{
    if (index == 1)
    {
        return getCTemp();
    }
    else if (index == 2)
    {
        return getFTemp();
    }
    else if (index == 3)
    {
        return getKTemp();
    }
}

//************************************************************
// Command Blocks

/**
 * \par Function
 *   setDLPFfreq
 * \par Description
 *   Sets the frequency of the digital low-pass filter
 * \param[in]
 *   index - Freq settings in Hz(1:260, 2:184, 3:94, 4:44, 5:21, 6:10, 7:5)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 260Hz,1; 184Hz,2; 94Hz,3; 44Hz,4; 21Hz,5; 10Hz,6; 5Hz,7
 */
void MeAccelGyro::setDLPFfreq(uint8_t index)
{
    if (index == 1)
    {
        setDLPFfreq260();
        return;
    }
    else if (index == 2)
    {
        setDLPFfreq184();
        return;
    }
    else if (index == 3)
    {
        setDLPFfreq94();
        return;
    }
    else if (index == 4)
    {
        setDLPFfreq44();
        return;
    }
    else if (index == 5)
    {
        setDLPFfreq21();
        return;
    }
    else if (index == 6)
    {
        setDLPFfreq10();
        return;
    }
    else if (index == 7)
    {
        setDLPFfreq05();
        return;
    }
}

/**
 * \par Function
 *   setGyroSensitivity
 * \par Description
 *   Sets the sensitivity of the gyro in deg/sec
 * \param[in]
 *   index - Sensitivity settings in deg/sec(1:250, 2:500, 3:1000, 4:2000)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 250 deg/s,1; 500 deg/s,2; 1000 deg/s,3; 2000 deg/s,4
 */
void MeAccelGyro::setGyroSensitivity(uint8_t index)
{
    if (index == 1)
    {
        setGyroSensitivity250();
        return;
    }
    else if (index == 2)
    {
        setGyroSensitivity500();
        return;
    }
    else if (index == 3)
    {
        setGyroSensitivity1000();
        return;
    }
    else if (index == 4)
    {
        setGyroSensitivity2000();
        return;
    }
}

/**
 * \par Function
 *   setAccelSensitivity
 * \par Description
 *   Sets the full scale sensitivity of the accelerometer in g's
 * \param[in]
 *   index - Sensitivity settings in g's(1:2, 2:4, 3:8, 4:16)
 * \par Output
 *   None
 * \return
 *   None
 * \par Others
 *   Note that the dropdown in the command block should have 2g,1; 4g,2; 8g,3; 16,4
 */
void MeAccelGyro::setAccelSensitivity(uint8_t index)
{
    if (index == 1)
    {
        setAccelSensitivity2G();
        return;
    }
    else if (index == 2)
    {
        setAccelSensitivity4G();
        return;
    }
    else if (index == 3)
    {
        setAccelSensitivity8G();
        return;
    }
    else if (index == 4)
    {
        setAccelSensitivity16G();
        return;
    }
}

#6

Part 4 of MeAccelGyro.cpp

// ***********************************************************************
// * Functions used by the library (could be exposed to user if desired)

// Read temperature value from sensor
 /**
 * \par Function
 *   getRawTemp
 * \par Description
 *   Get the raw (Least Significant Bit) temperature of the sensor
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of temperature
 * \par Others
 *   None
 */
double MeAccelGyro::getRawTemp(void) 
{
    return rawTemp;
}

/**
* \par Function
*   getCTemp
* \par Description
*   Get the temperature of the sensor in degrees C
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees C
* \par Others
*   None
*/
double MeAccelGyro::getCTemp(void) 
{
    return rawTemp / 340.00 + 36.53; // from datasheet p.30
}

/**
* \par Function
*   getKTemp
* \par Description
*   Get the temperature of the sensor in degrees K
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees K
* \par Others
*   None
*/
// Read temperature value in degrees K
double MeAccelGyro::getKTemp(void) 
{
    return rawTemp / 340.00 + 36.53 + 273.15;
}

/**
* \par Function
*   getFTemp
* \par Description
*   Get the temperature of the sensor in degrees F
* \param[in]
*   None
* \par Output
*   None
* \return
*   The value of temperature in degrees F
* \par Others
*   None
*/
// Read temperature value in degrees F
double MeAccelGyro::getFTemp(void) 
{
    return (rawTemp / 340.00 + 36.53) * 1.8 + 32.0;
}


/**
 * \par Function
 *   getAccelX
 * \par Description
 *   Get the acceleration value of X-axis converted to g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
double MeAccelGyro::getAccelX(void) 
{
    return accX / accelSensitivity;
}

/**
 * \par Function
 *   getAccelY
 * \par Description
 *   Get the acceleration value of Y-axis in g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
double MeAccelGyro::getAccelY(void) 
{
    return accY / accelSensitivity;
}

/**
 * \par Function
 *   getAccelZ
 * \par Description
 *   Get the acceleration value of Z-axis in g's.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of Z-axis
 * \par Others
 *   Z-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB
 */
double MeAccelGyro::getAccelZ(void) 
{
    return accZ / accelSensitivity;
}

/**
 * \par Function
 *   getSIAccelX
 * \par Description
 *   Get the acceleration value of X-axis in SI units (m/s^2).
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB => 1 m/s^2 = 1670.1
 */

double MeAccelGyro::getSIAccelX(void) 
{
    return accX / accelSensitivity * 9.81;
}

/**
 * \par Function
 *   getAccelY
 * \par Description
 *   Get the acceleration value of Y-axis in SI units (m/s^2).
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB => 1 m/s^2 = 1670.1
 */
double MeAccelGyro::getSIAccelY(void) 
{
    return accY / accelSensitivity * 9.81;
}

/**
 * \par Function
 *   getAccelZ
 * \par Description
 *   Get the acceleration value of Z-axis in SI units (m/s^2).
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of Z-axis
 * \par Others
 *   Z-axis angle value is calculated by complementary filter.
 *   Note that the LSB range is -32768 to +32767 for the default 2g sensitivity
 *   This implies that 1g = 16384 LSB => 1 m/s^2 = 1670.1
 */
double MeAccelGyro::getSIAccelZ(void) 
{
    return accZ / accelSensitivity * 9.81;
}

/**
 * \par Function
 *   getRawAccelX
 * \par Description
 *   Get the raw (Least Significant Bit) acceleration value of X-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 */
double MeAccelGyro::getRawAccelX(void) 
{
    return accX;
}

/**
 * \par Function
 *   getRawAccelY
 * \par Description
 *   Get the raw (Least Significant Bit) acceleration value of Y-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of X-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 */
double MeAccelGyro::getRawAccelY(void) 
{
    return accY;
}

/**
 * \par Function
 *   getRawAccelZ
 * \par Description
 *   Get the raw (Least Significant Bit) acceleration value of Z-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The LSB acceleration value of Z-axis
 * \par Others
 *   Z-axis angle value is calculated by complementary filter.
 */
double MeAccelGyro::getRawAccelZ(void) 
{
    return accZ;
}

/**
 * \par Function
 *   getAngleX
 * \par Description
 *   Get the angle value of X-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of X-axis
 * \par Others
 *   X-axis angle value is calculated by complementary filter.
 */
double MeAccelGyro::getAngleX(void) 
{
  return gx;
}

/**
 * \par Function
 *   getAngleY
 * \par Description
 *   Get the angle value of Y-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of Y-axis
 * \par Others
 *   Y-axis angle value is calculated by complementary filter.
 */
double MeAccelGyro::getAngleY(void) 
{
  return gy;
}

/**
 * \par Function
 *   getAngleZ
 * \par Description
 *   Get the angle value of Z-axis.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The angle value of Z-axis
 * \par Others
 *   Z-axis angle value is integral of Z-axis angular velocity.
 */
double MeAccelGyro::getAngleZ(void) 
{
  return gz;
}

/**
 * \par Function
 *   getGyroX
 * \par Description
 *   Get the data of gyroXrate.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The data of gyroXrate
 * \par Others
 *   None
 */
double MeAccelGyro::getGyroX(void) 
{
  return gyrX;
}

/**
 * \par Function
 *   getGyroY
 * \par Description
 *   Get the data of gyroYrate.
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   The data of gyroYrate
 * \par Others
 *   None
 */
double MeAccelGyro::getGyroY(void) 
{
  return gyrY;
}

/**
 * \par Function
 *   setDLPFfreq260
 * \par Description
 *   Sets the Digital Low-Pass Filter to 260Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq260(void) 
{
    writeReg(0x1a, 0x00); // Set DLPF to 260Hz
}

/**
 * \par Function
 *   setDLPFfreq184
 * \par Description
 *   Sets the Digital Low-Pass Filter to 184Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq184(void) 
{
    writeReg(0x1a, 0x01); // Set DLPF to 184Hz
}

/**
 * \par Function
 *   setDLPFfreq94
 * \par Description
 *   Sets the Digital Low-Pass Filter to 184Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq94(void) 
{
    writeReg(0x1a, 0x02); // Set DLPF to 94Hz
}

/**
 * \par Function
 *   setDLPFfreq44
 * \par Description
 *   Sets the Digital Low-Pass Filter to 44Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq44(void) 
{
    writeReg(0x1a, 0x03); // Set DLPF to 44Hz
}

/**
 * \par Function
 *   setDLPFfreq21
 * \par Description
 *   Sets the Digital Low-Pass Filter to 21Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq21(void) 
{
    writeReg(0x1a, 0x04); // Set DLPF to 21Hz
}

/**
 * \par Function
 *   setDLPFfreq10
 * \par Description
 *   Sets the Digital Low-Pass Filter to 10Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq10(void) 
{
    writeReg(0x1a, 0x05); // Set DLPF to 10Hz
}

/**
 * \par Function
 *   setDLPFfreq05
 * \par Description
 *   Sets the Digital Low-Pass Filter to 5Hz
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   DLPF Frequencies = 0x00=260Hz, 0x01=184Hz, 0x02=94Hz, 0x03=44Hz, 0x04=21Hz, 0x05=10Hz, 0x06=5Hz,,check data sheet p.13
 */
void MeAccelGyro::setDLPFfreq05(void) 
{
    writeReg(0x1a, 0x06); // Set DLPF to 5Hz
}

/**
 * \par Function
 *   setgyroSensitivity250
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 250 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
void MeAccelGyro::setGyroSensitivity250(void) 
{
    writeReg(0x1b, 0x00); // Set Gyro Full Scale Range ( 250 deg/s = 0x00, 500 deg/s=0x08 1000 deg/s=0x10, 2000 deg/s = 0x18 )
    gyroSensitivity = DEGS_250;
}

/**
 * \par Function
 *   setGyroSensitivity500
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 500 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
void MeAccelGyro::setGyroSensitivity500(void) 
{
    writeReg(0x1b, 0x08); // Set Gyro Full Scale Range ( 250 deg/s = 0x00, 500 deg/s=0x08 1000 deg/s=0x10, 2000 deg/s = 0x18 )
    gyroSensitivity = DEGS_500;
}

/**
 * \par Function
 *   setGyroSensitivity1000
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 1000 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
void MeAccelGyro::setGyroSensitivity1000(void) 
{
    writeReg(0x1b, 0x10); // Set Gyro Full Scale Range ( 250 deg/s = 0x00, 500 deg/s=0x08 1000 deg/s=0x10, 2000 deg/s = 0x18 )
    gyroSensitivity = DEGS_1000;
}

/**
 * \par Function
 *   setGyroSensitivity2000
 * \par Description
 *   Sets the LSB sensitivity of the gyro to 2000 deg/s
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 250 deg/s = 131.0; 500 deg/s = 65.5; 1000 deg/s = 32.8; 2000 deg/s = 16.4, check data sheet p.14
 */
void MeAccelGyro::setGyroSensitivity2000(void) 
{
    writeReg(0x1b, 0x18); // Set Gyro Full Scale Range ( 250 deg/s = 0x00, 500 deg/s=0x08 1000 deg/s=0x10, 2000 deg/s = 0x18 )
    gyroSensitivity = DEGS_2000;
}

/**
 * \par Function
 *   setAccelSensitivity2G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 2g (default at power-up)
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
void MeAccelGyro::setAccelSensitivity2G(void) 
{
    writeReg(0x1c, 0x00); // Set Accelerometer Full Scale Range ( �2g = 0x00 �4g=0x08 �8g=0x10, �16g = 0x18 )
    accelSensitivity = ACCEL_2G;
}

/**
 * \par Function
 *   setAccelSensitivity4G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 4g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
void MeAccelGyro::setAccelSensitivity4G(void) 
{
    writeReg(0x1c, 0x08); // Set Accelerometer Full Scale Range ( �2g = 0x00 �4g=0x08 �8g=0x10, �16g = 0x18 )
    accelSensitivity = ACCEL_4G;
}

/**
 * \par Function
 *   setAccelSensitivity8G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 8g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
void MeAccelGyro::setAccelSensitivity8G(void) 
{
    writeReg(0x1c, 0x10); // Set Accelerometer Full Scale Range ( �2g = 0x00 �4g=0x08 �8g=0x10, �16g = 0x18 )
    accelSensitivity = ACCEL_8G;
}

/**
 * \par Function
 *   setAccelSensitivity16G
 * \par Description
 *   Sets the LSB sensitivity of the accelerometer to 16g
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   LSB Sensitivity for 2g = 16384.0; 4g = 8192.0; 8g = 4096.0; 16g = 2048.0, check data sheet p.15,29
 */
void MeAccelGyro::setAccelSensitivity16G(void) 
{
    writeReg(0x1c, 0x18); // Set Accelerometer Full Scale Range ( �2g = 0x00 �4g=0x08 �8g=0x10, �16g = 0x18 )
    accelSensitivity = ACCEL_16G;
}

/**
 * \par Function
 *   deviceCalibration
 * \par Description
 *   Calibration function for the MeGyro. 
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   The calibration function will be called in initial process, please keep the 
 *   device in a rest status at that time.
 */
void MeAccelGyro::deviceCalibration(void)
{
  int8_t return_value;
  uint16_t x = 0;
  uint16_t num = 500;
  long xSum	= 0, ySum = 0, zSum = 0;
  for(x = 0; x < num; x++)
  {
    return_value = readData(0x43, i2cData, 6);
    xSum += ( (i2cData[0] << 8) | i2cData[1] );
    ySum += ( (i2cData[2] << 8) | i2cData[3] );
    zSum += ( (i2cData[4] << 8) | i2cData[5] );
  }
  gyrXoffs = xSum / num;
  gyrYoffs = ySum / num;
  gyrZoffs = zSum / num;
}

/**
 * \par Function
 *   writeReg
 * \par Description
 *   Write the registor of i2c device.
 * \param[in]
 *   reg - the address of registor.
 * \param[in]
 *   data - the data that will be written to the registor.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   To set the registor for initializing.
 */
int8_t MeAccelGyro::writeReg(int16_t reg, uint8_t data)
{
  int8_t return_value = 0;
  return_value = writeData(reg, &data, 1);
  return(return_value);
}

/**
 * \par Function
 *   readData
 * \par Description
 *   Write the data to i2c device.
 * \param[in]
 *   start - the address which will write the data to.
 * \param[in]
 *   pData - the head address of data array.
 * \param[in]
 *   size - set the number of data will be written to the devide.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   Calling the official i2c library to read data.
 */
int8_t MeAccelGyro::readData(uint8_t start, uint8_t *buffer, uint8_t size)
{
  int16_t i = 0;
  int8_t return_value = 0;
  Wire.beginTransmission(Device_Address);
  return_value = Wire.write(start);
  if(return_value != 1)
  {
    return(I2C_ERROR);
  }
  return_value = Wire.endTransmission(false);
  if(return_value != 0)
  {
    return(return_value);
  }
  delayMicroseconds(1);
  /* Third parameter is true: relase I2C-bus after data is read. */
  Wire.requestFrom(Device_Address, size, (uint8_t)true);
  while(Wire.available() && i < size)
  {
    buffer[i++] = Wire.read();
  }
  delayMicroseconds(1);
  if(i != size)
  {
    return(I2C_ERROR);
  }
  return(0); //return: no error 
}

/**
 * \par Function
 *   writeData
 * \par Description
 *   Write the data to i2c device.
 * \param[in]
 *   start - the address which will write the data to.
 * \param[in]
 *   pData - the head address of data array.
 * \param[in]
 *   size - set the number of data will be written to the devide.
 * \par Output
 *   None
 * \return
 *   Return the error code.
 *   the definition of the value of variable return_value:
 *   0:success
 *   1:BUFFER_LENGTH is shorter than size
 *   2:address send, nack received
 *   3:data send, nack received
 *   4:other twi error
 *   refer to the arduino official library twi.c
 * \par Others
 *   Calling the official i2c library to write data.
 */
//int8_t MeAccelGyro::writeData(uint8_t start, const uint8_t *pData, uint8_t size)
int8_t MeAccelGyro::writeData(uint8_t start, uint8_t* pData, uint8_t size)
{
  int8_t return_value = 0;
  Wire.beginTransmission(Device_Address);
  return_value = Wire.write(start); 
  if(return_value != 1)
  {
    return(I2C_ERROR);
  }
  Wire.write(pData, size);  
  return_value = Wire.endTransmission(true); 
  return(return_value); //return: no error                     
}

#7

Sample Arduino code for testing functions:

/**
 * \par Copyright (C), 2012-2016, MakeBlock
 * @file    MeAccelGyroTest.ino
 * @author  Dr. Keith "Kilo" Watt
 * @version V1.0.0
 * @date    2022/04/30
 * @brief   Description: this file is sample code for Me 3-Axis Accelerometer and Gyro device.
 *
 ************************
 * Available Blocks
 * 
 * Reporter Blocks
 *    double MeAccelGyro::getAngle(uint8_t index)
 *    double MeAccelGyro::getAccel(uint8_t index)
 *    double MeAccelGyro::getSIAccel(uint8_t index)
 *    double MeAccelGyro::getTemp(uint8_t index)
 *    
 * Command Blocks    
 *    void MeAccelGyro::setDLPFfreq(uint8_t index)
 *    void MeAccelGyro::setGyroSensitivity(uint8_t index)
 *    void MeAccelGyro::setAccelSensitivity(uint8_t index)
 *    
 * \par History:
 * <pre>
 * <Author>     <Time>        <Version>      <Descr>
 * Kilo Watt    2022/04/30     1.0.0          Extend MeGyro library to expose acceleration data
 * </pre>
 *
 */
#include "MeMegaPi.h"
#include <Wire.h>
#include "MeAccelGyro.h"

MeAccelGyro accel;
void setup()
{
  Serial.begin(115200);
  accel.begin();

  // Default accelerometer/gyro settings:
  // Gyro Sensitivity = 500 deg/sec
  // Accelerometer Sensitivity = 2g
  // DLPF Frequency = 184 Hz
  
  // Rotation Axes:
  // x-axis = roll
  // y-axis = pitch
  // z-axis = yaw

  
  // Choose the gyro Full Scale value in deg/s here [options are 1=250deg/s, 2=500deg/s, 3=1000deg/s, 4=2000deg/s] 
  accel.setGyroSensitivity(2);

   // Choose the accelerometer Full Scale value in g's here [options are 1=2g, 2=4g, 3=8g, 4=16g]
  accel.setAccelSensitivity(1);

  // Choose the Digtal Low-Pass Filter frequency in Hz here [options are 1=260Hz, 2=184Hz, 3=94Hz, 4=44Hz, 5=21Hz, 6=10Hz, 7=5Hz] 
  accel.setDLPFfreq(2);
}

void loop()
{
  accel.update();
  Serial.read();

  /* Gyro Angle Data */
/*
  Serial.print("X angle:");
  Serial.print(accel.getAngle(1) );
  Serial.print(" Y angle:");
  Serial.print(accel.getAngle(2) );
  Serial.print(" Z angle:");
  Serial.println(accel.getAngle(3) );
*/

  /* Acceleration in g's Data */

  Serial.print("X accel:");
  Serial.print(accel.getAccel(1) );
  Serial.print(" Y accel:");
  Serial.print(accel.getAccel(2) );
  Serial.print(" Z accel:");
  Serial.println(accel.getAccel(3) );


   /* SI units (m/s^2) Acceleration Data */
/*
  Serial.print("X accel:");
  Serial.print(accel.getSIAccel(1) );
  Serial.print(" Y accel:");
  Serial.print(accel.getSIAccel(2) );
  Serial.print(" Z accel:");
  Serial.println(accel.getSIAccel(3) );
*/

  /* Chip Temperature in Celsius Data */
/*
  Serial.print("C Temperature:");
  Serial.println(accel.getTemp(1) );
*/

  /* Chip  Temperature in Fahrenheit Data */
/*
  Serial.print("F Temperature:");
  Serial.println(accel.getTemp(2) );
*/

  /* Chip Temperature in Kelvin Data */
/*
  Serial.print("K Temperature:");
  Serial.println(accel.getTemp(3) );
*/

  delay(10);
}