Arduino SD卡与其他SPI设备一起使用时无法写入

Arduino SD卡与其他SPI设备一起使用时无法写入,arduino,sd-card,spi,Arduino,Sd Card,Spi,我有一个ADXL355加速计连接到一个Adafruit羽毛Adalogger。我可以配置和读取传感器。我还可以将二进制值写入SD卡。当我尝试从传感器读取数据,然后将数据写入SD卡时,就会出现问题。我能想到的唯一一件事是我不知怎么搞砸了SPI的通讯,但我不知道在哪里。我查看了我的电路板的引脚_ardino.h,SD卡(引脚4)与引脚10位于不同的寄存器中,因此我看不出我是如何破坏的 我的行动是这样进行的。全局传感器创建,Serial.begin,SD.begin,SPI.begin,测试传感器连接

我有一个ADXL355加速计连接到一个Adafruit羽毛Adalogger。我可以配置和读取传感器。我还可以将二进制值写入SD卡。当我尝试从传感器读取数据,然后将数据写入SD卡时,就会出现问题。我能想到的唯一一件事是我不知怎么搞砸了SPI的通讯,但我不知道在哪里。我查看了我的电路板的
引脚_ardino.h
,SD卡(引脚4)与引脚10位于不同的寄存器中,因此我看不出我是如何破坏的

我的行动是这样进行的。全局传感器创建,
Serial.begin
SD.begin
SPI.begin
,测试传感器连接,为SD卡上的输出创建文件,初始化传感器,读取传感器FIFO,写入文件,永远重复最后2次

该文件已创建,但仍保持为0文件大小(实际上未向卡中写入任何内容)

传感器可以在4 kHz下工作,这很难使用
数字写入功能实现,因此我切换到使用羽毛上的端口寄存器。我是这样做的:

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

#define cardSelect 4

ADXL355_SPIF adxl355(&DDRB, &PORTB, _BV(6)); // values taken from pins_arduino.h, tested and working on pin 10
void setup() {
  Serial.begin(57600);
  while(!Serial){
    // wait for Serial
  }
  SD.begin(cardSelect);
  SPI.begin();
  while(!adxl355.TestConnection()){
    delay(1000);  
  }
  adxl355.OpenFile("TestSPI.bin");
  adxl355.Initialize(1, 10, 0); // set range to 2g's, frequency to 4 Hz and filter to off
}

void loop() {
  while(true){ // avoid Arduino overhead of their loop function
    adxl355.ReadFIFO();
    adxl355.WriteFIFOToFile();
  }
}
bool ADXL355_SPIF::OpenFile(const String& fileName){
    sensorFile = SD.open(fileName, FILE_WRITE);
    if (!sensorFile){
        Serial.print("Could not create file: ");
        Serial.println(fileName);
        return false;
    }
    return true;
}
TestConnection
测试设备ID是否读取
0xAD
<代码>初始化
设置G范围、以Hz为单位的采样率和滤波器。我已经测试了串行输出,他们工作正常

OpenFile
如下所示:

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

#define cardSelect 4

ADXL355_SPIF adxl355(&DDRB, &PORTB, _BV(6)); // values taken from pins_arduino.h, tested and working on pin 10
void setup() {
  Serial.begin(57600);
  while(!Serial){
    // wait for Serial
  }
  SD.begin(cardSelect);
  SPI.begin();
  while(!adxl355.TestConnection()){
    delay(1000);  
  }
  adxl355.OpenFile("TestSPI.bin");
  adxl355.Initialize(1, 10, 0); // set range to 2g's, frequency to 4 Hz and filter to off
}

void loop() {
  while(true){ // avoid Arduino overhead of their loop function
    adxl355.ReadFIFO();
    adxl355.WriteFIFOToFile();
  }
}
bool ADXL355_SPIF::OpenFile(const String& fileName){
    sensorFile = SD.open(fileName, FILE_WRITE);
    if (!sensorFile){
        Serial.print("Could not create file: ");
        Serial.println(fileName);
        return false;
    }
    return true;
}
运行此操作后,将在SD卡上创建一个名为“TESTSPI.BIN”的文件,文件大小为0

ReadFIFO
读取FIFO中的条目数,存储为
fifoCount
,然后用FIFO中的值填充缓冲区(
sensorFIFO[32][3]
)。我已经把这个缓冲区打印成了序列号,表明它在工作。这就是这个函数

