|
|
View previous topic :: View next topic |
Author |
Message |
joint931
Joined: 03 May 2011 Posts: 3
|
LSM303DLH + PIC18F2550 |
Posted: Tue May 03, 2011 12:49 am |
|
|
I have a sensor accelerometer/magnetometer LSM303DLH (slave) linked in I2C to a pic18F2550(master).
Code: | #include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)
#use i2c(Master, SDA=PIN_B0, SCL=PIN_B1)
...
//Initialization code
//enable accelerometer
i2c_start();
i2c_write(0x30); // write acc
i2c_write(0x20); // CTRL_REG1_A
i2c_write(0x27); // normal power mode, 50 Hz data rate, all axes enabled
i2c_stop();
//enable magnetometer
i2c_start();
i2c_write(0x3C); // write mag
i2c_write(0x02); // MR_REG_M
i2c_write(0x00); // continuous conversion mode
i2c_stop();
...
// read magnetometer values
i2c_start();
i2c_write(0x3C); // write mag
i2c_write(0x03); // OUTXH_M
i2c_start(); // repeated start
i2c_write(0x3D); // read mag
ACC_Data[0] = i2c_read(0x03);//read OUT_X_L_A (MSB)
ACC_Data[1] = i2c_read(0x04);//read OUT_X_H_A (LSB)
ACC_Data[2] = i2c_read(0x05);//read OUT_Y_L_A (MSB)
ACC_Data[3] = i2c_read(0x06);//read OUT_Y_H_A (LSB)
ACC_Data[4] = i2c_read(0x07);//read OUT_Z_L_A (MSB)
ACC_Data[5] = i2c_read(0x08);//read OUT_Z_H_A (LSB)
i2c_stop(); |
I see on the scope that initialized as well, but ACC_Data[0]..[5] values always 255.
Does anyone know how to solve this problem? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue May 03, 2011 2:43 am |
|
|
I2C_Read, just _reads_. The only value it accepts, is a one bit flag to control ACK/NACK.
The I2C bus, only works in one direction at a time. You can't send values with the I2C_read command.
This is the whole point of repeated starts. You set the chip to 'read', send it the address you want to talk to, then turn the bus round, to read from the chip. You can't send address bytes at the same time as you read the data.
Slave devices, depending on what they do, either repeatedly return the data from a single address (when they are something like an 8bit ADC), or _automatically_ advance the address being read with each successive read.
Your device does this:
"To minimize the communication between the master and magnetic digital interface of the LSM303DLH, the address pointer is updated automatically without master intervention."
Now, OUT_X_L_A, is register 28.
OUT_X_H_M is register 3.
Your 'comments' on the reads, appear to be referring to the wrong registers.
So the sequence to read the values from the magnetometer interface, is:
Code: |
i2c_start();
i2c_write(0x3C); // write mag
i2c_write(0x3); // Select register OUT_X_L_M
i2c_start(); // repeated start
i2c_write(0x3D); // read mag
ACC_Data[0] = i2c_read();//read OUT_X_H_M (MSB)
ACC_Data[1] = i2c_read();//read OUT_X_L_M (LSB)
ACC_Data[2] = i2c_read();//read OUT_Y_H_M (MSB)
ACC_Data[3] = i2c_read();//read OUT_Y_L_M (LSB)
ACC_Data[4] = i2c_read();//read OUT_Z_H_M (MSB)
ACC_Data[5] = i2c_read(0);//read OUT_Z_L_M (LSB) NACK
i2c_stop();
|
Now some further comments:
1) have you got the pull-up resistors?. Though the chip has small ones internally, external ones are required.
2) Are you running the PIC off 3.3v?. The 18F4550, operates to 4.2v minimum. The chip you are trying to talk to operates to 3.3v _max_. The PIC18LF4550, will go down to 3.3v operation, but you show fuses as if you are intending to use USB, and if so, you will need to provide Vusb yourself, since the chip is not capable of providing the Vusb, when running off 3.3v.
Haven't looked at the rest of your code...
Best Wishes |
|
|
joint931
Joined: 03 May 2011 Posts: 3
|
Re: LSM303DLH + PIC18F2550 |
Posted: Thu May 05, 2011 3:39 am |
|
|
to Ttelmah:
1. Yes, I have a pull-up resistors (10kOhm) (LSM303DLH electrical connection 1 - recommended for I2C fast mode - page 20 from LSM303DLH documentation)
2. I have connected the pic18f2550 on my 5V power supply, on LSM303DLH 3.3V power supply.
Code read magnetometer values has been rewriten (for sample Ttelmah) but ACC_Data[0]..[5] values also always 255.
Сan some one help me where I am making mistake? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
|
joint931
Joined: 03 May 2011 Posts: 3
|
|
Posted: Wed May 11, 2011 12:47 pm |
|
|
Make a I2C level translator between the units, but get the same error (( Maybe a problem in the code:
Code: | #include <18F2550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)
#use i2c(Master, SDA=PIN_B0, SCL=PIN_B1)
#define USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 64
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_RX_SIZE 64
#include <pic18_usb.h>
#include <desc.h>
#include <usb.c>
#include <LSM303.c>
void main() {
int8 in_data[8];
int8 out_data[8];
int16 adc_var;
unsigned char ACC_Data[6];
SETUP_ADC_PORTS(AN0);
SETUP_ADC(ADC_CLOCK_DIV_64);
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_1);
SETUP_TIMER_1(T1_DISABLED);
SETUP_TIMER_2(T2_DISABLED, 127, 1);
SETUP_TIMER_3(T3_INTERNAL | T3_DIV_BY_8);
SETUP_CCP1(CCP_OFF);
SETUP_CCP2(CCP_OFF);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
usb_init();
while (TRUE) {
usb_task();
if (usb_enumerated()) {
if (usb_kbhit(1)) {
usb_get_packet(1, in_data, 64);
out_data[0] = 0;
set_adc_channel(0);
delay_us(30);
mm1=READ_ADC();
out_data[1] = adc_var;
out_data[2] = adc_var>>8;
LSM303Init();
i2c_start();
i2c_write(MAG_ADDRESS); // write mag
i2c_write(OUT_X_H_M); // Select register OUT_X_L_M
i2c_start(); // repeated start
i2c_write(0x3D); // read mag
/*
For magnetic sensor, the default (factory) 7-bit slave address is 0011110b
(0x3C) for write operations, or 00111101b (0x3D) for read operations.
*/
ACC_Data[0] = i2c_read();//read OUT_X_H_M (MSB)
ACC_Data[1] = i2c_read();//read OUT_X_L_M (LSB)
ACC_Data[2] = i2c_read();//read OUT_Y_H_M (MSB)
ACC_Data[3] = i2c_read();//read OUT_Y_L_M (LSB)
ACC_Data[4] = i2c_read();//read OUT_Z_H_M (MSB)
ACC_Data[5] = i2c_read(0);//read OUT_Z_L_M (LSB) NACK
i2c_stop();
out_data[3] = ACC_Data[1];
out_data[4] = ACC_Data[2];
out_data[5] = ACC_Data[3];
out_data[6] = ACC_Data[4];
out_data[7] = ACC_Data[5];
usb_put_packet(1, out_data, 64, USB_DTS_TOGGLE);
}
}
}
} |
initialization:
Code: | #ifndef LSM303
#define LSM303
//////////////////////////////////////
#define ACC_ADDRESS (0x30)
#define MAG_ADDRESS (0x3C)
#define CTRL_REG1_A (0x20)
#define CTRL_REG2_A (0x21)
#define CTRL_REG3_A (0x22)
#define CTRL_REG4_A (0x23)
#define CTRL_REG5_A (0x24)
#define HP_FILTER_RESET_A (0x25)
#define REFERENCE_A (0x26)
#define STATUS_REG_A (0x27)
#define OUT_X_L_A (0x28)
#define OUT_X_H_A (0x29)
#define OUT_Y_L_A (0x2A)
#define OUT_Y_H_A (0x2B)
#define OUT_Z_L_A (0x2C)
#define OUT_Z_H_A (0x2D)
#define INT1_CFG_A (0x30)
#define INT1_SOURCE_A (0x31)
#define INT1_THS_A (0x32)
#define INT1_DURATION_A (0x33)
#define INT2_CFG_A (0x34)
#define INT2_SOURCE_A (0x35)
#define INT2_THS_A (0x36)
#define INT2_DURATION_A (0x37)
#define CRA_REG_M (0x00)
#define CRB_REG_M (0x01)
#define MR_REG_M (0x02)
#define OUT_X_H_M (0x03)
#define OUT_X_L_M (0x04)
#define OUT_Y_H_M (0x05)
#define OUT_Y_L_M (0x06)
#define OUT_Z_H_M (0x07)
#define OUT_Z_L_M (0x08)
#define SR_REG_M (0x09)
#define IRA_REG_M (0x0A)
#define IRB_REG_M (0x0B)
#define IRC_REG_M (0x0C)
//////////////////////////////////////
void LSM303Init()
{
i2c_start();
i2c_write(ACC_ADDRESS);
i2c_write(CTRL_REG1_A);
i2c_write(0x27);
i2c_stop();
i2c_start();
i2c_write(MAG_ADDRESS);
i2c_write(MR_REG_M);
i2c_write(0x00);
i2c_stop();
}
#endif |
USB and ADC working perfectly, but ACC_Data[0]..[5] values also always 255 (( |
|
|
greenfalsk
Joined: 12 May 2011 Posts: 2
|
|
Posted: Thu May 12, 2011 10:40 pm |
|
|
left convert a ccs:
Code: | unsigned char temp, MR_Data[6];
int Mx, My, Mz;
void main(void)
{
Write(0x1E, 0x00, 0x14);//set CRA_REG_M register
Write(0x1E, 0x02, 0x00);//set MR_REG_M register
While (1)
{
Temp = Read(0x1E, 0x02); //read MR_REG_M
MR_Data[0] = ReadCurrentAddress(); //read OUT_X_H_M (MSB)
MR_Data[1] = ReadCurrentAddress(); //read OUT_X_L_M (LSB)
MR_Data[2] = ReadCurrentAddress(); //read OUT_Y_H_M (MSB)
MR_Data[3] = ReadCurrentAddress(); //read OUT_Y_L_M (LSB)
MR_Data[4] = ReadCurrentAddress();//read OUT_Z_H_M (MSB)
MR_Data[5] = ReadCurrentAddress(); //read OUT_Z_L_M (LSB)
Mx = (int) (MR_Data[0] << 8) + MR_Data[1];
My = (int) (MR_Data[2] << 8) + MR_Data[3];
Mz = (int) (MR_Data[4] << 8) + MR_Data[5];
}
} |
|
|
|
Marqueses
Joined: 30 Nov 2011 Posts: 6
|
|
Posted: Wed Nov 30, 2011 6:25 am |
|
|
Hello joint931,
i wonder if you solve your problem. I want to work with this IC and I hope don´t find this problem.
Thanks. |
|
|
halilcakmak34
Joined: 07 May 2012 Posts: 2
|
|
Posted: Mon May 07, 2012 2:51 pm |
|
|
Merhaba joint931;
Benim bu kullandığınız( sanırım LSM303 (IMU9)) accelerometre çeşidinden pic kullanarak değerleri almam lazım rica etsem bana yardımcı olabilir misiniz? Bitirme projesi olarak alıyorum ve çok az bir zamanım kaldı yardımcı olursanız gerçekten çok sevinirim. |
|
|
halilcakmak34
Joined: 07 May 2012 Posts: 2
|
|
Posted: Mon May 07, 2012 2:59 pm |
|
|
halilcakmak34 wrote: | Merhaba joint931;
Benim bu kullandığınız( sanırım LSM303 (IMU9)) accelerometre çeşidinden pic kullanarak değerleri almam lazım rica etsem bana yardımcı olabilir misiniz? Bitirme projesi olarak alıyorum ve çok az bir zamanım kaldı yardımcı olursanız gerçekten çok sevinirim. |
I am sorry. I don't know English. I am from Turkey, my department is computer engineer(4.class). Please, can you send me this project code. I will do as a final project. Really, I have very little time. Thank you very much for taking the time. |
|
|
vrs
Joined: 30 Apr 2013 Posts: 18
|
|
Posted: Wed May 08, 2013 3:02 am |
|
|
http://www.ccsinfo.com/forum/viewtopic.php?t=50012&highlight=minimu9
VALLA GARDAŞ BEN DEĞEERLERİ ALDIM BURALARA YAZDIM AMA DOĞRU DEĞERLERİ ALAMADIM.
++++++++++++++++++++++++++++
Locked.
Reason: Do not post links to old threads.
Do not post in Turkish. Use English.
- Forum Moderator
++++++++++++++++++++++++++++ |
|
|
|
|
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
|