CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

LSM303DLH + PIC18F2550

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
joint931



Joined: 03 May 2011
Posts: 3

View user's profile Send private message

LSM303DLH + PIC18F2550
PostPosted: Tue May 03, 2011 12:49 am     Reply with quote

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: 19535

View user's profile Send private message

PostPosted: Tue May 03, 2011 2:43 am     Reply with quote

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

View user's profile Send private message

Re: LSM303DLH + PIC18F2550
PostPosted: Thu May 05, 2011 3:39 am     Reply with quote

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: 19535

View user's profile Send private message

PostPosted: Thu May 05, 2011 4:35 am     Reply with quote

You can't directly connect a chip supporting 3.3v I2C, to a PIC at 5v....
You are going to need an I2C level translator between the units.
For a discrete one:
http://www.kip.uni-heidelberg.de/lhcb/Publications/external/AN97055.pdf
Or (has a link to a Nxp page with a similar design):
http://www.edaboard.com/thread171379.html
Several of the I2C buffer chips also support different voltages on the two sides.

Best Wishes
joint931



Joined: 03 May 2011
Posts: 3

View user's profile Send private message

PostPosted: Wed May 11, 2011 12:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 12, 2011 10:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 30, 2011 6:25 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 07, 2012 2:51 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 07, 2012 2:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 08, 2013 3:02 am     Reply with quote

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
++++++++++++++++++++++++++++
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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