J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Does anyone have the SPI C code for ADXL345 to share?

Sun Mar 18, 2018 1:57 pm

Does anyone have the SPI C code (using pigpio library or without library) for the ADXL345 sensor to share ? Thank you for any help.

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Sun Mar 18, 2018 2:22 pm

If you search for "linux C SPI ADXL345" anything you find should work on the Pi. Have you a particular need in mind?

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Sun Mar 18, 2018 3:01 pm

Hi Joan,

I wrote a piece of C code by making a system call to the SPI kernel previously. However, i suspect there is mistake in my code which result in high noise. The purpose of asking for code written in pigpio library or other c code is to test the sensor if it is my code issue or sensor issue. Do you know If there is SPI C code for the ADXL345 written with your pigpio library available to test?

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Sun Mar 18, 2018 5:39 pm

Here is some pigpio code using the pigpio SPI driver. All it does is read the raw XYZ data. No maths.

The speed defaults to 2MBps. I think the bottom limit is 40kbps.

Code: Select all

/*
gcc -Wall -pthread -o adxl345_spi adxl345_spi.c -lpigpio -lrt
sudo ./adxl345_spi 
*/

#include <stdio.h>
#include <stdlib.h>
#include <pigpio.h>

#define LOOPS 500000

#define READ_BIT  0x80
#define MULTI_BIT 0x40

#define BW_RATE     0x2C
#define POWER_CTL   0x2D
#define DATA_FORMAT 0x31
#define DATAX0      0x32

int readBytes(int handle, char *data, int count)
{
   data[0] |= READ_BIT;
   if (count > 1) data[0] |= MULTI_BIT;
   return spiXfer(handle, data, data, count);
}

int writeBytes(int handle, char *data, int count)
{
   if (count > 1) data[0] |= MULTI_BIT;
   return spiWrite(handle, data, count);
}

int main(int argc, char *argv[])
{
   int h;
   char data[7];
   int16_t x, y, z, lx, ly, lz;
   int i;
   int bytes;
   double start, duration;

   if (gpioInitialise() < 0) return 1;

   h = spiOpen(0, 2000000, 3);

   data[0] = BW_RATE;
   data[1] = 0x0F;
   writeBytes(h, data, 2);

   data[0] = DATA_FORMAT;
   data[1] = 0x01;
   writeBytes(h, data, 2);

   data[0] = POWER_CTL;
   data[1] = 0x08;
   writeBytes(h, data, 2);

   lx = 0;
   ly = 0;
   lz = 0;

   start = time_time();

   for (i=0; i<LOOPS; i++)
   {
      data[0] = DATAX0;
      bytes = readBytes(h, data, 7);
      if (bytes == 7)
      {
         x = (data[2]<<8)|data[1];
         y = (data[4]<<8)|data[3];
         z = (data[6]<<8)|data[5];

         if ((abs(x-lx) > 30) || (abs(y-ly) > 30) || (abs(z-lz) > 30))
         {
            printf("x=%d y=%d z=%d\n", x, y, z);

            lx = x;
            ly = y;
            lz = z;
         }
      }
      else printf("spiXfer error (%d)\n", bytes);
   }

   duration = time_time() - start;

   gpioTerminate();

   printf("%d loops in %.2f seconds (%.1f sps)\n",
      LOOPS, duration, LOOPS/duration);
}

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Tue Mar 20, 2018 1:10 pm

joan wrote:
Sun Mar 18, 2018 5:39 pm
Here is some pigpio code using the pigpio SPI driver. All it does is read the raw XYZ data. No maths.

The speed defaults to 2MBps. I think the bottom limit is 40kbps.

Code: Select all

/*
gcc -Wall -pthread -o adxl345_spi adxl345_spi.c -lpigpio -lrt
sudo ./adxl345_spi 
*/

#include <stdio.h>
#include <stdlib.h>
#include <pigpio.h>

#define LOOPS 500000

#define READ_BIT  0x80
#define MULTI_BIT 0x40

#define BW_RATE     0x2C
#define POWER_CTL   0x2D
#define DATA_FORMAT 0x31
#define DATAX0      0x32

int readBytes(int handle, char *data, int count)
{
   data[0] |= READ_BIT;
   if (count > 1) data[0] |= MULTI_BIT;
   return spiXfer(handle, data, data, count);
}

int writeBytes(int handle, char *data, int count)
{
   if (count > 1) data[0] |= MULTI_BIT;
   return spiWrite(handle, data, count);
}

