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.
ADXL345.cpp
00001 /* 00002 * mbed library program 00003 * ADXL345: 3-axis accelerometer, made by Analog Devices 00004 * http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf 00005 * 00006 * Copyright (c) 2017 Kenji Arai / JH1PJL 00007 * http://www.page.sannet.ne.jp/kenjia/index.html 00008 * http://mbed.org/users/kenjiArai/ 00009 * Modify: August 13th, 2017 00010 * Revised: September 23rd, 2017 00011 * 00012 */ 00013 00014 #include "ADXL345.h" 00015 00016 // definition for Nomalization 00017 #define ADXL345_SENSITIVITY_2G 4.0f 00018 #define ADXL345_SENSITIVITY_4G 8.0f 00019 #define ADXL345_SENSITIVITY_8G 16.0f 00020 #define ADXL345_SENSITIVITY_16G 32.0f 00021 #define ADXL345_SEN_FULL_RES 4.0f 00022 00023 //Gravity at Earth's surface in m/s/s 00024 #define GRAVITY (9.80665f / 1000) 00025 00026 #if MBED_MAJOR_VERSION == 2 00027 #define WAIT_MS(x) wait_ms(x) 00028 #elif MBED_MAJOR_VERSION == 5 00029 #define WAIT_MS(x) Thread::wait(x) 00030 #else 00031 #error "Running on Unknown OS" 00032 #endif 00033 00034 ADXL345::ADXL345 (PinName p_sda, PinName p_scl, 00035 uint8_t addr, uint8_t data_rate, uint8_t fullscale) : 00036 _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) 00037 { 00038 _i2c.frequency(400000); 00039 initialize (addr, data_rate, fullscale); 00040 } 00041 00042 ADXL345::ADXL345 (PinName p_sda, PinName p_scl, uint8_t addr) : 00043 _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) 00044 { 00045 _i2c.frequency(400000); 00046 initialize (addr, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00047 } 00048 00049 ADXL345::ADXL345 (PinName p_sda, PinName p_scl) : 00050 _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) 00051 { 00052 _i2c.frequency(400000); 00053 initialize(ADXL345_V_CHIP_ADDR, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00054 if (acc_ready == false){ 00055 initialize(ADXL345_G_CHIP_ADDR, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00056 } 00057 } 00058 00059 ADXL345::ADXL345 (I2C& p_i2c, 00060 uint8_t addr, uint8_t data_rate, uint8_t fullscale) : _i2c(p_i2c) 00061 { 00062 _i2c.frequency(400000); 00063 initialize (addr, data_rate, fullscale); 00064 } 00065 00066 ADXL345::ADXL345 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c) 00067 { 00068 _i2c.frequency(400000); 00069 initialize (addr, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00070 } 00071 00072 ADXL345::ADXL345 (I2C& p_i2c) : _i2c(p_i2c) 00073 { 00074 _i2c.frequency(400000); 00075 initialize(ADXL345_V_CHIP_ADDR, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00076 if (acc_ready == false){ 00077 initialize(ADXL345_G_CHIP_ADDR, ADXL345_DR_200HZ, ADXL345_FULL_RES_16G); 00078 } 00079 } 00080 00081 void ADXL345::initialize (uint8_t addr, uint8_t data_rate, uint8_t fullscale) 00082 { 00083 // Check acc is available or not 00084 acc_addr = addr; 00085 dt[0] = ADXL345_DEVID; 00086 _i2c.write(acc_addr, dt, 1, true); 00087 _i2c.read(acc_addr, dt, 1, false); 00088 if (dt[0] == ADXL345_DEVICE_ID){ 00089 acc_ready = true; 00090 } else { 00091 acc_ready = false; 00092 return; // acc chip is NOT on I2C line then terminate 00093 } 00094 // BW Rate 00095 dt[0] = ADXL345_BW_RATE; 00096 dt[1] = data_rate | ADXL345_NOT_LOW_PWR; // normal(not low power mode) 00097 setting_data[0] = dt[1]; 00098 _i2c.write(acc_addr, dt, 2, false); 00099 // Data format (measurement range) 00100 dt[0] = ADXL345_DATA_FORMAT; 00101 dt[1] = fullscale; 00102 setting_data[1] = dt[1]; 00103 _i2c.write(acc_addr, dt, 2, false); 00104 switch (fullscale){ 00105 case ADXL345_FS_2G: 00106 fs_factor = ADXL345_SENSITIVITY_2G; 00107 break; 00108 case ADXL345_FS_4G: 00109 fs_factor = ADXL345_SENSITIVITY_4G; 00110 break; 00111 case ADXL345_FS_8G: 00112 fs_factor = ADXL345_SENSITIVITY_8G; 00113 break; 00114 case ADXL345_FS_16G: 00115 fs_factor = ADXL345_SENSITIVITY_16G; 00116 break; 00117 case ADXL345_FULL_RES_16G: 00118 fs_factor = ADXL345_SEN_FULL_RES; 00119 break; 00120 default: 00121 fs_factor = 1.0f; 00122 break; 00123 } 00124 // Data ready flag 00125 dt[0] = ADXL345_INT_ENABLE; 00126 dt[1] = 0x80; 00127 setting_data[2] = dt[1]; 00128 _i2c.write(acc_addr, dt, 2, false); 00129 // Start measurement mode 00130 dt[0] = ADXL345_POWER_CTL; 00131 dt[1] = 0x08; 00132 setting_data[3] = dt[1]; 00133 _i2c.write(acc_addr, dt, 2, false); 00134 // offset compensation 00135 dt[0] = ADXL345_OFSX; 00136 dt[1] = 0x01; 00137 _i2c.write(acc_addr, dt, 2, false); 00138 dt[0] = ADXL345_OFSY; 00139 dt[1] = 0x00; 00140 _i2c.write(acc_addr, dt, 2, false); 00141 dt[0] = ADXL345_OFSZ; 00142 dt[1] = 0x00; 00143 _i2c.write(acc_addr, dt, 2, false); 00144 } 00145 00146 void ADXL345::read_reg_data(char *data) 00147 { 00148 // read all of X,Y & Z 00149 dt[0] = ADXL345_DATAX0; 00150 _i2c.write(acc_addr, dt, 1, true); 00151 _i2c.read(acc_addr, data, 6, false); 00152 } 00153 00154 void ADXL345::read_mg_data(float *dt_usr) 00155 { 00156 return read_mg_g_data(dt_usr, 0); 00157 } 00158 00159 void ADXL345::read_g_data(float *dt_usr) 00160 { 00161 return read_mg_g_data(dt_usr, 1); 00162 } 00163 00164 void ADXL345::read_data(float *dt_usr) 00165 { 00166 return read_mg_g_data(dt_usr, 2); 00167 } 00168 00169 void ADXL345::read_mg_g_data(float *dt_usr, uint8_t n) 00170 { 00171 char data[6]; 00172 float fct; 00173 00174 if (acc_ready == false){ 00175 dt_usr[0] = 0; 00176 dt_usr[1] = 0; 00177 dt_usr[2] = 0; 00178 return; 00179 } 00180 read_reg_data(data); 00181 if (n == 0){ 00182 fct = fs_factor; 00183 } else if (n == 1){ 00184 fct = fs_factor / 1000.0f; 00185 } else { 00186 fct = fs_factor * GRAVITY; 00187 } 00188 // change data type 00189 dt_usr[0] = float(int16_t((data[1] << 8) | data[0])) * fct; 00190 dt_usr[1] = float(int16_t((data[3] << 8) | data[2])) * fct; 00191 dt_usr[2] = float(int16_t((data[5] << 8) | data[4])) * fct; 00192 } 00193 00194 uint8_t ADXL345::read_id() 00195 { 00196 dt[0] = ADXL345_DEVID; 00197 _i2c.write(acc_addr, dt, 1, true); 00198 _i2c.read(acc_addr, dt, 1, false); 00199 return (uint8_t)dt[0]; 00200 } 00201 00202 bool ADXL345::data_ready() 00203 { 00204 if (acc_ready == true){ 00205 dt[0] = ADXL345_INT_SOURCE; 00206 _i2c.write(acc_addr, dt, 1, true); 00207 _i2c.read(acc_addr, dt, 1, false); 00208 if (dt[0] & 0x80){ // Check ready bit 00209 return true; 00210 } else { 00211 return false; 00212 } 00213 } 00214 return false; 00215 } 00216 00217 void ADXL345::frequency(int hz) 00218 { 00219 _i2c.frequency(hz); 00220 } 00221 00222 uint8_t ADXL345::read_reg(uint8_t addr) 00223 { 00224 if (acc_ready == true){ 00225 dt[0] = addr; 00226 _i2c.write(acc_addr, dt, 1, true); 00227 _i2c.read(acc_addr, dt, 1, false); 00228 } else { 00229 dt[0] = 0xff; 00230 } 00231 return (uint8_t)dt[0]; 00232 } 00233 00234 void ADXL345::write_reg(uint8_t addr, uint8_t data) 00235 { 00236 if (acc_ready == true){ 00237 dt[0] = addr; 00238 dt[1] = data; 00239 _i2c.write(acc_addr, dt, 2, false); 00240 } 00241 } 00242 00243 void ADXL345::debug_print(void) 00244 { 00245 printf("ADXL345 3-axes accelerometer\r\n"); 00246 printf(" DEVID=0x%02x\r\n", read_reg(ADXL345_DEVID)); 00247 printf(" THRESH_TAP=0x%02x\r\n", read_reg(ADXL345_THRESH_TAP)); 00248 printf(" OFSX=0x%02x,", read_reg(ADXL345_OFSX)); 00249 printf(" OFSY=0x%02x,", read_reg(ADXL345_OFSY)); 00250 printf(" OFSZ=0x%02x\r\n", read_reg(ADXL345_OFSZ)); 00251 printf(" DUR=0x%02x,", read_reg(ADXL345_DUR)); 00252 printf(" LATENT=0x%02x,", read_reg(ADXL345_LATENT)); 00253 printf(" WINDOW=0x%02x\r\n", read_reg(ADXL345_WINDOW)); 00254 printf(" THRESH_ACT=0x%02x,", read_reg(ADXL345_THRESH_ACT)); 00255 printf(" THRESH_INACT=0x%02x\r\n", read_reg(ADXL345_THRESH_INACT)); 00256 printf(" TIME_INACT=0x%02x,", read_reg(ADXL345_TIME_INACT)); 00257 printf(" ACT_INACT_CTL=0x%02x\r\n", 00258 read_reg(ADXL345_ACT_INACT_CTL)); 00259 printf(" THRESH_FF=0x%02x,", read_reg(ADXL345_THRESH_FF)); 00260 printf(" TIME_FF=0x%02x,", read_reg(ADXL345_TIME_FF)); 00261 printf(" TAP_AXES=0x%02x,", read_reg(ADXL345_TAP_AXES)); 00262 printf(" ACT_TAP_STATUS=0x%02x\r\n", 00263 read_reg(ADXL345_ACT_TAP_STATUS)); 00264 printf(" BW_RATE=0x%02x\r\n", read_reg(ADXL345_BW_RATE)); 00265 printf(" POWER_CTL=0x%02x\r\n", read_reg(ADXL345_POWER_CTL)); 00266 printf(" INT_ENABLE=0x%02x,", read_reg(ADXL345_INT_ENABLE)); 00267 printf(" INT_MAP=0x%02x,", read_reg(ADXL345_INT_MAP)); 00268 printf(" INT_SOURCE=0x%02x\r\n", read_reg(ADXL345_INT_SOURCE)); 00269 printf(" DATA_FORMAT=0x%02x\r\n", read_reg(ADXL345_DATA_FORMAT)); 00270 printf(" DATAX0=0x%02x,", read_reg(ADXL345_DATAX0)); 00271 printf(" 1=0x%02x,", read_reg(ADXL345_DATAX1)); 00272 printf(" DATAY0=0x%02x,", read_reg(ADXL345_DATAY0)); 00273 printf(" 1=0x%02x,", read_reg(ADXL345_DATAY1)); 00274 printf(" DATAZ0=0x%02x,", read_reg(ADXL345_DATAZ0)); 00275 printf(" 1=0x%02x\r\n", read_reg(ADXL345_DATAZ1)); 00276 printf(" FIFO_CTL=0x%02x,", read_reg(ADXL345_FIFO_CTL)); 00277 printf(" FIFO_STATUS=0x%02x\r\n", read_reg(ADXL345_FIFO_STATUS)); 00278 // internal data 00279 printf(" ---- fs_factor=%f, acc_addr=0x%02x\r\n", fs_factor, acc_addr); 00280 } 00281 00282 void ADXL345::self_test(void) 00283 { 00284 float dt0[3] ={0}; 00285 float dt1[3] ={0}; 00286 float dt2[3]; 00287 00288 dt[0] = ADXL345_DATA_FORMAT; 00289 dt[1] = 0x0B; 00290 _i2c.write(acc_addr, dt, 2, false); 00291 dt[0] = ADXL345_POWER_CTL; 00292 dt[1] = 0x08; 00293 _i2c.write(acc_addr, dt, 2, false); 00294 dt[0] = ADXL345_INT_ENABLE; 00295 dt[1] = 0x80; 00296 _i2c.write(acc_addr, dt, 2, false); 00297 WAIT_MS(40); 00298 for(uint8_t n = 0; n < 100; n++){ 00299 read_data(dt2); 00300 dt0[0] += dt2[0]; 00301 dt0[1] += dt2[1]; 00302 dt0[2] += dt2[2]; 00303 } 00304 dt0[0] /= 100; 00305 dt0[1] /= 100; 00306 dt0[2] /= 100; 00307 // 00308 dt[0] = ADXL345_DATA_FORMAT; 00309 dt[1] = 0x8B; 00310 _i2c.write(acc_addr, dt, 2, false); 00311 WAIT_MS(40); 00312 for(uint8_t n = 0; n < 100; n++){ 00313 read_data(dt2); 00314 dt1[0] += dt2[0]; 00315 dt1[1] += dt2[1]; 00316 dt1[2] += dt2[2]; 00317 } 00318 dt1[0] /= 100; 00319 dt1[1] /= 100; 00320 dt1[2] /= 100; 00321 printf("X, 1st, %+8.4f, 2nd, %+8.4f, diff, %+8.4f\r\n", 00322 dt0[0], dt1[0], dt0[0] - dt1[0]); 00323 printf("Y, 1st, %+8.4f, 2nd, %+8.4f, diff, %+8.4f\r\n", 00324 dt0[1], dt1[1], dt0[1] - dt1[1]); 00325 printf("Z, 1st, %+8.4f, 2nd, %+8.4f, diff, %+8.4f\r\n", 00326 dt0[2], dt1[2], dt0[2] - dt1[2]); 00327 //Recover original setting 00328 // BW Rate 00329 dt[0] = ADXL345_BW_RATE; 00330 dt[1] = setting_data[0]; 00331 _i2c.write(acc_addr, dt, 2, false); 00332 // Data format (measurement range) 00333 dt[0] = ADXL345_DATA_FORMAT; 00334 dt[1] = setting_data[1]; 00335 _i2c.write(acc_addr, dt, 2, false); 00336 // Data ready flag 00337 dt[0] = ADXL345_INT_ENABLE; 00338 dt[1] = setting_data[2]; 00339 _i2c.write(acc_addr, dt, 2, false); 00340 // Start measurement mode 00341 dt[0] = ADXL345_POWER_CTL; 00342 dt[1] = setting_data[3]; 00343 _i2c.write(acc_addr, dt, 2, false); 00344 WAIT_MS(40); 00345 read_data(dt2); // dummy read 00346 }
Generated on Wed Jul 27 2022 17:10:48 by
1.7.2