Acelerometer

Coordinator
Aug 12, 2010 at 2:45 PM
Edited Aug 12, 2010 at 2:48 PM
Ther is pretty good idea to have several sensors of aceleration and velocity connected over I2C.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213072318
As an example.

 

Coordinator
Aug 12, 2010 at 2:47 PM

 

#include <LiquidCrystal.h>
#include <Wire.h>
// based on Sketch by bGatti from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213072318
// for use with http://www.nkcelectronics.com/triple-axis-accelerometer-breakout--lis30302.html
// tested with a seeeduino board, i2c connection established using the breakout pads with angled
// pin headers soldered in.
// Copyright Shu Ning Bian 2008, released under GPLv2
int _slave_id = 0x1D;
int backlight_pin = 3;

LiquidCrystal lcd(5,6,7,8,9,10,11);

uint8_t read_register(uint8_t sub)
{
   i2c_send(_slave_id, &sub, 1);
   return i2c_read(_slave_id);
}
    
void write_register(uint8_t sub, uint8_t data)
{
  uint8_t bytes[] = {sub, data};
  i2c_send(_slave_id, bytes, 2);
}

uint8_t i2c_read(uint8_t id)
{
  Wire.requestFrom(_slave_id, 1);
  while(!Wire.available())
  {
    delay(10);
  }
  
  return Wire.receive();
  
}

void i2c_send(uint8_t id, uint8_t * data, uint8_t len)
{
  Wire.beginTransmission(id);
  for(int i = 0; i < len; ++i)
  {
    Wire.send(data[i]);
  }
  Wire.endTransmission();
}

void dot_print(int val)
{
  /* prints a number in the form of i.f where i is from val/10 and f
     from val%10
  */
  int i = val/10;
  int f = val%10;
  
  if ( val < 0 )
  {
    f*=-1;
  }

  if ( i>=0 )
  {
    // print a + to counter the - which is added by print when val is negative
    lcd.print("+");
  }

  lcd.print(i, DEC);
  lcd.print(".");
  lcd.print(f,DEC);
  if (i<10)
  {
    lcd.print(" ");
  }
}

void pretty_print(char x, char y, char z)
{
  /* The divisor of x,y, and z are chosen to give the "correct" value at 1g. They are worked out
     by trial and error, but a rough starting point can be calculated as follows:
    
     1. divided by 128 to normalise the range
     2. multiply by 2 since the range is +/- 2,
       * combined so this gives divided by 64, giving acceleration in gs
     3. multiply by 9.8 to give acceleration in ms/s/s,
       * combined this gives multiply by 9.8/64
     4. to make things into nicer integer maths, invert 9.8/64 to give 6.5
     5. now we can truncate and use divisor of 6, an integer, or sacrifice some cycles and use
        a floating value around 6 which gives the "correct" value of 9.8m/s/s for an axis when that
        axis is "pointing" towards the centre of the earth.
     Note I have multiplied everything by 10 implicitly to keep us in int domain
  */
  int xx = x * 100 / 55;
  int yy = y * 100 / 55;
  int zz = z * 100 / 63;

  lcd.clear();  
  lcd.print("X:");dot_print(xx);lcd.print(" ");
  lcd.print("Y:");dot_print(yy);lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("Z:");dot_print(zz);lcd.print(" (m/s/s)");
}

#define CTRL_REG2 0x21
#define CTRL_REG1 0x20

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  lcd.print("Setting up...");
  write_register(CTRL_REG2, B01000000);
  /* 0 - SPI mode selection
     1 - reboot memory contents
     0 - none
     0 - filtered data selection, 0 = bypassed
     0 - high pass filter enable for freefall/wakeup #2, 0 = bypassed
     0 - high pass filter enable for freefall/wakeup #1, 0 = bypassed
     0 - high pass coefficient 2
     0 - high pass coefficient 1
     the last 2 bits configure the high pass filter cutoff frequency
  */
  
  write_register(CTRL_REG1, B01000111);
  /* 0 - data rate selection, 1=100Hz
     1 - power down control, 1 = active mode
     0 - full scale selection, 0 = +/- 2g, 1 = +/- 8g
     0 - self test P enable, 0 = normal mode
     0 - self test M enabled, 0 = normal mode
     1 - z axis enable, 1 = enabled
     1 - y axis enable, 1 = enabled
     1 - x axis enable, 1 = enabled
  */
  
  pinMode(backlight_pin, OUTPUT);
  analogWrite(backlight_pin, 128);
}

void loop()
{

  #define OUT_X 0x29
  #define OUT_Y 0x2B
  #define OUT_Z 0x2D
  #define STATUS_REG 0x27

  //----------Status Register-----------------------
  byte  status = read_register(STATUS_REG);

  #define ZYXDA  0x08
  if ( status & ZYXDA == 0)
  {
    // ZYXDA is 1 when new set of data is available, so since its 0, lets skip
    return;
  }
  
  //----------X Values-----------------------
  char x_val = read_register(OUT_X);


  //----------Y Values-----------------------
  char y_val = read_register(OUT_Y);

 //----------Z Values-----------------------
  char z_val = read_register(OUT_Z);

  //Serial.print("status "); Serial.println(status, BIN);
  
  pretty_print(x_val, y_val, z_val);
  delay(200);
}
Coordinator
Aug 12, 2010 at 2:47 PM

 

