SparkFun HMC6343 i2c Code

Based on DMP's Vortex processor / SoC this board is a full computer capable of running a standard Windows and Linux installation on the backpack of your robot.
5 postsPage 1 of 1
5 postsPage 1 of 1

SparkFun HMC6343 i2c Code

Post by veltrop » Mon Mar 29, 2010 9:30 am

Post by veltrop
Mon Mar 29, 2010 9:30 am

Here is some code for the SparkFun HMC6343 Compass/Tilt sensor. It's not very different from other Roboard i2c code floating around, but thought I'd pass it along.

Code: Select all
#include <roboard>
#include <iostream>
#include <iomanip>
using namespace std;

int main(int argz, char** argv)
{
    if (!i2c_Initialize(I2CIRQ_DISABLE)) {
        cout << "Failed to Initialize i2c." <<endl;
    }

    i2c0_SetSpeed(I2CMODE_STANDARD, 100000);
   
    /////////////////////////////////////////////////////////////////
    // Calibration
    cout << "Calibrate? (y/n)"<<endl>> a;
       
    if (a == 'y') {
        usleep( 500000 ); // 500ms
       
        i2c0master_StartN(0x32>>1, I2C_WRITE, 1);
        i2c0master_WriteN(0x71);  // heading data
        usleep( 1000 ); // 1 ms

        cout << "Press y and enter when finished calibrating to save calibration."<<endl>> a;
       
        if (a == 'y') {
            i2c0master_StartN(0x32>>1, I2C_WRITE, 1);
            i2c0master_WriteN(0x7E);  // heading data
            cout <<"Calibration Saved"<<endl>>1, I2C_WRITE, 1);
        i2c0master_WriteN(0x50);  // heading data
        //i2c0master_WriteN(0x55);  // tilt data
        //i2c0master_WriteN(0x40);    // accel data
        //0x45 // mag data
        usleep( 1000 ); // 1 ms
   
        i2c0master_StartN( 0x33>>1, I2C_WRITE, 1 );
        i2c0master_SetRestartN( I2C_READ, 6 );
        i2c0master_WriteN(6);
        char msb1 = i2c0master_ReadN();
        char lsb1 = i2c0master_ReadN();
        char msb2 = i2c0master_ReadN();
        char lsb2 = i2c0master_ReadN();
        char msb3 = i2c0master_ReadN();
        char lsb3 = i2c0master_ReadN();
       
        int head = 0;
        if (msb1 & 0x0080) // 128 (2's compliment negative)
            head |= (msb1<<8 & 0xFFFFFF00) | (lsb1 & 0xFFFF00FF);
        else
            head |= (msb1<<8 & 0x0000FF00) | (lsb1 & 0x000000FF);
       
        int pitch = 0;
        if (msb2 & 0x0080) // 128 (2's compliment negative)
            pitch |= (msb2<<8 & 0xFFFFFF00) | (lsb2 & 0xFFFF00FF);
        else
            pitch |= (msb2<<8 & 0x0000FF00) | (lsb2 & 0x000000FF);
       
        int roll = 0;
        if (msb3 & 0x0080) // 128 (2's compliment negative)
            roll |= (msb3<<8 & 0xFFFFFF00) | (lsb3 & 0xFFFF00FF);
        else
            roll |= (msb3<<8 & 0x0000FF00) | (lsb3 & 0x000000FF);
       
        cout << setw(6) << (float)head/10.0f << " " << setw(6) << (float)pitch/10.0f << " " << setw(6) << (float)roll/10.0f <<endl;
               
        usleep(200000); // 200ms
    } while (1);
    ////////////////////////////////////////////////////////////////

    i2c_Close();

    return 0;
}
Here is some code for the SparkFun HMC6343 Compass/Tilt sensor. It's not very different from other Roboard i2c code floating around, but thought I'd pass it along.

Code: Select all
#include <roboard>
#include <iostream>
#include <iomanip>
using namespace std;