void ADXL355_SPIF::ReadFIFO(){
    ReadRegister(ADXL355_RA_FIFO_ENTRIES, 1);
    fifoCount = buffer[0];
    ReadFIFOInternal();
    return;
}

void ADXL355_SPIF::ReadFIFOInternal(){
    SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
    *sensorPort &= ~sensorBitValue;
    uint8_t spiCommand = ADXL355_RA_FIFO_DATA << 1 | ADXL355_READ;
    SPI.transfer(spiCommand);
    int i = 0;
    unsigned long tempV;
    unsigned long value;
    while(i < fifoCount){
        for (int ptr = 0; ptr < 3; ++ptr){
            buffer[0] = SPI.transfer(0x0);
            value = buffer[0];
            value <<= 12;
            tempV = SPI.transfer(0x0);
            tempV <<= 4;
            value |= tempV;
            tempV = SPI.transfer(0x0);
            tempV >>=4;
            value |= tempV;
            if (buffer[0] & 0x80) {
                value |= 0xFFF00000;
            }
            long lValue = static_cast<long>(value);
            sensorFIFO[i][ptr] = scaleFactor * lValue;
        }
        i += 3;
    }
    SPI.endTransaction();
    *sensorPort |= sensorBitValue;
    return;
}
允许此操作运行一段时间后,文件大小始终为0。我尝试了一个简单的二进制写函数来测试卡。看起来是这样的,而且奏效了

#include <SD.h>

#define cardSelectPin 4

const float pi=3.14159;

File oFile;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while(!Serial){
    // wait for serial
  }
  SD.begin(cardSelectPin);
  oFile = SD.open("Test.bin", FILE_WRITE);
  Serial.println(sizeof(int));
  Serial.println(sizeof(float));
  float testFloat[32][3];
  for (int i = 0; i < 32; ++i){
    for (int j = 0; j < 3; ++j){
      testFloat[i][j] = pi * (i + 1) + j;
    }
  }
  oFile.write(reinterpret_cast<const char *>(&testFloat), sizeof(float) * 96);
  oFile.close();
  Serial.println("Finished writing file.");
}

void loop() {
  // put your main code here, to run repeatedly:

}
#包括
#定义cardSelectPin 4
常数浮点pi=3.14159;
文件;
无效设置(){
//将安装代码放在此处,以便运行一次:
Serial.begin(9600);
而(!串行){
//等待序列号
}
SD.开始(cardSelectPin);
oFile=SD.open(“Test.bin”,文件写入);
Serial.println(sizeof(int));
Serial.println(sizeof(float));
float testFloat[32][3];
对于(int i=0;i<32;++i){
对于(int j=0;j<3;++j){
testFloat[i][j]=pi*(i+1)+j;
}
}
oFile.write(重新解释强制转换和测试浮点),sizeof(浮点)*96;
oFile.close();
Serial.println(“完成写入文件”);
}
void循环(){
//将主代码放在此处,以便重复运行:
}

非工作草图和工作草图之间的唯一区别是sd卡的关闭。sd卡必须关闭,我遇到了与您相同的问题,我假设文件在文件关闭调用时将其边界写入其文件系统。

要解决您的问题,请使用按钮。当您按下它时,它将关闭文件并停止读取/处理传感器。您也可以使用此按钮再次开始读取和记录sd卡上的传感器数据(切换)。

问题在于未正确调用
flush
。我已经创建了一个缓冲区来保存来自FIFO的数据,当它足够满时,它会刷新卡,这样后续的读取就会溢出。那时它将调用
flush
。这是变量
sensorWriteCount
的预期用途。此变量的类型为
uint8\u t
,而它本应为
uint16\u t


更改为正确的类型修复了问题。我会删除这个问题,因为它归结为一个打字错误,但一旦发布了答案,系统就不允许这样做。

这是不正确的。如果删除
close
语句,则第二个草图的工作原理与之前完全相同<代码>刷新将缓冲区写入卡。此外,非工作草图包含ADXL库中的
文件
,这似乎是问题所在。如果我将
文件
移动为全局文件,我会将数据取出。这个答案是错误的。我的问题是当我在sd卡上写入值时,数据的存储是有问题的,但是当我没有写入值时,它们是正确的。