Go Down

Topic: Saving Accelerometer data to SD card via SPI interface (Read 324 times) previous topic - next topic

henry321yu

May 13, 2019, 11:11 am Last Edit: May 28, 2019, 09:19 am by henry321yu
Hi hi,henry here
I'm working a project need to save many data to SD card,like accelerometer,encoder...
Now i'm only using accelermeter(adxl355) with ardiuno Nano.

And the results are so strange..

i connect
vcc(sd) -> 5V
vcc(accelermeter) -> 3.3V
sd_CS -> d8
accelermeter_CS -> d9
mosi(sd、accelermeter) -> d11(mosi)
miso(sd、accelermeter) -> d12(miso)
sclk(sd、accelermeter) -> d13(sclk)
gnd(sd、accelermeter) -> gnd

I can read and write accelermeter and sd card individually with the same circuit. I can not execute both actions when they are wiring to the nano.
When I'm wiring both together, I can write data to sd card,but can't read accelerometer.It wrote 0,0,0 in sd crard.
But when I cut off vcc(sd) 5v,i can read accelerometer but can't write data to sd card...
code attached~


wiring both:



cut off vcc(sd) 5v:



data:



circuit:


adxl355


HELP :o  :o  :o  :o  :o  :smiley-eek-blue:  :smiley-eek-blue:

Code: [Select]

#define DEVID_AD                 0x00
#define DEVID_MST                0x01
#define PARTID                   0x02
#define REVID                    0x03
#define STATUS                   0x04
#define FIFO_ENTRIES             0x05
#define TEMP2                    0x06
#define TEMP1                    0x07
#define XDATA3                   0x08
#define XDATA2                   0x09
#define XDATA1                   0x0A
#define YDATA3                   0x0B
#define YDATA2                   0x0C
#define YDATA1                   0x0D
#define ZDATA3                   0x0E
#define ZDATA2                   0x0F
#define ZDATA1                   0x10
#define FIFO_DATA                0x11
#define OFFSET_X_H               0x1E
#define OFFSET_X_L               0x1F
#define OFFSET_Y_H               0x20
#define OFFSET_Y_L               0x21
#define OFFSET_Z_H               0x22
#define OFFSET_Z_L               0x23
#define ACT_EN                   0x24
#define ACT_THRESH_H             0x25
#define ACT_THRESH_L             0x26
#define ACT_COUNT                0x27
#define FILTER                   0x28
#define FIFO_SAMPLES             0x29
#define INT_MAP                  0x2A
#define SYNC                     0x2B
#define RANGE                    0x2C
#define POWER_CTL                0x2D
#define SELF_TEST                0x2E
#define RESET                    0x2F

#include <SD.h>
#include <SPI.h>

const int SD_CS = 8; // Pin 10 on Arduino Uno
const int acc_CS = 9; //
long values[20],t[9];
double x, y, z, c;
void setup() { 
  Serial.begin(9600);
 
  if (!SD.begin(SD_CS)) {
    Serial.println("Card failed, or not present");
  }
  pinMode(SD_CS, OUTPUT);
  digitalWrite(SD_CS, HIGH);
   
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // 1000khz clock

  pinMode(acc_CS, OUTPUT);
  digitalWrite(acc_CS, HIGH);

  writeRegister(POWER_CTL, 0x00);  // writing 0 to to enable sensor
  writeRegister(RANGE, 0xC1);
  writeRegister(SELF_TEST, 0x00);  // writing 3 to to enable

  delay(500);
}
void loop() {
 
  acc_data();
 
  Serial.print(x,5);
  Serial.print(',');
  Serial.print(y,5);
  Serial.print(',');
  Serial.print(z,5);
  Serial.print('\n');

  digitalWrite(SD_CS, LOW);
  File test0 = SD.open("test0.txt", FILE_WRITE);
  if (test0) {   
    Serial.println("writing");
    test0.print(x);
    test0.print(",");
    test0.print(y);
    test0.print(",");
    test0.print(z);
    test0.print('\n');
    test0.close(); // close the file
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }
  digitalWrite(SD_CS, HIGH);
    delay(10);
}

