Arduino and XV-3500CB

I’m trying to connect a XV-3500CB gyro with my Arduino Diecimila…just for fun. I’ve done simple stuff with my arduino (blinking LEDs, etc) but never tried connecting anything like this before so please forgive my ignorance. I bought the gyro from ebay. It came connected to a breakout board from sure electronics.

Part: http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=150346774089
Datasheet: http://www.sure-electronics.net/download/DC-SS010_Ver1.0_EN.pdf

From what I gather from the data sheet, the board converts the gyro’s analog output to digital via I2C interface. I connected the board as follows.

Board Arduino
GND (all) GND
+5V +5V
IICCLK PIN 5
IICDAT PIN 4

I didn’t connect the ANA0 on the board to anything since I’m not quite sure what it’s for. Then I used the CMPS03 library from GrapeLabs to get the reading from the gyro since, I assume, that’s the same way I’m supposed to read the data via I2C from my board but I get no results. It writes to the board okay but I get a whole bunch of 0.

Library: http://www.grapelabs.de/index.php?id=52

Where did I go wrong? My connection or my code? Any help you can give is appreciated since I’m in way over my head here (but i guess that’s how you learn :slight_smile: ). Thanks in advance.

#include "Wire.h"
#include "CMPS03.h"

CMPS03 cmps03;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  Serial.println(cmps03.read());
  delay(1000);
}

Try connecting ANA0 to a analog input on the arduino and seeing if you are getting different readings from that.

When I print the output of ANA0 I get varying levels whenever I tilt the board, ranging between 270 and 288. according to the data sheet, this is the "Analog voltage output end of angular-rate sensor". I guess that means I've connected everything correctly so it must be a problem with my code.

OK my mistake (I think) was using the CMPS03 library since a lot of things are different to my setup such as the I2C address of the AD converter (MCP3421 in my case). Trying to fix that now.

MCP3421 datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22003b.pdf

Well, first off... something that your datasheet doesn't explicitly tell you is that the onboard ADC is running on a 3V supply, and therefore your I2C data and clock lines need to be level shifted to the proper voltages.

Here is the datasheet I found for the onboard ADC: http://ww1.microchip.com/downloads/en/DeviceDoc/22003b.pdf

I2C input voltages (about middle of page 3) should not exceed Vdd, which is 3.0V from the schematic on the module's datasheet.

The ATmega requires an input voltage of 60% of its power supply voltage to register as a "1" on the digital inputs. With 5V power supply that would be 3V.

Hmm, the ADC sheet annoyingly doesn't say what the output voltage is for a "1" but this is often about 80% and up of the supply voltage. So with 3V supply: 2.4V to 3V.

That makes a very marginal design. It's very likely that the ADC output can't produce high enough output voltage to drive the ATmega inputs to a high reliably, hence a reading of all "0". And in any case the ATmega output voltage is too high for the ADC's digital inputs. (It may work, but will "shorten" the life of the ADC.)

Of course, the I2C interface is only reading the module's onboard ADC. You could forego that and just read the ANAO with the Arduino analog input, but you will lose some resolution. Your onboard ADC is 18-bit over a 3V span for about 11 uV per count. The ATmega is 10-bit and by default is over a 5V span. You can switch to a lower reference voltage of 2.56V (http://arduino.cc/en/Reference/AnalogReference) which then gives you 2.5 mV per count.

Ok I found some data on the gyro chip as well: http://www.eea.epson.com/portal/pls/portal/docs/1/777485.PDF

It's output voltage is going to be 1.350 V +/- 0.067V over its full-range. This is from it having a range of +/- 100 deg/s, an output of 0.67 mV/deg/s, and a bias of 1350 mV.

So.... with the Arduino analog input and a 5V reference:

(1.350 - 0.067)/5 * 1023 = 262 1.350 / 5 * 1023 = 276 (1.350 + 0.067)/5 * 1023 = 290

And so there is the reading that you're seeing.

If you used the Arduino's 2.56V reference: (1.35 - 0.067)/2.56 * 1023 = 512 (1.35 + 0.67)/2.56 * 1023 = 566

Firstly thanks dilbert98122 and daveg360 for the help so far. I’ve found someone else who used the same gyro with the arduino (so I guess it must be possible to get this working) but he’s done things a little differently. This is my code at the moment (modified after my previous mistake):

#include "Wire.h"
//  I2C device address is 1 1 0 1 0 0 0
#define GYRO_ADDRESS (0xD << 3)
#define REGISTER_INPUT (0)

void setup() {
  Serial.begin(9600);
  Wire.begin();
}

int i2cread () {
  int data = 0;
  
  //Send input register address
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.send(REGISTER_INPUT);
  Wire.endTransmission();
  
  //Connect to device and request two bytes
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.requestFrom(GYRO_ADDRESS, 2);
  
  if (Wire.available()) {
     data = Wire.receive();
  }
  if (Wire.available()) {
     data |= Wire.receive() << 8;
  }
  
  Wire.endTransmission();
  
  return data;
}

void loop() {
  Serial.println(i2cread());
  delay(1000);
}

This is his code, obviously a simplified version (from inspired by segway™ - making a self-balancing 2 wheel vehicle: Calculating platform angle)

val = ((((analogRead(xPin)-xZero)/148.48)* 180/3.1415926535897932384626433832795))*-1); //accelerometer angle calculation

valG = valG + ((analogRead(gyroPin) - gZero)*4.8099347014925373134328358208962)/200; //integration of gyro and gyro angle calculation

angle = (val * 0.005) + (valG * 0.995); //complementary filter

valG = angle; //drift correction of gyro integration

I think he’s using an accelerometer so that’s why there’s the extra bit of calculation. What I don’t understand is why he’s just using analogRead() to read from the gyro.

The ATmega requires an input voltage of 60% of its power supply voltage to register as a "1" on the digital inputs. With 5V power supply that would be 3V.

Hmm, the ADC sheet annoyingly doesn't say what the output voltage is for a "1" but this is often about 80% and up of the supply voltage. So with 3V supply: 2.4V to 3V.

That makes a very marginal design. It's very likely that the ADC output can't produce high enough output voltage to drive the ATmega inputs to a high reliably, hence a reading of all "0". And in any case the ATmega output voltage is too high for the ADC's digital inputs. (It may work, but will "shorten" the life of the ADC.)

What if I use a resistor to step down the voltage for the IICCLK and IICDAT like detailed here?

http://www.pjrc.com/mp3/sta013.html#power

That looks like it should work ok by using the gyro module's 3.3v output pins for the pull-up source.

One could also set a reference Voltage of 1.4V at the AREF pin probably using a voltage divider, and get a lot of resolution.

On the other hand, if I2C MUST be used, for whatever reason, one could try to use a bootloaded ATmega168(or whatever) powered by 3.3V, so the I2C data levels will much between the mC an the sensor board ADC.

Right? ;)