int main(int argc, char *argv[])
{
   int h;
   char data[7];
   int16_t x, y, z, lx, ly, lz;
   int i;
   int bytes;
   double start, duration;

   if (gpioInitialise() < 0) return 1;

   h = spiOpen(0, 2000000, 3);

   data[0] = BW_RATE;
   data[1] = 0x0F;
   writeBytes(h, data, 2);

   data[0] = DATA_FORMAT;
   data[1] = 0x01;
   writeBytes(h, data, 2);

   data[0] = POWER_CTL;
   data[1] = 0x08;
   writeBytes(h, data, 2);

   lx = 0;
   ly = 0;
   lz = 0;

   start = time_time();

   for (i=0; i<LOOPS; i++)
   {
      data[0] = DATAX0;
      bytes = readBytes(h, data, 7);
      if (bytes == 7)
      {
         x = (data[2]<<8)|data[1];
         y = (data[4]<<8)|data[3];
         z = (data[6]<<8)|data[5];

         if ((abs(x-lx) > 30) || (abs(y-ly) > 30) || (abs(z-lz) > 30))
         {
            printf("x=%d y=%d z=%d\n", x, y, z);

            lx = x;
            ly = y;
            lz = z;
         }
      }
      else printf("spiXfer error (%d)\n", bytes);
   }

   duration = time_time() - start;

   gpioTerminate();

   printf("%d loops in %.2f seconds (%.1f sps)\n",
      LOOPS, duration, LOOPS/duration);
}
Dear Joan,

Thank you for this piece of code. I modified it based on the frequency and bits i set in my actual application. I would need your help to look at the data I logged. There is alot of fluctuation. Do you know what is wrong, is it my sensor issue? I am using Raspian with kernel version 4.9.35-v7+. I have been purged with this problem for quite some time even with my own SPI program and I think it is really affecting my robot. Thank you for any suggestion.

Code: Select all

/*
gcc -Wall -pthread -o adxl345_spi adxl345_spi.c -lpigpio -lrt
sudo ./adxl345_spi 
*/

#include <stdio.h>
#include <stdlib.h>
#include <pigpio.h>

#define LOOPS 500000

#define READ_BIT  0x80
#define MULTI_BIT 0x40

#define BW_RATE     0x2C
#define POWER_CTL   0x2D
#define DATA_FORMAT 0x31
#define DATAX0      0x32

int readBytes(int handle, char *data, int count)
{
   data[0] |= READ_BIT;
   if (count > 1) data[0] |= MULTI_BIT;
   return spiXfer(handle, data, data, count);
}

int writeBytes(int handle, char *data, int count)
{
   if (count > 1) data[0] |= MULTI_BIT;
   return spiWrite(handle, data, count);
}

int main(int argc, char *argv[])
{
   int h;
   char data[7];
   int16_t x, y, z, lx, ly, lz;
   int i;
   int bytes;
   double start, duration;

   if (gpioInitialise() < 0) return 1;

   h = spiOpen(1, 5000000, 3);

   data[0] = BW_RATE;
   data[1] = 0x0F;
   writeBytes(h, data, 2);

   data[0] = DATA_FORMAT;
   data[1] = 0x0B;
   writeBytes(h, data, 2);

   data[0] = POWER_CTL;
   data[1] = 0x08;
   writeBytes(h, data, 2);

   lx = 0;
   ly = 0;
   lz = 0;

   start = time_time();

   for (i=0; i<LOOPS; i++)
   {
      data[0] = DATAX0;
      bytes = readBytes(h, data, 7);
      if (bytes == 7)
      {
         x = (data[2]<<8)|data[1];
         y = (data[4]<<8)|data[3];
         z = (data[6]<<8)|data[5];

         if ((abs(x-lx) > 30) || (abs(y-ly) > 30) || (abs(z-lz) > 30))
         {
            printf("x=%d y=%d z=%d\n", x, y, z);

            lx = x;
            ly = y;
            lz = z;
         }
      }
      else printf("spiXfer error (%d)\n", bytes);
   }

   duration = time_time() - start;

   gpioTerminate();

   printf("%d loops in %.2f seconds (%.1f sps)\n",
      LOOPS, duration, LOOPS/duration);

	return 0;
}
Here is the data I logged. The data is recorded on the floor and the sensor is stationary

https://drive.google.com/open?id=1bQL7s ... VqpkNFHTP5

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Tue Mar 20, 2018 4:06 pm

I have no idea if they are normal readings or not. All I ever do is turn the device through various orientations and check the output looks reasonable.

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Tue Mar 20, 2018 5:38 pm

joan wrote:
Tue Mar 20, 2018 4:06 pm
I have no idea if they are normal readings or not. All I ever do is turn the device through various orientations and check the output looks reasonable.
Hi Joan,

