View unanswered posts | View active topics It is currently Tue Sep 02, 2014 11:46 am






Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
HiTechnic Compass Problems? 
Author Message
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post HiTechnic Compass Problems?
Hello,

I'm using the HiTechinc compass sensor to try to force my robot to move in straight lines and turn precise angles on uneven terrain.

The problem I'm having is that the sensor values skip from about 127 to about 233, and skip back to 243 or so when they hit 339. This leads to having a large portion of the compass being incredibly off of where it ought to be.

What might my options be for working around this issue? And are there any suggestions to what may be causing it?

Thanks,
-Mandy


Tue May 22, 2007 3:20 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
Hello,

what kind of code do you use to collect the HT compass sensor data?

jm

_________________
SuntzuMaster- a French gentlemen in USA.


Wed May 23, 2007 5:01 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
I'm using the NXT Compass Sensor testing program that was in the samples. I haven't changed anything in it. It doesn't appear to be doing anything particularly fancy with the numbers, but they're still going absolutely crazy.

Thanks for trying to help me,
-Mandy


Wed May 23, 2007 5:40 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
Hi,

I do think that the example is not working at all!!!

try to compile and let me know if that is OK.

by default the sensor is expected on the port S3 but you can change it inside the htCompassDrv.h file.

my code for you :

1) fisrt main program must be saved as htCompass.c

//*!!CLICK to edit 'wizard' created sensor & motor configuration. !!*//
#include "htCompassDrv.h"

task main()
{
int x = 50000;
eraseDisplay();

bHT_COMPASS = true;
StartTask(HT_COMPASS);

while(x-- != 0)
{
nxtDisplayString(1,"Heading=%04d",HT_COMPASS_Heading_Data);
wait1Msec(5);
}

bHT_COMPASS = false;
StopAllTasks();
}


****************************************************
2) second program must be saved as htCompassDrv.h.

****************************************************

//* ********************************************************** *
//* *
//* ********************************************************** *
typedef enum
{
subTypeNone = 0,
subTypeHiTechnicCompass = 1,
subTypeHiTechnicRcxIR = 2,
subTypeMindsensorsCompass = 20,
subTypeMindsensorsRcxIR = 21,
subTypeMindsensorsPSX = 22,
subTypeMindsensorsMotorMux = 22,
} TSensorSubTypes;

//* ********************************************************** *
//* *
//* ********************************************************** *
bool bHT_COMPASS = false;
const tSensors HT_COMPASS_I2C_Port = S3;
int HT_COMPASS_Heading_Data;

//* ********************************************************** *
//* *
//* ********************************************************** *
typedef struct{
byte nMsgSize;
byte I2C_Bus_Addr;
byte I2C_RegIndex;
} TI2C_Output;

typedef struct{
byte nMsgSize;
byte I2C_Bus_Addr;
byte I2C_RegIndex;
byte I2C_Data;
} TI2C_Output_Data;

int I2C_Error = 0;

//* ********************************************************** *
//* *
//* ********************************************************** *
inline bool I2C_Convers_Data(const tSensors I2C_Port,const byte I2C_Bus_Addr ,const byte I2C_RegIndex, ubyte *I2C_Reply, int I2C_Reply_Length,const byte I2C_Data ,int nDelay)
{
TI2C_Output_Data I2C_Output;
int nI2C_BytesReady = 0;

while (true)
{
nI2C_BytesReady = 0;
I2C_Output.nMsgSize = 3;
I2C_Output.I2C_Bus_Addr = I2C_Bus_Addr;
I2C_Output.I2C_RegIndex = I2C_RegIndex;
I2C_Output.I2C_Data = I2C_Data;

memset(I2C_Reply,0x00,I2C_Reply_Length);
sendI2CMsg(I2C_Port,I2C_Output.nMsgSize,0);
while (nI2CStatus[I2C_Port] == STAT_COMM_PENDING) {wait1Msec(0);}
while (nI2CBytesReady[I2C_Port] > 0)
{
readI2CReply(I2C_Port, I2C_Reply,1);
}
nI2CBytesReady[I2C_Port] = 0;
nI2CRetries = 5;
sendI2CMsg(I2C_Port,I2C_Output.nMsgSize,I2C_Reply_Length);
if (nI2CStatus[I2C_Port] == ERR_COMM_BUS_ERR)
{
I2C_Error++;
return(false);
}
while (nI2CStatus[I2C_Port] == STAT_COMM_PENDING) {wait1Msec(0);}
if (nI2CStatus[I2C_Port] != NO_ERR)
{
I2C_Error++;
return(false);
}
while(nI2C_BytesReady < I2C_Reply_Length)
{
nI2C_BytesReady = nI2CBytesReady[I2C_Port];
wait1Msec(0);
}
readI2CReply(I2C_Port,I2C_Reply,I2C_Reply_Length);
if (nI2CStatus[I2C_Port] != NO_ERR)
{
I2C_Error++;
return(false);
}
break;
}
wait1Msec(nDelay);
return(true);
}

