2017-10-10 1 views
0

Adafruit Feather Adalogger에 ADXL355 가속도계가 연결되어 있습니다. 나는 센서를 구성하고 읽을 수 있습니다. SD 카드에 이진 값을 쓸 수도 있습니다. 문제는 센서에서 읽은 다음 SD 카드에 기록하려고 할 때 발생합니다. 내가 생각할 수있는 유일한 것은 내가 어떻게 든 SPI 통신을 엉망으로 만든다는 것이다. 그러나 나는 어디에서 볼 수 없다. 내 보드에 대해서는 pins_arduino.h을 보았고 SD 카드 (핀 4)는 핀 10과 다른 레지스터에 있으므로 어떻게 부서지는지 알지 못합니다.다른 SPI 장치와 함께 사용하면 Arduino SD 카드에 쓸 수 없습니다.

내 작업은 다음과 같이 진행됩니다. 글로벌 센서 생성, 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(); 
    } 
} 

는 ADXL 생성자에게의 DeviceID가 0xAD를 읽고

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 테스트입니다. 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; 
} 

0 파일 크기 "TESTSPI.BIN"라는 SD 카드에 생성됩니까이 파일을 실행 한 후.

ReadFIFO은 FIFO에있는 항목 수를 읽고 fifoCount으로 저장 한 다음 버퍼 (sensorFIFO[32][3])에 FIFO 값을 채 웁니다. 이 버퍼를 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

문제는 flush이 올바르게 호출되지 않았습니다. 나는 FIFO로부터 데이터를 유지하기위한 버퍼를 만들었고 후속 읽기가 오버 플로우 될 정도로 충분히 가득차면 카드를 플러시 할 것이다. 그 당시에는 flush이라고합니다.이것은 변수 sensorWriteCount으로 의도 된 것입니다. 이 변수는 uint16_t 일 때 uint8_t 유형이었습니다.

올바른 유형으로 변경하면 문제가 해결되었습니다. 이 질문은 오타가 있기 때문에 삭제되었지만 답변이 게시되면 시스템에서이를 허용하지 않습니다.

0

작동하지 않는 스케치와 작동하는 스케치의 유일한 차이점은 sd 카드를 닫는 것입니다. sd 카드를 반드시 닫아야 만합니다. 동일한 문제가 있었는데 파일 닫기시 파일 시스템에 파일 경계가 기록되어 있다고 가정합니다.
문제를 해결하려면 누름 단추를 사용하십시오. 누를 때 파일을 닫고 센서 읽기/처리를 중지합니다. 이 버튼을 사용하여 SD 카드에서 센서 데이터를 다시 읽고 기록 할 수 있습니다 (토글).

+0

사실이 아닙니다. 'close' 문을 제거하면 두 번째 스케치가 이전과 똑같이 작동합니다. 'flush'는 버퍼를 카드에 씁니다. 또한 작동하지 않는 스케치는 ADXL 라이브러리의 'File'을 포함하고 있습니다. 'File'을 글로벌로 이동 시키면 데이터가 나옵니다. 이 대답은 잘못된 것입니다. – Matt

관련 문제