|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 13, 2007 12:23 pm |
|
|
You're repeating the same mistakes that have already been discussed
in this thread. You need to read the thread and study each little detail.
For example, what parameter is missing from the line shown in bold
below ?
Quote: |
void getHeading(){
disable_interrupts(global);
i2c_start();
i2c_write(COMP_W_ADDY);
i2c_write(GET_DATA_CMD);
i2c_stop();
delay_ms(6);
i2c_start();
i2c_write(COMP_R_ADDY);
msb = i2c_read();
lsb = i2c_read();
i2c_stop();
heading = ((int16)lsb | ((int16)msb << 8));
enable_interrupts(global);
}
|
|
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Tue Sep 25, 2007 12:56 pm |
|
|
Hi, I'm having trouble implementing this device. I am using a PIC18F4680 chip with the breakout board from Sparkfun. I tried using the exact code as posted in the 1 st page of this thread. I even tried making slight modifications to the code, such as outputting "msb", "lsb", and "heading" to double check that I'm getting anything, and I'm having no luck. I even switched the order of this OR statement, as someone else had previously mentioned:
Code: | heading = ((int16)lsb | ((int16)msb << 8)); |
I made sure to use resistors from SDA/SCL to high. I've messed with various values (10k, 5k, 1k...) and nothing. Do I have to configure the SDA/SCL pins as input/output using the TRIS command? Or am I missing something? Is there a way to "debug" the device? Anyone that has experience with this device could you please help. Thanks in advance! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 25, 2007 1:52 pm |
|
|
1. Post your CCS compiler version. This is a number such as 3.249,
or 4.013, or 4.056, etc. It's given at the top of the .LST file for
your project. The .LST file is in the project directory.
2. Post the code that you're using. The code on the 1st page is short,
and won't take up a lot of space if you post your slightly modified
version of it. The reason for you to post it is so we can look at your
fuse settings and anything else that might cause a problem with the
18F4680.
3. Post a detailed list of the connections between the PIC and the
HMC unit. Be sure to post the power and ground connections.
4. Have you ever made this PIC board do anything ? In other words,
can you make it blink an LED ?
5. This person has successfully used the code. Look at this page:
http://www.charlie-roberts.com/blindshot/blindshot.c |
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Tue Sep 25, 2007 2:15 pm |
|
|
1. 3.222
2. Code: |
// Compass Test
// 9/20/07
#include <18F4680.H>
#fuses XT,NOPROTECT,NOBROWNOUT,NOWDT,NOLVP,PUT
#use delay(clock=4000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3,Force_HW)
#include <stdlib.h>
#include "dxLCD.c" // my LCD driver
char myText[82];
void main()
{
int heading1 = 0;
int heading2 = 0;
long answer;
sprintf(myText, "\fCompass test:");
lcd_print(myText);
delay_ms(1000);
while(1)
{
i2c_start();
i2c_write(0x42); //slave address of HMC6352
i2c_write(0x41); //have also tried i2c_write('A');
i2c_stop();
delay_ms(6); //requires 6mS before data is ready to be read
i2c_start();
i2c_write(0x43); // READ
heading1 = i2c_read();
heading2 = i2c_read(0);
i2c_stop();
answer = (int16)msb | ((int16)lsb << 8);
sprintf(myText, "%d, %d, %ld", heading1, heading2, answer);
lcd_printat(1,3,myText);
delay_ms(3000);
}
}
|
3. I'm using the breakout board from sparkfun.com, which has only 4 pins. I have GND and 3.3 connected to ground and 3.3V. I have SDA connected to pin C4 with a 10k resistor connected from the same pin to 3.3V high. I also have SCL connected to pin C3 , with a 10k resistor pulling it to high as well. I have tried with several values, as was recommened from other sites (5k, 1k, etc...) but the datasheet says 10k should work.
4. Yes, this is the same PIC board that I use for all my prototyping. After being tired of troubleshooting the compass, I re-programmed the PIC with another code and it worked without a problem.
5. I have seen his code and have tried modeling mine after that (I think he got his code from you ).
I read somewhere that maybe I could have accidently changed the slave address of the device (0x42). If that's the case, is there a way to restore the default slave address to its original value? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 25, 2007 4:16 pm |
|
|
What's the Vdd voltage for the PIC ? Is it 5v or 3.3v ? |
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Tue Sep 25, 2007 5:38 pm |
|
|
the pic is 5V |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 25, 2007 5:53 pm |
|
|
That's probably why it doesn't work. Pins C3 and C4 have Schmitt
trigger CMOS inputs. The PIC data sheet says the high level input
voltage is 0.8 x Vdd for those pins. That's 4 volts. You have +3.3v
on the i2c bus pull-ups. They'll never get up to 4 volts.
There are a few ways to fix this problem. The two easiest ways are:
1. Change the voltage for the compass and the pull-ups voltage to +5v.
According to the HMC6352 data sheet, it can run at 5v:
Quote: | Low Voltage Operation (2.7 to 5.2V) |
http://www.ssec.honeywell.com/magnetic/datasheets/HMC6352.pdf
The circuit board from Sparkfun says 3.3v on it. But on the webpage
link that you posted, Sparkfun says this:
Quote: | Features:
Simple I2C interface
2.7 to 5.2V supply range |
So, you should be able to change the compass board and the pull-ups
to +5v operation, unless there is some other limitation that I don't
know about.
2. You could move the i2c bus to some other pins that have TTL levels.
Most pins on Port A and Port B have TTL levels. This means the
logic high level is only 2.0 volts. The 3.3v pullups will easily work
with TTL input pins on the PIC. However, you would have to use
the software i2c CCS library code. You can't use FORCE_HW on
pins other than C3 and C4.
But there's probably no real reason why you need to use hardware i2c. |
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Tue Sep 25, 2007 6:25 pm |
|
|
okay, so for some reason after uploading the following code into the pic, I started getting some response:
Code: |
#include <18F4680.H>
#fuses XT,NOPROTECT,NOBROWNOUT,NOWDT,NOLVP,PUT
#use delay(clock=4000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#include <stdlib.h>
#include "dxLCD.c" //my LCD driver
#define HMC6352_I2C_WRITE_ADDRESS 0x42
#define HMC6352_I2C_READ_ADDRESS 0x43
#define HMC6352_GET_DATA_COMMAND 0x41
char myText[82];
// Read the compass heading. This is in units
// of 1/10's of a degree, from 0 to 3599.
int16 HMC6352_read_heading(void)
{
int8 lsb;
int8 msb;
i2c_start();
i2c_write(HMC6352_I2C_WRITE_ADDRESS);
i2c_write(HMC6352_GET_DATA_COMMAND);
i2c_stop();
delay_ms(7); // Allow 1 ms extra for safety
i2c_start();
i2c_write(HMC6352_I2C_READ_ADDRESS);
msb = i2c_read();
lsb = i2c_read(0);
i2c_stop();
//return((int16)msb | ((int16)lsb << 8));
return((int16)lsb | ((int16)msb << 8));
}
//===================================
void main()
{
int16 heading;
while(1)
{
heading = HMC6352_read_heading();
sprintf(myText,"Degrees = %lu\r", heading/10);
lcd_printat(1,3,myText);
delay_ms(1000);
}
}
|
However, for the output, im getting a messed up reading. It reads from 100-999, when it should be reading from 1-360, but reading is not spread out. When I rotate the board around counterclockwise, it'll read from like 180 to 100 in steps of 5 or 10. Real smooth. but once it hits 100, it goes to 999 (or close to) and starts decrementing in steps of 100, while I'm still rotating it slowly. When it reaches the 360 area, it'll decrement slow again. So I'm not sure what this reading is telling me.
I tried your other methods too. Changing the voltage for the chip and the SDL/SCL highs to 5V made no difference for the output readings. And your other recommendation was spitting out wrong readings as well, sometimes locking up. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 25, 2007 7:03 pm |
|
|
What code does the lcd_printat() routine have in it ?
Are you clearing the existing text off the LCD line before you
write new text on it ?
Are you sending the "clear screen" command to the LCD ?
Currently, your sprintf() statement does not have any "white space"
after the numbers field.
Suppose you display 3 digits, such as:
Then you display two digits, such as:
Now, if you don't ensure that all the digits in "360" are cleared away
before you write the new digits, you will get this:
|
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Wed Sep 26, 2007 6:02 pm |
|
|
my lcd_printat() is the same as my lcd_print() function, exact it prints the text at a particular line. I should use lcd_print instead. I like your point about clear the screen and/or line. I remember it doing that in another function I was working with, when printing from 3 digit characters to 1 and 2 digit characters . I'll implement that into my code tomorrow and cross my fingers. |
|
|
axmanjr
Joined: 07 Aug 2007 Posts: 25 Location: Las Vegas, NV
|
|
Posted: Sat Nov 10, 2007 2:15 pm |
|
|
I don't mean to revive old threads but I have another question concerning the HMC6352.
How would I go about recalibrating the device? I read in the datasheet that you can calibrate it and I think that I may have to do this. The response that I have been receiving from it lately seem to be incorrect. It doesn't give me a full 360 degree reading. It's more like 140 degrees. When I rotate the device around it'll range from (estimate values) 150 to 290 degrees and when it reaches the min/max value, it'll reverse the value (meaning, when it reaches 290 while still rotating, it'll start going backwards down to 150 again).
Here's the familiar code that I'm using:
Code: | // Compass Test
// 9/27/07
#include <18F4680.H>
#fuses XT,NOPROTECT,NOBROWNOUT,NOWDT,NOLVP,PUT
#use delay(clock=4000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#include <stdio.h>
#include <stdlib.h>
#include "myGLCD.c"
#define HMC6352_I2C_WRITE_ADDRESS 0x42
#define HMC6352_I2C_READ_ADDRESS 0x43
#define HMC6352_GET_DATA_COMMAND 0x41
char myText[82];
// Read the compass heading. This is in units
// of 1/10's of a degree, from 0 to 3599.
void main()
{
int lsb;
int msb;
long heading;
while(1) {
i2c_start();
i2c_write(0x42);
i2c_write(0x41);
i2c_stop();
delay_ms(7); // Allow 1 ms extra for safety
i2c_start();
i2c_write(0x43);
msb = i2c_read();
lsb = i2c_read(0);
i2c_stop();
heading = ((long)lsb | ((long)msb << 8))/10;
sprintf(myText,"\fDegrees = %lu ", heading);
lcd_print(myText);
delay_ms(1000);
}
} |
Any help would be appreciated. Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 11, 2007 1:58 am |
|
|
My help would be to Google it.
Quote: | HMC6352 calibration CCS |
The first hit is a thread on the Sparkfun forum and it has all the
routines you need, down at the end of the thread. The data sheet
describes what you need to do, while in calibration mode. |
|
|
Guest
|
|
Posted: Wed Jul 22, 2009 5:21 pm |
|
|
I've been trying to calibrate the HMC6352. But I have no idea how do that. My default address is 0x21, so I do this: i2cwrite(0x42,0x43), cause: 0x42=0x21+'0' to write and 0x43='C'=calibration mode...but I have no response. Any idea?
Help would be appreciated.
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 22, 2009 5:46 pm |
|
|
Do a Google search for this. Find other forums where they've already
done it:
For example, there's some CCS code at the end of this thread. I don't
know if it works, but you can try it.
http://forum.sparkfun.com/viewtopic.php?p=28630
You can look at other hits from that search. Look at the compass.c
code that you can download from this page. It has a calibrate routine.
http://www.freelists.org/post/sharpclub/hmc6352-compass,4
In other words, if this forum doesn't have the information, probably
some other forum will. Use Google to find it. |
|
|
Guest
|
|
Posted: Thu Jul 23, 2009 6:15 am |
|
|
Thanks for the quick answer, but I've already google a lot trying to find a solution....and still doesn't work.
Thanks. |
|
|
|
|
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
|