byte readRegister (byte thisRegister) {
  byte inByte = 0 ;
  digitalWrite(acc_CS, LOW);
  SPI.transfer((thisRegister << 1) | 1);
  inByte = SPI.transfer(0x00);
  digitalWrite(acc_CS, HIGH);
  return inByte;
}
void writeRegister (byte thisRegister, byte value) {
  digitalWrite(acc_CS, LOW);
  SPI.transfer(thisRegister << 1);
  SPI.transfer(value);
  digitalWrite(acc_CS, HIGH);
}
void acc_data(){
  values[0] = readRegister(XDATA3);
  values[1] = readRegister(XDATA2);
  values[2] = readRegister(YDATA3);
  values[3] = readRegister(YDATA2);
  values[4] = readRegister(ZDATA3);
  values[5] = readRegister(ZDATA2);

  values[6] = readRegister(XDATA1);
  values[7] = readRegister(YDATA1);
  values[8] = readRegister(ZDATA1);

  t[0] = readRegister(TEMP2);
  t[1] = readRegister(TEMP1);

  x = (values[0] << 12) + (values[1]<<4) + (values[6]>>4);
  y = (values[2] << 12) + (values[3]<<4) + (values[7]>>4);
  z = (values[4] << 12) + (values[5]<<4) + (values[8]>>4);

  if (x >= 0x80000) {
    x = x-(2*0x80000);
  }
  if (y >= 0x80000) {
    y = y-(2*0x80000);
  }
  if (z >= 0x80000) {
    z = z-(2*0x80000);
  }
 
  c=(t[0]<<8)+t[1];
  c=((1852 - c)/9.05)+25.7;
 
  x=x*0.0000039;
  y=y*0.0000039;
  z=z*0.0000039;
  }

henry321yu

https://arduino.stackexchange.com/questions/43732/adxl345-becomes-0g-when-plugin-microsd-adapter-using-spi

..so its a glitch that alway have??
Nowonder most of people use i2c interface to do this.
But I have not seen many people discussing this issue.

hope someone can answer me :(

MorganS

Those accelerometers in the ADXL345 family respond to I2C commands when the SPI interface is de-selected. So if you are talking to other devices on the SPI bus, the accelerometer can misinterpret that as I2C.

There is no way to turn off the I2C in the chip. You have to use multiple SPI buses or a buffer chip that can disconnect the ADXL when it is not selected.

What adapter do you have for the SD card? The SD specification uses 3.3V but the Nano is 5V. Some cards will work at 5V for a short time before failing.

The ADXL is also 3.3V.
"The problem is in the code you didn't post."

Geek Emeritus

Code: [Select]
i connect
vcc(sd) -> 5V
vcc(accelermeter) -> 3.3V
mosi(sd、accelermeter) -> d11(mosi)
miso(sd、accelermeter) -> d12(miso)
sclk(sd、accelermeter) -> d13(sclk)
gnd(sd、accelermeter) -> gnd


not seeing CS, Chip Select.  most people use pin 10, but any digital pin will work.

set (pinMode(CS, OUTPUT); and digitalWrite(CS, LOW);  to interact with the card. set digitalWrite(CS, HIGH); when you are at "mischief managed"
All PMs will be deleted unopened due to arrogant argumentative pot stirring Malfoys.
 If you have not read "How to use this forum - please read", in particular: "7. If you are posting code or error messages, use "code" tags":  expect rude responses

henry321yu

#4
May 30, 2019, 04:41 am Last Edit: May 30, 2019, 04:44 am by henry321yu
Those accelerometers in the ADXL345 family respond to I2C commands when the SPI interface is de-selected.
There is no way to turn off the I2C in the chip. You have to use multiple SPI buses or a buffer chip that can disconnect the ADXL when it is not selected.
I'm using i2c now.but still happening strange things.my post
I can't connect other i2c device.can used sd card module though.
I think I2C Multiplexer might work?


What adapter do you have for the SD card? The SD specification uses 3.3V but the Nano is 5V. Some cards will work at 5V for a short time before failing.
It had adapter on its board.Works great.

henry321yu

not seeing CS, Chip Select.  most people use pin 10, but any digital pin will work.
sorry,i've added.

set (pinMode(CS, OUTPUT); and digitalWrite(CS, LOW);  to interact with the card. set digitalWrite(CS, HIGH); when you are at "mischief managed"
I did.No difference.

I think it's adxl355's problem.I can work with other i2c devices without adxl355.

Go Up