|
|
View previous topic :: View next topic |
Author |
Message |
Pichuqy_1
Joined: 03 Aug 2010 Posts: 38
|
Compass HM55B |
Posted: Sun Jan 23, 2011 3:42 pm |
|
|
Hi everybody. I'm using the compass HM55B from Hitachi. I've wrote the program but it doesn't work. I've read the datasheet about the compass and I've understood the protocol, but I can't understand what is wrong... Thanks a lot.
Code: |
#include <16F887.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#FUSES DEBUG
#define SDO PIN_C4
#define SDI PIN_C1
#define SCK PIN_C3
#define HM55B_ENABLE PIN_C2 ///CS Chip Select Input (Low = Select, High = Disable)
int16 dato_x,dato_y;
#use spi (MASTER,CLOCK_HIGH=5,CLOCK_LOW=5,DI=SDI,DO=SDO,CLK=SCK,MSB_FIRST,MODE=3,STREAM=brujula_out)
#use spi (MASTER,CLOCK_HIGH=5,CLOCK_LOW=5,DI=SDI,DO=SDO,CLK=SCK,LSB_FIRST,MODE=3,STREAM=brujula_in)
#include <HDM64GS12.c>
#include <graphics.c>
#include <HM55B.c>
#include <math.h>
void main()
{
float x,y,angulo;
while(TRUE){
getCompasXY();
if (bit_test(dato_x,10)==1) dato_x = dato_x | NEG_MASK ;
if (bit_test(dato_y,10)==1) dato_y = dato_y | NEG_MASK ;
x=(float)dato_x;
y=(float)dato_y;
angulo = atan2 (-y,x);
angulo*=57.2958;
printf ("Angulo= %f\n\r",angulo);
delay_ms(150);
}
}
//========================================================
//Command Set
//These commands are shifted-out to the Compass Module.
#define HM55B_RESET 0b0000 //Reset command for HM55B
#define HM55B_START 0b0001 //Start measurement command
#define HM55B_REPORT 0b0011 //Report measurement status (and transmit the measurement if it's ready)
#define HM55B_READY 0b1100 //11 -> Measurement completed; 00 -> no errors
#define NEG_MASK 0b1111100000000000 //For 11-bit negative to 16-bits
//
// This Hitachi HM55B compass module test program displays x (N/S) and y (W/E)
// axis measurements along with the direction the compass module is pointing,
// measured in degrees clockwise from north.
//
void getCompasXY()
{
int hm55bStatus=0; //variable utilizada para guardar el valro del flag de fin de conversion
// Send a reset command to HM55B
output_high(HM55B_ENABLE);
delay_us(20);
output_low(HM55B_ENABLE);
spi_xfer(brujula_out,HM55B_RESET,4);
output_high(HM55B_ENABLE); //Controlar esta linea. En el pdf lo especifica pero en los programas ejemplo no lo hacen.
delay_us(20);
// Send a start measurement command to HM55B
output_low(HM55B_ENABLE);
spi_xfer(brujula_out,HM55B_START,4);
delay_us(20);
output_high(HM55B_ENABLE);
delay_us(20);
output_low(HM55B_ENABLE);
while (hm55bStatus != HM55B_READY)
{
spi_xfer(brujula_out,HM55B_REPORT,4);
hm55bStatus = spi_xfer(brujula_in,0b0000,4);
}
dato_x=spi_xfer(brujula_in,HM55B_RESET,11);
dato_y=spi_xfer(brujula_in,HM55B_RESET,11);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
chung52h
Joined: 27 Sep 2011 Posts: 3
|
code CCS pic16f876a use HM55b |
Posted: Tue Sep 27, 2011 10:36 am |
|
|
Help me!!!
I need code CCS pic16f876a for Hm55B compass
Anyguy can send to me!!
Email: chung52h@gmail.com
Thanks so much!!!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Tue Sep 27, 2011 10:45 am |
|
|
PCM programmer did !!
ALL the code is there, in the zip file he points to !!!
I even downloaded it, read it( nice utilites by the way...),understood the code and if I had the compass module I could have it running in less than 1 hour. |
|
|
chung52h
Joined: 27 Sep 2011 Posts: 3
|
Can I help me!!! |
Posted: Wed Sep 28, 2011 3:06 am |
|
|
I read and tried it. but it did not work. I use code CCS:
Code: | #include <16F876a.h>
#include <math.h>
//#include <prototype.h>
//#include <protoalone.h>
//#include <utility.c>
//#include <hm55b.c>
#fuses HS,NOLVP,NOWDT
#CASE
#use delay(clock=20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)
#define HM55B_IN_OUT PIN_C1
#define HM55B_ENABLE PIN_C4
#define HM55B_CLK PIN_C3
#define CMD_RESET 0b0000
#define CMD_MEASURE 0b0001
#define CMD_REPORT 0b0011
#define CMD_READY 0b1100
#define NEG_MASK 0b1111100000000000
//
// Helper funtion to get data from the HM55B module.
//
int16 shiftInFromHm55b(int8 numBits)
{
int8 i;
int16 out = 0;
for(i=0; i<numBits; ++i)
{
output_high(HM55B_CLK);
shift_left(&out, 2, input(HM55B_IN_OUT));
output_low(HM55B_CLK);
}
return out;
}
//
// Helper funtion to send data to the HM55B module.
//
void shiftOutToHm55b(int8 var, int8 numBits)
{
int1 curBit;
int8 i;
//
// We are shifting out the LSB first.
//
for(i=0; i<numBits; ++i)
{
output_high(HM55B_CLK);
curBit = shift_right(&var, 1, 0);
if(curBit)
{
output_high(HM55B_IN_OUT);
}
else
{
output_low(HM55B_IN_OUT);
}
output_low(HM55B_CLK);
}
output_low(HM55B_IN_OUT);
}
//
// This Hitachi HM55B compass module test program displays x (N/S) and y (W/E)
// axis measurements along with the direction the compass module is pointing,
// measured in degrees clockwise from north.
//
void getCompassXY(int16 &x, int16 &y)
{
int16 hm55bStatus;
// Send a reset command to HM55B
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_RESET, 4);
// Send a start measurement command to HM55B
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_MEASURE, 4);
while(hm55bStatus != CMD_READY)
{
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_REPORT, 4);
hm55bStatus = shiftInFromHm55b(4);
}
x = shiftInFromHm55b(11);
y = shiftInFromHm55b(11);
output_high(HM55B_ENABLE);
if(bit_test(x, 10))
{
x |= NEG_MASK;
}
if(bit_test(y, 10))
{
y |= NEG_MASK;
}
}
float getCompassAngle()
{
int16 x, y;
float fx, fy, hypoth, angle;
getCompassXY(x, y);
//
// Now convert this the x and y magnitudes that the HM55B module gives us
// into something more useful like the angle of deflection from north.
//
fx = (signed int16)x;
fy = (signed int16)y;
hypoth = sqrt(fx*fx+fy*fy);
fx /= hypoth;
fy /= hypoth;
angle = (atan2(fx, fy))*180/3.14;
angle -= read_program_eeprom(0);
while(angle < 0)
{
angle += 360;
}
while(angle > 360)
{
angle -= 360;
}
return angle;
}
void calibrateCompass()
{
float offsetAngle;
//
// We could get better results if we calculated more angles and then
// interpolated between them, but I want to keep the calibration simple
// for now.
//
write_program_eeprom(0, 0); // Need to do this before getCompassAngle()
offsetAngle = getCompassAngle();
printf("Offset angle: %f\n", offsetAngle);
write_program_eeprom(0, offsetAngle);
}
//////////////////Main///////////////////////////////
void main()
{
calibrateCompass();
while(TRUE)
{
float angle;
angle = getCompassAngle();
printf("%f\n", angle);
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Sep 28, 2011 5:05 am |
|
|
'It did not work' doesn't help anyone is solving what might be wrong.
1) You should have 'errors' added to the use RS_232(...) options..
2) have you done a 'hello world' program to verify the PIC is good,proper PC link,etc.
3) trim down the code to just read and display the raw data from the compass
4) verify that the PIC<-> compass wiring is correct
5) return out ;
is wrong...
Correct syntax according to the F11 onscreen info is
return (out); |
|
|
chung52h
Joined: 27 Sep 2011 Posts: 3
|
|
Posted: Wed Oct 05, 2011 9:33 pm |
|
|
I tried again, but it also not working. code here:
Code: | #include <16F876a.h>
#include <math.h>
//#include <prototype.h>
//#include <protoalone.h>
//#include <utility.c>
//#include <hm55b.c>
#fuses HS,NOLVP,NOWDT
#CASE
#use delay(clock=20000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)
#define HM55B_IN_OUT PIN_C1
#define HM55B_ENABLE PIN_C4
#define HM55B_CLK PIN_C3
#define CMD_RESET 0b0000
#define CMD_MEASURE 0b0001
#define CMD_REPORT 0b0011
#define CMD_READY 0b1100
#define NEG_MASK 0b1111100000000000
//
// Helper funtion to get data from the HM55B module.
//
int16 shiftInFromHm55b(int8 numBits)
{
int8 i;
int16 out = 0;
for(i=0; i<numBits; ++i)
{
output_high(HM55B_CLK);
shift_left(&out, 2, input(HM55B_IN_OUT));
output_low(HM55B_CLK);
}
return out;
}
//
// Helper funtion to send data to the HM55B module.
//
void shiftOutToHm55b(int8 var, int8 numBits)
{
int1 curBit;
int8 i;
//
// We are shifting out the LSB first.
//
for(i=0; i<numBits; ++i)
{
output_high(HM55B_CLK);
curBit = shift_right(&var, 1, 0);
if(curBit)
{
output_high(HM55B_IN_OUT);
}
else
{
output_low(HM55B_IN_OUT);
}
output_low(HM55B_CLK);
}
output_low(HM55B_IN_OUT);
}
//
// This Hitachi HM55B compass module test program displays x (N/S) and y (W/E)
// axis measurements along with the direction the compass module is pointing,
// measured in degrees clockwise from north.
//
void getCompassXY(int16 &x, int16 &y)
{
int16 hm55bStatus;
// Send a reset command to HM55B
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_RESET, 4);
// Send a start measurement command to HM55B
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_MEASURE, 4);
while(hm55bStatus != CMD_READY)
{
output_high(HM55B_ENABLE);
output_low(HM55B_ENABLE);
shiftOutToHm55b(CMD_REPORT, 4);
hm55bStatus = shiftInFromHm55b(4);
}
x = shiftInFromHm55b(11);
y = shiftInFromHm55b(11);
output_high(HM55B_ENABLE);
if(bit_test(x, 10))
{
x |= NEG_MASK;
}
if(bit_test(y, 10))
{
y |= NEG_MASK;
}
}
//////////////////Main///////////////////////////////
void main()
{
while(TRUE)
{
printf("%f\n", x);
printf("%f\n", y);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 05, 2011 10:22 pm |
|
|
Did you look at his source code ? Did you look at his main.c file ?
http://www.glacialwanderer.com/robots/sensors/hm55b/
Compare your main() code with his main(). Note that he actually calls
the functions that he wrote. Also, you left out the calibrateCompass()
function. |
|
|
|
|
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
|