Do you have the same sensor lying around? If you have, is it okay if you show me the output using the updated code that I posted?

I am not really sure if it is normal to read this kind of data. I always have the impression that x and y axis should be around 0 and z should be around 256 when the sensor is flat on the ground. But from my sensor's output, i am not getting it. I really appreiate if anyone else can weight in on this matter. I been trying to fix this issue for weeks but is unsure if it is normal or just something wrong with the sensor.

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Thu Mar 22, 2018 8:53 pm

I don't get anything at all with your modified code. When I use 5MBps and a data format of 0x01 all looks okay.

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Fri Mar 23, 2018 5:59 pm

joan wrote:
Thu Mar 22, 2018 8:53 pm
I don't get anything at all with your modified code. When I use 5MBps and a data format of 0x01 all looks okay.
Okay, but kind of weird you should be able to read something from the modified code. I did not change much of your code. The only thing i changed is the data format, SPI clock rate and i am using Chip Enable 1.

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Fri Mar 23, 2018 6:12 pm

J.Bryan wrote:
Fri Mar 23, 2018 5:59 pm
joan wrote:
Thu Mar 22, 2018 8:53 pm
I don't get anything at all with your modified code. When I use 5MBps and a data format of 0x01 all looks okay.
Okay, but kind of weird you should be able to read something from the modified code. I did not change much of your code. The only thing i changed is the data format, SPI clock rate and i am using Chip Enable 1.
That explains why I got no readings. I did not notice the chip enable change. I'll try again.

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Fri Mar 23, 2018 7:20 pm

The results look fine to me. I logged all readings, not just those more than 30 different to the previous reading. A plot each for X, Y, and Z.
new_adxl345-x.jpg
new_adxl345-x.jpg (48.46 KiB) Viewed 1221 times
new_adxl345-y.jpg
new_adxl345-y.jpg (48.28 KiB) Viewed 1221 times
new_adxl345-z.jpg
new_adxl345-z.jpg (60.58 KiB) Viewed 1221 times

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Fri Mar 23, 2018 7:32 pm

joan wrote:
Fri Mar 23, 2018 7:20 pm
The results look fine to me. I logged all readings, not just those more than 30 different to the previous reading. A plot each for X, Y, and Z.

new_adxl345-x.jpg
new_adxl345-y.jpg
new_adxl345-z.jpg
Hi Joan,

Is your readings done without this sentence of code?

Code: Select all

if ((abs(x-lx) > 30) || (abs(y-ly) > 30) || (abs(z-lz) > 30))
I am not getting the same plot as you get. I am getting alot of noise, i will test it again and show you my result.

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Fri Mar 23, 2018 8:41 pm

Yes, I replaced the if statement with the unconditional printf("%d %d %d\n", x, y, z);

I then used gnuplot to plot part of the log for each axis.

plot [50000:90000][-250:250]'adxl345.log' using 1 # X
plot [50000:90000][-250:250]'adxl345.log' using 2 # Y
plot [50000:90000][0:500]'adxl345.log' using 3 # Z

J.Bryan
Posts: 42
Joined: Tue Aug 01, 2017 2:44 pm

Re: Does anyone have the SPI C code for ADXL345 to share?

Sat Mar 24, 2018 7:01 pm

joan wrote:
Fri Mar 23, 2018 8:41 pm
Yes, I replaced the if statement with the unconditional printf("%d %d %d\n", x, y, z);

I then used gnuplot to plot part of the log for each axis.

plot [50000:90000][-250:250]'adxl345.log' using 1 # X
plot [50000:90000][-250:250]'adxl345.log' using 2 # Y
plot [50000:90000][0:500]'adxl345.log' using 3 # Z
Hi Joan,

I would like your guidance on how to use the piscope to view the data on the SPI bus. Is it possible to do a simple view of the device ID and signal?

User avatar
joan
Posts: 13617
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Does anyone have the SPI C code for ADXL345 to share?

Sat Mar 24, 2018 7:58 pm

To see the signals on piscope you would have to drop the speed to something around 70kbps or less to make sure all the edges are captured.

I haven't used it for a while but http://abyz.me.uk/rpi/pigpio/examples.h ... SPI_mon_py may be a simpler alternative.

User avatar
CFLanger
Posts: 38
Joined: Fri Feb 06, 2015 5:04 pm
Contact: Website

Re: Does anyone have the SPI C code for ADXL345 to share?

Mon Apr 09, 2018 3:28 pm

when you get data coming out you have to calibrate it.
https://youtu.be/AHj_KB260eM
CFLanger
Senior Software Engineer at
www.ljtechnologies.com

Return to “C/C++”