Pages: 1 2 3 [4] 5   Go Down
Author Topic: New and growing well-documented, feature-complete I2C device library  (Read 20583 times)
0 Members and 1 Guest are viewing this topic.
Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Were you using a modified Wire library? I'm using the recently released 0022 version and I'm getting errors when compiling...

Ah, sorry. Yes and no. I'm doing most of my development in the Arduino 1.0 beta/RC releases for better forward compatibility, and they did change the Wire library. However, you should be able to fix this problem by simply changing one line near the top of I2Cdev.h:

FROM:
Code:
#define I2CDEV_IMPLEMENTATION       I2CDEV_ARDUINO1_WIRE

TO:
Code:
#define I2CDEV_IMPLEMENTATION       I2CDEV_ARDUINO0_WIRE

Let me know if this doesn't work.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Were you using a modified Wire library? I'm using the recently released 0022 version and I'm getting errors when compiling...

Ah, sorry. Yes and no. I'm doing most of my development in the Arduino 1.0 beta/RC releases for better forward compatibility, and they did change the Wire library. However, you should be able to fix this problem by simply changing one line near the top of I2Cdev.h:

FROM:
Code:
#define I2CDEV_IMPLEMENTATION       I2CDEV_ARDUINO1_WIRE

TO:
Code:
#define I2CDEV_IMPLEMENTATION       I2CDEV_ARDUINO0_WIRE

Let me know if this doesn't work.
Thanks!
This fixed everything except I'm missing the millis() function:
Code:
C:\Users\qql714\Desktop\arduino-0022\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':
C:\Users\qql714\Desktop\arduino-0022\libraries\I2Cdev\I2Cdev.cpp:183: error: 'millis' was not declared in this scope
C:\Users\qql714\Desktop\arduino-0022\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':
C:\Users\qql714\Desktop\arduino-0022\libraries\I2Cdev\I2Cdev.cpp:240: error: 'millis' was not declared in this scope
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This fixed everything except I'm missing the millis() function:

Oops! My mistake. I have a slightly newer version of the I2Cdev.h file that I hadn't yet pushed to the repository. It was including "Arduino.h" (the v1.0 file) instead of "WProgram.h" (the 0022 file) even if the implementation was set to use the "ARDUINO0" option. Pull down the new .h file and see if that fixes it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This fixed everything except I'm missing the millis() function:

Oops! My mistake. I have a slightly newer version of the I2Cdev.h file that I hadn't yet pushed to the repository. It was including "Arduino.h" (the v1.0 file) instead of "WProgram.h" (the 0022 file) even if the implementation was set to use the "ARDUINO0" option. Pull down the new .h file and see if that fixes it.

This worked for getting stuff working. Now I've moved onto the ITG3200, I cannot seem to get this device working:
Code:
//adxl initialize and test
...
  gyro.initialize(); // startup and initialize device
  if(gyro.testConnection()) {
    Serial.print("gyro test succeeded\n");
  } else {
    Serial.print("gyro test FAILED\n");
  }
//... hmc is same

Output:
adxl test succeeded
gyro test FAILED
magno test succeeded
setup sensors
looping
AX: 67643625455Ú676÷ñ]Ÿ=ûõI | GX: 0 | MX:
// ... then data (but no ITG3200 data its all zeros. and the HMC device hangs for about 20 seconds, times out then repeats

Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This worked for getting stuff working. Now I've moved onto the ITG3200, I cannot seem to get this device working:

Barring the possibility of a defective board or gyro module, I'd make sure you have the right address for the gyro first (assuming you haven't already). The ADXL345 can be either 0x53 or 0x1D, the ITG3200 can be either 0x68 or 0x69, and the HMC5883L can only be 0x1E. You can pass a specific address in when the class is instantiated, such as:

Code:
ITG3200 gyro(0x69);

I know that this code works with SparkFun's 6DOF board, and independently with their HMC5883L breakout, so all the device library code should be pretty solid. If it's not responding, I'd check either the address or a physical electrical connection.
Logged

