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 support@ccsinfo.com

Compass HM55B

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



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

Compass HM55B
PostPosted: Sun Jan 23, 2011 3:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 23, 2011 9:52 pm     Reply with quote

Use Google to search for a driver for the HM55B. Search for this:
Quote:

HM55B +CCS

Result:
http://www.glacialwanderer.com/robots/sensors/hm55b/
chung52h



Joined: 27 Sep 2011
Posts: 3

View user's profile Send private message

code CCS pic16f876a use HM55b
PostPosted: Tue Sep 27, 2011 10:36 am     Reply with quote

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: 9136
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 10:45 am     Reply with quote

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

View user's profile Send private message

Can I help me!!!
PostPosted: Wed Sep 28, 2011 3:06 am     Reply with quote

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: 9136
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 28, 2011 5:05 am     Reply with quote

'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

View user's profile Send private message

PostPosted: Wed Oct 05, 2011 9:33 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 05, 2011 10:22 pm     Reply with quote

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.
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