![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
test
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