我有一个ADXL355加速度计连接到Adafruit Feather Adalogger。我可以配置和读取传感器。我也可以将二进制值写入SD卡。当我尝试从传感器读取然后将该数据写入SD卡时,会出现问题。我唯一能想到的是我在某种程度上弄乱了SPI通信,但我无法看到它在哪里。我通过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]
)。我已将此缓冲区打印到Serial以显示它正在工作。这是函数
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 :(得分:1)
问题是没有正确调用flush
。我已经创建了一个缓冲区来保存来自FIFO的数据,当它足够充满以便后续读取溢出时,它会刷新卡。那时它会调用sensorWriteCount
。这是变量uint8_t
的目的。此变量的类型为uint16_t
,应该是 FOR v IN 1..2 OUTBOUND "teacher_id" GRAPH "graph_name"
FILTER LIKE(v._id, "pupil_collection_name/%")
FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name"
LIMIT lowerLimit,numberOfItems
RETURN homeworks
。
更改为正确的类型解决了问题。我本来会删除这个问题,因为它归结为一个错字,但是一旦发布了答案,系统就不允许这样做。
答案 1 :(得分:0)
非工作草图和工作草图之间的唯一区别是关闭SD卡。必须关闭SD卡,我遇到了同样的问题,我假设文件在文件关闭调用时在文件系统中写入边界。
要解决您的问题,请使用按钮。当您按下它时,它将关闭文件并停止读取/处理传感器。您也可以使用此按钮再次开始在SD卡上读取和记录传感器数据(切换)。