chipKIT® Development Platform

Inspired by Arduino™

BMA180 - SPI accel does not work on Chipkit MAX32

Created Tue, 23 Aug 2011 19:33:29 +0000 by noisette


noisette

Tue, 23 Aug 2011 19:33:29 +0000

The following SPI code to talk to a BMA180 accelerometer from Sparkfun does not work. Can someone help me use this sketch successfully ?

Thanks, Jean-Francois Gauthier

/**********************************************************

 * BMA180_SPI_Example.pde ----- Sample sketch for BMA180 Accelerometer using SPI Mode 3

 * 

 * A sample sketch that shows the basic functions of the BMA180 acclerometer.

 *

 

 **********************************************************/

#include <SPI.h>



#define ee_w_MASK           0x10

#define mode_config_MASK    0x03

#define bw_MASK             0xF0

#define range_MASK          0x0E

#define lat_int_MASK        0x01

#define lat_int             0x01

#define START               PORTB &= ~0x04

#define STOP                PORTB |= 0x04

#define READ                0x80

#define CSB                 10     //slave select pin



int x,y,z,temp;



void setup() {

  Serial.begin(115200);

  pinMode (CSB, OUTPUT); // set the slaveSelectPin as an output

  SPI.begin();

  SPI.setDataMode(SPI_MODE3);

  initializeBMA180();

}



void loop()

{

  readAccel();

  printAccel();

  delay(200);

}



void readAccel()

{

  START;

  SPI.transfer(0x02|READ);

  x = SPI.transfer(0xFF);

  x |= SPI.transfer(0xFF) << 8;

  x >>= 2;

  y = SPI.transfer(0xFF);

  y |= SPI.transfer(0xFF) << 8;

  y >>= 2;

  z = SPI.transfer(0xFF);

  z |= SPI.transfer(0xFF) << 8;

  z >>= 2;

  temp = SPI.transfer(0xFF);

  STOP;

}



void printAccel()

{

  Serial.print("X = ");

  Serial.print((int)x,DEC);

  Serial.print("  Y = ");

  Serial.print((int)y,DEC);

  Serial.print("  Z = ");

  Serial.print((int)z,DEC);

  Serial.print("  Temperature(C) = ");

  Serial.println(map((int8_t)temp,-128,127,-400,875)/10.0,1);

}



byte initializeBMA180()

{

  /*Set EEPROM image to write mode so we can change configuration*/

  delay(20);

  START;

  SPI.transfer(0x0D|READ);

  byte ee_w = SPI.transfer(0xFF);

  STOP;

  delay(1);

  START;

  ee_w |= ee_w_MASK;

  SPI.transfer(0x0D);

  SPI.transfer(ee_w);

  STOP;

  delay(20);

  //disable I2C as per the datasheet

  START;

  SPI.transfer(0x27|READ);

  byte dis_I2C = SPI.transfer(0xFF);

  dis_I2C |= 0x01;

  STOP;

  delay(1);

  START;

  SPI.transfer(0x27);

  SPI.transfer(dis_I2C);

  STOP;

  delay(20);

  /*Set mode configuration register to Mode 00*/

  START;

  SPI.transfer(0x30|READ);

  byte mode_config = SPI.transfer(0xFF);

  mode_config &= ~(mode_config_MASK);

  STOP;

  delay(1);

  START;

  SPI.transfer(0x30);

  SPI.transfer(mode_config);

  STOP;

  delay(20);

  /*Set bandwidth to 10Hz*/

  START;

  SPI.transfer(0x20|READ);

  byte bw = SPI.transfer(0xFF);

  bw &= ~(bw_MASK);

  bw |= 0x00 << 4;  

  STOP;

  delay(1);

  START;

  SPI.transfer(0x20);

  SPI.transfer(bw);

  STOP;

  delay(20);

  /*Set acceleration range to 2g*/

  START;

  SPI.transfer(0x35|READ);

  byte range = SPI.transfer(0xFF);

  range &= ~(range_MASK);

  range |= (0x02 << 1) ;  

  STOP;

  delay(1);

  START;

  SPI.transfer(0x35);

  SPI.transfer(range);

  STOP;

  delay(20);

  /*Set interrupt latch state to non latching*/

  START;

  SPI.transfer(0x21|READ);

  byte latch_int = SPI.transfer(0xFF);

  latch_int &= ~(0x01);

  STOP;

  delay(1);

  START;

  SPI.transfer(0x21);

  SPI.transfer(latch_int);

  STOP;

  delay(20); 

  /*Set interrupt type to new data*/

  START;

  SPI.transfer(0x21|READ);

  byte int_type = SPI.transfer(0xFF);

  int_type |= 0x02;

  STOP;

  delay(1);

  START;

  SPI.transfer(0x21);

  SPI.transfer(int_type);

  STOP;

  delay(20); 

  return(0);

}

rasmadrak

Wed, 24 Aug 2011 12:59:20 +0000

Can the accel handle the high CPU speed of the Chipkit? Try slowing down the SPI speed and check that the component works with 3.3V.


noisette

Wed, 24 Aug 2011 14:24:11 +0000

it works! Thanks! The SPI speed was indeed to fast, i needed to slow it down to clock divided by 128.