#include <Wire.h>

#define i2cID 0x1D

//TWI (I2C) sketch to communicate with the LIS302DL accelerometer - Modified and tested Ben Gatti - 6/9/2008
//http://www.st.com/stonline/products/literature/ds/12726.pdf
//Note 5.6K pullup resister on data lines.
//Device is 3 volt was tested at 5 volts no level shifting.
//Reference claims 6 volts is pin max.

//Modified from // TWI (I2C) sketch to communicate with the LIS3LV02DQ accelerometer
//http://www.nearfuturelaboratory.com/2007/01/11/arduino-and-twi/
//Modified code from http://research.techkwondo.com/blog/julian/279
//Thanks Julian.

// Using the Wire library (created by Nicholas Zambetti)
// http://wiring.org.co/reference/libraries/Wire/index.html
// On the Arduino board, Analog In 4 is SDA, Analog In 5 is SCL
// These correspond to pin 27 (PC4/ADC4/SDA) and pin 28 (PC5/ADC5/SCL) on the Atmega8
// The Wire class handles the TWI transactions, abstracting the nitty-gritty to make
// prototyping easy.

void setup()

{

  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(57600);

  Serial.println("Wire.begin");

  Wire.beginTransmission(i2cID);
  Wire.send(0x21); // CTRL_REG2 (21h)
  Wire.send(B01000000);
  //SPI 4/3 wire
  //1=ReBoot - reset chip defaults
  //n/a
  //filter off/on
  //filter for freefall 2
  //filter for freefall 1
  //filter freq MSB
  //filter freq LSB - Hipass filter (at 400hz) 00=8hz, 01=4hz, 10=2hz, 11=1hz (lower by 4x if sample rate is 100hz)
  Wire.endTransmission();

  Wire.beginTransmission(i2cID);
  Wire.send(0x20); // CTRL_REG1 (20h)
  Wire.send(B01000111);
  //sample rate 100/400hz
  //power off/on
  //2g/8g
  //self test
  //self test
  //z enable
  //y enable
  //x enable
  Wire.endTransmission();

}

void loop()
{

#define outXhigh 0x29
#define outYhigh 0x2B
#define outZhigh 0x2D
#define statusReg 0x27

boolean goodRead;
goodRead = false;

//----------Status Register-----------------------
  byte status;
  status = B00000000;
  //

//-------------------------------
  Wire.beginTransmission(i2cID);
  Wire.send(statusReg);
  Wire.endTransmission();

  Wire.requestFrom(i2cID, 1);
  if(Wire.available())
 {
   status = Wire.receive();
 }



//----------X Values-----------------------
  byte x_val;

//-------------------------------
  Wire.beginTransmission(i2cID);
  Wire.send(outXhigh);
  Wire.endTransmission();

Wire.requestFrom(i2cID, 1);
if(Wire.available())
 {
   x_val = Wire.receive();
 }


//----------Y Values-----------------------
  byte y_val;

//-------------------------------
  Wire.beginTransmission(i2cID);
  Wire.send(outYhigh);
  Wire.endTransmission();

Wire.requestFrom(i2cID, 1);
if(Wire.available())
 {
   y_val = Wire.receive();
 }

 //----------Z Values-----------------------
  byte z_val;

//-------------------------------
  Wire.beginTransmission(i2cID);
  Wire.send(outZhigh);
  Wire.endTransmission();

Wire.requestFrom(i2cID, 1);
if(Wire.available())
 {
   z_val = Wire.receive();
   goodRead=true;
 }
//-------------------------------


 if (goodRead==true)
 {

//Serial.print("x_val_l= "); Serial.println(x_val_l, DEC);
//Serial.print("x_val_h= "); Serial.println(x_val_h, DEC);
//Serial.print("x_val= "); Serial.println(x_val, DEC);

//Serial.print("y_val_l= "); Serial.println(y_val_l, DEC);
//Serial.print("y_val_h= "); Serial.println(y_val_h, DEC);
//Serial.print("y_val= "); Serial.println(y_val, DEC);

//Serial.print("z_val_l= "); Serial.println(z_val_l, DEC);
//Serial.print("z_val_h= "); Serial.println(z_val_h, DEC);
Serial.print("status "); Serial.println(status, BIN);
Serial.print(" val= "); Serial.print(x_val, DEC);
Serial.print(":"); Serial.print(y_val, DEC);
Serial.print(":"); Serial.println(z_val, DEC);
 }
 else
Serial.print("no data");

  delay(100);
}