Hey guys,
So I’m working on a compass sensor HMC6352 and lpc1769 with I2C protocol. The compass sensor suppose to give new heading every time I move its position, but I only get ‘0’ as the printf reading.
I’m totally new to I2c, so your guidance is really appreciated. I also have done my homework on this, here’s some extra detail if you decided to help me:
• As given in data sheet (pg.3) The compass sensor address (slave address) is 0x42 (read) / 0x43 (write). So, the 7bit address (before shifting and OR-ing) that i sent is 0x21 to either I2C_READ or I2C_WRITE
• The slave register address is 0x41 (data sheet pg. 5, table 1 – command ‘A’)
• I’m using SDA2 (P0.10) and SCL2 (p0.11) - I’m using lpc1769
• The code use 6000u sec delay as suggested (data sheet pg.8 table 3)
• Clock is 100kHz
• I connect 15kohm resistor between SCAL and SDA line to 5v. (10k is recommended for 3.3v. However 5v is still within the acceptable range. I’ve tried 2k, 10k, and 15k, but all give the same result)
So here’s the datasheet for reference https://www.sparkfun.com/datasheets/Com … MC6352.pdf.
And here’s the code
#include "lpc17xx_pinsel.h"
#include "lpc17xx_i2c.h"
#include "lpc17xx_timer.h"
#include "stdio.h"
#define I2CDEV LPC_I2C2
static const int READ_WRITE_OPERATION = 0x21;
static const int COMMAND_GET_DATA = 0x41;
void readFromCompassHMC6352(void);
static int I2CRead(uint8_t addr, uint8_t* buf, uint32_t len);
static int I2CWrite(uint8_t addr, uint8_t* buf, uint32_t len);
static int I2CRead(uint8_t addr, uint8_t* buf, uint32_t len)
{
I2C_M_SETUP_Type rxsetup;
rxsetup.sl_addr7bit = addr;
rxsetup.tx_data = NULL; // Get address to read at writing address
rxsetup.tx_length = 0;
rxsetup.rx_data = buf;
rxsetup.rx_length = len;
rxsetup.retransmissions_max = 3;
if (I2C_MasterTransferData(I2CDEV, &rxsetup, I2C_TRANSFER_POLLING) == SUCCESS){
return (0);
} else {
return (-1);
}
}
static int I2CWrite(uint8_t addr, uint8_t* buf, uint32_t len)
{
I2C_M_SETUP_Type txsetup;
txsetup.sl_addr7bit = addr;
txsetup.tx_data = buf;
txsetup.tx_length = len;
txsetup.rx_data = NULL;
txsetup.rx_length = 0;
txsetup.retransmissions_max = 3;
if (I2C_MasterTransferData(I2CDEV, &txsetup, I2C_TRANSFER_POLLING) == SUCCESS){
return (0);
} else {
return (-1);
}
}
void readFromCompassHMC6352(void)
{
int value = -1;
uint8_t data[2]={0,0};
while(1) {
// Send a "Get Data" command to the compass
data[0]= COMMAND_GET_DATA;
I2CWrite(READ_WRITE_OPERATION, data, 2);
// datasheet suggests to wait at least 6000 microseconds
Timer0_Wait(6);
// Read two bytes from the compass (compass heading)
data[0] = 1;
I2CRead(READ_WRITE_OPERATION, data, 2);
value = ((data[0] << 8 )+data[1]) / 10;
// read compass twice to clear last reading
Timer0_Wait(6);
data[0] = 0;
I2CRead(READ_WRITE_OPERATION,data, 2);
//Display the value on the display
if(value >= 0 && value <= 359) {
//Display degree value
printf("The angle is %d\n",value);
}
Timer0_Wait(60);
}
}
static void init_i2c(void)
{
PINSEL_CFG_Type PinCfg;
/* Initialize I2C2 pin connect
* P0.10 - I2C_SDA(Serial Data)
* P0.11 - I2C_SCL(Serial Clock line)
* */
PinCfg.Funcnum = 2;
PinCfg.Pinnum = 10;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 11;
PINSEL_ConfigPin(&PinCfg);
// Initialize I2C peripheral
I2C_Init(LPC_I2C2, 100000);
/* Enable I2C2 operation */
I2C_Cmd(LPC_I2C2, ENABLE);
}
int main(void)
{
init_i2c();
Timer0_Wait(1);
readFromCompassHMC6352();
return 1;
}
I’m pretty sure that there is a small mistake that I don’t notice somewhere in the code. Pleeeaseeeeeeee help… Thanks in advanced people!!!
edit - I have checked it with oscilloscope. All the address are sent correctly, however no data is received. Start, Stop, ACK bit are all present.
This is the order of the data that I see btw,
-
0x42 -I2CWRITE
-
0X41 - slave register address
-
0x43- I2CREAD
-
nothing - supposed to be the data from the sensor to LPC board.
Regards,
Francis