NZ
Offline Offline
Sr. Member
****
Karma: 0
Posts: 390
Turtle in a hard shell
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jeff,

I am not having much luck with your library for the ADS1115 sadly. I cant get consistant results, however I think it might just be a timing issue, but not 100% sure.

I have however used the code written in a topic I started, by retrolefty, which does work.
http://arduino.cc/forum/index.php/topic,69358.msg513467.html#msg513467

If you have any time, could you have a look?
Using Arduino 0022.

I assume you have used your library with success on one of these chips however?

retrolefty's code works, however when changing the ADS1115 to use another channel, I found I had to have a small delay between sending the new configuration to the chip, and reading the result. I just put in a delay(10) and that worked, however that isnt ideal I know. I dont know how to modify your library to achieve the same thing however.

Any help would be appreciated.

Regards
James
Logged

Albuquerque, NM
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I managed to get the Lascar SDG 24-M working by bitshifting (see code below). So far I haven't had a chance to create a library for it yet, but that is on my todo list.

Code:
/**
 * Lascar SGD 24-M Test Code
 *
 * Code for Atmel ATMega328 and compatible using the Arduino
 * programming platform, version 0022.
 *
 * @author     Klaus Guenther <thesaur@php.net>
 * @copyright 2011 Klaus Guenther. All rights reserved.
 * @version     0.5alpha
 * @license     MIT
 * @updated   2011-09-20
 */

// Include the Wire library for I2C connectivity
#include <Wire.h>
 
/**
 * Variable declarations
 */
 
// Panel Pilot address final bit must be 1 because
// Arduino's Wire library only allows for 7-bit addresses.
// The 8th bit is reserved to be a read/write marker that
// is automatically sent when sending bytes. In the @see setup()
// function below, the address is bitshifted one to the right.
// When data is sent, it is bitshifted left by one, and the
// write bit is set to 1. @see meter_write() below.
// Minimum address is 0x10, max 0xEF. Practically that means that
// every odd address between 0x11 and 0xEF is possible.
int devAddress = 0x31;

int page; // used by meter_write
char* data; // used by meter_write
 
/**
 * Sets default values and
 * performs initialization of components
 * at startup
 */
void setup()
{
  Wire.begin(); // initialize I2C bus
  devAddress = devAddress >> 1; // see comment on devAddress variable
}
 
/**
 * Required loop function for Arduino
 */
void loop()
{
  // testing writing to multiple pages
  meter_write(0, "    21"); // write 6 bytes to channel 1 (0)
  delay(10);                // wait 10ms
 
  meter_write(1, "     3"); // write 6 bytes to channel 2 (1)
  delay(10);                // wait 10ms
 
  meter_write(2, "    50"); // write 6 bytes to channel 3 (2)
  delay(10);                // wait 10ms
 
  meter_write(3, "   150"); // write 6 bytes to channel 4 (3)
  delay(10);                // wait 10ms
 
  meter_write(4, "   250"); // write 6 bytes to channel 5 (4)
  delay(10);                // wait 10ms
 
  meter_write(5, "  7.32"); // write 6 bytes to channel 6 (5)
  delay(10);                // wait 10ms
 
  meter_write(6, "     1"); // write 6 bytes to channel 7 (6)
  delay(10);                // wait 10ms
 
  meter_write(7, "  2.2k"); // write 6 bytes to channel 8 (7)
  delay(10);                // wait 10ms
 
  delay(2000); // wait 2 seconds before repeating loop
}

/**
 * Sends data to the meter to be displayed
 * Notes: - data must be always exactly 6 bytes
 *        - restricted ASCII characters allowed
 */
void meter_write(int page, char* data)
{
  // Note: devAddress is bitshifted one to the left, and the final
  // bit is set to 1 to indicate that this is a write action.
 
  Wire.beginTransmission(devAddress); // setup transmission
 
  // Set data to be sent
  Wire.send(page);  // Transmit integer denoting page (0 - 7)
  Wire.send(data);  // Transmit 6 bytes of data
                    // Code needs to be modified to clip data over 6 bytes
                    // and pad data under 6 bytes
  Wire.endTransmission(); // Commits data by transmitting it
}

