CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help to interface with HDPM01 compass module!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
redkit_redkit



Joined: 18 Aug 2010
Posts: 5

View user's profile Send private message

Help to interface with HDPM01 compass module!
PostPosted: Mon Nov 08, 2010 6:39 am     Reply with quote

Hi guys;
I'm trying to interface hdpm01 compass module with pic18f452. And i could'nt make it work. It uses I2C bus. I found some codes who can actually interface with this compass module.

this is datasheet link:
http://www.hoperf.com/upfile/HDPM01.pdf

this is example code:
http://www.hoperf.com/upfile/Compass_Demo.pdf

and i'm using this circuit for voltage level converting
http://img183.imageshack.us/img183/1147/i2ctranslatorsch.png

links of codes i found:
http://cineon01.medien.uni-weimar.de/elektrowiki/Pavlos_Iliopoulos#head-1d11159865d7fdcf0381d2e0391f1f2f8dc64ac8
http://jeelabs.org/2010/03/24/heading-board/#comments

And i wrote this code:

Code:
#include <18f452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_D2,rcv=PIN_D3,bits=8,ERRORS)
#use i2c(master,fast=400000,sda=PIN_C4,scl=PIN_C3)

byte xParam,yParam,minX=0,maxX=0,minY=0,maxY=0,rcvByte[4];

void compass_set()
{
   OUTPUT_LOW(PIN_C2);
   OUTPUT_LOW(PIN_C1);
   i2c_start();
   i2c_write( 0x60 );
   i2c_write( 00 );
   i2c_write( 02 );
   i2c_stop();
   delay_ms(10);
}

void compass_reset(void)
{
   OUTPUT_LOW(PIN_C2);
   OUTPUT_LOW(PIN_C1);
   i2c_start();
   i2c_write(0x60);
   i2c_write(00);
   i2c_write(04);
   i2c_stop();
   delay_ms(10);
}


void get_compass_data()
{  int i=0;

   OUTPUT_LOW(PIN_C2);
   OUTPUT_LOW(PIN_C1);
   i2c_stop();
   i2c_start();
   i2c_write(0x60);
   i2c_write(0x00);
   i2c_write(0x01);
   
   delay_ms(10);

   for (i=0;i<4;i++)
   {
    rcvByte[i]=0;
    rcvByte[i] = i2c_read();
   }

   xParam =  rcvByte[0] << 8;
   xParam= xParam | rcvByte[1];
   yParam  = rcvByte[2] << 8;
   yParam= yParam | rcvByte[3];
   i2c_stop();
}


void main()
{
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);

   printf("Program Started\r\n");
   delay_ms(100);
   compass_reset();
   compass_set();

   while(1)
   {
   get_compass_data();
   if (xParam>maxX){
     maxX=xParam;
   } else if (minX==0){
     minX=xParam;
   } else if (xParam<minX){
     minX=xParam;
   }
   if (yParam>maxY){
     maxY=yParam;
   } else if (minY==0){
     minY=yParam;
   } else if (yParam<minY){
     minY=yParam;
   }

   printf("x:%x y:%x  %x %x %x %x\n\r",xParam,yParam,rcvByte[0],rcvByte[1],rcvByte[2],rcvByte[3]);
   delay_ms(1000);

   }
}


Pin_c1 and pin_c2 is connected to mclk and xclr. And i'm only getting FF, nothing else.

Any ideas?
English is not my native language? If something wrong about my post, sorry.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 08, 2010 11:36 pm     Reply with quote

The MCLK signal needs to be a continous square wave at approximately
32768 KHz. This is in the HDPM01 data sheet. You can use the PWM
module on the PIC for this. Example:
http://www.ccsinfo.com/forum/viewtopic.php?t=17729&start=1
This shows 2 PWM channels, but you only need one channel.

You also need voltage converters (5v levels ==> 3v levels) on the MCLK
and XCLR lines, going from the PIC to the HDPM01. I think it would
be easier if you used a PIC that can run at +3v. Then you don't need
to do level conversions.

Your translation from the example source code to CCS code is not
correct in some places. I understand that you converted their
low level i2c code into CCS i2c functions. But, you did not do it
the same way as they did in their example program.

One problem is that your code doesn't do a NACK (not acknowledge)
on the last i2c_read() command in the sequence of 4 calls to i2c_read().
The last call must have a parameter of 0, as in i2c_read(0) which sends
a NACK to the HDPM01. Their sample code shows this NACK.
Look at the code in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=26969
Notice how the last i2c_read() in the sequence does a NACK (it has
the 0 parameter).
redkit_redkit



Joined: 18 Aug 2010
Posts: 5

View user's profile Send private message

PostPosted: Tue Nov 09, 2010 6:04 am     Reply with quote

Thanks it's working.

Actually I tried to give 32khz to mclk and it didn't work. and also other people who get it worked said to me they didn't used mclk because they didn't need to read pressure. Also datasheet says mclk needed if you want to read pressure. But when I edit my code according to what you say about my code's wrongs and mclk, I get it worked.

Thank you very much again.

Working code:
Code:

#include <18f452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_D2,rcv=PIN_D3,bits=8,ERRORS)
#use i2c(master,fast=400000,sda=PIN_C4,scl=PIN_C3)

#define C_SET 1
#define C_RESET 0
unsigned int16 xParam,yParam,minX=0,maxX=0,minY=0,maxY=0,rcvByte[4];

void compass_set()
{
   OUTPUT_LOW(PIN_C2);
   i2c_start();
   i2c_write( 0x60 );
   i2c_write( 00 );
   i2c_write( 02 );
   i2c_stop();
   delay_ms(10);
}

void compass_reset(void)
{
   OUTPUT_LOW(PIN_C2);
   i2c_start();
   i2c_write(0x60);
   i2c_write(00);
   i2c_write(04);
   i2c_stop();
   delay_ms(10);
}


void get_compass_data()
{  int i=0;

   OUTPUT_LOW(PIN_C2);
   i2c_stop();
   i2c_start();
   i2c_write(0x60);
   i2c_write(0x00);
   i2c_write(0x01);
   i2c_stop();
   delay_ms(10);

   i2c_start();

   i2c_write(0x60);
   i2c_write(0x01);
   i2c_start();
   i2c_write(0x61);

   for (i=0;i<3;i++)
   {
    rcvByte[i]=0;
    rcvByte[i] = i2c_read();
   }
   rcvByte[3] = i2c_read(0);

   xParam =  rcvByte[0] << 8;
   xParam= xParam | rcvByte[1];
   yParam  = rcvByte[2] << 8;
   yParam= yParam | rcvByte[3];
   i2c_stop();
}


void main()
{
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_PWM);
   setup_timer_2(T2_DIV_BY_4,38,1);
   set_pwm2_duty(19);

   printf("Compass Started\r\n");
   delay_ms(100);
   compass_reset();
   compass_set();

   while(1)
   {
   get_compass_data();
   if (xParam>maxX){
     maxX=xParam;
   } else if (minX==0){
     minX=xParam;
   } else if (xParam<minX){
     minX=xParam;
   }
   if (yParam>maxY){
     maxY=yParam;
   } else if (minY==0){
     minY=yParam;
   } else if (yParam<minY){
     minY=yParam;
   }

   printf("x:%lu y:%lu  %lu %lu %lu %lu\n\r",xParam,yParam,rcvByte[0],rcvByte[1],rcvByte[2],rcvByte[3]);
   
   delay_ms(1000);

   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group