3-Axis Accelerometer (LIS302DL)


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191

    Post 3-Axis Accelerometer (LIS302DL)

    Hi,

    I have been playing with ST's LIS302DL 3-axis accelerometer, which is quite nice IC. It uses I2C bus and device has 2 independed programmable interrupts. I'm using it only for motion detection (alarm) at the moment, but there are huge possibilities with the device (mainly due to my limited coding skills, but learning all the time)

    Here is piece of my code with comments. I hope somebody find it usefull.
    Code:
    '-------------------------------------------------------------------------------
    ' 3D Accelerometer
    '-------------------------------------------------------------------------------
    Accelerometer_Init:
                                'Command    SAD[6:1]    SAD[0] = SDO    R/W     SAD+R/W
    I2CDevice_3D_read=$39       'Read       001110      0               1       00111001 (39h)
    I2CDevice_3D_write=$38      'Write      001110      0               0       00111000 (38h)
    
    'Axes
    I2CAddress_3D = $20     'CTRL_REG1
    TEMP = %01000111        '47h -> DR=0, PD=1, FS=0, STP=00, Zen=1, Yen=1, Xen=1 (X,Y,Z enable, Output 100Hz)
    gosub I2C_Write_3D      '41h = X
    '---------------------
    
    'Filters
    I2CAddress_3D = $21     'CTRL_REG2
    TEMP = %00000111        '00h -> SIM = 0, BOOT = 0, --,  FDS = 0, HP FF_WU2 = 0, HP FF_WU1 = 1, HP coeff2 = 1, HP coeff1 = 1 (HP 0.25Hz for FF_WU1)
    gosub I2C_Write_3D
    
    '---------------------
    
    'Interrupts
    I2CAddress_3D = $22     'CTRL_REG3
    TEMP = %00000001        '01h -> IHL = 0, PP_OD = 0, I2CFG2-0 = 000, I1CFG2-0 = 001 (FF_WU 1 = INT1)
    gosub I2C_Write_3D
    
    '---------------------
    
    'Sensitivity
    I2CAddress_3D = $32     'FF_WU_THS_1
    TEMP = $02              ' 0Ah -> DCRM = 0, THS6 = 0, THS5 = 0, THS4 = 0, THS3 = 0, THS2 = 0, THS1 = 1, THS0 = 0 (~36mg wake-up threshold, ~18mg step)
    gosub I2C_Write_3D      
    
    '---------------------
    
    'Duration
    I2CAddress_3D = $33     'FF_DURATION_1
    TEMP = $0D              '05h -> D7 = 0, D6 = 0, D5 = 0, D4 = 0, D3 = 1, D2 = 1, D1 = 0, D0 = 1 (130ms, 0 - 2.55s, 10ms step)
    gosub I2C_Write_3D      '0Ah = 100ms, 0Fh = 150ms, 14h = 200ms, 28h = 400ms, 32h = 500ms,
    
    '---------------------
    
    'Wake-Up Thresholds
    I2CAddress_3D = $30     'FF_WU_GFG_1
    TEMP = %01101010        '6Ah -> AOI = 0, LIR = 1, ZHIE = 1, ZLIE = 0, YHIE = 1, YLIE = 0, XHIE = 1, XLIE = 0 (wake-up above thresholde on x,y,z)
    gosub I2C_Write_3D
    
    '---------------------
    
    'I2CAddress_3D = $36     'FF_WU_THS_2
    'TEMP = $14              '14h -> DCRM = 0, THS6 = 0, THS5 = 0, THS4 = 1, THS3 = 0, THS2 = 1, THS1 = 0, THS0 = 0 (~350mg wake-up threshold, ~18mg step)
    'gosub I2C_Write_3D
    
    ''---------------------
    'I2CAddress_3D = $37     'FF_DURATION_2
    'TEMP = $0A              '0Ah -> D7 = 0, D6 = 0, D5 = 0, D4 = 0, D3 = 1, D2 = 0, D1 = 1, D0 = 0 (100ms, 0 - 2.55sec, 10msec step)
    'gosub I2C_Write_3D
    
    ''---------------------
    
    'I2CAddress_3D = $34     'FF_WU_GFG_2
    'TEMP = $78              '78h -> AOI = 0, LIR = 1, ZHIE = 1, ZLIE = 1, YHIE = 1, YLIE = 0, XHIE = 0, XLIE = 0 (wake-up above thresholde on x,y,z)
    'gosub I2C_Write_3D
    
    '---------------------
    I2CAddress_3D = $23      'Reset acceration/tilt value. Needed if HP enable in CTRL_REG2
    gosub I2C_Read_3D
    Return
    
    '-------------------------------------------------------------------------------
    I2C_Write_3D:
    I2CWRITE SDA_3D, SCL_3D, I2CDevice_3D_write, I2CAddress_3D,[ TEMP ]
    Return
    
    I2C_Read_3D:
    I2cread SDA_3D, SCL_3D, I2CDevice_3D_read, I2CAddress_3D,[ TEMP ]
    Return
    
    '-------------------------------------------------------------------------------
    Accelerometer:
    IF Int1_3D = 1 THEN             ' Int1_3D is IO pin for Interrup coming from 3D sensor
            I2CAddress_3D = $31     ' Clear interrupt request
            gosub I2C_Read_3D
            I2CAddress_3D = $23     ' Reset acceration/tilt value after interrupt 
            gosub I2C_Read_3D
            PIR_Alarm = 1           ' This is indecator that something must be done in main program
    endif
    
    'IF Int2_3D = 1 THEN            ' For 2nd interrupt pin
    '        I2CAddress_3D = $35
    '        gosub I2C_Read_3D
    '        I2CAddress_3D = $23     
    '        gosub I2C_Read_3D
    '        PIR_Alarm = 1
    'endif
    return
    
    Accelerometer_Clear:            ' If sensor has moved during event hadling, then interrupt must be cleared once before new sequence
            I2CAddress_3D = $31
            gosub I2C_Read_3D
    Return
    '-------------------------------------------------------------------------------
    More info and datasheets can be found here: http://www.st.com/stonline/products/...6/lis302dl.htm

    BR,
    -Gusse-

  2. #2
    Join Date
    Sep 2008
    Location
    Stockholm
    Posts
    80


    Did you find this post helpful? Yes | No

    Default

    I also played around with an ST accelerometer, but I took the safe route and choosed LIS 244AL instead, with analouge outputs.

    Very easy to use when connected to ADC pins.

    ..But it sure was HELL to solder on that TINY little capsule..

    Humans isn't supposed to solder this stuff

    http://www.repulsiv.se/pics/lga16under.jpg

    (The lead in the pencil is 0.5mm)

    I destroyed the first one, but got the second one to work, after I bought some 0.2mm wire.

  3. #3
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Post

    One reason to use LIS302DL was mechanical dimensions: 0.8mm pitch and 0.5mm pad sizes and of cource this component was easily available.

    For me digital output version is much easier and more safe. Programmable HP filter and threshold trigger (for interrupt) works very well in my application.
    When accelerometer is enable (alarm mode), then most of the time PIC is sleeping and when it wake up, then INT-pin is polled.

    I was supprised how easy it was to use

    Next step is to write SW, which will use actual acceleration data capture by LIS302DL. Lets see how easy/difficult that will be...

  4. #4
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Post Acceleration data

    Here is code, which captures X and Y axis acceleration data and calculate average (over 5 samples) resultant acceleration and also maximum detected acceleration (that is also averaged).
    Code:
    Acceleratio     var word
    Acceleratio_max var word
    X_Data          var Byte
    Y_Data          var Byte
    COUNTER         VAR BYTE
    TEMP            VAR BYTE
    
    '-------------------------------------------------------------------------------
    Accelerometer_Init:
        Acceleratio = 0      
        Acceleratio_max = 0
        COUNTER = 0         
        
    'Axes
    I2CAddress_3D = $20     'CTRL_REG1
    TEMP = %01000011        'DR=0, PD=1, FS=0, STP=00, Zen=0, Yen=1, Xen=1 (X,Y enable, Output 100Hz)
    gosub I2C_Write_3D      '
    
    'Interrupts
    I2CAddress_3D = $22     'CTRL_REG3
    TEMP = %00000100        'IHL = 0, PP_OD = 0, I2CFG2-0 = 000, I1CFG2-0 = 100 (DataReady = INT1)
    gosub I2C_Write_3D
    
    Return
    
    '-------------------------------------------------------------------------------
    I2C_Write_3D:
    I2CWRITE SDA_3D, SCL_3D, I2CDevice_3D_write, I2CAddress_3D,[ TEMP ]
    Return
    
    I2C_Read_3D:
    I2cread SDA_3D, SCL_3D, I2CDevice_3D_read, I2CAddress_3D,[ TEMP ]
    Return
    
    '-------------------------------------------------------------------------------
    Acceleration_Menu:                          'Start from here
        gosub Accelerometer_Init       
        IF Int1_3D = 1 THEN                     'Int1_3D is IO pin for Interrup coming from 3D sensor, DataReady in device     
            COUNTER = COUNTER + 1
            '---------------------------
                I2CAddress_3D = $29             'Read OUTX value
                gosub I2C_Read_3D
                if TEMP > 127 then              'Two's complementary changed to amplitude information
                        X_Data = 255 - TEMP     'Acceleration data presented in two's complement
                    else      
                        X_Data = TEMP
                ENDIF
            '---------------------------
                I2CAddress_3D = $2B             'Read OUTY value 
                gosub I2C_Read_3D
                if TEMP > 127 then              'Two's complementary changed to amplitude information
                        Y_Data = 255 - TEMP     'Acceleration data presented in two's complement
                    else      
                        Y_Data = TEMP
                ENDIF
            '---------------------------
            Acceleratio = Acceleratio + (18 * SQR((X_Data * X_Data) + (Y_Data * Y_Data)))   'Average factor 5x
            '---------------------------                                                    'Calculate resultant force
                IF COUNTER = 5 then
                    COUNTER = 0
                    Acceleratio = Acceleratio/5    
                    IF Acceleratio > Acceleratio_max then
                        Acceleratio_max = Acceleratio
                    endif
                    'ADD YOUR CODE HERE TO SHOW ACCELERATIO AND ACCELERATIO_MAX ON YOUR DISPLAY
                    Acceleratio = 0
                endif
            '---------------------------
            Gosub Accelerometer_Clear
        endif
        goto Acceleration_Menu
    '-------------------------------------------------------------------------------
    Accelerometer_Clear:            'Clear interrupt
        I2CAddress_3D = $31
        gosub I2C_Read_3D
        Return
    BR,
    -Gusse-

  5. #5
    Join Date
    Sep 2008
    Location
    Stockholm
    Posts
    80


    Did you find this post helpful? Yes | No

    Default

    Looks really good, if I knowed this before I started myself I probably would have ordered a I2C version instead

    ..But I might borrow some of your code anyway

    I was thinking of using a timer and calculate speed from it, but I dont know how accurate it would be.

  6. #6
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Post Couple of corrections to code

    I noticed couple of misstakes in the code.

    One in the two's complement calculation formula. Previously posted formula gave result as: 255 = 0, 254 = (-)1, etc ... Correct formula should give 255 = (-)1, 254 = (-)2, etc ...
    Error was minor, but here is updated code (only change is 255 -> 256).

    Other in Acceleration_Menu -loop. Accelerometer_Init required only once you start.

    Code:
    Acceleratio     var word
    Acceleratio_max var word
    X_Data          var Byte
    Y_Data          var Byte
    COUNTER         VAR BYTE
    TEMP            VAR BYTE
    
    '-------------------------------------------------------------------------------
    Accelerometer_Init:
        Acceleratio = 0      
        Acceleratio_max = 0
        COUNTER = 0         
        
    'Axes
    I2CAddress_3D = $20     'CTRL_REG1
    TEMP = %01000011        'DR=0, PD=1, FS=0, STP=00, Zen=0, Yen=1, Xen=1 (X,Y enable, Output 100Hz)
    gosub I2C_Write_3D      '
    
    'Interrupts
    I2CAddress_3D = $22     'CTRL_REG3
    TEMP = %00000100        'IHL = 0, PP_OD = 0, I2CFG2-0 = 000, I1CFG2-0 = 100 (DataReady = INT1)
    gosub I2C_Write_3D
    
    Return
    
    '-------------------------------------------------------------------------------
    I2C_Write_3D:
    I2CWRITE SDA_3D, SCL_3D, I2CDevice_3D_write, I2CAddress_3D,[ TEMP ]
    Return
    
    I2C_Read_3D:
    I2cread SDA_3D, SCL_3D, I2CDevice_3D_read, I2CAddress_3D,[ TEMP ]
    Return
    
    '-------------------------------------------------------------------------------
    Acceleration_Menu:
        gosub Accelerometer_Init                'Start from here
    
    Acceleration_Loop:                                 
        IF Int1_3D = 1 THEN                     'Int1_3D is IO pin for Interrup coming from 3D sensor, DataReady in device     
            COUNTER = COUNTER + 1
            '---------------------------
                I2CAddress_3D = $29             'Read OUTX value
                gosub I2C_Read_3D
                if TEMP > 127 then              'Two's complementary changed to amplitude information
                        X_Data = 256 - TEMP     'Acceleration data presented in two's complement
                    else      
                        X_Data = TEMP
                ENDIF
            '---------------------------
                I2CAddress_3D = $2B             'Read OUTY value 
                gosub I2C_Read_3D
                if TEMP > 127 then              'Two's complementary changed to amplitude information
                        Y_Data = 256 - TEMP     'Acceleration data presented in two's complement
                    else      
                        Y_Data = TEMP
                ENDIF
            '---------------------------
            Acceleratio = Acceleratio + (18 * SQR((X_Data * X_Data) + (Y_Data * Y_Data)))   'Average factor 5x
            '---------------------------                                                    'Calculate resultant force
                IF COUNTER = 5 then
                    COUNTER = 0
                    Acceleratio = Acceleratio/5    
                    IF Acceleratio > Acceleratio_max then
                        Acceleratio_max = Acceleratio
                    endif
                    'ADD YOUR CODE HERE TO SHOW ACCELERATIO AND ACCELERATIO_MAX ON YOUR DISPLAY
                    Acceleratio = 0
                endif
            '---------------------------
            Gosub Accelerometer_Clear
        endif
        goto Acceleration_Loop
    '-------------------------------------------------------------------------------
    Accelerometer_Clear:            'Clear interrupt
        I2CAddress_3D = $31
        gosub I2C_Read_3D
        Return
    Quote Originally Posted by Glenn View Post
    Looks really good, if I knowed this before I started myself I probably would have ordered a I2C version instead

    ..But I might borrow some of your code anyway

    I was thinking of using a timer and calculate speed from it, but I dont know how accurate it would be.
    Thanks! Feel free to borrow, therefore I posted it here
    I would guess that digi output device would give overall better accuracy, but I might be wrong.

    BR,
    -Gusse-
    Last edited by Gusse; - 19th January 2009 at 11:45. Reason: It never goes right at once ....

  7. #7
    Join Date
    Jul 2007
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: 3-Axis Accelerometer (LIS302DL)

    [14-11, 15:02] rodrik: Hello Gusse, I find your post and liked it. I want to use the LIS302DL for car use. Is importance how the direction of placing ? can I just drop or have to locate in certain angle ? Regarding the codes. I want to have the data on serial port. Is data flows continuously or only above the predefined values the data flows out? Thank you in advance

    Haim Rodrik
    Last edited by rodrik; - 14th November 2012 at 13:09.

  8. #8
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Default Re: 3-Axis Accelerometer (LIS302DL)

    Hi Rodik,

    What is your planned application in car?

    If you are planning to monitor movements (i.e alarm use), then placing is not a problem. You can reset acceleration/tilt values for interrupt at any angle.
    If you are keen to know real acceleration values in all axis, then IC need to be at level, X&Y=0, Z=90. Bit more demanding, but ... Constant tilting will give static values.

    Values need to be read from IC via I2C, so if constant reading is needed then you have to do reading loop for that purpose. Data can be put to serial port as well as to LCD, so that is no problem. You have to adjust output part of the code.

    BR,
    -Gusse-

  9. #9
    Join Date
    Jul 2007
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: 3-Axis Accelerometer (LIS302DL)

    Hi Gusse,

    Thank you very much for your reply.
    I am sorry for delay. We moved to new house, I got internet just few days ago. I need to detect lifting big garbadge container. I can put the IC verticaly in manner that Z can detect forward movement X lift up detection. Y its useless. The G values not important jus detect lift up and if moves forward (towing) and stop. I can read the values via serial (SEROUT) pin.
    As I understand , I have configure a value if its exeedes , INT lines falls to "0" logic. I look at ZIP file as I see the "Power_3D VAR PortD.5 'Power_3D" its must be connected to LIS302DL's VCC. What about pin#1 ? (VDD_IO)
    Thanks again
    Have a great weekend

    Haim
    Last edited by rodrik; - 26th January 2013 at 20:43.

  10. #10
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Default Re: 3-Axis Accelerometer (LIS302DL)

    Hi Haim,

    It is OK to put IC vertically and reset acceration/tilt values (HP_FILTER_RESET (23h)).
    You have to configure certain parameters if you want to use interrupt. Here are couple of examples from working piece of codes:

    Code to init accelerometer:
    Code:
    Accelerometer_Init:
    
        'Axes
        I2CAddress_3D = $20     'CTRL_REG1
        TEMP = %01000111        'DR=0, PD=1, FS=0, STP=00, Zen=1, Yen=1, Xen=1 (X,Y,Z enable, Output 100Hz)
        gosub I2C_Write_3D      
        '---------------------
        
        'Filters
        I2CAddress_3D = $21     'CTRL_REG2
        TEMP = %00000111        'SIM = 0, BOOT = 0, --,  FDS = 0, HP FF_WU2 = 0, HP FF_WU1 = 1, HP coeff2 = 1, HP coeff1 = 1 (HP 0.25Hz for FF_WU1)
        gosub I2C_Write_3D
        
        '---------------------
        
        'Interrupts
        I2CAddress_3D = $22     'CTRL_REG3
        TEMP = %00000001        'IHL = 0, PP_OD = 0, I2CFG2-0 = 000, I1CFG2-0 = 001 (FF_WU 1 = INT1)
        gosub I2C_Write_3D
        
        '---------------------
        
        'Sensitivity
        I2CAddress_3D = $32     'FF_WU_THS_1
        TEMP = $02              'DCRM = 0, THS6 = 0, THS5 = 0, THS4 = 0, THS3 = 0, THS2 = 0, THS1 = 1, THS0 = 0 (~36mg wake-up threshold, ~18mg step)
        gosub I2C_Write_3D      
        
        '---------------------
        
        'Duration
        I2CAddress_3D = $33     'FF_DURATION_1
        TEMP = $0D              'D7 = 0, D6 = 0, D5 = 0, D4 = 0, D3 = 1, D2 = 1, D1 = 0, D0 = 1 (130ms, 0 - 2.55s, 10ms step)
        gosub I2C_Write_3D      '0Ah = 100ms, 0Fh = 150ms, 14h = 200ms, 28h = 400ms, 32h = 500ms,
        
        '---------------------
        
        'Wake-Up Thresholds
        I2CAddress_3D = $30     'FF_WU_GFG_1
        TEMP = %01101010        'AOI = 0, LIR = 1, ZHIE = 1, ZLIE = 0, YHIE = 1, YLIE = 0, XHIE = 1, XLIE = 0 (wake-up above thresholde on x,y,z)
        gosub I2C_Write_3D
        
        '---------------------
    Code how to deal when INT will occur:
    Code:
    Accelerometer:
        IF Int1_3D = 1 THEN         ' Int1_3D is IO pin for Interrup coming from 3D sensor
            gosub Accelerometer_Clear
            Accel_Alarm = 1         ' This is indecator that something must be done in main program        
        endif
        return
    
    Accelerometer_Clear:            ' If sensor has moved during event hadling, then interrupt must be cleared once before new sequence
        I2CAddress_3D = $31         ' Clear interrupt request
        gosub I2C_Read_3D
        I2CAddress_3D = $23         ' Reset acceration/tilt value after interrupt 
        gosub I2C_Read_3D
        Return
    Vdd_IO = Vdd = 5V. Even spec says 3.6V, I have used 5V already several years for same parts. Same voltage is used also for I2C pull-ups & CS (pins 1, 3, 6, 7).
    Last edited by Gusse; - 27th January 2013 at 22:00.

  11. #11
    Join Date
    Jul 2007
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: 3-Axis Accelerometer (LIS302DL)

    Thank you very much , I will try and let you know the results. If you need assistance for GSM and GPS, I am very very experienced
    thanks again
    haim

Similar Threads

  1. Replies: 4
    Last Post: - 15th April 2009, 01:54
  2. 3 HPWM channels
    By docwisdom in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 4th April 2006, 02:43
  3. having problems with Hantronix 20x4 lcd
    By Rhatidbwoy in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 22nd December 2005, 12:22
  4. Someone help me to simplify this
    By thrix in forum General
    Replies: 4
    Last Post: - 21st February 2004, 05:01
  5. Help wanted..
    By thrix in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 17th February 2004, 23:44

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts