Hitachi H48C 3-Axis - Arduino:

helo everybody, i have a question concerning the 3-axis accelerometer module H48C from hitachi. I got it from parallax ( http://www.parallax.com/detail.asp?product_id=28026 ). does someone have already experiences with it and arduino? in the basic stamp example code i'm stucking at this lines:

SHIFTOUT Dio, Clk, MSBFIRST, [%11\2, VRef\3] ' select vref register
SHIFTIN Dio, Clk, MSBPOST, [rvCount\13] ' read ref voltage counts

the shiftout function is in arduino availabe but no shiftin. and what does %11\2, VRef\3 mean? is it a 2bit long bytearray (11) and \3 means VRef is 3 bits long?

and i don't know either how to make a multiply high (**) in arduino.
IF (axCount >= rvCount) THEN
gForce = (axCount - rvCount) ** GfCnv

thanks in advance for your help, links, etc.
best regards, koji

Hi !

I saw your post here : http://forums.parallax.com/forums/default.aspx?f=8&m=137621

Have you done any progress since then ? The H48C seems really interesting to use on the Arduino but the BStamp code seems to be really difficult to be done.

HEY NNIMAR: NO UNFORTUNATELLY NOT, I STOPED TRYING AFTER A WHILE BECAUSE OF OTHER THINGS WHICH HAVE TO BE DONE. I SUPPOSE THE FUNCTION MYSHIFTOUT OR MYSHIFTIN OR BOTH OF THEM ARE THE PROBLEM. THE SERIAL COMMUNICATION IS VERY HARD TO DEBUG THOUGH. DO YOU HAVE ANY THOUGHTS WHAT'S THE PROB? OR MAYBE SOMEONE ELSE GOT IT RUNNING? WOULD BE GREAT.

// Constants:
int xAxis = 0;
int yAxis = 1;
int zAxis = 2;
int Cnt2Mv = (short) 52813; // 0.8058665536
int GfCnv = 14418; //0.22
65536

// Pins:
int dioPin;
int clkPin;
int csPin;

void setup()
{
beginSerial( 19200 );

int dioPin = 5;
int clkPin = 6;
int csPin = 7;

pinMode( dioPin, OUTPUT );
pinMode( clkPin, OUTPUT );
pinMode( csPin, OUTPUT );

digitalWrite( csPin, HIGH ); // disable device
digitalWrite( clkPin, LOW );
digitalWrite( dioPin, LOW );
}

void loop()
{
int value;
value = gForce( xAxis );
//Serial.print( "x = " );
//Serial.println( value );

value = gForce( yAxis );
//Serial.print( "y = " );
//Serial.println( value );

value = gForce( zAxis );
//Serial.print( "z = " );
//Serial.println( value );

delay( 1000 ); // wait 1sec
}

int gForce( int adcValue, int refValue )
{
if( adcValue >= refValue )
return umulf( adcValue - refValue, GfCnv );
else
return -umulf( refValue - adcValue, GfCnv );
}

int gForce( int axis )
{
int refValue = readValue( 3 );
// Serial.println(refValue);
delay( 1 ); // wait 1msec
int adcValue = readValue( axis );
// Serial.println(adcValue);
return gForce( adcValue, refValue );
}

int readValue( int channel )
{

digitalWrite(csPin, LOW) ;

myShiftOut(dioPin, clkPin, 5, MSBFIRST, (short) ( ( 0x18 + channel ) << 11 ) );

int value = myShiftIn( dioPin, clkPin, 13 );

digitalWrite( csPin, HIGH );

Serial.println(value);

return value;
}

void myShiftOut(int dataPin, int clockPin, int bitCount, int bitOrder, int val ) {

pinMode( dataPin, OUTPUT );

for( int i = 0; i < bitCount; i++) {

digitalWrite( clockPin, HIGH );

if (bitOrder == LSBFIRST) {
digitalWrite( dataPin, ( val & 1) );
val = val >> 1;
}
else {
digitalWrite( dataPin, ((val >> 15)&1) );
val = val << 1;
}

digitalWrite( clockPin, LOW );
}
}

int myShiftIn(int dataPin, int clockPin, int bitCount) {
int pinState;
int dataIn = 0;
pinMode( clockPin, OUTPUT );
pinMode( dataPin, INPUT );

for(int i = 0; i < bitCount; i++) {

digitalWrite(clockPin, HIGH) ;
//layMicroseconds( 20 );
int temp = digitalRead( dataPin );

if (temp) pinState = 1;
else pinState = 0;

dataIn = (dataIn << 1) | pinState;

digitalWrite(clockPin, LOW);
}

//Serial.println(dataIn);

return dataIn;
}

int umulf( int value, int fraction )
{
int result = 0;
int rest = 0;
int temp, temp2;

for ( int i = 1; i < 17; i ++ )
{
if ( fraction < 0 ) //b15 set
{
result += ( ( value >> i ) & 0x7FFF ); //accumulate integer result
temp = ( ( value & ( ( 1 << i ) - 1) ) << ( 16 - i ) ); //accumulate rest R/65536
temp2 = rest ^ temp; // never overflow if sign(rest) != sign(temp)
rest += temp; //accumulate rest R/65536
//if (CPU.carry()) result++; //update result if rest overflows
if ( temp2 >= 0 ) //b15 clear, signs equal -> test for overflow
{
if ( ( rest ^ temp ) < 0) result ++; //new rest has different sign than temp
}
}
fraction <<= 1; //next bit
}
if ( rest < 0 ) result ++; //roundoff
return result;
}

some working code:
i will do a more detailed wiki page later:

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

byte tempLSB = 0;
byte tempMSB = 0;

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

//// FUNCTIONS
void StartMassurement() {
  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--) {
      // The chip Shift out results on falling CLK 
      digitalWrite(CLK_pin, LOW);
      delayMicroseconds(1); // :-) just nothing       
      if( digitalRead(DIO_pin) == HIGH) {
        resultNibble += 1 << i;
      }
      else {
        resultNibble += 0 << i;
      }
      digitalWrite(CLK_pin, HIGH);
    }
return resultNibble;
}

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

int GetValue(byte Axis) { // x = B1000, y = 1001, z = B1010
  int Result = 0;
  StartMassurement();
  ShiftOutNibble(Axis);
  SampleIt();
  Result =  (ShiftInNibble() << 8) + (ShiftInNibble() << 4) + ShiftInNibble();
  EndMessurement();
  
  return Result;
  }

//// SETUP
void setup() {
  Serial.begin(57600);
  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() {
  Serial.print(2048 - GetValue(B1000));
  Serial.print(" ");
  Serial.print(2048 - GetValue(B1001));
  Serial.print(" ");
  Serial.print(2048 - GetValue(B1010));


  Serial.println("");
}