2017-10-10 201 views
0

我有一個ADXL355加速度計連接到Adafruit羽毛Adalogger上。我可以配置和讀取傳感器。我也可以將二進制值寫入SD卡。當我嘗試從傳感器讀取數據然後將數據寫入SD卡時,會出現問題。我能想到的唯一的事情是我搞砸了SPI通信,但我看不到在哪裏。我通過pins_arduino.h查看了我的主板,SD卡(第4針)與第10針不在同一個寄存器中,所以我沒有看到我是如何破壞的。Arduino SD卡在與另一個SPI設備一起使用時無法寫入

我的操作是這樣進行的。創建全局傳感器,Serial.begin,SD.begin,SPI.begin,測試傳感器連接,創建SD卡輸出文件,初始化傳感器,讀取傳感器FIFO,寫入文件,永遠重複上次2。

該文件已創建,但保持爲0文件大小,即沒有任何內容實際寫入該卡。

傳感器可以工作在4 kHz,這很難通過使用digitalWrite函數實現,所以我切換到使用羽化端口寄存器。我不喜歡這樣寫道:

#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(); 
    } 
} 

這裏是ADXL構造

ADXL355_SPIF::ADXL355_SPIF(volatile uint8_t * outReg, volatile uint8_t * outPort, uint8_t bitValue) : sensorOutReg(outReg), sensorPort(outPort), sensorBitValue(bitValue){ 
    *sensorOutReg |= sensorBitValue; 
    *sensorPort |= sensorBitValue; 
    sensorWriteCount = 0; 
} 

TestConnection測試,設備ID讀取0xADInitialize設置G範圍,以Hz爲單位的採樣率和濾波器。我用串行輸出測試了它們,它們正常工作。

OpenFile看起來是這樣的:

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; 
} 

運行此文件並得到所謂「TESTSPI.BIN」 0文件大小的SD卡上創建後。

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; 
} 

這裏是WriteFIFOToFile

void ADXL355_SPIF::WriteFIFOToFile(){ 
    if (fifoCount > 0){ 
     sensorFile.write(reinterpret_cast<const char *>(&sensorFIFO), 4 * fifoCount); 
    } 
    sensorWriteCount += fifoCount; 
    if (sensorWriteCount >= 100){ 
     sensorFile.flush(); 
     sensorWriteCount = 0; 
    } 
} 

允許這對於運行,而文件大小始終爲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: 

} 

回答

0

問題是沒有正確調用flush。我已經創建了一個緩衝區來保存來自FIFO的數據,並且當它充分足夠時刷新該卡,以致隨後的讀取會溢出。那時它會打電話給flush。這是變量sensorWriteCount的意圖。當它應該是uint16_t時,該變量的類型爲uint8_t

更改爲正確的類型可解決問題。我會刪除這個問題,因爲它可以歸結爲一個錯字,但是一旦發佈了答案,系統就不允許這樣做。

0

的不工作的草圖和工作一個之間的唯一區別是SD卡的關閉。 SD卡必須關閉,我遇到了同樣的問題,並且我認爲文件在文件關閉時將其邊界寫入文件系統。
要解決您的問題,請使用按鈕。當你按下它時,它會關閉文件並停止讀取/處理傳感器。您也可以使用此按鈕重新開始在SD卡上讀取和記錄傳感器數據(切換)。

+0

這是不正確的。如果我刪除close語句,第二個草圖就像以前一樣工作。 'flush'將緩衝區寫入卡。此外,非工作草圖包含ADXL庫中的「文件」,這似乎是問題所在。如果我將'File'移動到全局位置,則會獲取數據。這個答案是錯誤的。 – Matt