Go to Post Make other plans. No mass-produced food at an arena is ever going to be good. - sanddrag [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rating: Thread Rating: 11 votes, 5.00 average. Display Modes
  #16   Spotlight this post!  
Unread 03-02-2010, 10:27
Geek 2.0 Geek 2.0 is offline
Registered User
FRC #0107
Team Role: Programmer
 
Join Date: Sep 2009
Rookie Year: 2008
Location: Holland, MI
Posts: 120
Geek 2.0 will become famous soon enough
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by charrisTTI View Post
Here is java class for the ADXL345 when connected as I2C device at default address.

Code:
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

package edu.wpi.first.wpilibj;



/**
 *
 * digital accelerometer from the 2010 KOP
 *
 * this implementation just gets the 3 axis values and allows setting the range
 *
 * Possible enhancements:
 *      Add access to other features of the chip
 *      Add measurement of error during intialization and set channel offsets
 */
public class ADXL345DigitalAccelerometer extends SensorBase {
    private I2C i2c;
    // default address
    private static final byte kAddress = 0x3A;
    // register map from datasheet
    private static final byte OFSX = 0x1E;
    private static final byte OFSY = 0x1F;
    private static final byte OFSZ = 0x20;
    private static final byte BW_RATE = 0x2C;
    private static final byte  POWER_CTL = 0x2D;
    private static final byte DATA_FORMAT = 0x31;
    private static final byte DATAX0 = 0x32;
    private static final byte DATAY0 = 0x34;
    private static final byte DATAZ0 = 0x36;
    private static final byte FIFO_CTL = 0x38;
    private static final byte FIFO_STATUS = 0x39;

    // would use enums here if we had them
    // BW_RATE 0x2C
    private static final byte BW_RATE_R3200B1600 = 0x0F;
    private static final byte BW_RATE_R1600B0800 = 0x0E;
    private static final byte BW_RATE_R0800B0400 = 0x0D;
    private static final byte BW_RATE_R0400B0200 = 0x0C;
    private static final byte BW_RATE_R0200B0100 = 0x0B;
    private static final byte BW_RATE_R0100B0050 = 0x0A;
    private static final byte BW_RATE_R0050B0025 = 0x09;
    private static final byte BW_RATE_R0025B0012 = 0x08;
    private static final byte BW_RATE_R0012B0006 = 0x07;
    private static final byte BW_RATE_R0006B0003 = 0x06;

    private static final byte BW_RATE_LOW_POWER = 0x10;
    
    // POWER_CTL 0x2D
    private static final byte POWER_CTL_LINK = 0x20;
    private static final byte POWER_CTL_AUTO_SLEEP = 0x10;
    private static final byte POWER_CTL_MEASURE = 0x08;
    private static final byte POWER_CTL_SLEEP = 0x04;
    private static final byte POWER_CTL_WAKEUP8 = 0x00;
    private static final byte POWER_CTL_WAKEUP4 = 0x01;
    private static final byte POWER_CTL_WAKEUP2 = 0x02;
    private static final byte POWER_CTL_WAKEUP1 = 0x03;

    // DATA_FORMAT
    public static final byte DATA_FORMAT_02G = 0x00;
    public static final byte DATA_FORMAT_04G = 0x01;
    public static final byte DATA_FORMAT_08G = 0x02;
    public static final byte DATA_FORMAT_16G = 0x03;

    // store the current
    private byte range = DATA_FORMAT_02G;

    public class ADXL345Exception extends RuntimeException {

        /**
         * Create a new exception with the given message
         * @param message the message to pass with the exception
         */
        public ADXL345Exception(String message) {
            super(message);
        }

    }

    //
    // constuctior with slot number parameter
    //
    public ADXL345DigitalAccelerometer(int slot) {
        i2c = new I2C( DigitalModule.getInstance(slot), kAddress );
    }

    // initialize the sensor
    public void intitialize()
    {
        // set BW_RATE
        i2c.write(BW_RATE, BW_RATE_R0100B0050);
        // set POWER_CTL
        i2c.write(POWER_CTL, POWER_CTL_MEASURE);
    }

    // set the range (default is =/- 2g
    public void setRange( byte rangeParam )
    {
        if ( !( rangeParam == DATA_FORMAT_02G ||
                rangeParam == DATA_FORMAT_04G ||
                rangeParam == DATA_FORMAT_08G ||
                rangeParam == DATA_FORMAT_16G ) )
        {
            throw new ADXL345Exception("Invalid range!");
        }


        range = rangeParam;

        i2c.write(DATA_FORMAT, range);
    }

    // get acceleration routines
    public double getXAxis()
    {
        return getAxis( DATAX0 );
    }

    public double getYAxis()
    {
        return getAxis( DATAY0 );
    }

    public double getZAxis()
    {
        return getAxis( DATAZ0 );
    }

    protected double getAxis( byte registerParam )
    {
        // setup array for our data
        byte[] data = new byte[2];
        // read consecutive registers
        this.i2c.read( registerParam, (byte) data.length, data);

        // convert to 2s complement integer
        // [0] has low byte [1] has the high byte
        // jave does not have unsigned so we have to do it this way
        int intResult = ( data[0] & 0xFF ) | ( data[1] << 8 );

        // convert to double based on 10 bit result
        double returnValue = (double)intResult / 512.0 ;

        // now scale based upon our range
        switch( range )
        {
            case DATA_FORMAT_02G:
                returnValue *= 2.0;
                break;
            case DATA_FORMAT_04G:
                returnValue *= 4.0;
                break;
            case DATA_FORMAT_08G:
                returnValue *= 8.0;
                break;
            case DATA_FORMAT_16G:
                returnValue *= 16.0;
                break;
        }
        return returnValue;
    }
}
I'm not 100% sure, but by the looks of it (after reading the datasheet), it looks as if you're only taking the least significant byte when reading an axis. Wouldn't that give you a bad number? Again, I'm not sure.

Also, did this code work? I didn't see anything wrong with it.
Reply With Quote
  #17   Spotlight this post!  
Unread 03-02-2010, 10:46
charrisTTI charrisTTI is offline
Ramblin' Wreck
AKA: Charles Harris
FRC #0623
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2003
Location: Vienna, VA
Posts: 106
charrisTTI has a spectacular aura aboutcharrisTTI has a spectacular aura about
Send a message via AIM to charrisTTI
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by Geek 2.0 View Post
I'm not 100% sure, but by the looks of it (after reading the datasheet), it looks as if you're only taking the least significant byte when reading an axis. Wouldn't that give you a bad number? Again, I'm not sure.

Also, did this code work? I didn't see anything wrong with it.
Code worked fine in my testing.

If you look at the getAxis method you will see that I am doing a 2-byte read when I get the data (2 consecutive registers in one read). This insures that the data does not get corrupted. If two individual 1-byte reads were performed there is a chance that in between the first and second read the data could change. This would result in first read getting the low byte of the prior value and second read getting the high byte of the subsequent value. Putting the two together again could create some really funny numbers. See page 18 of the ADXL345 data sheet "Register 0x32 to Register 0x37" section for more information about this.

Here is an example of the problem: prior value is 0x0100 subsequent value is 0x00ff, a 1 bit change. Two single byte reads would read low byte 0x00 and high byte 0x00 giving 0x0000. No where near close to what the sensor is actually reading.
__________________
FRC 623 2003,2004,2005,2006,2007,2008, 2009, 2010, 2011
FRC 1900 2007
FVC 60 and 193 2006
FVC 3271 2007
FTC 226 and 369 2008, 2009, 2010, 2011
FTC 3806 2010

Last edited by charrisTTI : 03-02-2010 at 10:56.
Reply With Quote
  #18   Spotlight this post!  
Unread 03-02-2010, 11:02
Geek 2.0 Geek 2.0 is offline
Registered User
FRC #0107
Team Role: Programmer
 
Join Date: Sep 2009
Rookie Year: 2008
Location: Holland, MI
Posts: 120
Geek 2.0 will become famous soon enough
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by charrisTTI View Post
Code worked fine in my testing.

If you look at the getAxis method you will see that I am doing a 2-byte read when I get the data (2 consecutive registers in one read). This insures that the data does not get corrupted. If two individual 1-byte reads were performed there is a chance that in between the first and second read the data could change. This would result in first read getting the low byte of the prior value and second read getting the high byte of the subsequent value. Putting the two together again could create some really funny numbers. See page 18 of the ADXL345 data sheet "Register 0x32 to Register 0x37" section for more information about this.

Here is an example of the problem: prior value is 0x0100 subsequent value is 0x00ff, a 1 bit change. Two single byte reads would read low byte 0x00 and high byte 0x00 giving 0x0000. No where near close to what the sensor is actually reading.
Makes sense. Thanks for the code! Much easier than writing my own.
Reply With Quote
  #19   Spotlight this post!  
Unread 03-02-2010, 12:49
NerdGuy's Avatar
NerdGuy NerdGuy is offline
Registered User
FRC #2974
 
Join Date: Jan 2010
Location: Atlanta
Posts: 16
NerdGuy is an unknown quantity at this point
Re: 2010 Accelerometer I2C Object/Class

/sigh

we tested this code yesterday.

but it did not work for us and since the code seems to work for u guys.
We are probably doing something wrong.

For our wiring we plugged in (obviously 5v to 5v and 0v to ground and so on) but what i have a question on is which I2C channel those plug in to. There are 2 that are not labeled, so i guess the question here is what channel I2C is the kaddress is referring to?

Also I am using the class in the code by

-instantiating with an argument of 4 (which is where the digital module is plugged in to on the crio)

-calling the initialize() method

-and then calling the getXAxis() method in my polling while loop which runs every .02 seconds.



The only thing i could see that might cause a problem is that the accel does not show a significant enough amount of change in the .02s in which we check it.

If this is what is happening please let me know and if its not please try and help.


Thanks in advance.
__________________
"Life would be so much easier if we only had the source code."
Reply With Quote
  #20   Spotlight this post!  
Unread 03-02-2010, 15:28
charrisTTI charrisTTI is offline
Ramblin' Wreck
AKA: Charles Harris
FRC #0623
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2003
Location: Vienna, VA
Posts: 106
charrisTTI has a spectacular aura aboutcharrisTTI has a spectacular aura about
Send a message via AIM to charrisTTI
Re: 2010 Accelerometer I2C Object/Class

Here is my test program:

Code:
public class RobotTest extends SimpleRobot {
    ADXL345DigitalAccelerometer accelerometer = new ADXL345DigitalAccelerometer(4);
    
    public RobotTest()
    {
        accelerometer.intitialize();
        accelerometer.setRange(ADXL345DigitalAccelerometer.DATA_FORMAT_16G);
    }

    /**
     * This function is called once each time the robot enters autonomous mode.
     */
    public void autonomous() {
        
    }

    /**
     * This function is called once each time the robot enters operator control.
     */
    public void operatorControl() {
        this.getWatchdog().setEnabled(false);

        while( this.isOperatorControl() && this.isEnabled() )
        {
            System.out.println("Accel X, Y, Z: " + accelerometer.getXAxis() + " " + accelerometer.getYAxis() + " " + accelerometer.getZAxis() );
            Timer.delay(0.001);
        }
    }
}
Wiring should be from the I2C header on the digital side car. The I2C header is the row of 4 pins directly behind the special Lego RJ12 connector. Wire 5V to 5V, 0V to (-), SDA to SDA, SCL to SCL. Do not use the second row of pins labeled 1,2,3,&4.
__________________
FRC 623 2003,2004,2005,2006,2007,2008, 2009, 2010, 2011
FRC 1900 2007
FVC 60 and 193 2006
FVC 3271 2007
FTC 226 and 369 2008, 2009, 2010, 2011
FTC 3806 2010
Reply With Quote
  #21   Spotlight this post!  
Unread 03-02-2010, 15:53
Geek 2.0 Geek 2.0 is offline
Registered User
FRC #0107
Team Role: Programmer
 
Join Date: Sep 2009
Rookie Year: 2008
Location: Holland, MI
Posts: 120
Geek 2.0 will become famous soon enough
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by charrisTTI View Post
Wiring should be from the I2C header on the digital side car. The I2C header is the row of 4 pins directly behind the special Lego RJ12 connector. Wire 5V to 5V, 0V to (-), SDA to SDA, SCL to SCL. Do not use the second row of pins labeled 1,2,3,&4.
This is what he means (took me a bit to figure it out without the DSC in front of me, so I thought I'd make a visual aid).

Reply With Quote
  #22   Spotlight this post!  
Unread 03-02-2010, 16:18
NerdGuy's Avatar
NerdGuy NerdGuy is offline
Registered User
FRC #2974
 
Join Date: Jan 2010
Location: Atlanta
Posts: 16
NerdGuy is an unknown quantity at this point
Re: 2010 Accelerometer I2C Object/Class

possibly the most helpful post Ever.

I will try this in about an hour and post the results we were on the ones labeled not these.

Also i am curious what the pins labeled not these are for?
It says "Out" does that just mean those are all Digital Outputs?


Thanks again
__________________
"Life would be so much easier if we only had the source code."
Reply With Quote
  #23   Spotlight this post!  
Unread 03-02-2010, 16:48
jhersh jhersh is offline
National Instruments
AKA: Joe Hershberger
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: May 2008
Rookie Year: 1997
Location: Austin, TX
Posts: 1,006
jhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond repute
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by NerdGuy View Post
Also i am curious what the pins labeled not these are for?
It says "Out" does that just mean those are all Digital Outputs?
They are slow digital outputs (kinda like the Spike output channels). We never bothered to add support for them in WPILib, but there is support for them in the FPGA and the FPGA chip object layers. Teams technically could use them, but we don't know why they would.

-Joe
Reply With Quote
  #24   Spotlight this post!  
Unread 03-02-2010, 17:35
klee17's Avatar
klee17 klee17 is offline
software lead and slave driver
AKA: Keenan Lee
FRC #1126 (Sparx)
Team Role: Leadership
 
Join Date: Jan 2010
Rookie Year: 2010
Location: webster
Posts: 4
klee17 is an unknown quantity at this point
Send a message via Yahoo to klee17
Re: 2010 Accelerometer I2C Object/Class

We tried using the "these" pins instead of the "not these" pins and the accelerometer is returning values now. Thanks for the picture!
Reply With Quote
  #25   Spotlight this post!  
Unread 04-02-2010, 08:26
Geek 2.0 Geek 2.0 is offline
Registered User
FRC #0107
Team Role: Programmer
 
Join Date: Sep 2009
Rookie Year: 2008
Location: Holland, MI
Posts: 120
Geek 2.0 will become famous soon enough
Re: 2010 Accelerometer I2C Object/Class

Okay, I tried it out yesterday and everything seemed to work. Only problem I had was that it floated just enough to make numbers not work for integration to position. For instance, it would float from 0.0 to about 0.007 and then back to 0.0. Problem there is that it technically never had negative acceleration to counter that, meaning the velocity doesn't go back to 0, making my position infinitely change. Even if I do make a dead band, the readings aren't perfectly symmetrical, again meaning velocity doesn't go back to zero. I don't think I'm the only one with this problem. Any suggestions as to how I can use an accelerometer to at least approximate position, accurate enough to maybe 6 inches to a foot, during autonomous?
Reply With Quote
  #26   Spotlight this post!  
Unread 04-02-2010, 18:57
urg8rb8 urg8rb8 is offline
Registered User
FRC #0108
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Plantation
Posts: 23
urg8rb8 is an unknown quantity at this point
Re: 2010 Accelerometer I2C Object/Class

We tested out the code for the I2C Accelerometer and we seem to be having some issues. We are doing the following:

Code:
ADXL345DigitalAccelerometer accelerometer;

accelerometer = ADXL345DigitalAccelerometer(4);

accelerometer.initialize();
accelerometer.getZAxis();
For some reason, the code is getting blocked in the initialize() call and never returns out of it. We have the accelerometer plugged into the correct header on the sidecar and we do not have the "blob of solder" on the jumper so we are using the default address that is coded in the class object. What could be the problem?

Any help would be appreciated!
Reply With Quote
  #27   Spotlight this post!  
Unread 05-02-2010, 02:28
jhersh jhersh is offline
National Instruments
AKA: Joe Hershberger
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: May 2008
Rookie Year: 1997
Location: Austin, TX
Posts: 1,006
jhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond repute
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by urg8rb8 View Post
We tested out the code for the I2C Accelerometer and we seem to be having some issues. We are doing the following:

Code:
ADXL345DigitalAccelerometer accelerometer;

accelerometer = ADXL345DigitalAccelerometer(4);

accelerometer.initialize();
accelerometer.getZAxis();
For some reason, the code is getting blocked in the initialize() call and never returns out of it. We have the accelerometer plugged into the correct header on the sidecar and we do not have the "blob of solder" on the jumper so we are using the default address that is coded in the class object. What could be the problem?

Any help would be appreciated!
Is your sidecar powered? Is the clock line shorted? Will unplugging the sensor allow the initialize method to return?
Reply With Quote
  #28   Spotlight this post!  
Unread 05-02-2010, 10:51
charrisTTI charrisTTI is offline
Ramblin' Wreck
AKA: Charles Harris
FRC #0623
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2003
Location: Vienna, VA
Posts: 106
charrisTTI has a spectacular aura aboutcharrisTTI has a spectacular aura about
Send a message via AIM to charrisTTI
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by Geek 2.0 View Post
Okay, I tried it out yesterday and everything seemed to work. Only problem I had was that it floated just enough to make numbers not work for integration to position. For instance, it would float from 0.0 to about 0.007 and then back to 0.0. Problem there is that it technically never had negative acceleration to counter that, meaning the velocity doesn't go back to 0, making my position infinitely change. Even if I do make a dead band, the readings aren't perfectly symmetrical, again meaning velocity doesn't go back to zero. I don't think I'm the only one with this problem. Any suggestions as to how I can use an accelerometer to at least approximate position, accurate enough to maybe 6 inches to a foot, during autonomous?
One possible improvement would be to calculate and cancel any zero offset error at startup. At a time that you know the robot is not moving and there is no vibration (air compressor off) collect samples from each axis and calculate the average value. Use this as an offset to correct for any zero error on X and Y axis and 1G error on Z axis, assuming "normal" mounting scheme. The chip supports setting offsets for each channel.
__________________
FRC 623 2003,2004,2005,2006,2007,2008, 2009, 2010, 2011
FRC 1900 2007
FVC 60 and 193 2006
FVC 3271 2007
FTC 226 and 369 2008, 2009, 2010, 2011
FTC 3806 2010
Reply With Quote
  #29   Spotlight this post!  
Unread 05-02-2010, 11:09
urg8rb8 urg8rb8 is offline
Registered User
FRC #0108
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Plantation
Posts: 23
urg8rb8 is an unknown quantity at this point
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by jhersh View Post
Is your sidecar powered? Is the clock line shorted? Will unplugging the sensor allow the initialize method to return?
Yes, the sidecar is definitely powered. I am not sure about the clock line being shorted. The clock should be available on the SCL line on the sidecar right? Is it possible that we're missing other hardware modifications or connections? The only thing we've done was connect the 12V supply to the sidecar using the wago connector and the accelerometer to the I2C header.

Last edited by urg8rb8 : 05-02-2010 at 13:30.
Reply With Quote
  #30   Spotlight this post!  
Unread 05-02-2010, 15:37
jhersh jhersh is offline
National Instruments
AKA: Joe Hershberger
FRC #2468 (Appreciate)
Team Role: Mentor
 
Join Date: May 2008
Rookie Year: 1997
Location: Austin, TX
Posts: 1,006
jhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond reputejhersh has a reputation beyond repute
Re: 2010 Accelerometer I2C Object/Class

Quote:
Originally Posted by urg8rb8 View Post
Yes, the sidecar is definitely powered. I am not sure about the clock line being shorted. The clock should be available on the SCL line on the sidecar right? Is it possible that we're missing other hardware modifications or connections? The only thing we've done was connect the 12V supply to the sidecar using the wago connector and the accelerometer to the I2C header.
That should be all you need. And connect it to the NI 9403, of course.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with 2010 Accelerometer & I2C wt200999 C/C++ 33 08-02-2010 15:16
2010 accelerometer chsr C/C++ 1 22-01-2010 02:28
2010 Accelerometer Documentation? JDM Sensors 13 18-01-2010 12:42
Where to find a Gyro and Accelerometer Sensor Board for 2010 FRC? xSpongeX Sensors 4 18-01-2010 06:17
Accelerometer class - isn't reading zero at rest? oddjob C/C++ 3 02-02-2009 17:11


All times are GMT -5. The time now is 12:59.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi