ROBOTC.net forums
http://robotc.net/forums/

Hitechnic Compass Sensor: calibrating and reading values
http://robotc.net/forums/viewtopic.php?f=41&t=463
Page 1 of 1

Author:  Ford Prefect [ Tue Mar 18, 2008 10:09 am ]
Post subject:  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);
   }
}


Author:  wareagle609 [ Fri May 30, 2008 12:52 pm ]
Post subject: 

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

Author:  nxt [ Thu Jun 26, 2008 11:05 am ]
Post subject: 

Thanks for sharing this kind of info.

Author:  Ford Prefect [ Sat Jul 26, 2008 3:31 am ]
Post subject: 

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

Author:  Dick Swan [ Sun Oct 12, 2008 2:13 pm ]
Post subject:  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.

Author:  Ford Prefect [ Sat Nov 15, 2008 2:25 pm ]
Post subject:  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!

Author:  elizabeth.mabrey [ Fri Jun 17, 2011 12:11 pm ]
Post subject:  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.

Author:  mightor [ Fri Jun 17, 2011 12:54 pm ]
Post subject:  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

Author:  elizabeth.mabrey [ Mon Jun 27, 2011 6:58 am ]
Post subject:  Re: Hitechnic Compass Sensor: calibrating and reading values

thank you very much for the info...! :)

Page 1 of 1 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/