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