Bosh BMA180, Accelerometer
I purchased a Bosh BMA180 tri axis accelerometer from Sparkfun to play with. It has been one of the most frustrating devices I have ever used. I connected it up with SPI instead of the optional i2c interface because it can't handle 5 volts. SPI is unidirectional and simple voltage dividers allow me to connect it to my breadboard Arduino. The SDO/MISO and INT/INT0 connections are ok to direct connect because my processor sees the 3.3 volt output as a high signal.
Purchased from sparkfun.com
Datasheet
My code is chalk full of bugs but it's a start:
/////////////////////////////////////////////////////////////////////////////////////////////////////// // Tri Axis Accelerometer, BMA180 connected with SPI //function prototypes void solid(int r, int g, int b, int t); //Pin declarations #define PIN_INTERUPT 0 #define PIN_LEDR 3 #define PIN_LEDG 5 #define PIN_LEDB 6 #define DATAOUT 11 //MOSI #define DATAIN 12 //MISO - not used, but part of builtin SPI #define SPICLOCK 13 //SCK #define SLAVESELECT 10 //SS int r=0, g=0, b=0; /////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { delay(2000); Serial.begin(57600); Serial.println("BMA180 Test"); byte clr; pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK, OUTPUT); pinMode(SLAVESELECT, OUTPUT); digitalWrite(SLAVESELECT, HIGH); //disable device pinMode(PIN_INTERUPT, INPUT); SPCR = (1< //SPCR = (1< // The SPI control register (SPCR) has 8 bits, each of which control a particular SPI setting. // SPCR // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // | SPIE | SPE | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 | // SPIE - Enables the SPI interrupt when 1 // SPE - Enables the SPI when 1 // DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0 // MSTR - Sets the Arduino in master mode when 1, slave mode when 0 // CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0 // CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0 // SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz) clr=SPSR; clr=SPDR; // if connected correctly, ID register should be 3 while (read(0x00) != 3) { Serial.println("Error connecting to BMA180"); delay(1000); } Serial.println("Successfully connected to BMA180"); for (int j=0x20; j<0x40; j++) { //read_bits (j, 7, 0); } // You must turn this on to change anything from 0x20 to 0x3F write_bits(0x0D, 4, 4, 1); // ee-w, Allow updates from 0x20 to 0x50 write_bits(0x26, 0, 0, 1); // dis_i2c, Turn off I2C write_bits(0x35, 3, 1, 2); // range, Set the range, 2g write_bits(0x20, 7, 4, 4); // bw, Set the bandwidth, 150hz //write_bits(0x22, 2, 0, 3); // offset_finetuning, Turn on full calibration //write_bits(0x0E, 7, 7, 1); // en_offset_x, Start calibration on X axis //write_bits(0x0E, 6, 6, 1); // en_offset_y, Start calibration on Y axis //write_bits(0x0E, 5, 5, 1); // en_offset_z, Start calibration on Z axis write_bits(0x21, 6, 6, 0); // slope_int, Turn on/off interupt write_bits(0x21, 5, 5, 0); // high_int, Turn on/off interupt write_bits(0x21, 4, 4, 0); // low_int, Turn on/off interupt write_bits(0x21, 3, 3, 0); // tapsens_int, Turn on/off interupt write_bits(0x21, 2, 2, 0); // adv_int, Turn on/off interupt write_bits(0x21, 1, 1, 0); // new_data_int, Turn on/off interupt write_bits(0x21, 0, 0, 0); // lat_int, Turn on/off interupt write_bits(0x24, 0, 0, 1); // tapsens_filt, Tap sensor will use filtered data write_bits(0x0D, 4, 4, 0); // ee_w, disable updates attachInterrupt(0, bma180_interupt, CHANGE); } /////////////////////////////////////////////////////////////////////////////////////////////////////// char read(uint8_t address) { //returns the contents of any 1 byte register from any address //sets the MSB for every address byte (READ mode) char byte; address |= 0x80; digitalWrite(SLAVESELECT, LOW); //enable device by setting CSB to 0 txdata(address); byte = rxdata(); digitalWrite(SLAVESELECT, HIGH); //disable device by setting CSB to 1 return byte; } /////////////////////////////////////////////////////////////////////////////////////////////////////// void write(uint8_t address, char data) { //write any data byte to any single address //adds a 0 to the MSB of the address byte (WRITE mode) address &= 0x7F; // Set the RW bit to 0 (write) digitalWrite(SLAVESELECT, LOW); //enable device txdata(address); txdata(data); digitalWrite(SLAVESELECT, HIGH); //disable device } /////////////////////////////////////////////////////////////////////////////////////////////////////// char rxdata(void) { SPDR = 0x00; while (!(SPSR & (1< //while((SPSR&0x80) == 0x00); return SPDR; } /////////////////////////////////////////////////////////////////////////////////////////////////////// void txdata(char data) { SPDR = data; while (!(SPSR & (1< //while((SPSR&0x80) == 0x00); } /////////////////////////////////////////////////////////////////////////////////////////////////////// int read_bits(uint8_t address, int first, int last) { byte temp = 0; temp = read(address); temp = (temp<<(7-first)); // Get rid of the un-wanted right most bits temp = (temp>>(7-first+last)); // Get rid of the un-wanted left most bits Serial.print("Reading Register: 0"); Serial.print(address, HEX); Serial.print("h, bits "); Serial.print(first); Serial.print("-"); Serial.print(last); Serial.print(": 0"); Serial.print(temp, HEX); Serial.print("h "); Serial.print(temp, BIN); Serial.print(" binary"); Serial.println(); return temp; } /////////////////////////////////////////////////////////////////////////////////////////////////////// void write_bits(uint8_t address, int first, int last, int value) { byte temp = 0; byte save_left = 0; byte save_right = 0; temp = read(address); save_left = (temp>>first+1); // Get rid of the un-wanted right most bits save_left = (save_left< save_right = (temp<<8-last); // Get rid of the un-wanted right most bits save_right = (save_right>>8-last); // Get rid of the un-wanted right most bits temp = (save_left | save_right | (value< Serial.print("Writing Register: 0"); Serial.print(address, HEX); Serial.print("h, bits "); Serial.print(first); Serial.print("-"); Serial.print(last); Serial.print(", new value: "); Serial.print(value, HEX); Serial.print(": 0"); Serial.print(temp, HEX); Serial.print("h "); Serial.print(temp, BIN); Serial.print(" binary"); Serial.println(); write(address, temp); } /////////////////////////////////////////////////////////////////////////////////////////////////////// void bma180_interupt() { read_bits (0x0B, 7, 0); //Serial.println("Something happened"); } /////////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { delay(10); long total; signed short temp = 0; signed short x = 0; signed short y = 0; signed short z = 0; byte x_msb_byte = 0; byte x_lsb_byte = 0; byte y_msb_byte = 0; byte y_lsb_byte = 0; byte z_msb_byte = 0; byte z_lsb_byte = 0; digitalWrite(SLAVESELECT, LOW); //enable device by setting CSB to 0 txdata(0x02 | 0x80); x_lsb_byte = rxdata(); x_msb_byte = rxdata(); y_lsb_byte = rxdata(); y_msb_byte = rxdata(); z_lsb_byte = rxdata(); z_msb_byte = rxdata(); digitalWrite(SLAVESELECT, HIGH); //disable device by setting CSB to 1 temp = x_msb_byte; temp = (unsigned int)temp << 8; temp |= x_lsb_byte; temp = (unsigned int)temp >> 2; // Get rid of two non-value bits in LSB temp = (unsigned int)temp << 2; // Put it back x = temp / 4; temp = y_msb_byte; temp = (unsigned int)temp << 8; temp |= y_lsb_byte; temp = (unsigned int)temp >> 2; // Get rid of two non-value bits in LSB temp = (unsigned int)temp << 2; // Put it back y = temp / 4; temp = z_msb_byte; temp = (unsigned int)temp << 8; temp |= z_lsb_byte; temp = (unsigned int)temp >> 2; // Get rid of two non-value bits in LSB temp = (unsigned int)temp << 2; // Put it back z = temp / 4; if (x > 0) { r = map(x, 0, 4500, 0, 255); //r = 0; g = 0; b = 0; } else { r = 0; g = 0; //b = 0; b = map(x, 0, -4500, 0, 255); } //g = map(y, -5000, -5500, 0, 255); Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.print(z); total = abs(x) + abs(y) + abs(z); Serial.print(" "); Serial.print(total); Serial.println(); // PWM output to LED analogWrite(PIN_LEDR, r); analogWrite(PIN_LEDG, g); analogWrite(PIN_LEDB, b); } ///////////////////////////////////////////////////////////////////////////////////////////////////////
created: Dec. 1, 2013, 1:01 a.m.
modified: April 14, 2019, 12:42 a.m.