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
00049
00050
00051 #include <iostream>
00052 #include <string>
00053 #include <sstream>
00054 #include <math.h>
00055 #include <vector>
00056
00057 #include <ros/ros.h>
00058 #include <ros/time.h>
00059
00060 #include "bma180/bma180.h"
00061
00062
00063 Bma180::Bma180( double dMaxAcc_g, double dBandwidth_Hz, bool bCalibrate, double dRate_Hz, std::string sSub20Serial ):
00064 bSubDeviceOpen (false),
00065 bSubDeviceConfigured (false)
00066 {
00067 int iSpiErr;
00068 int iSPI_cfg_set;
00069 int iSPI_cfg_get;
00070 int iADCErr;
00071 int iADC_cfg_set;
00072 int iNumOfRanges;
00073 int iElCount;
00074 std::stringstream ss_errmsg;
00075 std::string ss_config, sub20Serial;
00076 sub_device sub20dev;
00077 sub_handle sub20handle;
00078 OneSub20Config OneSub20Configuration;
00079
00080 ROS_INFO("--------------------------------------");
00081 ROS_INFO("Max acceleration entered:: %f ", dMaxAcc_g);
00082 ROS_INFO("Sensor bandwidth entered:: %f ", dBandwidth_Hz);
00083 ROS_INFO("Sensor Reading Rate entered:: %f ", dRate_Hz);
00084 ROS_INFO("--------------------------------------");
00085
00086
00087 set_calibstatus( bCalibrate );
00088
00089
00090 iNumOfRanges = sizeof(bma180_cmd::chCMD_FULLSCALE_G) / sizeof(char);
00091 iElCount = 0;
00092 while( (dMaxAcc_g > bma180_cmd::dFULLRANGELOOKUP[iElCount]) && (iElCount < iNumOfRanges) )
00093 {
00094 iElCount++;
00095 };
00096 ROS_INFO("Range chosen G:: %f ", bma180_cmd::dFULLRANGELOOKUP[iElCount]);
00097
00098 chMaxAccRange_selected = bma180_cmd::chCMD_FULLSCALE_G[iElCount];
00099
00100
00101 iNumOfRanges = sizeof(bma180_cmd::chCMD_BANDWIDTH_HZ) / sizeof(char);
00102 iElCount = 0;
00103 while( (dBandwidth_Hz > bma180_cmd::dBWLOOKUP[iElCount]) && (iElCount < iNumOfRanges) )
00104 {
00105 iElCount++;
00106 };
00107 ROS_INFO("Range chosen BW:: %f ", bma180_cmd::dBWLOOKUP[iElCount]);
00108
00109 chBW_selected = bma180_cmd::chCMD_BANDWIDTH_HZ[iElCount];
00110
00111
00112 sub20dev = 0;
00113 sub20dev = sub_find_devices( sub20dev );
00114 while( sub20dev != 0 )
00115 {
00116 sub20handle = sub_open( sub20dev );
00117
00118 if( sub20handle > 0 )
00119 {
00120 sub20Serial.clear();
00121 sub20Serial.resize( bma180_cmd::uSERIALNUMLENGTH );
00122 sub_get_serial_number( sub20handle, const_cast<char*>(sub20Serial.c_str()), sub20Serial.size() );
00123 std::cout << "Serial Number : " << sub20Serial << std::endl;
00124 if( strcmp(sub20Serial.c_str(), sSub20Serial.c_str()) == 0 )
00125 {
00126 subhndl = sub20handle;
00127
00128
00129 std::cout << "---Initializing SPI Interface---" << " \n";
00130
00131 iSpiErr = sub_spi_config( sub20handle, 0, &iSPI_cfg_get );
00132 std::cout << "Sub SPI config : " << iSPI_cfg_get << " \n";
00133
00134
00135 iSPI_cfg_set = SPI_ENABLE|SPI_CPOL_FALL|SPI_SETUP_SMPL|SPI_MSB_FIRST|SPI_CLK_2MHZ;
00136
00137 iSpiErr = sub_spi_config( sub20handle, iSPI_cfg_set, 0 );
00138
00139 iSpiErr = sub_spi_config( sub20handle, 0, &iSPI_cfg_get );
00140
00141 if( iSPI_cfg_get == iSPI_cfg_set )
00142 {
00143 std::cout<< "SPI Configuration : " << iSPI_cfg_set << " successfully stored \n";
00144
00145 OneSub20Configuration.bSubSPIConfigured = true;
00146 OneSub20Configuration.handle_subdev = sub20handle;
00147
00148
00149 confsens_on_sub20( &OneSub20Configuration, chMaxAccRange_selected, chBW_selected );
00150 }
00151 else
00152 {
00153 ROS_INFO("ERROR - SPI Configuration : %d not accepted by device", iSPI_cfg_set);
00154
00155 OneSub20Configuration.bSubSPIConfigured = false;
00156 }
00157 if( OneSub20Configuration.bSubSPIConfigured )
00158 {
00159
00160 strSerial.clear();
00161 strSerial.resize( bma180_cmd::uSERIALNUMLENGTH );
00162 sub_get_serial_number( sub20handle, const_cast<char*>(strSerial.c_str()), strSerial.size() );
00163 OneSub20Configuration.strSub20Serial = strSerial;
00164 OneSub20Configuration.subdev = sub20dev;
00165 std::cout << "Device Handle : " << OneSub20Configuration.handle_subdev << std::endl;
00166 std::cout << "Serial Number : " << OneSub20Configuration.strSub20Serial << std::endl;
00167
00168
00169 Sub20Device_list.push_back( OneSub20Configuration );
00170 std::cout << "... Publishing to topic /bma180 ... " << std::endl;
00171 }
00172 break;
00173 }
00174 else
00175 {
00176 sub_close( sub20handle );
00177 }
00178 }
00179
00180 sub20dev = sub_find_devices( sub20dev );
00181 }
00182 };
00183
00184 Bma180::~Bma180()
00185 {
00186 int iSpiErr;
00187 OneSub20Config OneSub20Configuration;
00188
00189
00190 iSpiErr = sub_spi_config( subhndl, 0, 0 );
00191
00192 sub_close( subhndl );
00193 while( !Sub20Device_list.empty() )
00194 {
00195 OneSub20Configuration = Sub20Device_list.back();
00196 std::cout << "Sub device removed " << OneSub20Configuration.strSub20Serial << "\n";
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 iSpiErr, iADCErr, dummy, j = 0;
00209 bool SPIMeas = false, ADCMeas = false;
00210 OneBma180Meas sMeas;
00211 ros::Time dtomeas;
00212 char chCMD;
00213 std::stringstream ss_errmsg;
00214 std::list<OneSub20Config>::iterator iterat;
00215 int iChipSelect;
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( iChipSelect = 0; iChipSelect < bma180_cmd::iMAXNUM_OF_SENSORS; iChipSelect++ )
00231 {
00232
00233 if( iterat->Bma180Cluster[iChipSelect].bConfigured == true )
00234 {
00235 iSpiErr = 0;
00236
00237
00238
00239
00240 chCMD = bma180_cmd::chADR_ACCLXYZ | bma180_cmd::chFLAG_R;
00241 iSpiErr += sub_spi_transfer( iterat->handle_subdev, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00242 iSpiErr += sub_spi_transfer( iterat->handle_subdev, 0, chACC_XYZ, 7, SS_CONF(iChipSelect,SS_L) );
00243
00244 iSpiErr += sub_spi_transfer( iterat->handle_subdev, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00245
00246 if( iSpiErr == 0 )
00247 {
00248 SPIMeas = true;
00249 dAccX = bma180data_to_double(chACC_XYZ[1], chACC_XYZ[0], bma180_cmd::eACCEL, &uiRawX, iterat->Bma180Cluster[iChipSelect].dFullScaleRange );
00250 dAccY = bma180data_to_double(chACC_XYZ[3], chACC_XYZ[2], bma180_cmd::eACCEL, &uiRawY, iterat->Bma180Cluster[iChipSelect].dFullScaleRange );
00251 dAccZ = bma180data_to_double(chACC_XYZ[5], chACC_XYZ[4], bma180_cmd::eACCEL, &uiRawZ, iterat->Bma180Cluster[iChipSelect].dFullScaleRange );
00252 dTemp = bma180data_to_double(chACC_XYZ[6], chACC_XYZ[6], bma180_cmd::eTEMP, &dummy, iterat->Bma180Cluster[iChipSelect].dFullScaleRange );
00253
00254
00255 sMeas.dAccX[j] = dAccX;
00256 sMeas.dAccY[j] = dAccY;
00257 sMeas.dAccZ[j] = dAccZ;
00258 sMeas.dTemp = dTemp;
00259 sMeas.iChipSelect[j] = iChipSelect;
00260 j++;
00261 sMeas.iNumAccels = j;
00262
00263
00264
00265 if( (bExecuteCalibration == true) && (2>(int)Sub20Device_list.size()) )
00266 {
00267 if( iChipSelect == 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[iChipSelect].uiBiasImageX << " " << iterat->Bma180Cluster[iChipSelect].uiBiasImageY << " " << iterat->Bma180Cluster[iChipSelect].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 calib_bma180.get_estbiases( &dEstBiasX, &dEstBiasY, &dEstBiasZ );
00283 std::cout << "estimated biases : " << dEstBiasX << " " << dEstBiasY << " " << dEstBiasZ << std::endl;
00284
00285
00286
00287
00288 int iBcorrX, iBcorrY, iBcorrZ;
00289 iBcorrX = ((short)(dEstBiasX/iterat->Bma180Cluster[iChipSelect].dFullScaleRange*2048+0.5));
00290 iBcorrY = ((short)(dEstBiasY/iterat->Bma180Cluster[iChipSelect].dFullScaleRange*2048+0.5)) ;
00291 iBcorrZ = ((short)((dEstBiasZ-1)/iterat->Bma180Cluster[iChipSelect].dFullScaleRange*2048+0.5)) ;
00292 std::cout << "Bias adjustments [X Y Z] " << iBcorrX << " " << iBcorrY << " " << iBcorrZ << std::endl;
00293 std::cout << "Image values before adjustments " << iterat->Bma180Cluster[iChipSelect].uiBiasImageX << " " << iterat->Bma180Cluster[iChipSelect].uiBiasImageY << " " << iterat->Bma180Cluster[iChipSelect].uiBiasImageZ << std::endl;
00294 uiBcorrX = (unsigned short) (iterat->Bma180Cluster[iChipSelect].uiBiasImageX - ((short)(dEstBiasX/bma180_cmd::dFULLRANGELOOKUP[6]*2048)) );
00295 uiBcorrY = (unsigned short) (iterat->Bma180Cluster[iChipSelect].uiBiasImageY - ((short)(dEstBiasY/bma180_cmd::dFULLRANGELOOKUP[6]*2048)) );
00296 uiBcorrZ = (unsigned short) (iterat->Bma180Cluster[iChipSelect].uiBiasImageZ - ((short)((dEstBiasZ-1)/bma180_cmd::dFULLRANGELOOKUP[6]*2048)));
00297
00298 std::cout << "corrected biases " << uiBcorrX << " " << uiBcorrY << " " << uiBcorrZ << std::endl;
00299
00300
00301 if( !set_biassettings(iterat->handle_subdev, iChipSelect, uiBcorrX, uiBcorrY, uiBcorrZ, false) )
00302 {
00303 bExecuteCalibration = false;
00304 throw std::string("Bias corrections cannot be written to image - Calibration procedure aborted");
00305 }
00306
00307
00308 if( !calib_bma180.biasverify() )
00309 {
00310 bExecuteCalibration = false;
00311 throw std::string("BiasVerification cannot be executed - Calibration procedure aborted");
00312 }
00313 }
00314
00315 if( (calib_bma180.calibsens_completed()) && (calib_bma180.verification_active()) && (calib_bma180.verification_completed()) )
00316 {
00317 std::cout << "-----------------------------------------" << std::endl;
00318 std::cout << "...............VERIFY BIASES............." << std::endl;
00319 std::cout << "-----------------------------------------" << 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, iChipSelect, 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+++++++");
00346
00347 }
00348 else
00349 {
00350 ROS_INFO("++++++EEPROM WRITE ABORTED++++++");
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, calib values too large - Calibration procedure aborted");
00358 }
00359
00360 bExecuteCalibration = false;
00361 std::cout << "calibration completed hehe" << 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: For calibration, only ONE SubDevice must be connected");
00370 }
00371 }
00372 }
00373 else
00374 {
00375 throw std::string("Error on SPI communication - keep on running though");
00376 }
00377 }
00378 }
00379 }
00380
00381 if( SPIMeas )
00382 {
00383 sMeas.dtomeas = ros::Time::now();
00384 sMeas.bMeasAvailable = true;
00385 sMeas.strSerial = iterat->strSub20Serial;
00386
00387 list_meas.push_back( sMeas );
00388 }
00389 else
00390 {
00391 throw std::string("SUB20 connected but not configured - Restart of node suggested");
00392 }
00393 }
00394 };
00395
00396 double Bma180::bma180data_to_double( char chMSB, char chLSB, bma180_cmd::eSensorType eSensor, int *raw, double dAccScale )
00397 {
00398 short s16int;
00399 double dSensorMeas;
00400
00401 switch( eSensor )
00402 {
00403
00404 case bma180_cmd::eACCEL:
00405
00406 if( (chMSB & 0x80) == 0 )
00407 {
00408
00409 s16int = (short) ((((unsigned short)chMSB)&0xFF)<<6)+((((unsigned short)chLSB)&0xFC)>>2);
00410 }
00411 else
00412 {
00413
00414
00415 s16int = (short) (((((unsigned short)chMSB)&0x7F)<<6)+((((unsigned short)chLSB)&0xFC)>>2) - 8192);
00416 }
00417 dSensorMeas = (( (double) s16int) / 8192)*dAccScale;
00418 break;
00419
00420
00421 case bma180_cmd::eTEMP:
00422
00423 if( (chLSB & 0x80) == 0 )
00424 {
00425
00426 s16int = (short) (((unsigned short)chLSB)&0xFF);
00427 }
00428 else
00429 {
00430
00431
00432 s16int = (short) ((((unsigned short)chLSB)&0x7F) - 128 );
00433 };
00434 dSensorMeas = (( (double) s16int) / 8192)*2;
00435 break;
00436
00437 default :
00438 dSensorMeas = 0;
00439 }
00440 *raw = s16int;
00441 return dSensorMeas;
00442 };
00443
00444 unsigned short Bma180::bma180data_to_uint( char chMSB, char chLSB, bma180_cmd::eSensorType eSensor )
00445 {
00446 unsigned short u16int_bias;
00447
00448 switch (eSensor)
00449 {
00450
00451 case bma180_cmd::eBIAS_X:
00452 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0xF0)>>4);
00453 break;
00454
00455 case bma180_cmd::eBIAS_Y:
00456 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0x0F));
00457 break;
00458
00459 case bma180_cmd::eBIAS_Z:
00460 u16int_bias = (short) ((((unsigned short)chMSB)&0xFF)<<4)+((((unsigned short)chLSB)&0xF0)>>4);
00461 break;
00462 default :
00463 u16int_bias = 0;
00464 }
00465 return u16int_bias;
00466 };
00467
00468 bool Bma180::read_byte_eeprom_sub20( char chADR, char* pchREGISTER, unsigned short iChipSelect, sub_handle sub_h )
00469 {
00470 int iSpiErr = 0;
00471 bool bSuccess;
00472 char chCMD;
00473
00474
00475
00476 iSpiErr += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00477
00478 chCMD = chADR | bma180_cmd::chFLAG_R;
00479 iSpiErr += sub_spi_transfer( sub_h, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00480 iSpiErr += sub_spi_transfer( sub_h, 0, pchREGISTER, 1, SS_CONF(iChipSelect,SS_L) );
00481
00482 iSpiErr += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00483
00484 if( iSpiErr == 0)
00485 {
00486
00487 bSuccess = true;
00488 }
00489 else
00490 {
00491
00492 bSuccess = false;
00493 }
00494 return bSuccess;
00495 };
00496
00497 bool Bma180::write_bit_eeprom_sub20( char chADR, unsigned short iLSBOfByte, unsigned short iNumOfBits, char chBitSeq, unsigned short iChipSelect, sub_handle sub_h )
00498 {
00499 char chCMD;
00500 char chREGISTER;
00501 char chREGISTER_MODIFIED;
00502 int iSpiErr;
00503 char chMask;
00504 bool bSuccess;
00505 bool bEEReadSuccess;
00506
00507
00508 if( iLSBOfByte + iNumOfBits <= 8 )
00509 {
00510 iSpiErr = 0;
00511 bEEReadSuccess = true;
00512
00513
00514 chCMD = chADR | bma180_cmd::chFLAG_R;
00515 bEEReadSuccess &= read_byte_eeprom_sub20(chCMD, &chREGISTER, iChipSelect, sub_h );
00516
00517
00518
00519 if ( iNumOfBits < 8 )
00520 {
00521 chMask = ~( ((1<<iNumOfBits)-1)<<iLSBOfByte );
00522 }
00523 else
00524 {
00525
00526 chMask = 0x00;
00527 }
00528
00529 chREGISTER_MODIFIED = (chREGISTER&chMask ) | ( chBitSeq << iLSBOfByte );
00530
00531 chCMD = chADR;
00532 iSpiErr += sub_spi_transfer( sub_h, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00533 iSpiErr += sub_spi_transfer( sub_h, &chREGISTER_MODIFIED, 0, 1, SS_CONF(iChipSelect,SS_L) );
00534
00535 iSpiErr += sub_spi_transfer( sub_h, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00536
00537
00538
00539 chCMD = chADR | bma180_cmd::chFLAG_R;
00540 bEEReadSuccess &= read_byte_eeprom_sub20(chCMD, &chREGISTER, iChipSelect, sub_h);
00541
00542 if( (iSpiErr == 0) && (bEEReadSuccess) )
00543 {
00544 bSuccess = true;
00545 }
00546 else
00547 {
00548
00549 bSuccess = false;
00550 }
00551 }
00552 else
00553 {
00554
00555 bSuccess = false;
00556 }
00557 return bSuccess;
00558 };
00559
00560 void Bma180::confsens_on_sub20( OneSub20Config *pOneSub20Conf, char chFullscale, char chBandwidth )
00561 {
00562 int iSpiErr;
00563 int iChipSelect;
00564 bool bSuccess;
00565 char chCHIP_ID;
00566 char chALML_VER;
00567 char chCMD;
00568 char chREGSTATUS;
00569 unsigned short uiBiasX;
00570 unsigned short uiBiasY;
00571 unsigned short uiBiasZ;
00572 std::stringstream ss_errmsg;
00573 sub_handle handle_sub20;
00574 bool bEE_RWsuccess;
00575
00576
00577 handle_sub20 = pOneSub20Conf->handle_subdev;
00578 for( iChipSelect = 0; iChipSelect < bma180_cmd::iMAXNUM_OF_SENSORS; iChipSelect++ )
00579 {
00580 pOneSub20Conf->Bma180Cluster[iChipSelect].iNumOfCalibMeas = 0;
00581 iSpiErr = 0;
00582 bEE_RWsuccess = true;
00583
00584 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00585
00586 chCMD = bma180_cmd::chADR_VER|bma180_cmd::chFLAG_R;
00587 iSpiErr += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00588 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(iChipSelect,SS_L) );
00589 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(iChipSelect,SS_L) );
00590
00591 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00592
00593
00594 if( (iSpiErr == 0) && (0<(unsigned short)chCHIP_ID) && (0<(unsigned short)chALML_VER) )
00595 {
00596 ROS_INFO("-----------------------------------------");
00597 ROS_INFO("BMA 180 - Chip Select %d", iChipSelect);
00598 ROS_INFO("CHIP ID : %u ", (unsigned short)chCHIP_ID);
00599 ROS_INFO("ALML Ver : %u ", (unsigned short)chALML_VER);
00600
00601
00602 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_CTRLREG0, 4, 1, bma180_cmd::chCMD_SET_EEW, iChipSelect, handle_sub20 );
00603
00604 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_SOFTRESET, 0, 8, bma180_cmd::chCMD_SOFTRESET, iChipSelect, handle_sub20 );
00605
00606 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_CTRLREG0, 4, 1, bma180_cmd::chCMD_SET_EEW, iChipSelect, handle_sub20 );
00607
00608 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_RANGE, 1, 3, chFullscale, iChipSelect, handle_sub20 );
00609 bEE_RWsuccess &= read_byte_eeprom_sub20( bma180_cmd::chADR_RANGE, &chREGSTATUS, iChipSelect, handle_sub20 );
00610
00611 pOneSub20Conf->Bma180Cluster[iChipSelect].dFullScaleRange = bma180_cmd::dFULLRANGELOOKUP[((unsigned short)((chREGSTATUS & 0x0E)>>1))];
00612
00613 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_BWTCS, 4, 4, chBandwidth, iChipSelect, handle_sub20 );
00614 bEE_RWsuccess &= read_byte_eeprom_sub20( bma180_cmd::chADR_BWTCS, &chREGSTATUS, iChipSelect, handle_sub20 );
00615
00616 pOneSub20Conf->Bma180Cluster[iChipSelect].dSensorBandwidth = bma180_cmd::dBWLOOKUP[((unsigned short)((chREGSTATUS & 0xF0)>>4))];
00617 ROS_INFO("eeprom stored Fullrange : %f g ", pOneSub20Conf->Bma180Cluster[iChipSelect].dFullScaleRange);
00618 ROS_INFO("eeprom stored Bandwidth : %f Hz", pOneSub20Conf->Bma180Cluster[iChipSelect].dSensorBandwidth);
00619 ROS_INFO("-----------------------------------------");
00620
00621
00622 bEE_RWsuccess &= read_biassettings( handle_sub20, iChipSelect, &uiBiasX, &uiBiasY, &uiBiasZ );
00623 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageX = uiBiasX;
00624 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageY = uiBiasY;
00625 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageZ = uiBiasZ;
00626
00627 if( bEE_RWsuccess )
00628 {
00629
00630 pOneSub20Conf->Bma180Cluster[iChipSelect].bConfigured = true;
00631
00632 bSuccess = true;
00633 }
00634 else
00635 {
00636
00637 pOneSub20Conf->Bma180Cluster[iChipSelect].bConfigured = false;
00638
00639 bSuccess = false;
00640 }
00641 }
00642 else
00643 {
00644 ROS_INFO("-----------------------------------------");
00645 ROS_INFO(" BMA 180 - Chip Select %d ", iChipSelect);
00646 ROS_INFO(" NO SENSOR DETECTED ");
00647 ROS_INFO("-----------------------------------------");
00648
00649
00650 pOneSub20Conf->Bma180Cluster[iChipSelect].bConfigured = false;
00651 pOneSub20Conf->Bma180Cluster[iChipSelect].dFullScaleRange = 0;
00652 pOneSub20Conf->Bma180Cluster[iChipSelect].dSensorBandwidth = 0;
00653 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageX = 0;
00654 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageY = 0;
00655 pOneSub20Conf->Bma180Cluster[iChipSelect].uiBiasImageZ = 0;
00656
00657 bSuccess = false;
00658 }
00659 }
00660 };
00661
00662 bool Bma180::read_biassettings( sub_handle handle_sub20, int iChipSelect, unsigned short* uiBiasX, unsigned short* uiBiasY, unsigned short* uiBiasZ )
00663 {
00664 int iSpiErr;
00665 char chBiasXYZT[6];
00666 bool bSuccess;
00667 char chCMD;
00668 char chCHIP_ID;
00669 char chALML_VER;
00670
00671
00672
00673 iSpiErr = 0;
00674 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00675
00676
00677 chCMD = bma180_cmd::chADR_VER|bma180_cmd::chFLAG_R;
00678 iSpiErr += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00679 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(iChipSelect,SS_L) );
00680 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(iChipSelect,SS_L) );
00681
00682
00683 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00684
00685
00686 if( (iSpiErr == 0) && (0 < (unsigned short)chCHIP_ID) && (0 < (unsigned short)chALML_VER) )
00687 {
00688
00689
00690
00691
00692 chCMD = bma180_cmd::chADR_OFFSET_LSB1 | bma180_cmd::chFLAG_R;
00693 iSpiErr += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00694 iSpiErr += sub_spi_transfer( handle_sub20, 0, chBiasXYZT, 6, SS_CONF(iChipSelect,SS_L) );
00695
00696 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00697
00698 if( iSpiErr == 0 )
00699 {
00700 (*uiBiasX) = bma180data_to_uint( chBiasXYZT[3], chBiasXYZT[0], bma180_cmd::eBIAS_X );
00701 (*uiBiasY) = bma180data_to_uint( chBiasXYZT[4], chBiasXYZT[1], bma180_cmd::eBIAS_Y );
00702 (*uiBiasZ) = bma180data_to_uint( chBiasXYZT[5], chBiasXYZT[1], bma180_cmd::eBIAS_Z );
00703 bSuccess = true;
00704 }
00705 else
00706 {
00707 *uiBiasX = 0;
00708 *uiBiasY = 0;
00709 *uiBiasZ = 0;
00710 bSuccess = false;
00711 }
00712 }
00713 else
00714 {
00715 *uiBiasX = 0;
00716 *uiBiasY = 0;
00717 *uiBiasZ = 0;
00718 bSuccess = false;
00719 }
00720 return bSuccess;
00721 };
00722
00723 bool Bma180::set_biassettings( sub_handle handle_sub20, int iChipSelect, unsigned short uiBiasX, unsigned short uiBiasY, unsigned short uiBiasZ, bool bWriteEEPROM )
00724 {
00725 int iSpiErr;
00726 bool bSuccess;
00727 char chCMD;
00728 char chCHIP_ID;
00729 char chALML_VER;
00730 char chMSB;
00731 char chLSB;
00732 bool bEE_RWsuccess;
00733
00734
00735
00736 iSpiErr = 0;
00737 bEE_RWsuccess = true;
00738 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00739
00740 chCMD = bma180_cmd::chADR_VER|bma180_cmd::chFLAG_R;
00741 iSpiErr += sub_spi_transfer( handle_sub20, &chCMD, 0, 1, SS_CONF(iChipSelect,SS_L) );
00742 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCHIP_ID, 1, SS_CONF(iChipSelect,SS_L) );
00743 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chALML_VER, 1, SS_CONF(iChipSelect,SS_L) );
00744
00745 iSpiErr += sub_spi_transfer( handle_sub20, 0, &chCMD, 1, SS_CONF(iChipSelect,SS_H) );
00746
00747
00748 if( (iSpiErr == 0) && (0 < (unsigned short)chCHIP_ID) && (0 < (unsigned short)chALML_VER) )
00749 {
00750 if( !bWriteEEPROM == true )
00751 {
00752
00753 chMSB = (char) ((uiBiasX&0xFF0)>>4);
00754 chLSB = (char) ((uiBiasX&0x0F));
00755 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_X, 0, 8, chMSB, iChipSelect, handle_sub20 );
00756 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_LSB1, 4, 4, chLSB, iChipSelect, handle_sub20 );
00757
00758
00759 chMSB = (char) ((uiBiasY&0xFF0)>>4);
00760 chLSB = (char) ((uiBiasY&0x0F));
00761 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_Y, 0, 8, chMSB, iChipSelect, handle_sub20 );
00762 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_LSB2, 0, 4, chLSB, iChipSelect, handle_sub20 );
00763
00764
00765 chMSB = (char) ((uiBiasZ&0xFF0)>>4);
00766 chLSB = (char) ((uiBiasZ&0x0F));
00767 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_Z, 0, 8, chMSB, iChipSelect, handle_sub20 );
00768 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_OFFSET_LSB2, 4, 4, chLSB, iChipSelect, handle_sub20 );
00769
00770 if( bEE_RWsuccess )
00771 {
00772 std::cout << "Writing to image " << std::endl;
00773 bSuccess = true;
00774 }
00775 else
00776 {
00777 bSuccess = false;
00778 std::cout << " !!!CANNOT WRITE IMAGE!!! " << std::endl;
00779 }
00780 }
00781 else
00782 {
00783
00784
00785
00786 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_EE_GAIN_Z, 0, 8, 0x00, iChipSelect, handle_sub20 );
00787 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_EE_OFFSET_LSB2, 0, 8, 0x00, iChipSelect, handle_sub20 );
00788 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_EE_OFFSET_X, 0, 8, 0x00, iChipSelect, handle_sub20 );
00789 bEE_RWsuccess &= write_bit_eeprom_sub20( bma180_cmd::chADR_EE_OFFSET_Z, 0, 8, 0x00, iChipSelect, handle_sub20 );
00790
00791 if( bEE_RWsuccess )
00792 {
00793 std::cout << "***************EEPROM written ******************** " << std::endl;
00794 bSuccess = true;
00795 }
00796 else
00797 {
00798 bSuccess = false;
00799 }
00800 }
00801 }
00802 else
00803 {
00804
00805 bSuccess = false;
00806 }
00807 return bSuccess;
00808 };
00809
00810
00811 void Bma180::set_calibstatus( bool bCalibrate )
00812 {
00813 if( bCalibrate == true )
00814 {
00815 std::string myAnswer;
00816 std::cout << "Sensors shall be calibrated <Y/N>? ";
00817 std::getline( std::cin, myAnswer );
00818 if( (0 == myAnswer.find('Y')) || (0 == myAnswer.find('y')) )
00819 {
00820 unsigned short myCS;
00821 std::cout << "Specify ChipSelect <0..4>? ";
00822 if( std::cin >> myCS )
00823 {
00824 if( myCS < bma180_cmd::iMAXNUM_OF_SENSORS )
00825 {
00826 bExecuteCalibration = true;
00827 bCalibrationCompleted = false;
00828 iCalib_CS = myCS;
00829 }
00830 else
00831 {
00832 bExecuteCalibration = false;
00833 bCalibrationCompleted = true;
00834 }
00835 }
00836 else
00837 {
00838 bExecuteCalibration = false;
00839 bCalibrationCompleted = true;
00840 std::cin.clear();
00841 }
00842 }
00843 else
00844 {
00845 bExecuteCalibration = false;
00846 bCalibrationCompleted = true;
00847 }
00848 }
00849 else
00850 {
00851 bExecuteCalibration = false;
00852 bCalibrationCompleted = true;
00853 }
00854 };
00855
00856
00857
00858
00859
00860
00861 int main( int argc, char **argv )
00862 {
00863 int count = 1, i = 0;
00864
00865
00866 ros::init(argc, argv, "bma180");
00867 ros::NodeHandle nh;
00868 ros::Publisher bma180_pub = nh.advertise<bma180::bma180meas>("bma180", 100);
00869
00870
00871 double dMaxAcc_g, dRate_Hz, dBandwidth_Hz;
00872 bool bCalibrate;
00873 std::string sSub20Serial;
00874
00875
00876
00877 if( nh.getParam("/bma180/max_acc_g", dMaxAcc_g) == false )
00878 {
00879 dMaxAcc_g = bma180_cmd::dDEFAULT_MAXACC_g;
00880 };
00881 if( nh.getParam("/bma180/bandwidth_Hz", dBandwidth_Hz) == false )
00882 {
00883 dBandwidth_Hz = bma180_cmd::dDEFAULT_BANDWIDTH_Hz;
00884 };
00885 if( nh.getParam("/bma180/rate_Hz", dRate_Hz) == false )
00886 {
00887 dRate_Hz = bma180_cmd::dDEFAULT_RATE_Hz;
00888 };
00889 if( nh.getParam("/bma180/calibrate", bCalibrate) == false )
00890 {
00891 bCalibrate = bma180_cmd::bDEFAULT_CALIBRATE;
00892 };
00893 if( nh.getParam("/bma180/sub20serial", sSub20Serial) == false )
00894 {
00895 sSub20Serial = bma180_cmd::sSUB20SERIAL;
00896 };
00897
00898 Bma180 bma180_attached( dMaxAcc_g, dBandwidth_Hz, bCalibrate, dRate_Hz, sSub20Serial );
00899 OneBma180Meas sOneMeas;
00900 bma180::bma180meas msg;
00901 std::list<OneBma180Meas> measurements_list;
00902
00903
00904
00905
00906
00907 ros::Rate loop_rate(dRate_Hz);
00908
00909 while( nh.ok() )
00910 {
00911
00912 try
00913 {
00914 bma180_attached.GetMeasurements(measurements_list);
00915 }
00916 catch( std::string strType )
00917 {
00918 std::cout << " An exception occurred: " << strType << std::endl;
00919 std::exit(1);
00920 }
00921
00922 while( !measurements_list.empty() )
00923 {
00924 sOneMeas = measurements_list.back();
00925 measurements_list.pop_back();
00926
00927 if( sOneMeas.bMeasAvailable == true )
00928 {
00929 msg.strIdSubDev = sOneMeas.strSerial;
00930
00931
00932 for( i = 0; i < sOneMeas.iNumAccels; i++ )
00933 {
00934 msg.iChipSelect.push_back( sOneMeas.iChipSelect[i] );
00935 msg.fAccelX.push_back( sOneMeas.dAccX[i] );
00936 msg.fAccelY.push_back( sOneMeas.dAccY[i] );
00937 msg.fAccelZ.push_back( sOneMeas.dAccZ[i] );
00938 }
00939 msg.header.stamp = sOneMeas.dtomeas;
00940 bma180_pub.publish( msg );
00941
00942
00943 msg.iChipSelect.clear();
00944 msg.fAccelX.clear();
00945 msg.fAccelY.clear();
00946 msg.fAccelZ.clear();
00947 }
00948 }
00949
00950 ros::spinOnce();
00951 loop_rate.sleep();
00952 ++count;
00953 }
00954 }
00955
00956