|
|
View previous topic :: View next topic |
Author |
Message |
redkit_redkit
Joined: 18 Aug 2010 Posts: 5
|
Help to interface with HDPM01 compass module! |
Posted: Mon Nov 08, 2010 6:39 am |
|
|
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
|
|
Posted: Mon Nov 08, 2010 11:36 pm |
|
|
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
|
|
Posted: Tue Nov 09, 2010 6:04 am |
|
|
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);
}
} |
|
|
|
|
|
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
|