Mega 2560を使用して、アナログ(つまり、analogRead()を介して測定)とI2Cベースのセンサーの混合物と通信しています。サンプルデータは次の場所に配置されます。 16バイトのアレイで、512バイトのバッファが完全にいっぱいになるとSDカードに書き込まれます。私が直面している問題は、
以下のコードから、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しかかかりません。 MAX30102。文字列よりも構造体を優先することで(すべてのデータをbinファイルではなくtxtファイルとして書き込んだこのコードの以前の反復から)、SDカードにバイナリを書き込むことができるように思えます。」 m絶対に私の速度を抑えます。文字列を操作するよりもバイト単位で作業する方が効率的ではありませんか?unsignedlongを読み取ってからバイトバッファ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
バイト?なぜそれらを未使用のままにしたのですか?また、なぜバイトをmeasure
からbuffer1
に絶えずポンピングする必要があるのかは明らかではありません。 、つまりメモリからメモリへ。'32
struct measure
要素を直接使用しますか?int
が取ることができる以上であるため