Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of BNO055_HelloWorld by
Revision 1:b178e785986d, committed 2018-05-22
- Comitter:
- SES01
- Date:
- Tue May 22 11:29:05 2018 +0000
- Parent:
- 0:a8e6e26ebe0f
- Commit message:
- test
Changed in this revision
diff -r a8e6e26ebe0f -r b178e785986d BNO055.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BNO055.cpp Tue May 22 11:29:05 2018 +0000
@@ -0,0 +1,280 @@
+#include "BNO055.h"
+#include "mbed.h"
+
+BNO055::BNO055(PinName SDA, PinName SCL) : _i2c(SDA,SCL){
+ //Set I2C fast and bring reset line high
+ _i2c.frequency(100000);
+ address = BNOAddress;
+ accel_scale = 1.0f;
+ rate_scale = 1.0f/16.0f;
+ angle_scale = 1.0f/16.0f;
+ temp_scale = 1;
+ }
+
+void BNO055::reset(){
+//Perform a power-on-reset
+ readchar(BNO055_SYS_TRIGGER_ADDR);
+ rx = rx | 0x20;
+ writechar(BNO055_SYS_TRIGGER_ADDR,rx);
+//Wait for the system to come back up again (datasheet says 650ms)
+ wait_ms(675);
+}
+
+bool BNO055::check(){
+//Check we have communication link with the chip
+ readchar(BNO055_CHIP_ID_ADDR);
+ if (rx != 0xA0) return false;
+//Grab the chip ID and software versions
+ tx[0] = BNO055_CHIP_ID_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,7,false);
+ ID.id = rawdata[0];
+ ID.accel = rawdata[1];
+ ID.mag = rawdata[2];
+ ID.gyro = rawdata[3];
+ ID.sw[0] = rawdata[4];
+ ID.sw[1] = rawdata[5];
+ ID.bootload = rawdata[6];
+ setpage(1);
+ tx[0] = BNO055_UNIQUE_ID_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,ID.serial,16,false);
+ setpage(0);
+ return true;
+ }
+
+void BNO055::SetExternalCrystal(bool yn){
+// Read the current status from the device
+ readchar(BNO055_SYS_TRIGGER_ADDR);
+ if (yn) rx = rx | 0x80;
+ else rx = rx & 0x7F;
+ writechar(BNO055_SYS_TRIGGER_ADDR,rx);
+}
+
+void BNO055::set_accel_units(char units){
+ readchar(BNO055_UNIT_SEL_ADDR);
+ if(units == MPERSPERS){
+ rx = rx & 0xFE;
+ accel_scale = 0.01f;
+ }
+ else {
+ rx = rx | units;
+ accel_scale = 1.0f;
+ }
+ writechar(BNO055_UNIT_SEL_ADDR,rx);
+}
+
+void BNO055::set_anglerate_units(char units){
+ readchar(BNO055_UNIT_SEL_ADDR);
+ if (units == DEG_PER_SEC){
+ rx = rx & 0xFD;
+ rate_scale = 1.0f/16.0f;
+ }
+ else {
+ rx = rx | units;
+ rate_scale = 1.0f/900.0f;
+ }
+ writechar(BNO055_UNIT_SEL_ADDR,rx);
+}
+
+void BNO055::set_angle_units(char units){
+ readchar(BNO055_UNIT_SEL_ADDR);
+ if (units == DEGREES){
+ rx = rx & 0xFB;
+ angle_scale = 1.0f/16.0f;
+ }
+ else {
+ rx = rx | units;
+ rate_scale = 1.0f/900.0f;
+ }
+ writechar(BNO055_UNIT_SEL_ADDR,rx);
+}
+
+void BNO055::set_temp_units(char units){
+ readchar(BNO055_UNIT_SEL_ADDR);
+ if (units == CENTIGRADE){
+ rx = rx & 0xEF;
+ temp_scale = 1;
+ }
+ else {
+ rx = rx | units;
+ temp_scale = 2;
+ }
+ writechar(BNO055_UNIT_SEL_ADDR,rx);
+}
+
+void BNO055::set_orientation(char units){
+ readchar(BNO055_UNIT_SEL_ADDR);
+ if (units == WINDOWS) rx = rx &0x7F;
+ else rx = rx | units;
+ writechar(BNO055_UNIT_SEL_ADDR,rx);
+}
+
+void BNO055::setmode(char omode){
+ writechar(BNO055_OPR_MODE_ADDR,omode);
+ op_mode = omode;
+}
+
+void BNO055::setpowermode(char pmode){
+ writechar(BNO055_PWR_MODE_ADDR,pmode);
+ pwr_mode = pmode;
+}
+
+void BNO055::get_accel(void){
+ tx[0] = BNO055_ACCEL_DATA_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ accel.rawx = (rawdata[1] << 8 | rawdata[0]);
+ accel.rawy = (rawdata[3] << 8 | rawdata[2]);
+ accel.rawz = (rawdata[5] << 8 | rawdata[4]);
+ accel.x = float(accel.rawx)*accel_scale;
+ accel.y = float(accel.rawy)*accel_scale;
+ accel.z = float(accel.rawz)*accel_scale;
+}
+
+void BNO055::get_gyro(void){
+ tx[0] = BNO055_GYRO_DATA_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ gyro.rawx = (rawdata[1] << 8 | rawdata[0]);
+ gyro.rawy = (rawdata[3] << 8 | rawdata[2]);
+ gyro.rawz = (rawdata[5] << 8 | rawdata[4]);
+ gyro.x = float(gyro.rawx)*rate_scale;
+ gyro.y = float(gyro.rawy)*rate_scale;
+ gyro.z = float(gyro.rawz)*rate_scale;
+}
+
+void BNO055::get_mag(void){
+ tx[0] = BNO055_MAG_DATA_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ mag.rawx = (rawdata[1] << 8 | rawdata[0]);
+ mag.rawy = (rawdata[3] << 8 | rawdata[2]);
+ mag.rawz = (rawdata[5] << 8 | rawdata[4]);
+ mag.x = float(mag.rawx);
+ mag.y = float(mag.rawy);
+ mag.z = float(mag.rawz);
+}
+
+void BNO055::get_lia(void){
+ tx[0] = BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ lia.rawx = (rawdata[1] << 8 | rawdata[0]);
+ lia.rawy = (rawdata[3] << 8 | rawdata[2]);
+ lia.rawz = (rawdata[5] << 8 | rawdata[4]);
+ lia.x = float(lia.rawx)*accel_scale;
+ lia.y = float(lia.rawy)*accel_scale;
+ lia.z = float(lia.rawz)*accel_scale;
+}
+
+void BNO055::get_grv(void){
+ tx[0] = BNO055_GRAVITY_DATA_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ gravity.rawx = (rawdata[1] << 8 | rawdata[0]);
+ gravity.rawy = (rawdata[3] << 8 | rawdata[2]);
+ gravity.rawz = (rawdata[5] << 8 | rawdata[4]);
+ gravity.x = float(gravity.rawx)*accel_scale;
+ gravity.y = float(gravity.rawy)*accel_scale;
+ gravity.z = float(gravity.rawz)*accel_scale;
+}
+
+void BNO055::get_quat(void){
+ tx[0] = BNO055_QUATERNION_DATA_W_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,8,0);
+ quat.raww = (rawdata[1] << 8 | rawdata[0]);
+ quat.rawx = (rawdata[3] << 8 | rawdata[2]);
+ quat.rawy = (rawdata[5] << 8 | rawdata[4]);
+ quat.rawz = (rawdata[7] << 8 | rawdata[6]);
+ quat.w = float(quat.raww)/16384.0f;
+ quat.x = float(quat.rawx)/16384.0f;
+ quat.y = float(quat.rawy)/16384.0f;
+ quat.z = float(quat.rawz)/16384.0f;
+}
+
+void BNO055::get_angles(void){
+ tx[0] = BNO055_EULER_H_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address+1,rawdata,6,0);
+ euler.rawyaw = (rawdata[1] << 8 | rawdata[0]);
+ euler.rawroll = (rawdata[3] << 8 | rawdata[2]);
+ euler.rawpitch = (rawdata[5] << 8 | rawdata[4]);
+ euler.yaw = float(euler.rawyaw)*angle_scale;
+ euler.roll = float(euler.rawroll)*angle_scale;
+ euler.pitch = float(euler.rawpitch)*angle_scale;
+}
+
+
+void BNO055::get_temp(void){
+ readchar(BNO055_TEMP_ADDR);
+ temperature = rx / temp_scale;
+}
+
+void BNO055::get_calib(void){
+ readchar(BNO055_CALIB_STAT_ADDR);
+ calib = rx;
+}
+
+void BNO055::read_calibration_data(void){
+ char tempmode = op_mode;
+ setmode(OPERATION_MODE_CONFIG);
+ wait_ms(20);
+ tx[0] = ACCEL_OFFSET_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address,calibration,22,false);
+ setmode(tempmode);
+ wait_ms(10);
+}
+
+void BNO055::write_calibration_data(void){
+ char tempmode = op_mode;
+ setmode(OPERATION_MODE_CONFIG);
+ wait_ms(20);
+ tx[0] = ACCEL_OFFSET_X_LSB_ADDR;
+ _i2c.write(address,tx,1,true);
+ _i2c.write(address,calibration,22,false);
+ setmode(tempmode);
+ wait_ms(10);
+}
+
+void BNO055::set_mapping(char orient){
+ switch (orient){
+ case 0:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x21);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x04);
+ break;
+ case 1:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x24);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x00);
+ break;
+ case 2:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x24);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x00);
+ break;
+ case 3:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x21);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x02);
+ break;
+ case 4:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x24);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x03);
+ break;
+ case 5:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x21);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x01);
+ break;
+ case 6:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x21);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x07);
+ break;
+ case 7:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x24);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x05);
+ break;
+ default:
+ writechar(BNO055_AXIS_MAP_CONFIG_ADDR,0x24);
+ writechar(BNO055_AXIS_MAP_SIGN_ADDR,0x00);
+ }
+}
\ No newline at end of file
diff -r a8e6e26ebe0f -r b178e785986d BNO055.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BNO055.h Tue May 22 11:29:05 2018 +0000
@@ -0,0 +1,280 @@
+#ifndef BNO055_H
+#define BNO055_H
+
+#include "mbed.h"
+//
+#define BNOAddress (0x28 << 1)
+//Register definitions
+/* Page id register definition */
+#define BNO055_PAGE_ID_ADDR 0x07
+/* PAGE0 REGISTER DEFINITION START*/
+#define BNO055_CHIP_ID_ADDR 0x00
+#define BNO055_ACCEL_REV_ID_ADDR 0x01
+#define BNO055_MAG_REV_ID_ADDR 0x02
+#define BNO055_GYRO_REV_ID_ADDR 0x03
+#define BNO055_SW_REV_ID_LSB_ADDR 0x04
+#define BNO055_SW_REV_ID_MSB_ADDR 0x05
+#define BNO055_BL_REV_ID_ADDR 0x06
+/* Accel data register */
+#define BNO055_ACCEL_DATA_X_LSB_ADDR 0x08
+#define BNO055_ACCEL_DATA_X_MSB_ADDR 0x09
+#define BNO055_ACCEL_DATA_Y_LSB_ADDR 0x0A
+#define BNO055_ACCEL_DATA_Y_MSB_ADDR 0x0B
+#define BNO055_ACCEL_DATA_Z_LSB_ADDR 0x0C
+#define BNO055_ACCEL_DATA_Z_MSB_ADDR 0x0D
+/* Mag data register */
+#define BNO055_MAG_DATA_X_LSB_ADDR 0x0E
+#define BNO055_MAG_DATA_X_MSB_ADDR 0x0F
+#define BNO055_MAG_DATA_Y_LSB_ADDR 0x10
+#define BNO055_MAG_DATA_Y_MSB_ADDR 0x11
+#define BNO055_MAG_DATA_Z_LSB_ADDR 0x12
+#define BNO055_MAG_DATA_Z_MSB_ADDR 0x13
+/* Gyro data registers */
+#define BNO055_GYRO_DATA_X_LSB_ADDR 0x14
+#define BNO055_GYRO_DATA_X_MSB_ADDR 0x15
+#define BNO055_GYRO_DATA_Y_LSB_ADDR 0x16
+#define BNO055_GYRO_DATA_Y_MSB_ADDR 0x17
+#define BNO055_GYRO_DATA_Z_LSB_ADDR 0x18
+#define BNO055_GYRO_DATA_Z_MSB_ADDR 0x19
+/* Euler data registers */
+#define BNO055_EULER_H_LSB_ADDR 0x1A
+#define BNO055_EULER_H_MSB_ADDR 0x1B
+#define BNO055_EULER_R_LSB_ADDR 0x1C
+#define BNO055_EULER_R_MSB_ADDR 0x1D
+#define BNO055_EULER_P_LSB_ADDR 0x1E
+#define BNO055_EULER_P_MSB_ADDR 0x1F
+/* Quaternion data registers */
+#define BNO055_QUATERNION_DATA_W_LSB_ADDR 0x20
+#define BNO055_QUATERNION_DATA_W_MSB_ADDR 0x21
+#define BNO055_QUATERNION_DATA_X_LSB_ADDR 0x22
+#define BNO055_QUATERNION_DATA_X_MSB_ADDR 0x23
+#define BNO055_QUATERNION_DATA_Y_LSB_ADDR 0x24
+#define BNO055_QUATERNION_DATA_Y_MSB_ADDR 0x25
+#define BNO055_QUATERNION_DATA_Z_LSB_ADDR 0x26
+#define BNO055_QUATERNION_DATA_Z_MSB_ADDR 0x27
+/* Linear acceleration data registers */
+#define BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR 0x28
+#define BNO055_LINEAR_ACCEL_DATA_X_MSB_ADDR 0x29
+#define BNO055_LINEAR_ACCEL_DATA_Y_LSB_ADDR 0x2A
+#define BNO055_LINEAR_ACCEL_DATA_Y_MSB_ADDR 0x2B
+#define BNO055_LINEAR_ACCEL_DATA_Z_LSB_ADDR 0x2C
+#define BNO055_LINEAR_ACCEL_DATA_Z_MSB_ADDR 0x2D
+/* Gravity data registers */
+#define BNO055_GRAVITY_DATA_X_LSB_ADDR 0x2E
+#define BNO055_GRAVITY_DATA_X_MSB_ADDR 0x2F
+#define BNO055_GRAVITY_DATA_Y_LSB_ADDR 0x30
+#define BNO055_GRAVITY_DATA_Y_MSB_ADDR 0x31
+#define BNO055_GRAVITY_DATA_Z_LSB_ADDR 0x32
+#define BNO055_GRAVITY_DATA_Z_MSB_ADDR 0x33
+/* Temperature data register */
+#define BNO055_TEMP_ADDR 0x34
+/* Status registers */
+#define BNO055_CALIB_STAT_ADDR 0x35
+#define BNO055_SELFTEST_RESULT_ADDR 0x36
+#define BNO055_INTR_STAT_ADDR 0x37
+#define BNO055_SYS_CLK_STAT_ADDR 0x38
+#define BNO055_SYS_STAT_ADDR 0x39
+#define BNO055_SYS_ERR_ADDR 0x3A
+/* Unit selection register */
+#define BNO055_UNIT_SEL_ADDR 0x3B
+#define BNO055_DATA_SELECT_ADDR 0x3C
+/* Mode registers */
+#define BNO055_OPR_MODE_ADDR 0x3D
+#define BNO055_PWR_MODE_ADDR 0x3E
+#define BNO055_SYS_TRIGGER_ADDR 0x3F
+#define BNO055_TEMP_SOURCE_ADDR 0x40
+/* Axis remap registers */
+#define BNO055_AXIS_MAP_CONFIG_ADDR 0x41
+#define BNO055_AXIS_MAP_SIGN_ADDR 0x42
+/* Accelerometer Offset registers */
+#define ACCEL_OFFSET_X_LSB_ADDR 0x55
+#define ACCEL_OFFSET_X_MSB_ADDR 0x56
+#define ACCEL_OFFSET_Y_LSB_ADDR 0x57
+#define ACCEL_OFFSET_Y_MSB_ADDR 0x58
+#define ACCEL_OFFSET_Z_LSB_ADDR 0x59
+#define ACCEL_OFFSET_Z_MSB_ADDR 0x5A
+/* Magnetometer Offset registers */
+#define MAG_OFFSET_X_LSB_ADDR 0x5B
+#define MAG_OFFSET_X_MSB_ADDR 0x5C
+#define MAG_OFFSET_Y_LSB_ADDR 0x5D
+#define MAG_OFFSET_Y_MSB_ADDR 0x5E
+#define MAG_OFFSET_Z_LSB_ADDR 0x5F
+#define MAG_OFFSET_Z_MSB_ADDR 0x60
+/* Gyroscope Offset registers*/
+#define GYRO_OFFSET_X_LSB_ADDR 0x61
+#define GYRO_OFFSET_X_MSB_ADDR 0x62
+#define GYRO_OFFSET_Y_LSB_ADDR 0x63
+#define GYRO_OFFSET_Y_MSB_ADDR 0x64
+#define GYRO_OFFSET_Z_LSB_ADDR 0x65
+#define GYRO_OFFSET_Z_MSB_ADDR 0x66
+/* Radius registers */
+#define ACCEL_RADIUS_LSB_ADDR 0x67
+#define ACCEL_RADIUS_MSB_ADDR 0x68
+#define MAG_RADIUS_LSB_ADDR 0x69
+#define MAG_RADIUS_MSB_ADDR 0x6A
+
+/* Page 1 registers */
+#define BNO055_UNIQUE_ID_ADDR 0x50
+
+//Definitions for unit selection
+#define MPERSPERS 0x00
+#define MILLIG 0x01
+#define DEG_PER_SEC 0x00
+#define RAD_PER_SEC 0x02
+#define DEGREES 0x00
+#define RADIANS 0x04
+#define CENTIGRADE 0x00
+#define FAHRENHEIT 0x10
+#define WINDOWS 0x00
+#define ANDROID 0x80
+
+//Definitions for power mode
+#define POWER_MODE_NORMAL 0x00
+#define POWER_MODE_LOWPOWER 0x01
+#define POWER_MODE_SUSPEND 0x02
+
+//Definitions for operating mode
+#define OPERATION_MODE_CONFIG 0x00
+#define OPERATION_MODE_ACCONLY 0x01
+#define OPERATION_MODE_MAGONLY 0x02
+#define OPERATION_MODE_GYRONLY 0x03
+#define OPERATION_MODE_ACCMAG 0x04
+#define OPERATION_MODE_ACCGYRO 0x05
+#define OPERATION_MODE_MAGGYRO 0x06
+#define OPERATION_MODE_AMG 0x07
+#define OPERATION_MODE_IMUPLUS 0x08
+#define OPERATION_MODE_COMPASS 0x09
+#define OPERATION_MODE_M4G 0x0A
+#define OPERATION_MODE_NDOF_FMC_OFF 0x0B
+#define OPERATION_MODE_NDOF 0x0C
+
+typedef struct values{
+ int16_t rawx,rawy,rawz;
+ float x,y,z;
+ }values;
+
+typedef struct angles{
+ int16_t rawroll,rawpitch,rawyaw;
+ float roll, pitch, yaw;
+ } angles;
+
+typedef struct quaternion{
+ int16_t raww,rawx,rawy,rawz;
+ float w,x,y,z;
+ }quaternion;
+
+typedef struct chip{
+ char id;
+ char accel;
+ char gyro;
+ char mag;
+ char sw[2];
+ char bootload;
+ char serial[16];
+ }chip;
+
+/** Class for operating Bosch BNO055 sensor over I2C **/
+class BNO055
+{
+public:
+
+/** Create BNO055 instance **/
+ BNO055(PinName SDA, PinName SCL);
+
+/** Perform a power-on reset of the BNO055 **/
+ void reset();
+/** Check that the BNO055 is connected and download the software details
+and serial number of chip and store in ID structure **/
+ bool check();
+/** Turn the external timing crystal on/off **/
+ void SetExternalCrystal(bool yn);
+/** Set the operation mode of the sensor **/
+ void setmode(char mode);
+/** Set the power mode of the sensor **/
+ void setpowermode(char mode);
+
+/** Set the output units from the accelerometer, either MPERSPERS or MILLIG **/
+ void set_accel_units(char units);
+/** Set the output units from the gyroscope, either DEG_PER_SEC or RAD_PER_SEC **/
+ void set_anglerate_units(char units);
+/** Set the output units from the IMU, either DEGREES or RADIANS **/
+ void set_angle_units(char units);
+/** Set the output units from the temperature sensor, either CENTIGRADE or FAHRENHEIT **/
+ void set_temp_units(char units);
+/** Set the data output format to either WINDOWS or ANDROID **/
+ void set_orientation(char units);
+/** Set the mapping of the exes/directions as per page 25 of datasheet
+ range 0-7, any value outside this will set the orientation to P1 (default at power up) **/
+ void set_mapping(char orient);
+
+/** Get the current values from the accelerometer **/
+ void get_accel(void);
+/** Get the current values from the gyroscope **/
+ void get_gyro(void);
+/** Get the current values from the magnetometer **/
+ void get_mag(void);
+/** Get the corrected linear acceleration **/
+ void get_lia(void);
+/** Get the current gravity vector **/
+ void get_grv(void);
+/** Get the output quaternion **/
+ void get_quat(void);
+/** Get the current Euler angles **/
+ void get_angles(void);
+/** Get the current temperature **/
+ void get_temp(void);
+
+/** Read the calibration status register and store the result in the calib variable **/
+ void get_calib(void);
+/** Read the offset and radius values into the calibration array**/
+ void read_calibration_data(void);
+/** Write the contents of the calibration array into the registers **/
+ void write_calibration_data(void);
+
+/** Structures containing 3-axis data for acceleration, rate of turn and magnetic field.
+ x,y,z are the scale floating point values and
+ rawx, rawy, rawz are the int16_t values read from the sensors **/
+ values accel,gyro,mag,lia,gravity;
+/** Stucture containing the Euler angles as yaw, pitch, roll as scaled floating point
+ and rawyaw, rawroll & rollpitch as the int16_t values loaded from the registers **/
+ angles euler;
+/** Quaternion values as w,x,y,z (scaled floating point) and raww etc... as int16_t loaded from the
+ registers **/
+ quaternion quat;
+
+/** Current contents of calibration status register **/
+ char calib;
+/** Contents of the 22 registers containing offset and radius values used as calibration by the sensor **/
+ char calibration[22];
+/** Structure containing sensor numbers, software version and chip UID **/
+ chip ID;
+/** Current temperature **/
+ int temperature;
+
+ private:
+
+ I2C _i2c;
+ char rx,tx[2],address; //I2C variables
+ char rawdata[22]; //Temporary array for input data values
+ char op_mode;
+ char pwr_mode;
+ float accel_scale,rate_scale,angle_scale;
+ int temp_scale;
+
+void readchar(char location){
+ tx[0] = location;
+ _i2c.write(address,tx,1,true);
+ _i2c.read(address,&rx,1,false);
+}
+
+void writechar(char location, char value){
+ tx[0] = location;
+ tx[1] = value;
+ _i2c.write(address,tx,2);
+}
+
+void setpage(char value){
+ writechar(BNO055_PAGE_ID_ADDR,value);
+}
+ };
+#endif
\ No newline at end of file
diff -r a8e6e26ebe0f -r b178e785986d BNO055.lib --- a/BNO055.lib Sun May 31 07:23:02 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/StressedDave/code/BNO055/#1db1628eb8b2
diff -r a8e6e26ebe0f -r b178e785986d main.cpp
--- a/main.cpp Sun May 31 07:23:02 2015 +0000
+++ b/main.cpp Tue May 22 11:29:05 2018 +0000
@@ -1,40 +1,356 @@
#include "mbed.h"
+#include <math.h>
+
#include "BNO055.h"
+#define DIGITS 8
+//円周率
+#define PI 3.14159265358979
+//モータードライバ
+#define HF_MOTRE 0x01
+#define HB_MOTRE 0x02
+#define MF_MOTRE 0x03
+#define MB_MOTRE 0x04
+#define ARM_UD 0x05
+#define ARM_OC 0x06
+#define RERAY 0x07
+#define R1 0x0A
+//モータードライバへの命令
+#define STOP 0
+#define CW 1
+#define CCW -1
+#define bSTOP 10
+#define bCW 11
+#define bCCW -11
+
+#define sCW 21
+#define sCCW -21
+#define shCW 31
+#define shCCW -31
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+//DigitalOut ledx(LED4);
+Serial serial(P0_15, P0_1);
+Serial s485(P0_26, P0_16);
+DigitalOut DE(P0_27);
+
+AnalogIn test(P0_4);
+
+//Serial serial2(p28, p27);
+I2C md_i2c_tx(P0_11, P0_10);
+Ticker timer;
Serial pc(USBTX, USBRX);
-BNO055 imu(I2C_SDA,I2C_SCL);
-DigitalOut led(LED1);
+
+BNO055 imu(dp15, dp25);
+double yaw, roll, pitch;
+
+
+int cnt_now = -1;
+volatile unsigned char dualshock_cmd_getflag = 0;
+volatile unsigned char dualshock_data[9] = {0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80};
+volatile unsigned char dualshock_data_number = 0;
+
+uint16_t cnt1 = 0;
+volatile unsigned char dualshock_cmd_getflag1 = 0;
+volatile unsigned char dualshock_data1[9] = {0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80};
+volatile unsigned char dualshock_data_number1 = 0;
+
+uint16_t cnt2 = 0;
+volatile unsigned char dualshock_cmd_getflag2 = 0;
+volatile unsigned char dualshock_data2[9] = {0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80};
+volatile unsigned char dualshock_data_number2 = 0;
+char str[20];
+char usart_rx = 0;
+double lx, ly, lraw_rad, lclearance, ldistance, langle;
+double rx, ry, rraw_rad, rclearance, rdistance, rangle;
+
+void cv2bin( unsigned char n ) {
+ int i;
+
+ for( i = DIGITS-1; i >= 0; i-- ) {
+ printf( "%d", ( n >> i ) & 1 );
+ }
+ printf( "\n" );
+}
+
+void joy_cal() {
+ //以下ジョイスティック計算
+ rx = -(128-dualshock_data[3])*2;
+ ry = (128-dualshock_data[4])*2;
+ if (rx >= 255) rx = 255;
+ if (rx <= -255) rx = -255;
+ if (ry >= 255) ry = 255;
+ if (ry <= -255) ry = -255;
+ rraw_rad = atan2(ry, rx)/PI;
+ rdistance = hypot(rx, ry) - rclearance;
+ rdistance *= (255 / (255 - rclearance));
+ if (rdistance < 0) rdistance = 0;
+ if (rdistance >= 255) rdistance = 255;
+ rangle = (rraw_rad < 0 ? 2 + rraw_rad : rraw_rad) * 180;
+ rangle = rdistance == 0 ? 0 : rangle;
+
+ if (rx > 0) {
+ rx -= rclearance;
+ if (rx < 0) rx = 0;
+ } else if (rx < 0) {
+ rx += rclearance;
+ if (rx > 0) rx = 0;
+ }
+ rx *= (255 / (255 - rclearance));
+
+ lx = -(128-dualshock_data[5])*2;
+ ly = (128-dualshock_data[6])*2;
+ if (lx >= 255) lx = 255;
+ if (lx <= -255) lx = -255;
+ if (ly >= 255) ly = 255;
+ if (ly <= -255) ly = -255;
+ lraw_rad = atan2(ly, lx)/PI;
+ ldistance = hypot(lx, ly) - lclearance;
+ ldistance *= (255 / (255 - lclearance));
+ if (ldistance < 0) ldistance = 0;
+ if (ldistance >= 255) ldistance = 255;
+ langle = (lraw_rad < 0 ? 2 + lraw_rad : lraw_rad) * 180;
+ langle = ldistance == 0 ? 0 : langle;
+}
+
+//タイマ割り込み
+void time() {
+
+ if (dualshock_cmd_getflag & 0x02) {
+ dualshock_cmd_getflag = 0;
+ dualshock_data[1] = 0x00;
+ dualshock_data[2] = 0x00;
+ dualshock_data[3] = 0x80;
+ dualshock_data[4] = 0x80;
+ dualshock_data[5] = 0x80;
+ dualshock_data[6] = 0x80;
+ led2 = 0;
+ }
+ else
+ dualshock_cmd_getflag |= 0x02;
+}
+
+
+void usart(){
+ unsigned char rxdata;
+
+ rxdata = serial.getc();
+ serial.putc(dualshock_data_number);
+ if (dualshock_data_number == 0 && rxdata == 'S')
+ dualshock_data_number++;
+ else if(dualshock_data_number >= 1 && dualshock_data_number <= 6) {
+ if (dualshock_data_number <= 2)
+ dualshock_data[dualshock_data_number] = ~rxdata;
+ else
+ dualshock_data[dualshock_data_number] = rxdata;
+ dualshock_data_number++;
+ }
+ else if (dualshock_data_number == 7 && rxdata == 'E') {
+ dualshock_cmd_getflag = 0x01;
+ dualshock_data_number = 0;
+ led2 = 1;
+ joy_cal();
+ }
+ //ledx = !ledx;
+}
+
+void ics() {
+ wait_ms(1);
+ led3 = 0;
+ //EN_IN = 0;
+}
+
+
+//i2c通信
+void md_setoutput(unsigned char address, int rotate, int duty) {
+ char val;
+ char data[2];
+
+ /* H30新型:処理最適化 */
+ switch (rotate) {
+ case CW: data[0] = 'F'; break;// 電圧比例制御モード(PWMがLの区間はフリー)
+ case CCW: data[0] = 'R'; break;
+ case STOP: data[0] = 'S'; break;
+
+ case bCW: data[0] = 'f'; break; // 電圧比例制御モード(PWMがLの区間はブレーキ)
+ case bCCW: data[0] = 'r'; break;
+ case bSTOP: data[0] = 's'; break;
+
+ case sCW: data[0] = 'A'; break; // 速度比例制御モード
+ case sCCW: data[0] = 'B'; break;
+
+ case shCW: data[0] = 'a'; break; // 速度比例制御モード(命令パケット最上位ビットに指令値9ビット目を入れることで分解能2倍)
+ case shCCW: data[0] = 'b'; break;
+ }
+
+ data[1] = duty & 0xFF;
+
+ val = md_i2c_tx.write(address << 1, data, 2); //duty送信
+}
+
+void set_pos(int id, float angle) {
+ float pos = 0;
+ int data = 0; //3500~11500
+ angle += 135;
+ pos = (8000 / 270) * angle;
+ data = (int)(pos > 0.5 ? pos + 0.5 : pos - 0.5);
+ data += 3500;
+
+ //int CMD = 0b10000000 + id;
+ //char pos_H = (uint16_t)((data & 0b11111110000000) >> 7);
+ //char pos_L = (uint16_t)(data & 0b00000001111111);
+
+
+ led3 = 1;
+ //EN_IN = 1;
+ //servo.putc(CMD);
+ //servo.putc(pos_H);
+ //servo.putc(pos_L);
+}
int main() {
- pc.baud(115200);
- pc.printf("BNO055 Hello World\r\n\r\n");
- led = 1;
-// Reset the BNO055
+ wait_ms(10);
+ unsigned char stick_gain = 4;
+ //led1 = 1;
+ led2 = 0;
+ led3 = 0;
+ //ledx = 1;
+ serial.baud(19200);//シリアル通信
+ s485.baud(19200);
+
+
+ //serial2.baud(19200);//シリアル通信
+ pc.baud(230400);
+
+ md_i2c_tx.frequency(20000000UL/(16 + 2 * 2 * 16)/2);//I2C通信
+ timer.attach_us(time, 100000); //タイマ割り込み
+ serial.attach(&usart, Serial::RxIrq); //受信割り込み
+ //serial2.attach(&usart2, Serial::RxIrq); //受信割り込み
+
+ //EN_IN = 0;
+ //servo.baud(115200);
+ //servo.format(8, Serial::Even, 1);
+ //servo.attach(&ics, Serial::TxIrq);
+
+
imu.reset();
-// Check that the BNO055 is connected and flash LED if not
- if (!imu.check())
- while (true){
- led = !led;
- wait(0.1);
+ imu.check();
+
+
+ // テスト用回転モード切り替え記録
+ int Mcw = CW;
+ int Mccw = CCW;
+ int Mstop = STOP;
+
+ lclearance = 60; //平行移動
+ rclearance = 90; //旋回
+ float power_up = 0;
+ while (1) {
+ DE = 1;
+ s485.printf("S");
+ //DE = 0;
+ //led1 = EMS_STATE;
+ //set_pos(0, -65);
+ //CS = 0;
+ //isoSPI.write(165);
+ //CS = 1;
+ /********************以下速度アップ処理********************/
+ if (dualshock_data[2] & 0x04) power_up = 1;
+ else power_up = 0.8;
+ /********************以下メカナムメイン処理********************/
+ if (rx > 0) {
+ ////////////////////頭を右方向に旋回
+ md_setoutput(HF_MOTRE,Mcw,rx*power_up);
+ md_setoutput(HB_MOTRE,Mcw,rx*power_up);
+ md_setoutput(MF_MOTRE,Mcw,rx*power_up);
+ md_setoutput(MB_MOTRE,Mcw,rx*power_up);
+ } else if (rx < 0) {
+ ////////////////////頭を左方向に旋回
+ md_setoutput(HF_MOTRE,Mccw,-rx*power_up);
+ md_setoutput(HB_MOTRE,Mccw,-rx*power_up);
+ md_setoutput(MF_MOTRE,Mccw,-rx*power_up);
+ md_setoutput(MB_MOTRE,Mccw,-rx*power_up);
+ } else {
+ ////////////////////旋回をしない場合平行移動を行う
+ //
+ if ((ldistance != 0) && ((langle < 45) || (langle >= 315))){ //右
+ md_setoutput(HF_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(HB_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(MF_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(MB_MOTRE,Mccw,ldistance*power_up);
+ } else if ((ldistance != 0) && (langle < 135)) { //前
+ md_setoutput(HF_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(HB_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(MF_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(MB_MOTRE,Mcw,ldistance*power_up);
+ } else if ((ldistance != 0) && (langle < 225)) { //左
+ md_setoutput(HF_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(HB_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(MF_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(MB_MOTRE,Mcw,ldistance*power_up);
+ } else if ((ldistance != 0) && (langle < 315)) { //後
+ md_setoutput(HF_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(HB_MOTRE,Mccw,ldistance*power_up);
+ md_setoutput(MF_MOTRE,Mcw,ldistance*power_up);
+ md_setoutput(MB_MOTRE,Mccw,ldistance*power_up);
+ } else { //停止
+ md_setoutput(HF_MOTRE,Mstop,0);
+ md_setoutput(HB_MOTRE,Mstop,0);
+ md_setoutput(MF_MOTRE,Mstop,0);
+ md_setoutput(MB_MOTRE,Mstop,0);
}
-// Display sensor information
- pc.printf("BNO055 found\r\n\r\n");
- pc.printf("Chip ID: %0z\r\n",imu.ID.id);
- pc.printf("Accelerometer ID: %0z\r\n",imu.ID.accel);
- pc.printf("Gyroscope ID: %0z\r\n",imu.ID.gyro);
- pc.printf("Magnetometer ID: %0z\r\n\r\n",imu.ID.mag);
- pc.printf("Firmware version v%d.%0d\r\n",imu.ID.sw[0],imu.ID.sw[1]);
- pc.printf("Bootloader version v%d\r\n\r\n",imu.ID.bootload);
-// Display chip serial number
- for (int i = 0; i<4; i++){
- pc.printf("%0z.%0z.%0z.%0z\r\n",imu.ID.serial[i*4],imu.ID.serial[i*4+1],imu.ID.serial[i*4+2],imu.ID.serial[i*4+3]);
+ }
+
+ /* 回転モード設定(テスト用) */
+ if (dualshock_data[2] & 0x40) { //通常フリー
+ Mcw = CW;
+ Mccw = CCW;
+ Mstop = STOP;
+ led1 = 0;
+ } else if (dualshock_data[2] & 0x20) { //通常ブレーキ
+ Mcw = bCW;
+ Mccw = bCCW;
+ Mstop = bSTOP;
+ led1 = 1;
+ } else if (dualshock_data[2] & 0x10) { //速調
+ Mcw = sCW;
+ Mccw = sCCW;
+ Mstop = bSTOP;
+ led1 = 1;
+ }
+ {
+ imu.setmode(OPERATION_MODE_IMUPLUS);
+ imu.get_calib();
+ imu.get_angles();
+ imu.get_quat();
+
+ double q1, q2, q3, q4;
+ q1 = imu.quat.w;
+ q2 = imu.quat.x;
+ q3 = imu.quat.y;
+ q4 = imu.quat.z;
+
+ double q3q3 = q3 * q3;
+
+ double m1 = +2.0 * (q1 * q2 + q3 * q4);
+ double m2 = +1.0 - 2.0 * (q2 * q2 + q3q3);
+ //roll = atan2(m1, m2) * 57.2957795131;
+
+ m1 = +2.0 * (q1 * q3 - q4 * q2);
+ m1 = (m1 > 1.0)? 1.0 : m1;
+ m1 = (m1 < -1.0)? -1.0 : m1;
+ //pitch = asin(m1) * 57.2957795131;
+
+ m1 = +2.0 * (q1 * q4 + q2 * q3);
+ m2 = +1.0 - 2.0 * (q3q3 + q4 * q4);
+ //yaw = atan2(m1, m2) * 57.2957795131;
+
+ //pc.printf("yaw\t = %05d, roll\t = %05d, pitch\t = %05d\r\n", (int)yaw, (int)roll, (int)pitch);
+ pc.printf("%05d\r\n", test.read_u16());
+ }
+
+ wait_ms(10);
}
- pc.printf("\r\n");
- while (true) {
- imu.setmode(OPERATION_MODE_NDOF);
- imu.get_calib();
- imu.get_angles();
- pc.printf("%0z %5.1d %5.1d %5.1d\r\n",imu.calib,imu.euler.roll,imu.euler.pitch,imu.euler.yaw);
- wait(1.0);
- }
-}
+}
\ No newline at end of file
