Zeitmessung in Aruino

Hallo Zusammen,

ich arbeite mit MAX86150 was mit Arduino uno gesteuert werden soll, ich benötige zum jeweiligen Analogwerte die millisekunden. Weil wenn ich es z.b. in Matlab als EKG-Graph auswerten möchte, brauche ich zwei Parameter( y-Achse= Analogwert, x-Wert= Zeit für jeden Messwert).
Wisst ihr eventuell wie ich die Zeit von jedem Messwert rausbekomme?
Dachte an millis() , doch in dem Code kann ich nur 20 ms sehen! ich freue mich über eure Rückmeldung


#include <Wire.h>
#include "max86150.h"

MAX86150 Sensor;

#define MAX_BRIGHTNESS 255

//+++ Vektoren für die Speicherung von Roten- und IR-Werten erstellen

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)

//Arduino Uno hat nicht genug SRAM, um 100 Samples von IR-LED-Daten und roten LED-Daten im 32-Bit-Format zu speichern
//Um dieses Problem zu lösen, wird das 16-Bit-MSB der abgetasteten Daten abgeschnitten. Samples werden zu 16-Bit-Daten

uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100];  //red LED sensor data
uint16_t EKGBuffer[100];  //EKG sensor data
uint16_t PPGBuffer[100];  //EKG sensor data

#else

uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100];  //red LED sensor data
uint32_t EKGBuffer[100];  //EKG sensor data
uint32_t PPGBuffer[100];  //EKG sensor data

#endif

int32_t bufferLength; //data length
int32_t Idxmax, Idxmin;  //SPO2 Variable und index der Max und Min Werten in der Reihe

int LastTime;
int peakValue_ekg;
int peakValue_ppg;

int16_t ecgsigned16;
uint16_t redunsigned16;
uint16_t ppgunsigned16;

long ppgAvg, ppgBaseline;
long redAvg, redBaseline;
long ecgAvg, ecgBaseline;
long t = 0;

uint16_t Samples, periode;
unsigned long time_now;


void setup() {

  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  if (!Sensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
    Serial.println(F("MAX86150 was not found. Please check wiring/power."));
    while (1);
  }

  byte ledBrightness = 128; //Options: 0=Off to 255=50mA,60
  byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  byte sampleRate = 200; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 118; //Options: 69, 118, 215, 411. 411
  int adcRange = 2048   ; //Options: 2048, 4096, 8192, 16384  ,  4096

  Sensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings

  Serial.println("OK! - all done");

}

