Precise Timing of SPI Communication

Hi all,

I am currently trying to connect an accelerometer to an Arduino Uno via SPI communication. The only thing I want to achieve here is to read the z-axis acceleration and know precisely when these readings are taken relative to other readings. I will then print these values to the serial monitor.

Here is the current code I am using:

#include <SparkFun_ADXL345.h>         

ADXL345 adxl = ADXL345(10); // set slave pin to 10      

bool xPrint = false;        // change these if I also want x or y data
bool yPrint = false;        //
bool zPrint = true;         //

void setup()
{
  Serial.begin(9600);       // set baud rate at 9600           
  adxl.powerOn();           // turn on accelerometer          
  adxl.setRangeSetting(4);  // set range to +/- 4g          
  adxl.setSpiBit(0);        // initialize 4-wire connection
  adxl.set_bw(3200);        // bandwidth should be 0.1Hz to 3200Hz (according to datasheet)
  adxl.setRate(6400);       // data rate should be twice the bandwidth (according to datasheet)  
}

void loop()
{
  int x,y,z;   
  adxl.readAccel(&x, &y, &z); // read data from accelerometer
  xPrint ? Serial.print(x) : Serial.print("");      // if x-data is enabled, print its value,
  xPrint ? Serial.print(' ') : Serial.print("");    // otherwise don't print anything
  yPrint ? Serial.print(y) : Serial.print("");
  yPrint ? Serial.print(' ') : Serial.print("");
  zPrint ? Serial.print(z) : Serial.print("");
  zPrint ? Serial.print(' ') : Serial.print("");
  Serial.println(millis()/1000.0,3);                // print a timestamp on the same line
}

My main concern is the timing. My questions are:

  • Should the baud rate of the serial monitor correlate to the accelerometer's bandwidth or data rate at all?
  • Does setting the bandwidth to 3200Hz ensure the data readings are being taken at that rate?
  • Above all, how can I print the accelerometer's data to the serial monitor at precise intervals?

I am also considering not printing a time stamp and just assuming that the readings are being taken at that set rate. I could still make the time domain graph this way.

Any advice is greatly appreciated. Thanks!

You need to post a link to the datasheet for the accelerometer and the documentation for the library if you want to get advice about it.

I suggest you save the value of millis() to a variable immediately after you have taken a reading and the then you can send the reading and the corresponding time value at your leisure.

You have not said what time interval you want between readings. Have a look at how millis() is used to manage timing in Several things at a time

...R

Here is the accelerometer datasheet.
Here is the SparkFun ADXL345 library documentation.

Sorry for the confusion regarding my post. I am only interested in printing the z-axis value to the screen with a precise time as to when the reading was taken relative to other readings. I believe I have two options for completing this project:

  • Printing a time stamp using millis() or micro(), keeping track of only one reading overall, or
  • Assume a constant sampling rate so I wouldn't need a time stamp.
    I am not too concerned about the exact time interval between readings, anywhere between 1000Hz and 3200Hz should work but I need to know/set exactly what that value is. I guess this is more of a conceptual question but how can I ensure the sampling rate is the same rate that the serial monitor outputs?

Thanks again.

AnthonyBuo:
I am not too concerned about the exact time interval between readings, anywhere between 1000Hz and 3200Hz should work but I need to know/set exactly what that value is.

Just to be sure I understand, do you mean that you want to take a reading at intervals varying from 1000 microseconds to 312 microseconds.

If you want to print (in Ascii format) the values from 3 integers, some space characters and the value of millis(). That amounts to (very roughly) 25 bytes. At 9600 baud that would take about 25,000 microisecs. Even at 500,000 baud it would take 500 microsecs. (assuming my maths is correct)

In other words sampling at that frequency and sending data between each sample in that simple format is not going to work. You could perhaps take several readings, save them to an array and then pause and send the data from the array.

It may be possible to send the data more efficiently but you would still need a very high baud rate.

...R