//* ********************************************************** *
//* *
//* ********************************************************** *
inline bool I2C_Convers(const tSensors I2C_Port,const byte I2C_Bus_Addr ,const byte I2C_RegIndex, ubyte *I2C_Reply, int I2C_Reply_Length, int nDelay)
{
TI2C_Output I2C_Output;
int nI2C_BytesReady = 0;

while (true)
{
nI2C_BytesReady = 0;
I2C_Output.nMsgSize = 2;
I2C_Output.I2C_Bus_Addr = I2C_Bus_Addr;
I2C_Output.I2C_RegIndex = I2C_RegIndex;

memset(I2C_Reply,0x00,I2C_Reply_Length);
sendI2CMsg(I2C_Port,I2C_Output.nMsgSize,0);
while (nI2CStatus[I2C_Port] == STAT_COMM_PENDING) {wait1Msec(0);}
while (nI2CBytesReady[I2C_Port] > 0)
{
readI2CReply(I2C_Port, I2C_Reply,1);
}
nI2CBytesReady[I2C_Port] = 0;
nI2CRetries = 5;
sendI2CMsg(I2C_Port,I2C_Output.nMsgSize,I2C_Reply_Length);
if (nI2CStatus[I2C_Port] == ERR_COMM_BUS_ERR)
{
I2C_Error++;
return(false);
}
while (nI2CStatus[I2C_Port] == STAT_COMM_PENDING) {wait1Msec(0);}
if (nI2CStatus[I2C_Port] != NO_ERR)
{
I2C_Error++;
return(false);
}
while(nI2C_BytesReady < I2C_Reply_Length)
{
nI2C_BytesReady = nI2CBytesReady[I2C_Port];
wait1Msec(0);
}
readI2CReply(I2C_Port,I2C_Reply,I2C_Reply_Length);
if (nI2CStatus[I2C_Port] != NO_ERR)
{
I2C_Error++;
return(false);
}
break;
}
wait1Msec(nDelay);
return(true);
}

//* ********************************************************** *
//* *
//* ********************************************************** *
task HT_COMPASS()
{
byte I2C_Bus_Addr = 0x02;
int Heading_Data_Tmp = 0;

ubyte I2C_Reply_Msg_LSB_MSB[6];

ubyte I2C_Reply_Software_Version[8];
ubyte I2C_Reply_Vendor_ID[8];
ubyte I2C_Reply_Sensor_Module_Type[8];

nSchedulePriority = kDefaultTaskPriority;
SensorType[HT_COMPASS_I2C_Port] = sensorI2CCustomFast;
SensorSubType[HT_COMPASS_I2C_Port] = subTypeHiTechnicCompass;
SensorMode[HT_COMPASS_I2C_Port] = modeRaw;
I2C_Convers(HT_COMPASS_I2C_Port,I2C_Bus_Addr ,(const byte)0x00,I2C_Reply_Software_Version,8,50);
I2C_Convers(HT_COMPASS_I2C_Port,I2C_Bus_Addr ,(const byte)0x08,I2C_Reply_Vendor_ID,8,50);
I2C_Convers(HT_COMPASS_I2C_Port,I2C_Bus_Addr ,(const byte)0x10,I2C_Reply_Sensor_Module_Type,8,50);
I2C_Convers_Data(HT_COMPASS_I2C_Port,I2C_Bus_Addr ,(const byte)0x41,I2C_Reply_Msg_LSB_MSB,1,0x00,50);
while (bHT_COMPASS) {
if (!I2C_Convers(HT_COMPASS_I2C_Port,I2C_Bus_Addr ,(const byte)0x44,I2C_Reply_Msg_LSB_MSB,2,0)) continue;
Heading_Data_Tmp = ((uword)((0xFF & I2C_Reply_Msg_LSB_MSB[1]) << 8) + (uword) (0xFF & I2C_Reply_Msg_LSB_MSB[0]));
HT_COMPASS_Heading_Data = Heading_Data_Tmp;
SensorValue[HT_COMPASS_I2C_Port] = Heading_Data_Tmp;
wait1Msec(4);
}
return;
}

_________________
SuntzuMaster- a French gentlemen in USA.


Wed May 23, 2007 8:11 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
be carefull the 8) is in fact << 8 )

