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()); } }
buffLener opprinnelig0, så øker du det umiddelbart til16og deretter kopierer du dataene til den bufferen ved forskyvning16. Men hva med den første16byte? Hvorfor la du dem ubrukt? Det er heller ikke klart hvorfor du til og med trenger å stadig pumpe byte frameasuretilbuffer1, dvs. fra minne til minne. Hvorfor ikke ' t du bare erklærer en matrise med32struct measureelementer og bruke det direkte?unsigned intfor buffLen, fordi 15 * 3200 er mer ennintkan ta