I2C cmps03

Hey there,

I have got a cmps03 and tried to read the values with the PWM signal (pulseIn) but apperently that function works like a delay. I measure the difference between the start of loop and the end in milliseconds and if I read the cmps03 values the difference goes to 600-700 and without to 2-4. So I guess I need to read the values with the I2C process instead but I researched it but I wasn't able to find something that works. Can you help me maybe ?

P.S.: I'm using a Arduino Mega

Using Google I found an explanation of the I2C functionality.

Please explain where you have problems there. Simple code:

#inlcude "Wire.h"

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

void loop() {
  Wire.beginTransmission(0x60);
  Wire.write(0x01);
  Wire.endTransmission();
  Wire.requestFrom(0x60);
  uint8_t value = Wire.read();
  Serial.println(value, DEC);
}

There's no error checking but it might work.

Ah and is there any way to change the i2c adress? As far as i understand it should look like this:

  int8_t flag = -1;
  Wire.begin();
  Wire.beginTransmission(0x60);
  Wire.write(0x0C);
  Wire.write(0xA0);
  Wire.write(0x0D);
  Wire.write(0xAA);
  Wire.write(0x0E);
  Wire.write(0xA5);
  Wire.write(0x0F);
  Wire.write(0x62);
  flag = Wire.endTransmission();

Ah and is there any way to change the i2c adress?

Why would you need that? Don't do it except you're forced to.

Yeah sadly I'm forced to because I have another device with the same adress

What device is that? Post a link to it's datasheet!

The device is the Adafruit Motorshile v2.3. And if not necessary the compass module doens't have to work with i2c it would be best for me if it would work with its pwm but that takes to much time to read. (I read the millis taken for one iteration of loop and with pulsein it needs around 700 ms and with out only around 2 ms) How can I deny this long waiting ? (I saw something with nointerrupts() and interrupts())

The Adafruit Motoshield can bei configured to any I2C address between 0x60 and 0x80 by using on-board jumpers. Much easier than to use the error prone procedure of that compass module.

okay and then how can I read the value with i2c, because your code above doens't work.
It gives values out from 0 - 8 and 245 - 255 and not from 0 - 255 as I would like. And if I turn my module 180 degrees the value is the same, which is not what I need.

The first picture shows how the values look like and the second shows how the values should look like.

cm.png

cm2.png

okay and then how can I read the value with i2c, because your code above doens't work.

The code wasn't intended as a finished package ready for you to use. It shows you how you can use the Wire library to read registers from your device. It's up to you to extend that code to something useful for you.

It gives values out from 0 - 8 and 245 - 255 and not from 0 - 255 as I would like. And if I turn my module 180 degrees the value is the same, which is not what I need.

According to the documentation I linked above that code should return the direction as a byte value. If your module returns something different it may be another hardware than the linked document describes.
You might try to read out register 0. What value do you get there? If that value isn't constant, your wiring may be broken. If it's constant but less than 14 you have another firmware revision than the document describes.

First off all I would like to thank you for your persistent help in solving my problem. I know I ask stupid questions and my englisch sounds worse.

So after your advice I read out the register 0 and it returned a stable 16. And again I checked for register 1 and still it gives out on to different directions the value 0 and 255. But that isn't how it is supposed to work afterall. I need a full circle. And could it be that this is so because I once tried to change the calibration but I'm not sure if it worked?

And could it be that this is so because I once tried to change the calibration but I'm not sure if it worked?

It may. I have no clue how the module internally works, so everything might be possible. Did you read the manual? It explicitly tells you not to try to calibrate before you have verified that the I2C interface works.

Now I restored the factory calibration, I guess. But still nothing works with i2c, the values go from 255 to 235 but with the same rotation again to 255. And with pwm everything works as expected, but the high delay coming from the method pulsein(). I give up on i2c but could you now help me with the pwm signal please?

I wouldn't give up the I2C that fast. Have you tried to read the registers 2 and 3 instead of 1?

And with pwm everything works as expected, but the high delay coming from the method pulsein().

What's a "high delay"? Can you quantify that?

I give up on i2c but could you now help me with the pwm signal please?

I can try but you have to provide much more information.

What’s a “high delay”? Can you quantify that?

I measure the millis taken for one loop iteration and normally that takes up to 2 millis but with pulsein() it takes dependend on the angle up to 700 millis.

I wouldn’t give up the I2C that fast. Have you tried to read the registers 2 and 3 instead of 1?

Yeah, it has the same problem but instead of values up to 255 it goes higher, which is still not helpfull.

I measure the millis taken for one loop iteration and normally that takes up to 2 millis but with pulsein() it takes dependend on the angle up to 700 millis.

In that case the PWM signal doesn't work too. If you'd receive a correct signal the pulseIn() might need between 1ms and 37ms, in the worst case (if you have to wait for the start of the signal) it needs 100ms. If you need 700ms you module is probably broken.

Yeah, it has the same problem but instead of values up to 255 it goes higher, which is still not helpfull.

Post a series of values you get there.