1 2 Previous Next 15 Replies Latest reply on Feb 27, 2015 8:31 PM by bathula.navya.deepika

    How to use SPI with ADXL345 accelerometer and PSoC 5 board

    kevin.kickbusch
              Hi everyone! I'm trying to get data out of a ADXL345 accelerometer and display it on the LCD of the PSoC5. I'm having difficulties trying to display the results. At this point, I'm only trying to get the x and y axis results, one for each line of the LCD. I'm currently a student at a university and have asked my professors if they have any idea how to use SPI, but none have been able to help with the PSoC related stuff. I've looked at other threads in this forum but none have really solved the problem and I've pretty much exhausted the internet searching for answers. I did find some code (AccelSPI_test.c) that I spliced and added into my code. It wasn't meant for the PSoC5 though, so I had to change some things. I think I only need an SPI Master in the top design, and not a slave. I've attached the main c file for anyone to look at with the AccelSPI_test.c file under it. If anyone can help or has any ideas how to do this it would be great. If you need more information, like TopDesign, or pin assignments, I can post this too, but I think those are ok right now.   
        • 1. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
          user_1377889

          Since the ADXL345 has got an I2C-interface (I am not a friend of SPI), why don't you use this? With the basic APIs of I2C-master (start, restart read etc) you can setup your connection byte-by-byte easily.

             

          In your routine task() you initialize your device and get data, better is to separate initialization and reading off data.

             

          You do not tell us where your program runs into troubles. Debugging the code will reveill that.

             

          Best is to upload a complete project archive here (use Creator -> File -> Create Workspace Bundle (minimal) and upload the resulting .zip here), so we can check not only the code but all the settings.

             

           

             

          Bob

          • 2. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
            user_78878863

            A complete project helps to see where your hardware might be configured wrong.

               

            Things to look for:

               
                  
            • SPI clock too fast (then the slave select output might go high inbetween the bytes)
            •     
            • each write to the SPI also does a read - and this will fill up the buffer, so you might read wrong values afterwards. So clear the read buffer after each write
            •     
            • wrong SPI mode (must be 1/1)
            •     
            • when reading the registers, *1 must be shifted, as its the higher byte, and *0 is the lower byte
            •    
               

            You should attach a logic analyzer and see whats going over the wire, and see whether it is what you expect. Then you can look at the software...

            • 3. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
              ki.leung

              I think the code is very well written, here is some suggestions

                 
                   1.       I think you should read all the data first into an array and then process the whole array; in that case you can check that value immediate after the reading.   
                 
                      
                 
                   2.       I would avoid use any names with leading underscore such as _POWER_CTL, as that normal are used for system usage   
                 
                      
                 
                   3.       Try not to mix // and /* */ together such as   
                 
                                   /*LCD_Position(0,9);       //Initialize string position 9   
                 
                                   LCD_PrintString(point); //Prints . at 0,9, may not need?   
                 
                                   LCD_Position(0,12);      //Initialize string position 12   
                 
                                   LCD_PrintString(G);      //Prints G at 0,12*/   
                 
                      
                 
                  I prefer to use   
                 
                      
                 
                  #if 0   
                 
                  LCD_Position(0,9);            //Initialize string position 9   
                 
                                   LCD_PrintString(point); //Prints . at 0,9, may not need?   
                 
                                   LCD_Position(0,12);      //Initialize string position 12   
                 
                                   LCD_PrintString(G);      //Prints G at 0,12   
                 
                  #endif   
                 
                      
                 
                  Or   
                 
                      
                 
                  #ifndef  NO_PRINT   
                 
                  LCD_Position(0,9);            //Initialize string position 9   
                 
                                   LCD_PrintString(point); //Prints . at 0,9, may not need?   
                 
                                   LCD_Position(0,12);      //Initialize string position 12   
                 
                                   LCD_PrintString(G);      //Prints G at 0,12   
                 
                  #endif   
                 
                       
                 
                  And define that at the beginning of the file like this.   
                 
                  #define NO_PRINT   
                 
                  You then can check your setting in one place and no need to check the code   
                 
                      
                 
                   4.       I think PSoC5 does not have bit variables. That is why sbit would not work   
                 
                      
                 
                   5.       I normally control the CS of SPI directly and not using the output from the SPI component. You can change it back to use the output of the component. But directly controlling it save a lot of headache during debugging.   
                 
                      
                 
                   6.        It would also help if you use more defines such as   
                 
                      
                 
                  #define CARRAGE_RETURN  (13)   
                 
                  #define X_READING (0)   
                 
                  #define Y_READING (0)   
                 
                      
                 
                  UART1_Write(CARRAGE_RETURN );   
                 
                  readings[X_READING] = ADXL345_Read(SENSOR_DATAX0) << 8;   
                 
                  readings[Y_READING] = ADXL345_Read(SENSOR_DATAY0) << 8;   
                 
                      
                 
                   7.       As mentioned, it would be easier if you post the complete project.   
                 
                      
                 
                  8. I would debug one portion of code a time, IE made sure the UART part works first by write something the the array direcly and send it out to the UART. Once it can display correctly then start doing   
                 

              my 2cents

              • 4. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                ki.leung
                    My bad!!   
                   
                        
                   
                    8. I would debug one portion of code a time, IE made sure the UART part works first by write something the the array direcly and send it out to the UART. Once it can display correctly then start doing the reading of the sensor.   
                • 5. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                  kevin.kickbusch
                          Thanks for the suggestions everyone. Hopefully this zip file will contain everything you need to look at, I've never used that feature before. As for the problem that I'm running into, I can display the title of the axis(X and Y) on the LCD but it won't display the data if should be getting from the accelerometer. I think the 2 problems are getting the accelerometer data and converting that data into a string to print on the LCD. One of my profs thought maybe that the LCD could only hold so much data so it wouldn't print something that was really long, but I don't think that is the case as I've shortened it to the first 6 values. I didn't know about the sbit stuff so thank you for that. I couldn't figure out why that wasn't working. I currently don't use UART anywhere (it's in there, just commented out), is it something I should be using? As for using SPI over I2C, I've been working on the project with many different accelerometers and boards over the past year and this just seems like the one that has been making the most progress. If I can't make it work with SPI, I'll switch over to I2C. I'm really not too picky on which I'll end up using, at this point I'd use whatever made it work. Sorry to keep you guys waiting for a few days, I was out of town and couldn't work on this then.   
                  • 6. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                    user_14586677

                    The easy way to convert data to formatted data is sprintf(), basically printf() that

                       

                    outputs to a character buffer for printing on LCD.

                       

                     

                       

                    Attached the format specifications useful for sprintf(). If you are using character

                       

                    LCD there is an API f() call in datasheet for printing a character buffer/array to the

                       

                    LCD, as well as f()'s for moving the cursor to the position where you want the

                       

                    formatted data to be written on LCD.

                       

                     

                       

                    Regards, Dana.,

                    • 7. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                      ki.leung

                      1. You have a while loop in your task() function. it will never come out so it won't run the Updatedisplay function().

                         

                      2. You should be able to step and break within creator to debug your project.

                         

                      3. For some simply test. I would suggest to added a 1second delay inside the main loop and also increment and x and y counter every loop and shown it on the LCD. So you can see the change of the counters updated on the LCD.

                         

                      4. One step a time is actually quicker to the finish line.

                      • 8. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                        kevin.kickbusch
                                I've changed a few things around and got actual numbers to be outputted on the LCD, but they only update when the accelerometer is unplugged. These numbers that change are from noise in the air we believe. Once the ADXL is plugged back in, the numbers stop changing. If the ADXL is plugged in when the PSoC board is programmed, it displays a single 0 on each line. We expected this but when I would change the default readings at the start of the code, the 0's would still be displayed. I've cleaned up some stuff that I don't think I'll need and am no longer using a printf() as LCD_PrintNumber() seems to be giving us data. I also fixed the while loop in task() and spilt task() into ADXLReady() and GetData(). Any ideas how I can get data from the ADXL? I know the registers are correct and I've tried different ADXL's and PSoC boards so it's not a hardware issue.   
                        • 9. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                          user_78878863

                          First thing to note is that the SPI master is configured wrong. Its set to CPOL=0/CPHA=0, but the data sheet says it needs to be 1/1.

                             

                          Can you attach a scope or logic analyzer to the SPI bus and check what goes over the wire, and whether the ADXL345 actually responds to the commands? Only if you can make sure that it answers it makes sense to look for other problems.

                             

                          Also, your read logic is wrong. You only send the address byte to the ADXL345, but you never receive any data. For that, you need to send a second (dummy) byte, during which the ADXL345 will send your data back (see data sheet, page 16). Don't forget to skip the first byte you get from the read buffer, and you also need to wait for the transmission to finish (readRxStatus / readTXStatus).

                             

                          I suggest you start reading the SPI master component data sheet, at least the API and the functional descriptions, and the ADXL345 data sheet, the part about SPI. Look at especially at the timing diagrams in both data sheets.

                             

                          Btw: you still mix high and low bytes (DATAX0 is low, DATAX1 is high).

                          • 10. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                            ki.leung

                            1. ADXL345 use the CS pin to switch between I2C and SPI mode, did you follow suggestion from the data sheet "Preventing bus traffic errors"?

                               


                            2. SPI uses the CS pin to restart. It was mentioned by others that the line switches to high if the TX buffer is not filled up fast enough.
                             I would suggest to control the CS line via a control register. Or use I2C mode as other suggested.

                               


                            3. Try to read the ID register( which is a constant) first to make sure the SPI and the related circuit is working correctly.

                               


                            4. There are different setting for all the registers, make sure the default reset value is what your wants.
                             if not you need to set it up for your application.

                               


                            5. I would suggest to read the values (6 bytes in one go).

                            • 11. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                              user_78878863

                              The SPI clock is set to 150kHz, so I suppose that the PSoC is fast enough to fill the transmit buffer. The real problem is that only a single byte is send, so the ADXL345 never gets a chance to send its data back.

                              • 12. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                                kevin.kickbusch
                                        Thanks for all the suggestions so far, this is my first time working with SPI or I2C so a lot of this is new to me. I tried going the I2C route until I figured out how to get actual numbers displayed (I was getting greek letters, numbers, and random symbols at first) so I continued with the SPI. I won't be able to get into the lab until Tuesday so hopefully I can figure the signal stuff out after that because if I can't it'll be another week because the university will be shut down for the holiday. I've taken a look at the various data sheets involved, but having never used it before it's difficult to know what's used for what and its purpose. Thank you guys for your patience, you're an awesome group of people!   
                                • 14. Re: How to use SPI with ADXL345 accelerometer and PSoC 5 board
                                  m.roshandelpoor_1580446

                                  Hi friends.could u runing adxl345 with spi or i2c?because i cant solved this problem!!!

                                     

                                  If you solved this problem please give me your project to understanding how i can to do?

                                     

                                  tanks...

                                  1 2 Previous Next