Shop OBEX P1 Docs P2 Docs Learn Events
Request for translation (H48C Accelerometer code) — Parallax Forums

Request for translation (H48C Accelerometer code)

bulkheadbulkhead Posts: 405
edited 2007-04-23 15:45 in General Discussion
Hello, I am working on a sensor project with the Javelin stamp. I have acquired a lot of sensors but a few of them don't have sample code written for the Javelin. I was wondering if someone could help me translate the basic code to java? These are the sensors I'm using:

-Sensirion Temp/Humidity sensor www.parallax.com/detail.asp?product_id=28018
-Hitachi H48C Tri-axis Accelerometer www.parallax.com/detail.asp?product_id=28026

Any help would be appreciated, thanks.

Post Edited (bulkhead) : 7/31/2006 9:53:24 PM GMT

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-28 20:58
  • bulkheadbulkhead Posts: 405
    edited 2006-07-28 21:09
    Ok, thanks. I forgot to check there for code, I'll take a look.
  • bulkheadbulkhead Posts: 405
    edited 2006-07-28 21:22
    Ok, I got the Sensirion working by just hooking up my clock and data pins directly to the module. You might want to add a comment on the sht11.java file that warns not to use that wiring diagram with the module setup, since it already has the resistors built in.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-28 21:36
    To be clear,
    the 4k7 pullup and pulldown resistors are built into the SHT11 module?
    the capacitor and 220 ohm resistor are not built into the SHT11?

    Please specify exactly what is built in and what is external
    so I can adapt the schematic.

    regards peter
  • bulkheadbulkhead Posts: 405
    edited 2006-07-28 23:01
    Well, I am not really sure, but looking at the documentation for the SHT11 module (www.parallax.com/dl/docs/prod/acc/SensirionDocs.pdf) it appears most of the resistors are there. It is missing the 0.1uf capacitor though. The major difference I was pointing out was that the pin numbers for the Sensirion refer to the ones on the actual SHT11 unit (not module). If the module were hooked up to that schematic, it would not work (the Vdd line is pin8 on the module, not pin4, among other things).

    I hooked up mine directly to the module (no resistors or capacitors in between) and it worked fine. I guess the schematic isn't needed with the Sensirion module. However, you could add the note about the optional 4.7k ohm pull-down resistor on the clock line. Hope this is clear.
  • bulkheadbulkhead Posts: 405
    edited 2006-07-29 04:39
    Alright, I took a look at translating the sample code for the H48C tri-axis accelerometer. Attached is what I have done so far. The parts that I could not translate are the ones with the "**" operator or the debug print statements, of which I am not familiar with. If anyone could help me finish it, that would be great. I'm sure there's also ways to rewrite this class so that it takes advantage of the OOP style of java rather than just translating line for line, but I just need code that makes it work. Thanks.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-29 06:45
    Haven't you tested the H48C_test program I attached earlier?

    The basic stamp ** operator (multiply integer with fraction)
    is performed by the UnsignedIntMath.umulf() method.

    You find the UnsignedIntMath class here:
    http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/math/

    regards peter
  • bulkheadbulkhead Posts: 405
    edited 2006-07-31 17:24
    Sorry, I didn't see that you attached a program earlier. I just loaded it and all I am getting is 0 for the g-force values on each axis. What should I do?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-31 18:56
    The problem is probably the modes. Try changing CPU.SHIFT_MSB etc
    in method gforce(int channel).
    Take a look at the timing diagrams in the documentation.

    The PBASIC code is as comment included. I translated it from that
    code. Not tested because I don't have a H48C.

    regards peter
  • bulkheadbulkhead Posts: 405
    edited 2006-07-31 20:12
    Ok, I double checked that method and it appears the bitcount parameter and shift mode parameter are switched in the shiftIn() method. Fixing that in both places, I get the following numbers: x = -2 y = 0 and z = 102. When I move the unit around, the numbers do change, getting smaller or larger, so it appears the unit is functioning. Should I just add/subtract each value by a constant so at rest the reading is "0" at rest? Or is the shifting off by 1 or 2? As a side note, is there a way to test to see if it is reading the accleration properly?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-31 20:51
    Can you post your modified H48C_test?
    I would like to see what you changed to get the readings.

    If the unit is not moving, I assume x and y should be 0 when there is no tilt.
    For z, isn't it the gravity that is measured?

    regards peter
  • bulkheadbulkhead Posts: 405
    edited 2006-07-31 21:25
    Hmm, forgot about gravity. I turned on the javelin again and tested it with the unit vertical, and the x reading was roughly 100. Orienting it sideways gave a y reading of roughly 100. The other two values are around 0, so I assume it is just a margin of error. It seems like it is working fine. I am guessing the "100" stands for "1.00" g's, so all seems well.

    I have attached my modified version. The only thing I changed was switching the bitcount and mode on shiftIn.
  • bulkheadbulkhead Posts: 405
    edited 2006-07-31 21:52
    I converted the test program in to a class that has methods XAxis() YAxis() and ZAxis() for easy use. Attached is the class and a test program that prints the x, y, and z-axis force values. The H48C class needs to be put into the sensor.accelerometer class.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-07-31 22:10
    I did the same, optimizing the code.
    regards peter
  • kojiWakojiWa Posts: 4
    edited 2007-04-18 11:14
    hello, i'm sitting infront of the same problem. the difference is that i have an arduino board. i don`t have a shiftin and shiftout function. i saw your code and it is much easier to read for me then basic stamp. the method i couldn't see is the CPU.carry() method. could you explain me or translate me the functionallity? thanks & best regards, koji
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-04-18 12:32
    CPU.carry() returns true if there is an overflow after adding or subtracting two 16bit numbers.
    If there is no overflow, it returns false.

    regards peter
  • kojiWakojiWa Posts: 4
    edited 2007-04-18 15:54
    hello Peter, thanks for your repply. i changed your java code for arduino and tried to add the missing methods. unfortunatelly it doesn't work and i get 0 as result in every axis. i attached the script. do you mind to take a look on it? thanks in advance & best regards, koji

    EDIT: PS: it prints 255 for refValue and adcValue

    Post Edited (kojiWa) : 4/18/2007 9:09:54 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-04-19 11:13
    Your umulf conversion is incorrect.
    Here is the javelin version

    · /**
    ·· * Multiply unsigned integer with unsigned fraction.
    ·· *
    ·· * @param value Unsigned int to multiply
    ·· * @param fraction Unsigned multiplier (represents Multiplier / 65536)
    ·· * @return value * fraction rounded off unsigned integer result
    ·· */
    · public static int umulf(int value, int fraction) {
    ··· int i, result=0, rest=0;
    ··· for (i=1; i<17; i++) {
    ····· if (fraction < 0) { //b15 set
    ······· result += (value >>> i);··················· //accumulate integer result
    ······· rest += ( (value & ((1<<i)-1)) << (16-i) ); //accumulate rest R/65536
    ······· if (CPU.carry()) result++;················· //update result if rest overflows
    ····· }
    ····· fraction <<= 1; //next bit
    ··· }
    ··· if (rest < 0) result++; //roundoff
    ··· return result;
    · }

    You replaced the bold line with
    ······ result += (value >>= i);··················· //accumulate integer result
    This alters value which must not be.
    The javelin >>> means logical right shift, shifting in 0's at b15
    The javelin >> means arithmetic shift right, copying b15 to b14 (aka sign extension)
    Assuming you don't have the >>> equivalent use
    result += ((value >> i) & 0x7FFF);

    Here is an adapted umulf

    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;
    · }

    See what results you get with this modified umulf.

    regards peter


    ·
  • kojiWakojiWa Posts: 4
    edited 2007-04-19 12:34
    Thank you Peter for your help. i changed the umulf method but unfortunatelly the results are the same. i think the problem must lie in my shiftOut or/and shiftIn function but i can't find any possibilities for a good debugging. could you check them? thank you so much, koji


    void myShiftOut( int dataPin, int clockPin, int bitCount, int bitOrder, byte val )
    {
    for( int i = 0; i < bitCount; i++ )
    {
    if ( bitOrder == LSBFIRST )
    digitalWrite( dataPin, !! ( val & ( 1 << i ) ) );
    else
    digitalWrite( dataPin, !! ( val & ( 1 << ( ( bitCount - 1 ) - i ) ) ) );

    digitalWrite( clockPin, HIGH );
    digitalWrite( clockPin, LOW );
    }
    }


    byte myShiftIn( int dataPin, int clockPin, int bitCount )
    {
    int pinState;
    byte dataIn = 0;

    pinMode( clockPin, OUTPUT );
    pinMode( dataPin, INPUT );

    for( int i = bitCount; i >= 0; i -- )
    {
    digitalWrite( clockPin, LOW );
    delayMicroseconds( 20 );
    int temp = digitalRead( dataPin );
    if( temp )
    {
    pinState = 1;
    dataIn = dataIn | ( 1 << i );
    }
    else
    {
    pinState = 0;
    }
    digitalWrite( clockPin, HIGH );
    }

    return dataIn;
    }



    PS: another question is if the shiftIn and shiftOut function from the javelin library is accessible to see?
    thanks

    Post Edited (kojiWa) : 4/19/2007 2:04:44 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-04-23 14:32
    Try this.

    void myShiftOut(int dataPin, int clockPin, int bitCount, int bitOrder, int val ) {
    · for( int i = 0; i < bitCount; i++) {
    ··· if (bitOrder == LSBFIRST) {
    ····· digitalWrite( dataPin, !! ( val & 1) );
    ····· val = val >> 1;
    ··· }
    ··· else {
    ····· digitalWrite( dataPin, !! ((val >> 15)&1) );
    ····· val = val << 1;
    ··· }
    ··· digitalWrite( clockPin, HIGH );
    ··· 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, LOW );
    ··· delayMicroseconds( 20 );
    ··· int temp = digitalRead( dataPin );
    ··· if (temp) pinState = 1;
    ··· else pinState = 0;
    ··· dataIn = (dataIn << 1) | pinState;
    ··· digitalWrite(clockPin,HIGH);
    · }
    }


    regards peter
  • kojiWakojiWa Posts: 4
    edited 2007-04-23 15:45
    hello Peter, thanks for your effort. unfortunatelly it still doesn't work. i added a return function in the end of shiftIn and printed the dataIn value out. the result is everytime 8191. Do you have still any idea? sorry for the circumstances. thanks & best, koji



    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, LOW );
    delayMicroseconds( 20 );
    int temp = digitalRead( dataPin );
    if (temp) pinState = 1;
    else pinState = 0;
    dataIn = (dataIn << 1) | pinState;
    digitalWrite(clockPin,HIGH);
    }
    Serial.println(dataIn);
    return dataIn;
    }
Sign In or Register to comment.