void loop() {
  unsigned long time_last;


  bufferLength = 100;

  bool finger_status = true;

  //read the first 100 samples, and determine the signal range
  for (byte i = 0 ; i < bufferLength ; i++)
  {

    while (Sensor.available() == false) //do we have new data?

      Sensor.check(); //Check the sensor for new data

    // Werten in einem Vektor hinzufügen
    redBuffer[i] = (Sensor.getRed() >> 2);
    irBuffer[i] = (Sensor.getIR() >> 2);


    redunsigned16 = redBuffer[i];
    ppgunsigned16 = irBuffer[i];

    ecgsigned16 = (int16_t) (Sensor.getECG() >> 2);
    time_now = millis();
    //Samples++;


    ppgAvg += ( ppgunsigned16 - ppgAvg ) >> 1 ; //get the running average
    if ((abs(ppgBaseline - ppgAvg)) > 1000)
      ppgBaseline = ppgAvg;
    ppgBaseline +=  ( ppgAvg - ppgBaseline ) >> 8; //get the long baseline

    redAvg += ( redunsigned16 - redAvg ) >> 1 ; //get the running average
    if ((abs(redBaseline - redAvg)) > 1000)
      redBaseline = redAvg;
    redBaseline +=  ( redAvg - redBaseline ) >> 8; //get the long baselin e

    ecgAvg += ( ecgsigned16 - ecgAvg ) >> 1 ; //get the running average
    if ((abs(ecgBaseline - ecgAvg)) > 100)
      ecgBaseline = ecgAvg;
    ecgBaseline +=  ( ecgAvg - ecgBaseline ) >> 8; //get the long baseline


    Sensor.nextSample(); //We're finished with this sample so move to next sample




    // Rot_Filterung
    double filter_ROT_h  = Filter_rot_h();
    double ROT_s_gef = redunsigned16 - filter_ROT_h;
    //Serial.print("rot:");
    //Serial.print(ROT_s_gef - redBaseline);
    //Serial.print(',');

    // PPG_Filterung
    double filter_h  = Filter_ppg_h();
    double PPG_s_gef = ppgunsigned16 - filter_h;


    // EKG_Filterung   40 Hz

    double a0 = 0.20657128726265578 , a1 = 0.41314257452531156, a2 =  0.20657128726265578, b1 = 0.36952595241514796 , b2 =  -0.19581110146577102;
    static int  s_n = 0, s_n1 = 0 , s_n2 = 0, g_n = 0 , g_n1 = 0, g_n2 = 0 ;
    double  Data_3 = ecgsigned16;
    s_n2 = s_n1 ;
    s_n1 = s_n ;
    s_n = Data_3;
    g_n2 = g_n1 ;
    g_n1 = g_n  ;
    g_n = s_n * a0 + s_n1 * a1  + s_n2 *  a2  + g_n1  * b1  + g_n2  * b2;
    double  EKG_FILTER_L  = g_n;
    //Serial.print("PPG:");
    Serial.print(PPG_s_gef - ppgBaseline);
    Serial.print(',');
    //Serial.print("EKG:");
    Serial.println( EKG_FILTER_L - ecgBaseline);
    // Serial.print(",");
    // Serial.println(time_now-time_last);




  }
  //time_last=time_now;
}


/////////////// Get PPG- und Rot-Data + Filtering



int Get_AD1() {
  return redunsigned16;
}

int Get_AD2() {
  return ppgunsigned16;
}






double Filter_ppg_h() { //10Hz High-filetr

  const double a0 =  0.9780302754084559 , a1 = -1.9560605508169118, a2 = 0.9780302754084559 , b1 = 1.9555778328194147 , b2 = -0.9565432688144089;
  static int s_n = 0, s_n1 = 0 , s_n2 = 0, g_n = 0 , g_n1 = 0, g_n2 = 0 ;
  double  Data_6 = Get_AD2();
  s_n2 = s_n1;
  s_n1 = s_n;
  s_n = Data_6;
  g_n2 = g_n1;
  g_n1 = g_n;
  g_n = s_n * a0 + s_n1 * a1  + s_n2 * a2 + g_n1 * b1  + g_n2 *  b2;
  double  val_ppg_f = g_n;
  return val_ppg_f;
}
double Filter_rot_h() { //10Hz High-filetr

  const double a0 =  0.9780302754084559 , a1 = -1.9560605508169118, a2 = 0.9780302754084559 , b1 = 1.9555778328194147 , b2 = -0.9565432688144089;
  static int s_n = 0, s_n1 = 0 , s_n2 = 0, g_n = 0 , g_n1 = 0, g_n2 = 0 ;
  double  Data_5 = Get_AD1();
  s_n2 = s_n1;
  s_n1 = s_n;
  s_n = Data_5;
  g_n2 = g_n1;
  g_n1 = g_n;
  g_n = s_n * a0 + s_n1 * a1  + s_n2 * a2 + g_n1 * b1  + g_n2 *  b2;
  double  val_ppg_f2 = g_n;
  return val_ppg_f2;
}




// float a0 = 1.4122534649030236 , a1 =-1.3007020142696517e-16 , a2 = -0.2406852435460524  , b1 = 1.3007020142696517e-16 , b2 =  - 0.8008026466657076;
// Serial.print("Rot:");
// Serial.println(redunsigned16 - redBaseline);

