View unanswered posts | View active topics It is currently Mon Jul 28, 2014 10:25 am






Reply to topic  [ 9 posts ] 
Hitechnic Compass Sensor: calibrating and reading values 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Hitechnic Compass Sensor: calibrating and reading values
calibrating and reading the Hitechnic Compass Sensor values:
(the code has been developed by Hitechnic.com and was sent to me by email attachement). I simplfied it (see below), so it can be used easily as a driver.

Edit:
if the Compass Sensor Drive doesn't work with some I²C sensor definitions, see this: viewtopic.php?p=2568&highlight=#2568
starwarslegokid wrote:
In 1.38, sensorI2CCustomStd is not a valid sensor type.
Try sensorI2CCustom and see if that works. There is also a sensorI2CHiTechnicCompass, that may be right up your ally as well.
Hope This Helps
Scott B-)



Code:
/*
                                 Test HiTechnic Compass Sensor

This program reads the HiTechnic compass and displays the heading on the screen.
Two NXT buttons can also be used
      Left Arrow Button - send command to put the compass in Calibration Mode
      Right Arrow Button - send command to put the compass in Read Mode

The memory model for the HiTechnic compass is

Address       Type          Contents
00 – 07H    chars       Sensor version number
08 – 0FH    chars       Manufacturer
10 – 17H    chars       Sensor type
18 – 3DH    bytes       Not used
3E, 3FH    chars       Reserved
40H          byte          Not used
41H          byte          Mode control
42H          byte          Heading } two degree heading
43H          byte          Heading } one degree adder
44, 45H    word          Heading (low byte, high byte)

*/

task main()
{
  int hUpper, hLower, heading;

  TButtons nBtn;

  typedef struct{
    byte nMsgSize;
    byte nDeviceAddress;
    byte nLocationPtr;
    byte nCompassMode;
  } TI2C_Output;

  SensorType[S3] = sensorI2CCustomStd;
  wait10Msec(5);
  nI2CBytesReady[S3]=0;
  while(nI2CStatus[S3]== STAT_COMM_PENDING)
  wait1Msec(2);

  byte replyMessage[6];

  TI2C_Output sOutput;

  while(true)
  {
    nxtDisplayTextLine(1, "Mode = Read");
     nI2CBytesReady[S3] = 0;
      sOutput.nMsgSize = 2;                            //read the value from the sensor
    sOutput.nDeviceAddress = 0x02;
    sOutput.nLocationPtr = 0x42;
    sendI2CMsg(S3, sOutput.nMsgSize, 6);

    while (nI2CStatus[S3] == STAT_COMM_PENDING)
      wait1Msec(2);

    if (nI2CStatus[S3] == NO_ERR)
    {
      readI2CReply(S3, replyMessage[0], 6);            //get the compass heading

      hUpper = (replyMessage[0] & 0x00FF);
      hLower = (replyMessage[1] & 0x00FF);
      heading = (hUpper << 1) | hLower ;                //convert contents of 0x44 0x45

         nxtDisplayTextLine(4, "U-val %d", hUpper);
      nxtDisplayTextLine(5, "L-val %d", hLower);
      nxtDisplayTextLine(6, "Heading = %d", heading);

    }
    else
    {
      nxtDisplayTextLine(1, "i2c err %d", nI2CStatus[S3]);
    }

  //check if a button has been pressed.

  nBtn = nNxtButtonPressed; // check for button press

     switch (nBtn)
     {
        case kLeftButton:
           {
              PlayTone(440,1000);
              sOutput.nMsgSize = 3;
              sOutput.nDeviceAddress = 0x02;
              sOutput.nLocationPtr = 0x41;               //Calibration mode command
              sOutput.nCompassMode = 0x43;

              nI2CBytesReady[S3] = 0;
               sendI2CMsg(S3, sOutput.nMsgSize, 0);
               wait1Msec(40);
               while ((nBtn = nNxtButtonPressed) != kRightButton)
                 {                        //wait for the right button to be pressed before leaving cal mode;
                    nxtDisplayTextLine(1, "Mode = Cal ");
                    wait1Msec(1000);
                    PlaySound(soundBlip);
                 }
              break;
           }
         case kRightButton:
            {
               PlaySound(soundBeepBeep);

               sOutput.nMsgSize = 3;
              sOutput.nDeviceAddress = 0x02;
              sOutput.nLocationPtr = 0x41;
               sOutput.nCompassMode   = 0x00;                  //Read mode command
              nI2CBytesReady[S3] = 0;
               sendI2CMsg(S3, sOutput.nMsgSize, 0);
               wait1Msec(1250);                                    //wait for the cal info to be saved
               break;
           }
      }

  }
}


this is the simplified driver:

Code:

/*
                                 HiTechnic Compass Driver
                                 HTCompassDrv.h
                                 Version  1.0.2.


*/



tSensors CompassPort;

void HTCompassSensor(tSensors port)
{
   SensorType[port] = sensorI2CCustomStd;
  wait10Msec(5);
  nI2CBytesReady[port]=0;
  while(nI2CStatus[port]== STAT_COMM_PENDING)
  wait1Msec(2);

  CompassPort=port;
}


