Jutilise un Mega 2560 pour communiquer avec un mélange de capteurs analogiques (mesurés via analogRead ()) et basés sur I2C. Les données échantillonnées sont placées dans un tableau de 16 octets, puis écrit sur une carte SD une fois quun tampon de 512 octets est complètement rempli. Le problème que je rencontre est que lorsque je collecte des données à partir dun oxymètre de pouls MAX30102 en utilisant
measure.pox = pulseOx.getIR();
daprès mon code ci-dessous, le temps de cycle de ma boucle collectHR () tombe à environ 20 mS. Si je préalloue cet endroit en utilisant la ligne directement en dessous (en stockant une constante au lieu de lire un nouveau uint32_t à chaque boucle), mon temps de cycle est denviron une demi-milliseconde. Ce qui est déroutant pour moi, cest que si je transforme uint32_t en une chaîne en utilisant dtostrf:
dtostrf(pulseOx.getIR(),3,0,pOxBuf); // read pulseOx, convert it into a 3 byte string
il ne faut quenviron 1,2 mS pour lire un échantillon à partir de le MAX30102. Il me semble quen privilégiant une structure sur une chaîne (dune itération antérieure de ce code qui écrivait toutes les données sous forme de fichier txt au lieu dun fichier bin) afin que je puisse écrire du binaire sur ma carte SD, je » Je ralentis absolument ma vitesse. Ne devrait-il pas être plus efficace de travailler par octet que de travailler avec une chaîne? Que se passe-t-il pour les 18 autres ms qui se produisent entre la lecture du long unsigned et son placement dans byte buffer, buffer1? Implémentation de ce code en utilisant des tableaux de chaînes au lieu dune structure, Jai pu courir à environ 125 Hz. Maintenant, je suis à environ 50 Hz. Japprécierais tout renseignement ici. Code pertinent indiqué ci-dessous:
#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
est initialement0
, puis vous laugmentez immédiatement à16
, puis copiez les données dans cette mémoire tampon au décalage16
. Mais quen est-il du premier16
octets? Pourquoi les avez-vous laissés inutilisés? De plus, la raison pour laquelle vous devez constamment pomper des octets demeasure
àbuffer1
nest pas claire. , cest-à-dire de mémoire en mémoire. Pourquoi ne ' que vous déclarez simplement un tableau de32
struct measure
et les utiliser directement?unsigned int
pour buffLen, car 15 * 3200 est plus que ce queint
peut prendre