I decided to try to add SparkFun's MPR121 keypad to the project. Apparently, the MPR121 wasn't easy to address with Wire, so the example code uses a modified version of Atmel's own code. I looked through it and thought it might be worth considering adding to your library, since it looks like it allows for more variation as well as natively supporting 8-bit addresses.

http://www.sparkfun.com/datasheets/Sensors/Capacitive/MPR121_Keypad_Example.zip

« Last Edit: September 28, 2011, 04:34:18 pm by thesaur » Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have however used the code written in a topic I started, by retrolefty, which does work.
http://arduino.cc/forum/index.php/topic,69358.msg513467.html#msg513467
...
I assume you have used your library with success on one of these chips however?
...
retrolefty's code works, however when changing the ADS1115 to use another channel, I found I had to have a small delay between sending the new configuration to the chip, and reading the result. I just put in a delay(10) and that worked, however that isnt ideal I know. I dont know how to modify your library to achieve the same thing however.

Hi James,

Actually, I haven't personally tested the library code with an actual device on my end. I put together that library at retrolefty's request, and there was a bit of back-and-forth debugging that had to occur because of my lack of physical hardware. Even after we fixed the obvious bugs and he started to get some decent readings, I think he still had a bit of trouble with reliability. I need to get one of the chips myself and revisit the code, but sadly there are still half a dozen things that are higher on my priority list at the moment. I've just ordered a breakout board with the chip on it, but I can't guarantee when I'll be able to finish up the code.

One thing you might be able to do as a temporary workaround is, as you said, just add a "delay(10)" call right after you call one of the setXXX() methods to change the chip's configuration. I'm assuming that most of the time you're just taking ADC measurements, so hopefully adding that delay in won't have a large effect on the performance of your sketch.

So I managed to get the Lascar SDG 24-M working by bitshifting (see code below). So far I haven't had a chance to create a library for it yet, but that is on my todo list.
...
I decided to try to add SparkFun's MPR121 keypad to the project. Apparently, the MPR121 wasn't easy to address with Wire, so the example code uses a modified version of Atmel's own code. I looked through it and thought it might be worth considering adding to your library, since it looks like it allows for more variation as well as natively supporting 8-bit addresses.

Good job on the PanelPilot code! Bit-shifting to get around the 7-bit restriction is an interesting approach. If I can get a native (non-Wire) I2C implementation written, I'll try to add support for those non-spec writable addresses as well.

As for the MPR121, I don't know if you saw it or not (maybe you tried it and it didn't work), but that device is actually already in the I2Cdevlib, at least partially, thanks to Andrew Schamp:

https://github.com/jrowberg/i2cdevlib/tree/master/MPR121

He wrote that code because he needed it and I didn't have the chip at the time (I do now though), and as far as I know the code does work at least partially. I haven't made it to the point in my projects where I need to use that board yet, but that will happen eventually, and the library code will need to work then. It is a nice device though, whatever code you use to power it.
Logged

Albuquerque, NM
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As for the MPR121, I don't know if you saw it or not (maybe you tried it and it didn't work), but that device is actually already in the I2Cdevlib, at least partially, thanks to Andrew Schamp
Nope! Hadn't seen that for some reason. I will definitely try it.

The main thing that is hampering me with i2cdevlib is the lack of plug and play examples. Thankfully there is one, so it's a start. Do you have a fixed API for classes? I would love it if you could create a basic skeleton class implementing the API that could be used when adding new devices. Basically copy/paste and fill in the details.
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The main thing that is hampering me with i2cdevlib is the lack of plug and play examples. Thankfully there is one, so it's a start. Do you have a fixed API for classes? I would love it if you could create a basic skeleton class implementing the API that could be used when adding new devices. Basically copy/paste and fill in the details.