_________________
SuntzuMaster- a French gentlemen in USA.


Wed May 23, 2007 8:14 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
I tried your suggestion, and since I couldn't easily integrate it into the other programs I'm working on, I took a closer look at the numbers I was getting - recording exactly where things went crazy. Oddly enough the raw data was jumping from 127 to -128. This caused a signed byte problem pop up as the best suspect.

As it turns out, there was a problem in the original file, "NXT Compass Sensor Driver.c," that in this line here:
Quote:
SensorValue[nDDPortIndex] = nReplyBytes[1] * 256 + (uword) nReplyBytes[0];

it had extended the sign of the byte so as to throw everything into the negatives. To fix this, the program has to do as little type casting as it can when working with the individual bytes. In the end, the above line needs to be replaced with something more like this:
Quote:
int loOrder = nReplyBytes[0];
loOrder &= 0xff;
int hiOrder = nReplyBytes[1];
hiOrder &= 0xff;
hiOrder <<= 8;
SensorValue[nDDPortIndex] = hiOrder | loOrder;

By dealing only in ints, it avoids the nasty C sign extensions that were causing everything to go crazy.

There's still the problem that a 90 degree turn clockwise from North displays on the compass as 50 degrees, and a 90 degree turn clockwise from South displays as something more like 110 degrees, but there may be interference from all the computers here in the lab.

Thanks for helping, this stuff sure is confusing.

:) -- Mandy


Thu May 24, 2007 11:26 am
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
Good!

I do not have the issue that you are experimenting with the compass data. based on my current experiment the timing that is used to poll the sensor could play a big role... I really encourage you if that is not yet done to compile my code and to test it on your lab... Then you could check if you have with my code the same kind of issue when the compass is moving from position to another.

let me know.

PS: my program display on the NXT screen the current compass data
0->359 Deg.

_________________
SuntzuMaster- a French gentlemen in USA.


Thu May 24, 2007 12:01 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
It certainly works, and it makes the same little error in the exact headings. I just couldn't use it with the other code I have. To edit it to make it work with the rest of the project would have been as much work as staring at hex most of the morning was. But thanks anyway!

:) -- Mandy


Thu May 24, 2007 12:09 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
Just in case did you put the compass sensor at...at least 15 cm from the brick and motors? and does the compass sensor leveled ?

jm.

_________________
SuntzuMaster- a French gentlemen in USA.


Thu May 24, 2007 1:02 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
It's as far away from anything as I could get it. It's sitting level on the table, and is the length of the longest wire in the kit away from the rest of the robot. I know that I'll have to attach it now that I'm pretty sure it's working, but till the attachment's built I've just been testing it free of the robot. With the robot not spinning in circles it's easier to see the screen and keep the USB untangled.

--Mandy


Thu May 24, 2007 1:55 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
What is the interval used by the compass driver to poll the H/W and what is the interval that you have in your program to poll the compass driver?

jm

_________________
SuntzuMaster- a French gentlemen in USA.


Thu May 24, 2007 2:29 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
By the way deos your compass calibrated for your lab environment?

_________________
SuntzuMaster- a French gentlemen in USA.


Thu May 24, 2007 2:32 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
Probably not. I don't know how to make it do that with RobotC, and we don't have the fancy graphical software that HiTechnic's instructions to do so are for.

Is there a way to get it to calibrate in RobotC?

-Mandy


Thu May 24, 2007 2:50 pm
Profile
Rookie

Joined: Sun Apr 15, 2007 8:33 am
Posts: 40
Location: USA
Post 
Do you have the NXT-G if yes then download the Compass NXT-G block from HT and then it is really easy to create a small program to do that using the NXT-G...

I know how to do that with ROBOTC but there is a need to add some I2C calls to make it works... I shall try that tonight and if I come with something that I like I shall share it with you.

jm.

_________________
SuntzuMaster- a French gentlemen in USA.


Thu May 24, 2007 2:55 pm
Profile
Rookie

Joined: Mon May 21, 2007 11:48 am
Posts: 13
Location: Windows machine in a Linux lab
Post 
I do not have NXT-G, and I've not been able to get Lejos to work on this computer. I wanted to see if maybe it has a calibrate method for the compass somewhere that would allow it to remember its settings when I switched back to RobotC. This is only my second week working with the robot, so I may not know much about how to do some things that other people who either have the fancy graphics based programming software or have been working with the NXT for a long time might take for granted.

I'm doing my best with what I've got. If I can't calibrate the sensor I'll just make do with knowing that it's not going to be perfect every time.

-Mandy


Thu May 24, 2007 3:13 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 21 posts ]  Go to page 1, 2  Next

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.