我有一个ADXL355加速度计连接到Adafruit Feather Adalogger . 我可以配置和读取传感器 . 我也可以将二进制值写入SD卡 . 当我尝试从传感器读取然后将该数据写入SD卡时,会出现问题 . 我能想到的唯一一件事是我看到了哪里 . 我通过 pins_arduino.h
浏览了我的电路板,而SD卡(引脚4)与10号寄存器位于不同的寄存器上,所以我不打算破坏它们 .
我的操作就这样进行 . 全局传感器创建, 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
测试DeviceID读取 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”的SD卡上创建一个文件,文件大小为0 .
ReadFIFO
读取FIFO中的条目数,存储为 fifoCount
,然后使用FIFO中的值填充缓冲区( sensorFIFO[32][3]
) . 我've printed this buffer to Serial to show that it'正在工作 . 这是那个功能
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:
}
2 回答
问题是没有正确调用
flush
. 我已经创建了一个缓冲区来保存来自FIFO的数据,当它足够充满以便后续读取溢出时,它会刷新卡 . 那时它会调用flush
. 这是变量sensorWriteCount
的目的 . 该变量的类型为uint8_t
,应该是uint16_t
.更改为正确的类型修复了问题 . 我会删除这个问题,因为它归结为一个错字,但一旦发布了答案,系统就不允许这样做 .
非工作草图和工作草图之间的唯一区别是关闭SD卡 . 必须关闭SD卡,我遇到了同样的问题,我假设文件在文件关闭调用时在其文件系统中写入边界 .
要解决您的问题,请使用按钮 . 当您按下它时,它将关闭文件并停止读取/处理传感器 . 您也可以使用此按钮再次开始在SD卡上读取和记录传感器数据(切换) .