Utilizez un Mega 2560 pentru a comunica cu un amestec de senzori analogici (adică măsurați prin analogRead ()) și I2C. Datele eșantionate sunt plasate în o matrice de 16 octeți, apoi scrisă pe un card SD odată ce un buffer de 512 octeți este complet umplut. Problema pe care o „întâlnesc este că atunci când colectez date dintr-un oximetru de impuls MAX30102 folosind
measure.pox = pulseOx.getIR();
din codul meu de mai jos, timpul ciclului buclei mele collectHR () scade la aproximativ 20 mS. Dacă prealocez acest loc folosind linia direct sub el (stocând o constantă în loc să citesc un nou uint32_t fiecare buclă), durata ciclului meu este de aproximativ o jumătate de milisecundă. Ceea ce este confuz pentru mine este că, dacă arunc uint32_t într-un șir folosind dtostrf:
dtostrf(pulseOx.getIR(),3,0,pOxBuf); // read pulseOx, convert it into a 3 byte string
este nevoie de aproximativ 1,2 mS pentru a citi de fapt un eșantion din MAX30102. Mi se pare că, favorizând o structură peste un șir (dintr-o iterație anterioară a acestui cod care scria toate datele ca fișier txt în loc de fișier bin), astfel încât să pot scrie binare pe cardul meu SD, Îmi strâng absolut viteza. Nu ar trebui să funcționeze bytewise să fie mai eficient decât să lucrați cu un șir? Ce se întâmplă cu celelalte 18 mS care se întâmplă între citirea lungului nesemnat și plasarea acestuia în buffer byte, buffer1? Implementarea acestui cod folosind matrice de șiruri în loc de struct, Am reușit să rulez la aproximativ 125 Hz. Acum sunt la aproximativ 50 Hz. Aș aprecia orice perspectivă aici. Codul relevant prezentat mai jos:
#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
este inițial0
, apoi îl măriți imediat la16
și apoi copiați datele în acel tampon la offset16
. Dar ce zici de primul16
octeți? De ce i-ați lăsat neutilizați? De asemenea, nu este clar de ce trebuie chiar să pompați în mod constant octeți de lameasure
labuffer1
, adică de la memorie la memorie. De ce nu ' doar declarați o matrice de32
struct measure
elemente și utilizați-l direct?unsigned int
pentru buffLen, deoarece 15 * 3200 este mai mult decât poate duraint