Hallo Moses,

Du solltest Programme als Code-Section posten. Das geht ganz einfach.
Nur drei Schritte:
1.) wechsle zur Arduino-IDE drücke Strg-T für automtatisches formatieren

2.) mache mit der Maus einen Rechtsklick und wähle "für Forum kopieren

3.wechsle zur Forum-Texteingabe und drückte Strg-V um den Inhalt der Zwischenablage einzufügen.
fertig

Wenn ein Programm als Code-Section eingefügt ist kann man es viel besser lesen
und eine Code-Section kann man mit einem einzigen Mausklick in die Zwischenablage kopieren.

Um mal deinen Schreibstil imitieren:

"Tips geht nicht richtig. Kein sketch."

Na merkste was?

So kurz und knapp hilft das fast gar nichts.

Du wirst am Ende deutlich schneller ans Ziel kommen wenn du dir Zeit nimmst eine ausführliche Beschreibung und einen vollständigen Sketch zu posten.

vgs

1 Like

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
mfg ein Moderator.

Wieso?
millis() zählt bis 4294967295, also etwas mehr als 49 Tage.

1 Like

Vielen Dank! :grinning:

das frage ich mich auch ? :sweat_smile:

Vieleicht ist das ein Problem des Speicherplazzes.

Grüße Uwe

1 Like

Das dürfte in die Hose gehen.
So auch an anderen Stellen....

@TO: Welchen Arduino verwendest Du?
Deine Arrays brauchen schon einiges an RAM.

Gruß Tommy

1 Like

Und ich sehe keine 20ms.
Auch nirgendwo, dass/wo du überhaupt Zeiten ausgibst.

1 Like

Wieso?
Welche Geister siehst du da?

1 Like

Arduino Uno

schöne Grüße

asdsadsadasdasd

Hallo Moses,

ich schreibe jetzt richtig Klartext in der Hoffnung das du das verstehst und das nächste Posting dann den Empfehlungen entspricht.

Du scheinst es darauf anzulegen deine potentiellen Helfer durch jeweils nur halbverständliche Postings vergraulen zu wollen.

Wenn man sich die Gunst der potentiellen Helfer erhalten will dann verhält man sich so:

  1. serielle Ausgaben postet man auch als Code-Section und NICHT als Bild
  2. als hilfesuchender produziert man keine Bilderrätsel sondern schreibt leicht verständliche Erklärungen
  3. Wenn etwas bestimmtes angefragt wurde dann reagiert man auf die Frage.
    In diesem Fall ist gemeint einen vollständigen Sketch zu posten

Das Minimum wäre nachvollziehbar zu erklären warum man den Sketch nicht posten will oder gerade nicht kann.

Die Entscheidung ob hier richtig Unterstützung aufkommt oder nicht liegt jetzt bei dir.
vgs

1 Like

Ich sehe da deutlich mehr als 20, z.B. 2961 2900 usw.

Was wundert dich daran?
Dass deine monströsen Arrayfüllaktionen und Berechnungen Zeit brauchen?
Mich nicht....

1 Like

Du hast eine Laufzeit zwischen 19 und 21 ms je Umlauf.
Bedenke: das aufaddieren der ms ist interruptbasiert.

Sieh zu, das Deine Rechnerei schneller wird.

Ich sehe da 2900, 2921, 2940, 2961 als aufaddiertes Ergebnis.

1 Like

Das wird nix.
Der UNO hat 2048 Bytes RAM, Deine Arrays belegen 2400 Bytes.

--> Ende Gelände.

Gruß Tommy

@moses760 Das ist nicht dein Ernst:

Das sind 100 Umläufe in 20 ms.

Ohne das Kleinvieh zu zählen sehe ich da nur 800 Byte in Arrays.

Aber nirgendwo die 20.

Was ist denn jetzt hiermit?

???

Du hast Recht, ich habe das #if defined übersehen und beides zusammen gezählt
Sorry.

Gruß Tommy