I haven't dropped this project--not by a long shot--but I've been swamped with tasks for other projects, so I apologize for the silence. I've got the beginnings of a website up at i2cdevlib.com, including some of the reverse-engineering efforts on the MPU-6050, and more class-library style documentation for most of these devices than you'll find anywhere else (example: ADXL345 docs). There are still some formatting issues that I need to fix, but it's coming along.

I have also done my best to create some very basic tested examples, as requested. All examples are up on the repository under the [device]/Examples/ subfolders. I have at least one tested example for the following devices so far:


All examples are built using Arduino 1.0 RC1, hence the extensions. With very little modification, they will work in v0022 also. The library will very shortly be smart enough to tell which version of Arduino you're using, so you won't need to change the IMPLEMENTATION constant. My working copy is doing that already, but there are some tweaks I need finish before I push it up to Github.

I still have more to create, and the next one I'm trying to finish is the DMP-enabled MPU-6050 (which is what makes that chip particularly awesome, as you probably know). Most of it is done, but I'm having trouble with one particular step of the process that I can't replicate reliably yet.

I dod manage to get my hands on an ADS1115, but I haven't been able to test it yet to debug the device library. I have also incorporated a slightly modified version of Gene Knight's NBWire I2C implementation, and I've successfully tested many classes completely outside of Arduino's Wire library. I'm not ready to call it done yet though.

Stay tuned!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Jeff,

Thanks for your work on this.  I've got an ADS1115 and I'd like to push some additional helper functions to the repository.  I've added:

Code:
        int16_t getDifferential0();
        int16_t getDifferential1();
        int16_t getDifferential2();
        int16_t getDifferential3();

To go alongside the getDiffx functions you have for the single-sided differentials. 

I've pushed it here: https://github.com/farzanegan/i2cdevlib/tree/master/ADS1115

However, I believe I found a pretty big bug in the underlying i2c classes that I'd like to discuss with you.
Logged

Roanoke, VA
Offline Offline
Jr. Member
**
Karma: 6
Posts: 66
Creating order out of chaos!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your work on this.  I've got an ADS1115 and I'd like to push some additional helper functions to the repository.
...
However, I believe I found a pretty big bug in the underlying i2c classes that I'd like to discuss with you.

Thanks! I'll be happy to incorporate your changes (though I may change the function names a bit across the board to make everything more obvious, since "getDiff0" and "getDifferential0" are not at all informative in context). If possible, can you submit a pull request on Github for just those two files? I could just copy and paste your code, but it will keep track of the fact that you contributed it automatically if we use a pull request instead.

I'm also intrigued by the bug you may have found. I haven't done enough extensive testing with lots of different types of devices to say that it's anything close to bug-free, so it might be as you say. Send me a PM here, or just reply on the thread, or use this contact form to send me an email and we can get down to business.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure, I'm a git n00b, so if you can walk me through doing just two files, I'll be glad to follow along.

I'll PM you the bug discussion.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, and I agree about those function names- but I didn't want to be so arrogant as to change them   smiley-eek,  I was trying to follow along with the convention you started.   Since 4 of them are differential and the other 4 are single-ended, I suggest keeping the differential names I added and maybe make the 'getDiffx' to be 'getSingleX'?   Or you could name them with the ends already: getDifferential0x1, getDifferential2x3; or even getCounts0xGND, getCounts2x3.  I dunno- naming functions is one of the hardest tasks in coding  smiley


For me, there are really only two differentials in common use 0-1 and 2-3.  There are other quasi-differential 0-3, 1-3, but there there is no 0-2 for some reason.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Jeff has updated the I2C library with changes to how registers are being set.  In some cases, registers might have been getting cleared by accident in larger fields.  If you got some weird behavior, this might be the case.

Thanks to Jeff for being so responsive!

-frederick
Logged

Pages: 1 2 3 [4] 5   Go Up
Jump to: