Sunday, September 25, 2011

Arduino, Wire, and I2C Part 2: RTFDS

In my last post, I wrote a simple Arduino sketch that would get data from the ADXL345 accelerometer, but the "data" was all zeroes. This time around, I actually go about looking at the data sheet in more detail to learn how to properly get measurements from the accelerometer.

The first mention of enabling measurements is in the "Power Sequencing" section of the datasheet. The second paragraph indicates that to enter measurement mode, you must set the measurement bit in the POWER_CTL register at 0x2D. Another statement worth noting is that the manufacturer recommends configuring the device in standby mode and then enabling measurements. The datasheet also states that the device is in standby mode on start-up. The final bit of important information (for this project) in this section of the datasheet is tables 6 and 7, which contain the bit codes for data output rates.

The next section of the datasheet discusses power consumption as it relates to the data rate of the device. For this project, I'm not going to concern myself with how much power is being used as it's all being powered through the Arduino via USB (note that the Arduino does have a limited amount of supply current, as does USB, but this is in the mA range, where this device is at most using 1/10th of 1mA - 145μA).

Page 10 of the datasheet is where the I2C documentation starts, and that's more or less where I left off previously. Moving forward from here, we reach the section on interrupts. The SEN-10724 board does not have the interrupt pins (8 and 9) connected, so interrupts are not available. That said, the interrupt section does contain interesting information about what you could do with the sensor, if you chose to "wire up" your own board.

Page 13 is the first significant discussion of self-test mode for this device. This seems like a good place to start in terms of learning about the sensor and making sure the board and sensor are both functional. Clearly, there are a number of things to pay attention to. Enabling self-test involves setting a bit in the DATA_FORMAT register (0x31), but based on prior experience, I think it's safe to assume that more is involved than that. The next seven pages of the datasheet cover the details of each individual register, followed by even more information about self-test mode. A fair number of these registers are intended to set thresholds for interrupt functions and can therefore be ignored for any application involving the SEN-10724. For implementing a rudimentary test of the sensor using the Arduino, we need to look at:
  1. DATA_FORMAT - register for enabling self-test mode
  2. BW_RATE - register for defining the data output rate
  3. POWER_CTL - register for turning measurements on
The datasheet curiously enough does not mention sample rate, so it's my assumption that the data rate and sample rate are the same, and it's entirely up to the user to implement any data conditioning.

With the above information in hand, I added the following constants to the previously posted Arduino sketch:
static const uint8_t ADXL345 = 0x53;
static const uint8_t BW_RATE = 0x2C;
static const uint8_t POWER_CTL = 0x2D;
static   const uint8_t BIT_MEASURE = 0x08;
static const uint8_t DATA_FORMAT = 0x31;
static   const uint8_t BIT_SELF_TEST = (1 << 7);
static   const uint8_t BIT_RANGE_2G = 0x00;
static   const uint8_t BIT_RANGE_4G = 0x01;
static   const uint8_t BIT_RANGE_8G = 0x02;
static   const uint8_t BIT_RANGE_16G = 0x03;
static   const uint8_t BIT_FULL_RES = 0x08;
static const uint8_t DATAX0 = 0x32;
The data rate must be at least 100Hz for proper self-test function, according to the datasheet, but the datasheet also indicates that this is the default data rate on power-up, and that low-power mode (which trades cleaner measurements for power levels) is not selected. As such, I'll leave the BW_RATE register alone for now. The datasheet also states that the measurement range be set to the full resolution 16g mode. Note that "full resolution" is a separate configuration bit in of itself. The bits for self-test mode and for the measurement range all reside in the DATA_FORMAT register, so updating that one register should be enough. The datasheet also recommends averaging samples. For this stage of the process, I'm not going to do that, for two reasons: 1) I'm a bit lazy, and 2) the atmega328 chip on which the Arduino UNO is based doesn't even have a divide instruction, so averaging would have to be done using a software implementation of add and sub instructions on the chip. Finally, as far as code changes for this stage of effort, I'm going to cut the delay between reading samples down to match the 100Hz sample rate. The sample rate of 100Hz means that there is an accelerometer measurement every 1/100th of a second, or every 10 ms.

The resulting Arduino sketch, which is also available for direct download, executes and reports on a self-test of the ADXL345 accelerometer. If you open the serial monitor (set to 9600 baud) in the Arduino software, it will show the progress of the register settings (helpful debugging, and left-over from the HMC5883L version of the same, which has a slightly better datasheet IMO) and if the device pasts the tests (measurements are within ranges described in table 2 of the datasheet), it will print the measurements, followed by "OK", then turn off measurement and test mode. Otherwise, it will continue to show measurements and indicate which axis is reading out of spec.

... And that's it. Self test for the ADXL345 (and HMC5883L). The ITG-3200 does not have a self-test mode, so there won't be a follow-up for that.

No comments:

Post a Comment