Jeg bruker en Mega 2560 for å kommunisere med en blanding av analoge (dvs. målt via analogRead ()) og I2C-baserte sensorer. Samplede data plasseres i en 16 byte matrise, deretter skrevet til et SD-kort når en 512 byte buffer er fullstendig fylt. Problemet jeg kjører på er at når jeg samler inn data fra et MAX30102 pulsoksymeter ved hjelp av
measure.pox = pulseOx.getIR();
fra koden min nedenfor, faller syklustiden til collectHR () -sløyfen til omtrent 20 mS. Hvis jeg forhåndslokaliserer dette stedet ved å bruke linjen rett under den (lagrer en konstant i stedet for å lese en ny uint32_t hver sløyfe), er syklustiden min omtrent et halvt millisekund. Det som er forvirrende for meg er at hvis jeg kaster uint32_t inn i en streng ved hjelp av dtostrf:
dtostrf(pulseOx.getIR(),3,0,pOxBuf); // read pulseOx, convert it into a 3 byte string
tar det bare omtrent 1,2 mS å lese en prøve fra MAX30102. Det virker for meg at ved å favorisere en struktur over en streng (fra en tidligere iterasjon av denne koden som skrev alle data som en txt-fil i stedet for en bin-fil) slik at jeg kan skrive binært til SD-kortet mitt, jeg » Jeg strupes absolutt av farten min. Bør ikke arbeid bytevis være mer effektivt enn å jobbe med en streng? Hva skjer med de andre 18 mS som oppstår mellom å lese den usignerte lange og plassere den i byte-buffer, buffer1? Implementere denne koden ved hjelp av strengarrayer i stedet for en struktur, Jeg klarte å løpe på omtrent 125 Hz. Nå er jeg omtrent 50 Hz. Jeg vil sette pris på noe innblikk her. Relevant kode vist nedenfor:
#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
er opprinnelig0
, så øker du det umiddelbart til16
og deretter kopierer du dataene til den bufferen ved forskyvning16
. Men hva med den første16
byte? Hvorfor la du dem ubrukt? Det er heller ikke klart hvorfor du til og med trenger å stadig pumpe byte frameasure
tilbuffer1
, dvs. fra minne til minne. Hvorfor ikke ' t du bare erklærer en matrise med32
struct measure
elementer og bruke det direkte?unsigned int
for buffLen, fordi 15 * 3200 er mer ennint
kan ta