int main(int argz, char** argv)
{
    if (!i2c_Initialize(I2CIRQ_DISABLE)) {
        cout << "Failed to Initialize i2c." <<endl;
    }

    i2c0_SetSpeed(I2CMODE_STANDARD, 100000);
   
    /////////////////////////////////////////////////////////////////
    // Calibration
    cout << "Calibrate? (y/n)"<<endl>> a;
       
    if (a == 'y') {
        usleep( 500000 ); // 500ms
       
        i2c0master_StartN(0x32>>1, I2C_WRITE, 1);
        i2c0master_WriteN(0x71);  // heading data
        usleep( 1000 ); // 1 ms

        cout << "Press y and enter when finished calibrating to save calibration."<<endl>> a;
       
        if (a == 'y') {
            i2c0master_StartN(0x32>>1, I2C_WRITE, 1);
            i2c0master_WriteN(0x7E);  // heading data
            cout <<"Calibration Saved"<<endl>>1, I2C_WRITE, 1);
        i2c0master_WriteN(0x50);  // heading data
        //i2c0master_WriteN(0x55);  // tilt data
        //i2c0master_WriteN(0x40);    // accel data
        //0x45 // mag data
        usleep( 1000 ); // 1 ms
   
        i2c0master_StartN( 0x33>>1, I2C_WRITE, 1 );
        i2c0master_SetRestartN( I2C_READ, 6 );
        i2c0master_WriteN(6);
        char msb1 = i2c0master_ReadN();
        char lsb1 = i2c0master_ReadN();
        char msb2 = i2c0master_ReadN();
        char lsb2 = i2c0master_ReadN();
        char msb3 = i2c0master_ReadN();
        char lsb3 = i2c0master_ReadN();
       
        int head = 0;
        if (msb1 & 0x0080) // 128 (2's compliment negative)
            head |= (msb1<<8 & 0xFFFFFF00) | (lsb1 & 0xFFFF00FF);
        else
            head |= (msb1<<8 & 0x0000FF00) | (lsb1 & 0x000000FF);
       
        int pitch = 0;
        if (msb2 & 0x0080) // 128 (2's compliment negative)
            pitch |= (msb2<<8 & 0xFFFFFF00) | (lsb2 & 0xFFFF00FF);
        else
            pitch |= (msb2<<8 & 0x0000FF00) | (lsb2 & 0x000000FF);
       
        int roll = 0;
        if (msb3 & 0x0080) // 128 (2's compliment negative)
            roll |= (msb3<<8 & 0xFFFFFF00) | (lsb3 & 0xFFFF00FF);
        else
            roll |= (msb3<<8 & 0x0000FF00) | (lsb3 & 0x000000FF);
       
        cout << setw(6) << (float)head/10.0f << " " << setw(6) << (float)pitch/10.0f << " " << setw(6) << (float)roll/10.0f <<endl;
               
        usleep(200000); // 200ms
    } while (1);
    ////////////////////////////////////////////////////////////////

    i2c_Close();

    return 0;
}
veltrop offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 59
Joined: Wed Jul 22, 2009 8:04 am
Location: Japan

Post by limor » Sat Apr 03, 2010 1:20 am

Post by limor
Sat Apr 03, 2010 1:20 am

thanks!
thanks!
limor offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1812
Joined: Mon Oct 11, 2004 1:00 am
Location: London, UK

Post by veltrop » Mon Apr 05, 2010 3:45 am

Post by veltrop
Mon Apr 05, 2010 3:45 am

Just noticed that above the "if (a == 'y') { " statements the "cin >> a" got truncated becuase of the bugs with the greater-than and less-than characters.

Proceed with caution ;)
Just noticed that above the "if (a == 'y') { " statements the "cin >> a" got truncated becuase of the bugs with the greater-than and less-than characters.

Proceed with caution ;)
veltrop offline
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 59
Joined: Wed Jul 22, 2009 8:04 am
Location: Japan

Post by PaulL » Mon Apr 05, 2010 3:51 am

Post by PaulL
Mon Apr 05, 2010 3:51 am

Yup, posting code can be problematic at times. Frustrating that posting such code causes truncation. Do the moderators have any suggestions???
Yup, posting code can be problematic at times. Frustrating that posting such code causes truncation. Do the moderators have any suggestions???
PaulL offline
Savvy Roboteer
Savvy Roboteer
Posts: 395
Joined: Sat Sep 15, 2007 12:52 am

Post by pujiyanto » Mon Aug 09, 2010 8:18 am

Post by pujiyanto
Mon Aug 09, 2010 8:18 am

I'm using AVR, ATMEGA 8535, but I can hardly get the data with I2C communication

I try to display the result in 16x2 LCD, but my result stuck at 264 even if the module is rotate.
here are my code

Code: Select all
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 7/12/2010
Author  :
Company :
Comments:


Chip type           : ATmega8535
Program type        : Application
Clock frequency     : 11.059200 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 128
*****************************************************/

#include <mega8535>
#include <stdlib>
#include <string>
#include <delay>


unsigned int headinga, pitcha, rolla;
unsigned char heading[4], pitch[4], roll[4];
unsigned int temp[6];
int i;

// I2C Bus functions
#asm
   .equ __i2c_port=0x15 ;PORTC
   .equ __sda_bit=1
   .equ __scl_bit=0
#endasm
#include <i2c>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd>

// Declare your global variables here

void command (unsigned char cmd)
{
i2c_start();
i2c_write(0x32);
i2c_write(cmd);
i2c_stop();
}

void read ()
{

  i2c_start();
  i2c_write(0x33);
for(i=0;i<6;i++)
{
  temp[i] = i2c_read(1);
}
  i2c_stop();


}

