Keywords

Arduino Parallax H48C 3-axis acelerometer

description

This sensor is controlled by a serial protocol as shown in figure 5.1

  1. a start bit is send (function StartBit())
  2. command send to get the right data (function ShiftOutNibble(Command)) see table 5.1
  3. The chip needs one CLK cycle to sample data, then the OUTPUT of DIO becomes INPUT (function SampleIt())
  4. The 12bit result is shifted in in three 4bit blocks (function ShiftInNibble()) and connected to one integer (range -2048 to 2048)
  5. The sampling ends by deselcting the chip (function EndBit())

The function GetValue(byte Command) includes everything in the right order:

  aX = GetValue(B1000);
  aY = GetValue(B1001);
  aZ = GetValue(B1010);

CODE

/*
/////////////////////////////////
Htachi H48C3 Axis Accelerometer 
parallax (#28026)

AUTHOR:   kiilo kiilo@kiilo.org
License:  http://creativecommons.org/licenses/by-nc-sa/2.5/ch/

http://parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/28026/List/1/ProductID/97/Default.aspx?SortField=ProductName%2cProductName
http://sage.medienkunst.ch/tiki-index.php?page=HowTo_Arduino_Parallax_H48C_Accelerometer
http://arduino.cc

/////////////////////////////////
*/
//// VARS
int CS_pin = 9;
int CLK_pin = 10;
int DIO_pin = 11;

int aX  = 0;
int aY  = 0;
int aZ  = 0;

//// FUNCTIONS
void StartBit() {
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(CS_pin, LOW);
  digitalWrite(CLK_pin, LOW);
  delayMicroseconds(1);
  digitalWrite(DIO_pin, HIGH);
  digitalWrite(CLK_pin, HIGH);
  delayMicroseconds(1);

  }

void ShiftOutNibble(byte DataOutNibble) {
  for(int i = 3; i >= 0; i--) { // i = 3 ... 2 ... 1 ... 0 
    digitalWrite(CLK_pin, LOW);
    // set DIO first
    if ((DataOutNibble & (1 << i)) == (1 << i)) {  // DataOutNibble AND 1 x 2^i Equals 1 x 2^i ?
      digitalWrite(DIO_pin, HIGH);      
      }
    else {
      digitalWrite(DIO_pin, LOW);
      }
    // with CLK rising edge the chip reads the DIO from arduino in
    digitalWrite(CLK_pin, HIGH);
    // data rate is f_clk 2.0 Mhz --> 0,5 micro seeconds 
    delayMicroseconds(1); // :-) just nothing 
  }
}

void SampleIt() {
  digitalWrite(CLK_pin, LOW);
  delayMicroseconds(1);
  digitalWrite(CLK_pin, HIGH);
  delayMicroseconds(1);

  pinMode(DIO_pin, INPUT);
  digitalWrite(CLK_pin, LOW);
  delayMicroseconds(1);
  digitalWrite(CLK_pin, HIGH);
  if (digitalRead(DIO_pin)== LOW) {
    // Blink LED because ok
    }
}

byte ShiftInNibble() {
  byte resultNibble;
  resultNibble = 0;

    for(int i = 3 ; i >= 0; i--) { // from bit 3 to 0
      // The chip Shift out results on falling CLK 
      digitalWrite(CLK_pin, LOW);
      delayMicroseconds(1); // :-) just nothing       
      if( digitalRead(DIO_pin) == HIGH) { // BIT set or not?
        resultNibble += 1 << i; // Store 1 x 2^i in our ResultNibble
      }
      else {
        resultNibble += 0 << i; // YES this is alway 0, just for symetry ;-)
      }
      digitalWrite(CLK_pin, HIGH);
      //delayMicroseconds(1); // :-) just nothing
    }
return resultNibble;
}

void EndBit() {
  digitalWrite(CS_pin, HIGH);
  digitalWrite(CLK_pin, HIGH);
}

int GetValue(byte Command) { // x = B1000, y = B1001, z = B1010
  int Result = 0;
  StartBit();
  ShiftOutNibble(Command);
  SampleIt();
  Result =  2048 - ((ShiftInNibble() << 8) + (ShiftInNibble() << 4) + ShiftInNibble());
  EndBit();

  return Result;
  }

//// SETUP
void setup() {
  Serial.begin(115200);
  pinMode(CS_pin, OUTPUT);
  pinMode(CLK_pin, OUTPUT);
  pinMode(DIO_pin, OUTPUT);
  // initialize device & reset
  digitalWrite(CS_pin,LOW);
  digitalWrite(CLK_pin,LOW);
  delayMicroseconds(1);
  digitalWrite(CS_pin, HIGH);
  digitalWrite(CLK_pin,HIGH);
}


//// LOOP
void loop() {

  aX = GetValue(B1000);
  aY = GetValue(B1001);
  aZ = GetValue(B1010);

  Serial.print(aX);
  Serial.print(" ");
  Serial.print(aY);
  Serial.print(" ");
  Serial.print(aZ);
  Serial.println("");
  delay(100);  // loop every 10 times per sec.
}

Link

Author

  • kiilo AT kiilo DOT org

Share