저는 Mega 2560을 사용하여 아날로그 (예 : analogRead ()를 통해 측정) 및 I2C 기반 센서의 혼합과 통신합니다. 샘플링 된 데이터는 512 바이트 버퍼가 완전히 채워지면 SD 카드에 16 바이트 배열이 기록됩니다. 문제는
아래 코드에서 collectHR () 루프의주기 시간이 약 20mS로 떨어집니다. 바로 아래에있는 줄을 사용하여이 지점을 미리 할당하면 (각 루프마다 새 uint32_t를 읽는 대신 상수 저장) 사이클 시간은 약 0.5 밀리 초입니다. 저에게 혼란스러운 점은 dtostrf를 사용하여 uint32_t를 문자열로 캐스트하는 경우 :
dtostrf(pulseOx.getIR(),3,0,pOxBuf); // read pulseOx, convert it into a 3 byte string
실제로 샘플을 읽는 데 약 1.2mS 밖에 걸리지 않습니다. 이진 파일을 SD 카드에 쓸 수 있도록 모든 데이터를 bin 파일 대신 txt 파일로 작성한이 코드의 이전 반복에서 나온 문자열보다 구조체를 선호하는 것 같습니다. 내 속도를 절대적으로 제한합니다. 바이트 단위로 작업하는 것이 문자열로 작업하는 것보다 더 효율적이어야하지 않습니까? 부호없는 long을 읽고이를 바이트 버퍼 buffer1에 배치하는 사이에 발생하는 다른 18mS는 어떻게됩니까? 구조체 대신 문자열 배열을 사용하여이 코드를 구현하면 약 125Hz에서 실행할 수 있었지만 이제는 약 50Hz입니다. 여기에 대한 정보가 있으면 감사하겠습니다. 관련 코드는 다음과 같습니다.
#include <Wire.h> #include "MAX30105.h" #include <SPI.h> #include <SdFat.h> #define moisture0 A0 // Upper back sensor analog pin #define moisture1 A7 // Trunk sensor analog pin #define ECGpin A3 // ECG analog pin SdFat SD; // replace SD with SDfat. File sdLog; // placeholder to create datalogger struct meas // a 16 byte structure to hold all of our measurements { unsigned long mils; int ECG; uint32_t pox; int tempInt; int m1; int m2; }; struct meas measure; // create an instance of the above structure byte buffer1[512]; byte *measureLoc = (byte *) &measure; // to access measure structure as bytes char fileName[] = "WIHMSlog.bin"; void setup { Serial.begin(230400); } void loop() { sdLog = SD.open(fileName, O_WRITE | O_CREAT | O_AT_END); // Create file for the datalogging and verify its existance collectHR(); sdlog.close() } void collectHR() { unsigned int loopCount = 0; int buffLen = 0; // starting position in buffer int buffSize = 16; while (loopCount < 3200) { // some multiple of 32 (since 512 byte/sd block divided by 16 bytes per loop cycle = 32 cycles per sd write cycle measure.ECG = analogRead(ECGpin); // read ECG and stick the int into measures measure.pox = pulseOx.getIR(); //measure.pox = 5555; // Placeholder value measure.mils = micros(); measure.m1 = analogRead(moisture0); measure.m2 = loopCount; // just a test to ensure this is actually iterating in the card if (buffLen == 512) { // SD buffer is full, time to write! sdLog.write(buffer1, 512); buffLen = 0; } memcpy(buffer1 + buffLen, measureLoc, buffSize); // place the 16 byte data structure into the buffer buffLen = buffLen + buffSize; // increase the index size in the array loopCount++; Serial.println(micros()); } }
buffLen
는 처음에는0
이고 즉시16
그런 다음 오프셋16
의 해당 버퍼에 데이터를 복사합니다.하지만 첫 번째16
바이트? 왜 사용하지 않은 상태로 두 셨나요? 또한measure
에서buffer1
로 바이트를 지속적으로 펌프해야하는 이유도 명확하지 않습니다. 즉, 메모리에서 메모리로. '32
struct measure
요소를 사용하고 직접 사용 하시겠습니까?int
가 차지할 수있는 것보다 많기 때문입니다.