void count()
{
headinga = (temp[0]<<8 + temp [1])/10;
pitcha = (temp[2]<<8 + temp [3])/10;
rolla = (temp[4]<<8 + temp [5])/10;
   
      heading[0] = headinga % 1000 / 100 + 48;
      heading[1] = headinga % 100 / 10 + 48;
      heading[2] = headinga % 10 / 1 + 48;   
      heading[3] = NULL;
     
/* this part is used to convert binary to ascii. for example, if the heading result 271 degree, then
1. mod it with 1000 result in 271, then devide it with 100 result will be 2 (rounded) then add the result with  0 ascii (48) then it store at heading[0];
2. mod it with 100 result in 71, then devide it with 10 result will be 7 (rounded) then add the result with  0 ascii (48) then it store at heading[1];
3. mod it with 10 result in 1, then devide it with 1 result will be 1 (rounded) then add the result with  0 ascii (48) then it store at heading[3];
*/
      pitch[0] = pitcha % 1000 / 100 + 48;
      pitch[1] = pitcha % 100 / 10 + 48;
      pitch[2] = pitcha % 10 / 1 + 48;   
      pitch[3] = NULL;
     
      roll[0] = rolla % 1000 / 100 + 48;
      roll[1] = rolla % 100 / 10 + 48;
      roll[2] = rolla % 10 / 1 + 48;   
      roll[3] = NULL;
 
 
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// I2C Bus initialization
i2c_init();

// LCD module initialization
lcd_init(16);
command(0x82);
delay_ms(500);

while (1)
      {       
       command(0x50);
       delay_ms(2);
       read();
       count();
       lcd_clear();
       lcd_puts(heading);
       
}

I'm using AVR, ATMEGA 8535, but I can hardly get the data with I2C communication

I try to display the result in 16x2 LCD, but my result stuck at 264 even if the module is rotate.
here are my code

Code: Select all
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 7/12/2010
Author  :
Company :
Comments:


Chip type           : ATmega8535
Program type        : Application
Clock frequency     : 11.059200 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 128
*****************************************************/

#include <mega8535>
#include <stdlib>
#include <string>
#include <delay>


unsigned int headinga, pitcha, rolla;
unsigned char heading[4], pitch[4], roll[4];
unsigned int temp[6];
int i;

// I2C Bus functions
#asm
   .equ __i2c_port=0x15 ;PORTC
   .equ __sda_bit=1
   .equ __scl_bit=0
#endasm
#include <i2c>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd>

// Declare your global variables here

void command (unsigned char cmd)
{
i2c_start();
i2c_write(0x32);
i2c_write(cmd);
i2c_stop();
}

void read ()
{

  i2c_start();
  i2c_write(0x33);
for(i=0;i<6;i++)
{
  temp[i] = i2c_read(1);
}
  i2c_stop();


}

void count()
{
headinga = (temp[0]<<8 + temp [1])/10;
pitcha = (temp[2]<<8 + temp [3])/10;
rolla = (temp[4]<<8 + temp [5])/10;
   
      heading[0] = headinga % 1000 / 100 + 48;
      heading[1] = headinga % 100 / 10 + 48;
      heading[2] = headinga % 10 / 1 + 48;   
      heading[3] = NULL;
     
/* this part is used to convert binary to ascii. for example, if the heading result 271 degree, then
1. mod it with 1000 result in 271, then devide it with 100 result will be 2 (rounded) then add the result with  0 ascii (48) then it store at heading[0];
2. mod it with 100 result in 71, then devide it with 10 result will be 7 (rounded) then add the result with  0 ascii (48) then it store at heading[1];
3. mod it with 10 result in 1, then devide it with 1 result will be 1 (rounded) then add the result with  0 ascii (48) then it store at heading[3];
*/
      pitch[0] = pitcha % 1000 / 100 + 48;
      pitch[1] = pitcha % 100 / 10 + 48;
      pitch[2] = pitcha % 10 / 1 + 48;   
      pitch[3] = NULL;
     
      roll[0] = rolla % 1000 / 100 + 48;
      roll[1] = rolla % 100 / 10 + 48;
      roll[2] = rolla % 10 / 1 + 48;   
      roll[3] = NULL;
 
 
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// I2C Bus initialization
i2c_init();

// LCD module initialization
lcd_init(16);
command(0x82);
delay_ms(500);

while (1)
      {       
       command(0x50);
       delay_ms(2);
       read();
       count();
       lcd_clear();
       lcd_puts(heading);
       
}

pujiyanto offline
Newbie
Newbie
Posts: 1
Joined: Mon Aug 09, 2010 8:10 am


5 postsPage 1 of 1
5 postsPage 1 of 1
cron