Society of Robots - Robot Forum

Software => Software => Topic started by: Jak24 on July 09, 2013, 02:45:37 PM

Title: getting data from a custom compass sensor
Post by: Jak24 on July 09, 2013, 02:45:37 PM
Hi!

So recently I got my hands on a couple of relatively good compass modules from china:
http://www.robotplayer.com/products/post.asp?pid=149 (http://www.robotplayer.com/products/post.asp?pid=149)
the page is in chinese, but with google translate I got the gist of it.
they work great with they're own controller,
http://www.robotplayer.com/products/post.asp?pid=109 (http://www.robotplayer.com/products/post.asp?pid=109)
however I would like to get it to work with by arduino.
I started looking through the files for the drag and drop programming software for these controllers and I guess I found the C file that is used to get data from the compass,
Code: [Select]
#ifdef _GETCOMPASSB_
 #ifndef  _GETCOMPASSB_EXISTS_
  #define _GETCOMPASSB_EXISTS_
  #include <jmkernel.h>
  #include "I2C_Soft.h"

  #ifndef _COMPASS_
   #define _COMPASS_ unsigned long
  #endif

  unsigned int GetCompassB(_COMPASS_ which){
    struct select *information=&which;
    unsigned char ddr1=portarray[1][information->group1];
    unsigned char ddr2=portarray[1][information->group2];
    unsigned char port1=portarray[2][information->group1];
    unsigned char port2=portarray[2][information->group2];
    unsigned char pin1=portarray[0][information->group1];
    unsigned char pin2=portarray[0][information->group2];
    unsigned char bit1=information->bit1;
    unsigned char bit2=information->bit2;
    SDA_DDR=ddr2;
    SDA_PORT=port2;
    SDA_PIN=pin2;
    SDA_BIT=bit2;
    SCL_DDR=ddr1;
    SCL_PORT=port1;
    SCL_BIT=bit1;

    unsigned char low;
    unsigned char high;
    unsigned int angle;
    Soft_I2C_Start();
    Soft_I2C_Write(0x76);
    Soft_I2C_Write(0x01);
    Soft_I2C_Start();
    Soft_I2C_Write(0x77);
    high=Soft_I2C_Read(0);
    low=Soft_I2C_Read(1);
    Soft_I2C_Stop();

    if(high==1)
      angle=256+low;
    else
      if(high==0)
        angle=low;
      else
        angle=9999;
    return angle;
  }
 #endif
#endif
now my question is how would I write this for my Arduino, here is one of my (failed) attempts:
Code: [Select]
#include <Wire.h>
#include <SoftwareSerial.h>
void setup(){
  Wire.begin();                                               // Conects I2C
  Serial.begin(9600);
}
 void loop()
{
   char high, low;             
 
   int bearing;                             
   Wire.begin();
   Wire.write(0x76);           
   Wire.write(0x01);                             
   //Wire.endTransmission();
   Wire.begin();
   Wire.write(0x77);             
   high = Wire.read();           
   low = Wire.read();           
             
      if(high==1)
      {
      bearing=256+low;
      }
   
      if(high==0)
  { 
    bearing=low;
  }
 
   Serial.println(bearing);
}

Any ideas/tips on how to get this to work would be much appreciated, please forgive my ignorance if I made a dumb programming mistake.

Title: Re: getting data from a custom compass sensor
Post by: waltr on July 09, 2013, 06:12:40 PM
The Compass chip interfaces with I2C whereas your code is using the UART (Asynchronous).
Search and use the I2C code for the arduino and also wire the compass to the arduino's I2C pins with the proper pull-up resistors.
Title: Re: getting data from a custom compass sensor
Post by: jwatte on July 10, 2013, 01:52:41 PM
@waltr: No, his code is using the Wire library, which is the I2C interface of the Arduino.

@Jak24: Are you properly pulling the I2C lines (A4/A5) up to VCC with 2.2 kOhm resistors?
Do you have an oscilloscope or logic analyzer available so you can look at the signals?
Title: Re: getting data from a custom compass sensor
Post by: Jak24 on July 10, 2013, 02:17:49 PM
re you properly pulling the I2C lines (A4/A5) up to VCC with 2.2 kOhm resistors?
now it is, and it sends back 255 continuously no matter what to orientation is
Do you have an oscilloscope or logic analyzer available so you can look at the signals?
I have an oscilloscope , could you advise me how to go about testing it?


Regards
Jak24
Title: Re: getting data from a custom compass sensor
Post by: jwatte on July 10, 2013, 03:08:06 PM
Hook the oscilloscope to the clock and data lines when using the working controller, and look at the signals. Measure timing (how fast does it run?)
Then, hook the oscilloscope to the Arduino set-up to the clock and data lines, and look at the signals. Are they different? Too fast? Different voltage? Different rise/fall times?
Title: Re: getting data from a custom compass sensor
Post by: waltr on July 10, 2013, 07:15:31 PM
Ok.
I saw this in the code:
Serial.begin(9600);
which sure looks like async serial.
Always learning something here.
Title: Re: getting data from a custom compass sensor
Post by: jwatte on July 10, 2013, 09:29:50 PM
Yes, Serial.begin(9600) configures the UART for serial communication. But that serial communication only happens when you make other calls to the Serial module. The Wire module is totally separate. As is the Servo module, or the LiquidCrystal module, or pretty much any other module :-)
Title: Re: getting data from a custom compass sensor
Post by: Jak24 on July 14, 2013, 03:12:48 PM
Hook the oscilloscope to the clock and data lines when using the working controller, and look at the signals. Measure timing (how fast does it run?)
Then, hook the oscilloscope to the Arduino set-up to the clock and data lines, and look at the signals. Are they different? Too fast? Different voltage? Different rise/fall times?

So I took a couple of pictures of the oscilloscope and here are the results
Custom controller sda line:
 (http://i1325.photobucket.com/albums/u639/warmthofwinter/customcontrollersda_zps82111f73.jpg) (http://s1325.photobucket.com/user/warmthofwinter/media/customcontrollersda_zps82111f73.jpg.html)
Custom controller scl line:
(http://i1325.photobucket.com/albums/u639/warmthofwinter/customcontrollerscl_zps3a819095.jpg) (http://s1325.photobucket.com/user/warmthofwinter/media/customcontrollerscl_zps3a819095.jpg.html)
Arduino scl line:
(http://i1325.photobucket.com/albums/u639/warmthofwinter/arduinoscl_zps38d2e96d.jpg) (http://s1325.photobucket.com/user/warmthofwinter/media/arduinoscl_zps38d2e96d.jpg.html)
Arduino sda line:
(http://i1325.photobucket.com/albums/u639/warmthofwinter/arduinosda_zps87391278.jpg) (http://s1325.photobucket.com/user/warmthofwinter/media/arduinosda_zps87391278.jpg.html)
At least to me, It seem that the arduino lines aren't transmitting any data packets.
I apologize if I didn't measure it properly, or didn't show the correct detail, I just recently got this oscilloscope and I
am still learning how to use it.
Any ideas on how to continue ?
Title: Re: getting data from a custom compass sensor
Post by: jwatte on July 14, 2013, 10:59:32 PM
The i2c bus transmits at 400 kHz by default IIRC. Some devices only support 100 kHz, so you may have to change it to do that.

I doubt that a scope showing signals at 60 Hz or 5 kHz would see signals at 400 kHz; you need significantly faster scanning to see that.

However, looking at your oscilloscope pictures, you're seeing lots of noise at 60 Hz (line noise) meaning your input voltage isn't particularly clean.