int HTCompassValue(tSensors port)
{
  int hUpper, hLower, heading;
  TButtons nBtn;

   typedef struct{
    byte nMsgSize;
    byte nDeviceAddress;
    byte nLocationPtr;
    byte nCompassMode;
  } TI2C_Output;

  byte replyMessage[6];

  TI2C_Output sOutput;

     nI2CBytesReady[S3] = 0;
      sOutput.nMsgSize = 2;                            //read the value from the sensor
    sOutput.nDeviceAddress = 0x02;
    sOutput.nLocationPtr = 0x42;
    sendI2CMsg(S3, sOutput.nMsgSize, 6);

    while (nI2CStatus[S3] == STAT_COMM_PENDING)
      wait1Msec(2);

    if (nI2CStatus[S3] == NO_ERR)
    {
      readI2CReply(S3, replyMessage[0], 6);            //get the compass heading

      hUpper = (replyMessage[0] & 0x00FF);
      hLower = (replyMessage[1] & 0x00FF);
      heading = (hUpper << 1) | hLower ;                //convert contents of 0x44 0x45
    }

    return heading;
    //  hier kann spaeter noch fuer die Kalibrierung erweitert werden
     //  nBtn = nNxtButtonPressed; // check for button press
}


Test-File:

Code:

#include "HTCompassDrv.h"

task main()
{
   int heading;

   while(true)
   {
     HTCompassSensor(S3);  // setzt HTCompass an CompassPort=S3
     heading=HTCompassValue(CompassPort);
     nxtDisplayTextLine(6, "Heading = %5d", heading);
   }
}



Last edited by Ford Prefect on Sat Jul 26, 2008 3:33 am, edited 4 times in total.



Tue Mar 18, 2008 10:09 am
Profile
Rookie

Joined: Fri May 30, 2008 12:01 pm
Posts: 3
Post 
I found that one but I am using Mindstorms and do not know how to integrate that code into the program. Im sorry, Im just very new at this


Fri May 30, 2008 12:52 pm
Profile
Rookie

Joined: Sat Apr 12, 2008 11:09 am
Posts: 49
Location: holland
Post 
Thanks for sharing this kind of info.


Thu Jun 26, 2008 11:05 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
if the Compass Sensor Drive doesn't work with some I²C sensor definitions, see this:
starwarslegokid wrote:
In 1.38, sensorI2CCustomStd is not a valid sensor type.

Try sensorI2CCustom and see if that works. There is also a sensorI2CHiTechnicCompass, that may be right up your ally as well.

Hope This Helps
Scott B-)


viewtopic.php?p=2568&highlight=#2568

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Jul 26, 2008 3:31 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 614
Post Re: Hitechnic Compass Sensor: calibrating and reading values
I have added a short program to the ROBOTC sample programs folder to calibrate the HiTechnic Compass. It will be in release 1.46.

But in general you should not have to calibrate the compass -- see the technical documentation on the HiTechnic site.


Sun Oct 12, 2008 2:13 pm
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: Hitechnic Compass Sensor: calibrating and reading values
Compass compensation is needed because of ferromagnetic parts on the robot and in the local environment which disrupt and distort the Earth's magnetic field (deviation).

You'll have to do this at every new robot and every new room it's working in!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Nov 15, 2008 2:25 pm
Profile
Expert

Joined: Sun Aug 19, 2007 2:43 pm
Posts: 135
Location: New Jersey
Post Re: Hitechnic Compass Sensor: calibrating and reading values
I have a strange question due to my lack of understanding the hardware:

I am planning using the same compass for both robolab and robotc platform. I did the calibration when the robot was running in robotc platform. Then, I use the same robot and compass, but different firmware (i.e robolab), I suspect I will have to write a robolab program in robolab to calibrate the compass again? Correct?

What are pros and cons of the calibration? I understand it will mainly be the accuracy. However, will it remain consistent. Eg. it's heading is at north (magnetic north), but is off by 10degrees. Will it remain always 10 off, or it may fluctuate unless calibration is done.

Thank you in advance.


Fri Jun 17, 2011 12:11 pm
Profile WWW
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3164
Location: Rotterdam, The Netherlands
Post Re: Hitechnic Compass Sensor: calibrating and reading values
Calibration is needed to offset the interference from motors and the actual NXT brick itself. If the robot remains the same then changing the hardware should not influence the readings. In other words, if you calibrate the compass in ROBOTC, it will be calibrated for all firmwares.
The pros of calibration is that the effects of the brick and motors is minimized (not completely eliminated as the magnetic fields do fluctuate). There are no cons other than that you should do this for each robot model you make. If you change the positions of your motors, you should ideally recalibrate your robot.
As for the consistency, I have no idea, I would suggest you use another compass (in your mobile phone for example) to verify :)

Also, if you want to get a good result multiplying PI, use 1.0*PI and not 1*PI, one is float multiplication, the other isn't.

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Fri Jun 17, 2011 12:54 pm
Profile WWW
Expert

Joined: Sun Aug 19, 2007 2:43 pm
Posts: 135
Location: New Jersey
Post Re: Hitechnic Compass Sensor: calibrating and reading values
thank you very much for the info...! :)


Mon Jun 27, 2011 6:58 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 9 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


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 post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.