Read a Bosch SBM380 Accelerometer using I2C

Download pre-release library modules and new examples to use with Astrobe for Cortex-M3. Forum members can also upload their own source code examples.

Read a Bosch SBM380 Accelerometer using I2C

Postby cfbsoftware » Sat Jun 09, 2012 1:14 am

Code: Select all
MODULE Accelerometer;
(* ========================================================================= 
   Example ARM Oberon I2C Accelerometer Program 

   Description:
     Reads the accelerometer X, Y, Z and temperature values every 50ms and
     displays the values whenever the change exceeds a specified threshold.
   
   Target:
     LPC17xx systems with a Bosch SBM380 3-axis Accelerometer
     connected to the I2C2 bus

   Tested with:
     Olimex LPC1766-STK 
     
   Refs:
     NXP LPC17xx User Manual UM10360
     Bosch SBM380 Datasheet
     Oberon for Cortex-M3 Microcontrollers
   
   (c) 2010-2012 CFB Software   
   http://www.astrobe.com 
   
   ========================================================================= *)

IMPORT MCU, I2C, SYSTEM, Main, Out, Timer;


PROCEDURE* DataToInt(lsb, msb: SYSTEM.BYTE): INTEGER;
(* The result is a 10-bit 2's complement integer:
     result:9:2 := msb:7:0, result:0:1 = lsb:7:6
   First store the data as the most significant 10 bits of the result
   so that we can then use ASR to extend the sign bit while shifting the
   data to the least significant 10 bits.
*)
  RETURN ASR(LSL(ORD(msb), 24) + LSL(ORD(lsb), 16), 22)
END DataToInt;


PROCEDURE* DataToDegs(data: SYSTEM.BYTE): INTEGER;
(* data = 0..255, result = -30 deg to 97.5 deg *)
  RETURN -30 + (ORD(data) DIV 2)
END DataToDegs;


PROCEDURE* Diff(prev, this: INTEGER): INTEGER;
  RETURN ABS(prev - this)
END Diff;


PROCEDURE OutData(label: ARRAY OF CHAR; data: INTEGER);
BEGIN
  Out.String(label); Out.Int(data, 5)
END OutData;


PROCEDURE Run();
CONST
  I2CFreq = 400000;
  I2CBus = 2;
  SBM380Addr = 038H;
  (* Minimum change to be reported *)
  Threshold = 10;
  (* 10-bit signed integer *)
  MaxXYZ = 511;
VAR
  data: ARRAY 8 OF SYSTEM.BYTE;
  status, thisX, thisY, thisZ, prevX, prevY, prevZ, degrees: INTEGER;
  dataAddr: CHAR;
BEGIN
  I2C.Init(I2CBus, I2CFreq);
  dataAddr := 02X;
 
  prevX := MaxXYZ + Threshold + 1;
  prevY := MaxXYZ + Threshold + 1;
  prevZ := MaxXYZ + Threshold + 1;
 
  WHILE TRUE DO
    status := I2C.Read(SBM380Addr, dataAddr, data);
    IF status = I2C.OK THEN
     
    (* Convert the raw data *)
      thisX := DataToInt(data[0], data[1]);
      thisY := DataToInt(data[2], data[3]);
      thisZ := DataToInt(data[4], data[5]);
      degrees := DataToDegs(data[6]);
     
      (* Check if the change is enough to be reported *)
      IF (Diff(prevX, thisX) > Threshold)
      OR (Diff(prevY, thisY) > Threshold)
      OR (Diff(prevZ, thisZ) > Threshold) THEN
        OutData("x:", thisX);
        OutData(", y:", thisY);
        OutData(", z:", thisZ);
        OutData(", deg:", degrees);
        Out.Ln();
        prevX := thisX; prevY := thisY; prevZ := thisZ;
      END
     
    ELSE
      OutData("I2C Read Error: ", status);
      Out.Ln()
    END;
    Timer.MSecDelay(50)
  END
END Run;


BEGIN
  Run()
END Accelerometer.
Attachments
Accelerometer.zip
Accelerometer.zip
(1.39 KiB) Downloaded 105 times
cfbsoftware
Site Admin
 
Posts: 361
Joined: Fri Dec 31, 2010 12:30 pm

Return to Cortex-M3

cron