00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <iostream>
00049 #include <string>
00050 #include <ros/ros.h>
00051 #include "bma180/bma180s.h"
00052 #include <sstream>
00053 #include <ros/time.h>
00054 #include <math.h>
00055 #include <vector>
00056
00057 #define ROS_INFO printf
00058 #define ROS_WARN printf
00059 #define ROS_ERROR printf
00060
00061 Bma180::Bma180( double max_acceleration_g, double dBandwidth_Hz, bool bCalibrate, double dRate_Hz, std::string sSub20Serial ):
00062 bSubDeviceOpen (false),
00063 bSubDeviceConfigured (false)
00064 {
00065 int error_code;
00066 int iSPI_cfg_set;
00067 int iSPI_cfg_get;
00068 int iNumOfRanges;
00069 int iElCount;
00070 std::stringstream ss_errmsg;
00071 std::string ss_config, sub20Serial;
00072 sub_device sub20dev;
00073 sub_handle sub20handle;
00074 OneSub20Config OneSub20Configuration;
00075
00076 printf("Max acceleration entered: %f [g].\n", max_acceleration_g);
00077 printf("Sensor bandwidth entered: %f [Hz].\n", dBandwidth_Hz);
00078 printf("Sensor Reading Rate entered: %f [Hz].\n", dRate_Hz);
00079
00080
00081 set_calibstatus( bCalibrate );
00082
00083
00084 iNumOfRanges = sizeof(bma180_cmd::COMMAND_FULLSCALE_G) / sizeof(char);
00085 iElCount = 0;
00086 while( (max_acceleration_g > bma180_cmd::dFULLRANGELOOKUP[iElCount]) && (iElCount < iNumOfRanges) )
00087 {
00088 iElCount++;
00089 };
00090 printf("Range chosen: %f [g].\n", bma180_cmd::dFULLRANGELOOKUP[iElCount]);
00091
00092 chMaxAccRange_selected = bma180_cmd::COMMAND_FULLSCALE_G[iElCount];
00093
00094
00095 iNumOfRanges = sizeof(bma180_cmd::COMMAND_BANDWIDTH_HZ) / sizeof(char);
00096 iElCount = 0;
00097 while( (dBandwidth_Hz > bma180_cmd::dBWLOOKUP[iElCount]) && (iElCount < iNumOfRanges) )
00098 {
00099 iElCount++;
00100 };
00101 printf("Range chosen BW: %f.\n", bma180_cmd::dBWLOOKUP[iElCount]);
00102
00103 chBW_selected = bma180_cmd::COMMAND_BANDWIDTH_HZ[iElCount];
00104
00105
00106 sub20dev = 0;
00107 sub20dev = sub_find_devices(sub20dev);
00108 while( sub20dev != 0 )
00109 {
00110 sub20handle = sub_open( sub20dev );
00111
00112 if( sub20handle > 0 )
00113 {
00114 sub20Serial.clear();
00115 sub20Serial.resize( bma180_cmd::uSERIALNUMLENGTH );
00116 sub_get_serial_number( sub20handle, const_cast<char*>(sub20Serial.c_str()), sub20Serial.size() );
00117 printf( "Serial Number: %s.\n", sub20Serial.c_str() );
00118 if( strcmp(sub20Serial.c_str(), sSub20Serial.c_str()) == 0 )
00119 {
00120 subhndl = sub20handle;
00121
00122
00123 std::cout << "---Initializing SPI Interface---" << std::endl;;
00124
00125 error_code = sub_spi_config( sub20handle, 0, &iSPI_cfg_get );
00126 std::cout << "Sub SPI config : " << iSPI_cfg_get << std::endl;
00127
00128
00129
00130 iSPI_cfg_set = SPI_ENABLE | SPI_CPOL_FALL | SPI_SETUP_SMPL | SPI_MSB_FIRST | SPI_CLK_2MHZ;
00131
00132 error_code = sub_spi_config( sub20handle, iSPI_cfg_set, 0 );
00133
00134 error_code = sub_spi_config( sub20handle, 0, &iSPI_cfg_get );
00135
00136 if( iSPI_cfg_get == iSPI_cfg_set )
00137 {
00138 std::cout<< "SPI Configuration: " << iSPI_cfg_set << " successfully stored." << std::endl;
00139
00140
00141 OneSub20Configuration.bSubSPIConfigured = true;
00142 OneSub20Configuration.handle_subdev = sub20handle;
00143
00144
00145 confsens_on_sub20( &OneSub20Configuration, chMaxAccRange_selected, chBW_selected);
00146 }
00147 else
00148 {
00149 ROS_INFO("ERROR! SPI Configuration %d not accepted by device.\n", iSPI_cfg_set);
00150
00151
00152 OneSub20Configuration.bSubSPIConfigured = false;
00153 }
00154 if( OneSub20Configuration.bSubSPIConfigured )
00155 {
00156
00157 serial_number.clear();
00158 serial_number.resize( bma180_cmd::uSERIALNUMLENGTH );
00159 sub_get_serial_number( sub20handle, const_cast<char*>(serial_number.c_str()), serial_number.size() );
00160 OneSub20Configuration.strSub20Serial = serial_number;
00161 OneSub20Configuration.subdev = sub20dev;
00162 std::cout << "Device Handle: " << OneSub20Configuration.handle_subdev << std::endl;
00163 std::cout << "Serial Number: " << OneSub20Configuration.strSub20Serial << std::endl;
00164
00165
00166 Sub20Device_list.push_back( OneSub20Configuration );
00167 std::cout << "Publishing to topic /bma180." << std::endl;
00168 }
00169 break;
00170 }
00171 else
00172 {
00173 sub_close( sub20handle );
00174 }
00175 }
00176
00177 sub20dev = sub_find_devices( sub20dev );
00178 }
00179 };
00180
00181 Bma180::~Bma180()
00182 {
00183 int error_code;
00184 OneSub20Config OneSub20Configuration;
00185
00186
00187
00188
00189 error_code = sub_spi_config( subhndl, 0, 0 );
00190
00191
00192 sub_close( subhndl );
00193 while( !Sub20Device_list.empty() )
00194 {
00195 OneSub20Configuration = Sub20Device_list.back();
00196 std::cout << "Sub device removed " << OneSub20Configuration.strSub20Serial << std::endl;
00197 Sub20Device_list.pop_back();
00198 }
00199 };
00200
00201 void Bma180::GetMeasurements( std::list<OneBma180Meas> &list_meas )
00202 {
00203 char chACC_XYZ[7];
00204 double dAccX, dAccY, dAccZ;
00205 double dEstBiasX, dEstBiasY, dEstBiasZ;
00206 int uiBcorrX, uiBcorrY, uiBcorrZ, uiRawX, uiRawY, uiRawZ;
00207 double dTemp;
00208 int error_code, dummy, j = 0;
00209 bool SPIMeas = false;
00210 OneBma180Meas sMeas;
00211
00212 char chCMD;
00213 std::stringstream ss_errmsg;
00214 int chip_select;
00215 std::list<OneSub20Config>::iterator iterat;
00216
00217
00218 if( 1 > (int)Sub20Device_list.size() )
00219 {
00220 throw std::string( "No SubDevice connected OR access rights to USB not given" );
00221 }
00222
00223
00224 for( iterat = Sub20Device_list.begin(); iterat != Sub20Device_list.end(); iterat++ )
00225 {
00226
00227 if( iterat->bSubSPIConfigured == true)
00228 {
00229
00230 for( chip_select = 0; chip_select < bma180_cmd::MAX_NUM_SENSORS; chip_select++ )
00231 {
00232
00233 if( iterat->Bma180Cluster[chip_select].bConfigured == true )
00234 {
00235 error_code = 0;
00236
00237
00238
00239
00240 chCMD = bma180_cmd::ADDRESS_ACCLXYZ | bma180_cmd::FLAG_R;
00241 error_code += sub_spi_transfer( iterat->handle_subdev, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00242 error_code += sub_spi_transfer( iterat->handle_subdev, 0, chACC_XYZ, 7, SS_CONF(chip_select,SS_L) );
00243
00244 error_code += sub_spi_transfer( iterat->handle_subdev, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00245
00246 if( error_code == 0 )
00247 {
00248 SPIMeas = true;
00249 dAccX = bma180data_to_double(chACC_XYZ[1], chACC_XYZ[0], bma180_cmd::eACCEL, &uiRawX, iterat->Bma180Cluster[chip_select].dFullScaleRange );
00250 dAccY = bma180data_to_double(chACC_XYZ[3], chACC_XYZ[2], bma180_cmd::eACCEL, &uiRawY, iterat->Bma180Cluster[chip_select].dFullScaleRange );
00251 dAccZ = bma180data_to_double(chACC_XYZ[5], chACC_XYZ[4], bma180_cmd::eACCEL, &uiRawZ, iterat->Bma180Cluster[chip_select].dFullScaleRange );
00252 dTemp = bma180data_to_double(chACC_XYZ[6], chACC_XYZ[6], bma180_cmd::eTEMP, &dummy, iterat->Bma180Cluster[chip_select].dFullScaleRange );
00253
00254
00255 sMeas.dAccX[j] = dAccX;
00256 sMeas.dAccY[j] = dAccY;
00257 sMeas.dAccZ[j] = dAccZ;
00258 sMeas.dTemp = dTemp;
00259 sMeas.chip_select[j] = chip_select;
00260 j++;
00261 sMeas.iNumAccels = j;
00262
00263
00264
00265 if( bExecuteCalibration == true && 2 > (int)Sub20Device_list.size() )
00266 {
00267 if( chip_select == iCalib_CS )
00268 {
00269 if( calib_bma180.calibsens_completed() == false && calib_bma180.calibsens_set() == false )
00270 {
00271 std::cout << " Bias read from image: " << iterat->Bma180Cluster[chip_select].uiBiasImageX << " " << iterat->Bma180Cluster[chip_select].uiBiasImageY << " " << iterat->Bma180Cluster[chip_select].uiBiasImageZ << std::endl;
00272
00273 calib_bma180.setcalibsens( sMeas );
00274 }
00275 else
00276 {
00277 calib_bma180.setdata_bma180( sMeas );
00278 }
00279 if( calib_bma180.calibsens_completed() && !calib_bma180.verification_active() )
00280 {
00281
00282
00283 calib_bma180.get_estbiases(&dEstBiasX, &dEstBiasY, &dEstBiasZ);
00284 std::cout << "estimated biases : " << dEstBiasX << " " << dEstBiasY << " " << dEstBiasZ << std::endl;
00285
00286
00287
00288
00289 int iBcorrX, iBcorrY, iBcorrZ;
00290 iBcorrX = (short)( dEstBiasX / iterat->Bma180Cluster[chip_select].dFullScaleRange * 2048 + 0.5 );
00291 iBcorrY = (short)( dEstBiasY / iterat->Bma180Cluster[chip_select].dFullScaleRange * 2048 + 0.5 ) ;
00292 iBcorrZ = (short)( (dEstBiasZ - 1) / iterat->Bma180Cluster[chip_select].dFullScaleRange * 2048 + 0.5 ) ;
00293
00294 std::cout << "Bias adjustments [X Y Z] " << iBcorrX << " " << iBcorrY << " " << iBcorrZ << std::endl;
00295 std::cout << "Image values before adjustments " << iterat->Bma180Cluster[chip_select].uiBiasImageX << " " << iterat->Bma180Cluster[chip_select].uiBiasImageY << " " << iterat->Bma180Cluster[chip_select].uiBiasImageZ << std::endl;
00296 uiBcorrX = (unsigned short)( iterat->Bma180Cluster[chip_select].uiBiasImageX - ((short)( dEstBiasX / bma180_cmd::dFULLRANGELOOKUP[6] * 2048 )) );
00297 uiBcorrY = (unsigned short)( iterat->Bma180Cluster[chip_select].uiBiasImageY - ((short)( dEstBiasY / bma180_cmd::dFULLRANGELOOKUP[6] * 2048 )) );
00298 uiBcorrZ = (unsigned short)( iterat->Bma180Cluster[chip_select].uiBiasImageZ - ((short)( (dEstBiasZ - 1) / bma180_cmd::dFULLRANGELOOKUP[6] * 2048 )) );
00299
00300 std::cout << "corrected biases " << uiBcorrX << " " << uiBcorrY << " " << uiBcorrZ << std::endl;
00301
00302
00303 if( !set_biassettings( iterat->handle_subdev, chip_select, uiBcorrX, uiBcorrY, uiBcorrZ, false) )
00304 {
00305 bExecuteCalibration = false;
00306 throw std::string( "Bias corrections cannot be written to image. Calibration procedure aborted." );
00307 }
00308
00309
00310 if( !calib_bma180.biasverify() )
00311 {
00312 bExecuteCalibration = false;
00313 throw std::string( "Bias verification cannot be executed. Calibration procedure aborted." );
00314 }
00315 }
00316
00317 if( calib_bma180.calibsens_completed() && calib_bma180.verification_active() && calib_bma180.verification_completed() )
00318 {
00319 std::cout << "Verifying biases..." << std::endl;
00320
00321
00322 if( !calib_bma180.get_verifiedbiases( &dEstBiasX, &dEstBiasY, &dEstBiasZ ) )
00323 {
00324 bExecuteCalibration = false;
00325 throw std::string( "Verified biases cannot be retrieved. Calibration procedure aborted." );
00326 };
00327
00328 if( bma180_cmd::dCALIB_ACCURACY > fabs(dEstBiasX) && bma180_cmd::dCALIB_ACCURACY > fabs(dEstBiasY) && bma180_cmd::dCALIB_ACCURACY > fabs( dEstBiasZ - 1 ) )
00329 {
00330
00331 uiBcorrX = 0;
00332 uiBcorrY = 0;
00333 uiBcorrZ = 0;
00334 std::string myAnswer;
00335 std::cin.ignore();
00336 std::cout << "Really write EEPROM <Y/N>? ";
00337 std::getline( std::cin, myAnswer );
00338 if( 0 == myAnswer.find('Y') || 0 == myAnswer.find('y') )
00339 {
00340 if( !set_biassettings( iterat->handle_subdev, chip_select, uiBcorrX, uiBcorrY, uiBcorrZ, true ) )
00341 {
00342 bExecuteCalibration = false;
00343 throw std::string( "Biases cannot be written into EEPROM. Calibration procedure aborted.");
00344 };
00345 ROS_INFO("EEPROM has been written.\n");
00346
00347 }
00348 else
00349 {
00350 ROS_INFO("EEPROM write aborted.\n");
00351 }
00352 }
00353 else
00354 {
00355 std::cout << "Error values " << fabs(dEstBiasX) << " " << fabs(dEstBiasY) << " " << fabs(dEstBiasZ-1) << std::endl;
00356 bExecuteCalibration = false;
00357 throw std::string( "Bias verification failed because the calibration values are too large. Calibration procedure aborted.");
00358 }
00359
00360 bExecuteCalibration = false;
00361 std::cout << "Calibration completed successfully." << std::endl;
00362 }
00363 }
00364 }
00365 else
00366 {
00367 if( bExecuteCalibration == true && 1 < (int)Sub20Device_list.size() )
00368 {
00369 throw std::string( "As a pre-caution, please connect only one Sub20 device during calibration.");
00370 }
00371 }
00372 }
00373 else
00374 {
00375 throw std::string( "There has been an SPI communication error. Continuing attempts to communicate with the device will be made." );
00376 }
00377 }
00378 }
00379 }
00380
00381
00382 if( SPIMeas )
00383 {
00384
00385 sMeas.bMeasAvailable = true;
00386 sMeas.serial_number = iterat->strSub20Serial;
00387
00388
00389 list_meas.push_back( sMeas );
00390 }
00391 else
00392 {
00393 throw std::string( "SUB20 connected but not configured. A restart of the ROS node is suggested.");
00394 }
00395 }
00396 };
00397
00398 double Bma180::bma180data_to_double( char chMSB, char chLSB, bma180_cmd::eSensorType eSensor, int *raw, double dAccScale )
00399 {
00400 short s16int;
00401 double dSensorMeas;
00402
00403 switch( eSensor )
00404 {
00405
00406 case bma180_cmd::eACCEL:
00407
00408 if( (chMSB & 0x80) == 0 )
00409 {
00410
00411 s16int = (short)( (((unsigned short)chMSB) & 0xFF) << 6) + ((((unsigned short)chLSB) & 0xFC) >> 2 );
00412 }
00413 else
00414 {
00415
00416
00417 s16int = (short)( ((((unsigned short)chMSB) & 0x7F ) << 6 ) + ((((unsigned short)chLSB) & 0xFC) >> 2 ) - 8192 );
00418 }
00419 dSensorMeas = ( ((double)s16int) / 8192 ) * dAccScale;
00420 break;
00421
00422
00423 case bma180_cmd::eTEMP:
00424
00425 if( (chLSB & 0x80) == 0 )
00426 {
00427
00428 s16int = (short)( ((unsigned short)chLSB) & 0xFF );
00429 }
00430 else
00431 {
00432
00433
00434 s16int = (short)( (((unsigned short)chLSB) & 0x7F ) - 128 );
00435 };
00436 dSensorMeas = ( ( (double)s16int) / 8192 ) * 2;
00437 break;
00438
00439 default :
00440 dSensorMeas = 0;
00441 }
00442 *raw = s16int;
00443 return (dSensorMeas);
00444 };
00445
00446 unsigned short Bma180::bma180data_to_uint( char chMSB, char chLSB, bma180_cmd::eSensorType eSensor )
00447 {
00448 unsigned short u16int_bias;
00449 switch( eSensor )
00450 {
00451
00452 case bma180_cmd::eBIAS_X:
00453 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0xF0)>>4);
00454 break;
00455
00456
00457 case bma180_cmd::eBIAS_Y:
00458 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0x0F));
00459 break;
00460
00461
00462 case bma180_cmd::eBIAS_Z:
00463 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0xF0)>>4);
00464 break;
00465 default :
00466 u16int_bias = 0;
00467 }
00468 return (u16int_bias);
00469 };
00470
00471 bool Bma180::read_byte_eeprom_sub20( char chADR, char* pchREGISTER, unsigned short chip_select, sub_handle sub_h )
00472 {
00473 int error_code = 0;
00474 bool bSuccess;
00475 char chCMD;
00476
00477
00478
00479
00480 error_code += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00481
00482 chCMD = chADR | bma180_cmd::FLAG_R;
00483 error_code += sub_spi_transfer( sub_h, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00484 error_code += sub_spi_transfer( sub_h, 0, pchREGISTER, 1, SS_CONF(chip_select,SS_L) );
00485
00486 error_code += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00487
00488 if (error_code == 0)
00489 {
00490
00491 bSuccess = true;
00492 }
00493 else
00494 {
00495
00496 bSuccess = false;
00497 }
00498 return (bSuccess);
00499 };
00500
00501 bool Bma180::write_bit_eeprom_sub20( char chADR, unsigned short iLSBOfByte, unsigned short iNumOfBits, char chBitSeq, unsigned short chip_select, sub_handle sub_h )
00502 {
00503 char chCMD;
00504 char chREGISTER;
00505 char chREGISTER_MODIFIED;
00506 int error_code;
00507 char chMask;
00508 bool bSuccess;
00509 bool bEEReadSuccess;
00510
00511
00512 if ( iLSBOfByte + iNumOfBits <= 8 )
00513 {
00514 error_code = 0;
00515 bEEReadSuccess = true;
00516
00517
00518 chCMD = chADR | bma180_cmd::FLAG_R;
00519 bEEReadSuccess &= read_byte_eeprom_sub20(chCMD, &chREGISTER, chip_select, sub_h );
00520
00521
00522
00523 if ( iNumOfBits < 8 )
00524 {
00525 chMask = ~( ((1 << iNumOfBits) - 1) << iLSBOfByte );
00526 }
00527 else
00528 {
00529
00530 chMask = 0x00;
00531 }
00532
00533 chREGISTER_MODIFIED = ( chREGISTER & chMask ) | ( chBitSeq << iLSBOfByte );
00534
00535 chCMD = chADR;
00536 error_code += sub_spi_transfer( sub_h, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00537 error_code += sub_spi_transfer( sub_h, &chREGISTER_MODIFIED, 0, 1, SS_CONF(chip_select,SS_L) );
00538
00539 error_code += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00540
00541
00542
00543
00544 chCMD = chADR | bma180_cmd::FLAG_R;
00545 bEEReadSuccess &= read_byte_eeprom_sub20(chCMD, &chREGISTER, chip_select, sub_h);
00546
00547 if( (error_code == 0) && (bEEReadSuccess) )
00548 {
00549 bSuccess = true;
00550 }
00551 else
00552 {
00553
00554 bSuccess = false;
00555 }
00556 }
00557 else
00558 {
00559
00560 bSuccess = false;
00561 }
00562 return bSuccess;
00563 };
00564
00565 void Bma180::confsens_on_sub20( OneSub20Config *pOneSub20Conf, char chFullscale, char chBandwidth )
00566 {
00567 int error_code;
00568 int chip_select;
00569 bool bSuccess;
00570 char chCHIP_ID;
00571 char chALML_VER;
00572 char chCMD;
00573 char chREGSTATUS;
00574 unsigned short uiBiasX;
00575 unsigned short uiBiasY;
00576 unsigned short uiBiasZ;
00577 std::stringstream ss_errmsg;
00578 sub_handle handle_sub20;
00579 bool bEE_RWsuccess;
00580
00581
00582 handle_sub20 = pOneSub20Conf->handle_subdev;
00583 for( chip_select = 0; chip_select < bma180_cmd::MAX_NUM_SENSORS; chip_select++ )
00584 {
00585 pOneSub20Conf->Bma180Cluster[chip_select].iNumOfCalibMeas = 0;
00586 error_code = 0;
00587 bEE_RWsuccess = true;
00588
00589 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00590
00591 chCMD = bma180_cmd::ADDRESS_VER | bma180_cmd::FLAG_R;
00592 error_code += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00593 error_code += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(chip_select,SS_L) );
00594 error_code += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(chip_select,SS_L) );
00595
00596 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00597
00598
00599 if( error_code == 0 && 0 < (unsigned short)chCHIP_ID && 0 < (unsigned short)chALML_VER )
00600 {
00601 ROS_INFO("BMA 180 - Chip Select %d\n", chip_select);
00602 ROS_INFO("CHIP ID: %u\n", (unsigned short)chCHIP_ID);
00603 ROS_INFO("ALML Ver: %u\n", (unsigned short)chALML_VER);
00604
00605
00606 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_CTRLREG0, 4, 1, bma180_cmd::COMMAND_SET_EEW, chip_select, handle_sub20 );
00607
00608 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_SOFTRESET, 0, 8, bma180_cmd::COMMAND_SOFTRESET, chip_select, handle_sub20 );
00609
00610 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_CTRLREG0, 4, 1, bma180_cmd::COMMAND_SET_EEW, chip_select, handle_sub20 );
00611
00612 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_RANGE, 1, 3, chFullscale, chip_select, handle_sub20 );
00613 bEE_RWsuccess &= read_byte_eeprom_sub20( bma180_cmd::ADDRESS_RANGE, &chREGSTATUS, chip_select, handle_sub20 );
00614
00615 pOneSub20Conf->Bma180Cluster[chip_select].dFullScaleRange = bma180_cmd::dFULLRANGELOOKUP[((unsigned short)((chREGSTATUS & 0x0E)>>1))];
00616
00617 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_BWTCS, 4, 4, chBandwidth, chip_select, handle_sub20 );
00618 bEE_RWsuccess &= read_byte_eeprom_sub20( bma180_cmd::ADDRESS_BWTCS, &chREGSTATUS, chip_select, handle_sub20 );
00619
00620 pOneSub20Conf->Bma180Cluster[chip_select].dSensorBandwidth = bma180_cmd::dBWLOOKUP[((unsigned short)((chREGSTATUS & 0xF0)>>4))];
00621 ROS_INFO("EEPROM stored Fullrange: %f [g]\n", pOneSub20Conf->Bma180Cluster[chip_select].dFullScaleRange);
00622 ROS_INFO("EEPROM stored Bandwidth: %f [Hz]\n", pOneSub20Conf->Bma180Cluster[chip_select].dSensorBandwidth);
00623
00624
00625 bEE_RWsuccess &= read_biassettings( handle_sub20, chip_select, &uiBiasX, &uiBiasY, &uiBiasZ );
00626 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageX = uiBiasX;
00627 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageY = uiBiasY;
00628 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageZ = uiBiasZ;
00629
00630 if( bEE_RWsuccess )
00631 {
00632
00633 pOneSub20Conf->Bma180Cluster[chip_select].bConfigured = true;
00634
00635 bSuccess = true;
00636 }
00637 else
00638 {
00639
00640 pOneSub20Conf->Bma180Cluster[chip_select].bConfigured = false;
00641
00642 bSuccess = false;
00643 }
00644 }
00645 else
00646 {
00647 ROS_INFO("BMA 180 %d: No sensor detected\n", chip_select);
00648
00649
00650 pOneSub20Conf->Bma180Cluster[chip_select].bConfigured = false;
00651 pOneSub20Conf->Bma180Cluster[chip_select].dFullScaleRange = 0;
00652 pOneSub20Conf->Bma180Cluster[chip_select].dSensorBandwidth = 0;
00653 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageX = 0;
00654 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageY = 0;
00655 pOneSub20Conf->Bma180Cluster[chip_select].uiBiasImageZ = 0;
00656
00657 bSuccess = false;
00658 }
00659 }
00660 };
00661
00662 bool Bma180::read_biassettings( sub_handle handle_sub20, int chip_select, unsigned short* uiBiasX, unsigned short* uiBiasY, unsigned short* uiBiasZ )
00663 {
00664 int error_code;
00665 char chBiasXYZT[6];
00666 bool bSuccess;
00667 char chCMD;
00668 char chCHIP_ID;
00669 char chALML_VER;
00670
00671
00672
00673
00674 error_code = 0;
00675 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00676
00677 chCMD = bma180_cmd::ADDRESS_VER|bma180_cmd::FLAG_R;
00678 error_code += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00679 error_code += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(chip_select,SS_L) );
00680 error_code += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(chip_select,SS_L) );
00681
00682 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00683
00684
00685 if( (error_code == 0) && ( 0 < (unsigned short)chCHIP_ID) && ( 0 < (unsigned short)chALML_VER) )
00686 {
00687
00688
00689
00690
00691 chCMD = bma180_cmd::ADDRESS_OFFSET_LSB1 | bma180_cmd::FLAG_R;
00692 error_code += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00693 error_code += sub_spi_transfer( handle_sub20, 0, chBiasXYZT, 6, SS_CONF(chip_select,SS_L) );
00694
00695 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00696
00697 if( error_code == 0 )
00698 {
00699 (*uiBiasX) = bma180data_to_uint( chBiasXYZT[3], chBiasXYZT[0], bma180_cmd::eBIAS_X );
00700 (*uiBiasY) = bma180data_to_uint( chBiasXYZT[4], chBiasXYZT[1], bma180_cmd::eBIAS_Y );
00701 (*uiBiasZ) = bma180data_to_uint( chBiasXYZT[5], chBiasXYZT[1], bma180_cmd::eBIAS_Z );
00702 bSuccess = true;
00703 }
00704 else
00705 {
00706 (*uiBiasX) = 0;
00707 (*uiBiasY) = 0;
00708 (*uiBiasZ) = 0;
00709 bSuccess = false;
00710 }
00711 }
00712 else
00713 {
00714 (*uiBiasX) = 0;
00715 (*uiBiasY) = 0;
00716 (*uiBiasZ) = 0;
00717 bSuccess = false;
00718 }
00719 return bSuccess;
00720 };
00721
00722 bool Bma180::set_biassettings( sub_handle handle_sub20, int chip_select, unsigned short uiBiasX, unsigned short uiBiasY, unsigned short uiBiasZ, bool bWriteEEPROM )
00723 {
00724 int error_code;
00725 bool bSuccess;
00726 char chCMD;
00727 char chCHIP_ID;
00728 char chALML_VER;
00729 char chMSB;
00730 char chLSB;
00731 bool bEE_RWsuccess;
00732
00733
00734
00735
00736 error_code = 0;
00737 bEE_RWsuccess = true;
00738 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00739
00740
00741 chCMD = bma180_cmd::ADDRESS_VER | bma180_cmd::FLAG_R;
00742 error_code += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(chip_select,SS_L) );
00743 error_code += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(chip_select,SS_L) );
00744 error_code += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(chip_select,SS_L) );
00745
00746
00747 error_code += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(chip_select,SS_H) );
00748
00749
00750 if( error_code == 0 && ( 0 < (unsigned short) chCHIP_ID) && ( 0 < (unsigned short)chALML_VER) )
00751 {
00752 if( !bWriteEEPROM == true)
00753 {
00754
00755 chMSB = (char)( (uiBiasX&0xFF0) >> 4 );
00756 chLSB = (char)( (uiBiasX&0x0F) );
00757 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_X, 0, 8, chMSB, chip_select, handle_sub20 );
00758 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_LSB1, 4, 4, chLSB, chip_select, handle_sub20 );
00759
00760
00761 chMSB = (char)( (uiBiasY&0xFF0) >> 4 );
00762 chLSB = (char)( (uiBiasY&0x0F));
00763 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_Y, 0, 8, chMSB, chip_select, handle_sub20 );
00764 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_LSB2, 0, 4, chLSB, chip_select, handle_sub20 );
00765
00766
00767 chMSB = (char)( (uiBiasZ&0xFF0) >> 4 );
00768 chLSB = (char)( (uiBiasZ&0x0F) );
00769 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_Z, 0, 8, chMSB, chip_select, handle_sub20 );
00770 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::ADDRESS_OFFSET_LSB2, 4, 4, chLSB, chip_select, handle_sub20 );
00771
00772 if( bEE_RWsuccess )
00773 {
00774 std::cout << "Writing to image " << std::endl;
00775 bSuccess = true;
00776 }
00777 else
00778 {
00779 bSuccess = false;
00780 ROS_WARN("Cannot write BMA180 image.\n");
00781 }
00782 }
00783 else
00784 {
00785
00786
00787
00788 bEE_RWsuccess &= write_bit_eeprom_sub20(bma180_cmd::ADDRESS_EE_GAIN_Z, 0, 8, 0x00, chip_select, handle_sub20 );
00789 bEE_RWsuccess &= write_bit_eeprom_sub20(bma180_cmd::ADDRESS_EE_OFFSET_LSB2, 0, 8, 0x00, chip_select, handle_sub20 );
00790 bEE_RWsuccess &= write_bit_eeprom_sub20(bma180_cmd::ADDRESS_EE_OFFSET_X, 0, 8, 0x00, chip_select, handle_sub20 );
00791 bEE_RWsuccess &= write_bit_eeprom_sub20(bma180_cmd::ADDRESS_EE_OFFSET_Z, 0, 8, 0x00, chip_select, handle_sub20 );
00792
00793 if( bEE_RWsuccess )
00794 {
00795 ROS_INFO("BMA180 EEPROM written.\n");
00796 bSuccess = true;
00797 }
00798 else
00799 {
00800 bSuccess = false;
00801 }
00802 }
00803 }
00804 else
00805 {
00806
00807 bSuccess = false;
00808 }
00809 return bSuccess;
00810 };
00811
00812
00813 void Bma180::set_calibstatus( bool bCalibrate)
00814 {
00815 if( bCalibrate == true )
00816 {
00817 std::string myAnswer;
00818 std::cout << "Sensors shall be calibrated <Y/N>? ";
00819 std::getline( std::cin, myAnswer );
00820 if( (0 == myAnswer.find('Y')) || (0 == myAnswer.find('y')) )
00821 {
00822 unsigned short myCS;
00823 std::cout << "Specify ChipSelect <0..4>? ";
00824 if( std::cin >> myCS )
00825 {
00826 if( myCS < bma180_cmd::MAX_NUM_SENSORS )
00827 {
00828 bExecuteCalibration = true;
00829 bCalibrationCompleted = false;
00830 iCalib_CS = myCS;
00831 }
00832 else
00833 {
00834 bExecuteCalibration = false;
00835 bCalibrationCompleted = true;
00836 }
00837 }
00838 else
00839 {
00840 bExecuteCalibration = false;
00841 bCalibrationCompleted = true;
00842 std::cin.clear();
00843 }
00844 }
00845 else
00846 {
00847 bExecuteCalibration = false;
00848 bCalibrationCompleted = true;
00849 }
00850 }
00851 else
00852 {
00853 bExecuteCalibration = false;
00854 bCalibrationCompleted = true;
00855 }
00856 };
00857
00858
00859
00860
00861
00862
00863 int main(int argc, char **argv)
00864 {
00865 int count = 1;
00866 int i = 0;
00867
00868
00869
00870 double max_acceleration_g, dRate_Hz, dBandwidth_Hz;
00871 bool bCalibrate;
00872 std::string sSub20Serial;
00873
00874
00875 max_acceleration_g = 2.0;
00876 dBandwidth_Hz = 100;
00877 dRate_Hz = 100;
00878 bCalibrate = false;
00879 sSub20Serial = "0651";
00880
00881 Bma180 bma180_attached( max_acceleration_g, dBandwidth_Hz, bCalibrate, dRate_Hz, sSub20Serial );
00882 OneBma180Meas sOneMeas;
00883 bma180::bma180meas msg;
00884 std::list<OneBma180Meas> measurements_list;
00885
00886
00887
00888
00889 while( true )
00890 {
00891
00892 try
00893 {
00894 bma180_attached.GetMeasurements(measurements_list);
00895 }
00896
00897 catch( std::string e )
00898 {
00899 ROS_ERROR( "An exception occurred: %s\n", e.c_str() );
00900 std::exit(1);
00901 }
00902
00903 while( !measurements_list.empty() )
00904 {
00905 sOneMeas = measurements_list.back();
00906 measurements_list.pop_back();
00907
00908
00909 if( sOneMeas.bMeasAvailable == true )
00910 {
00911 msg.strIdSubDev = sOneMeas.serial_number;
00912
00913
00914 for( i = 0; i < sOneMeas.iNumAccels; i++ )
00915 {
00916 printf("BMA180 %d\tx: %1.4f\ty: %1.4f\tz: %1.4f\n", sOneMeas.chip_select[i], sOneMeas.dAccX[i], sOneMeas.dAccY[i], sOneMeas.dAccZ[i] );
00917 }
00918 }
00919 }
00920
00921
00922 usleep( 1e6 / dRate_Hz );
00923
00924 ++count;
00925 }
00926 }
00927
00928