Forum: Mikrocontroller und Digitale Elektronik PPG-Sensor (MAX301 102) über I2C-Schnittstelle (Hilfe)


von Tareq (Gast)


Lesenswert?

Guten Tag liebe Community,

dies ist mein erster Post, deswegen entschuldige ich mich vorab bei 
falscher Formatierung.

Für die Universität muss ich folgendes Projekt fertig kriegen. Da wegen 
der Coronapandemie die praktische Seite des Projekts weggefallen ist und 
ich somit große Probleme mit dem Code habe, bitte ich hier um Hilfe.



Hier habe ich nochmal den zu vervollständigenden Code reinkopiert.

Danke im Voraus

Tareq

#define F_CPU 16000000

//Nachfolgend müssen vier Bibliotheks-Dateien eingebunden werden (bitte 
Punkte passend ersetzen)
#include ...
#include ...
#include ...
#include ...

// MAX30102 I2C device ID & Konfigurationsregister Adressen
#define MAX30102_ID          0xAE
#define MAX30102_REG_INT_STATUS    0x00
#define MAX30102_REG_INT_EN      0x02
#define MAX30102_REG_FIFO_DATA    0x07
#define MAX30102_REG_FIFO_CONFIG  0x08
#define MAX30102_REG_MODE_CONFIG  0x09
#define MAX30102_REG_SPO2_CONFIG  0x0A
#define MAX30102_REG_LED1_PA    0x0C


// Ring Puffer für gleitende Mittelwertbildung
#define BUFFER_SIZE 128                      // Mittelwertbildung über 
128 Werte ...
#define BUFFER_BITS 7                      // ... entsprechend 2^7 
(=128)
#define BUFFER_MASK 0x7F                    // Maskierwort für das 
Überlauf-Handling von 127 --> 0

uint16_t buffer[BUFFER_SIZE];                  // Enthält letzte 128 
PPG-Werte für die Mittelwertbildung
uint8_t buffer_index = 0;                    // Index-Nummer des 
nächsten Eintragselements im Array
uint32_t buffer_sum = 0;                    // Laufende Summe über alle 
Array-Werte

// Weitere globale Variablen und Felder
uint8_t i2c_data[3];                      // Array für neu ausgelesene 
FIFO-Werte
uint16_t ppg_raw;                        // Enthält Höchstwertige 16 
Bits des 18-Bit FIFO-Werts
uint16_t ppg_avg;                        // Enthält den aus buffer_sum 
berechneten Mittelwert
int16_t ppg_ac;                          // Enthält Wechselanteil des 
PPG-Wertes
                                // (aus Differenz zum Mittelwert)
uint8_t graph;                          // Enthält Anzahl der Zeichen je 
Zeile für den Text-Graph


void sensor_init(void)
{                                // Initialisierungssequenz für die 
Pulsmessung
                                // (nicht genannte Parameter auf "0" 
setzen!)
  i2c_write_byte(MAX30102_ID, MAX30102_REG_MODE_CONFIG, ...);  // 
Heart-Rate Modus (nur rote LED)
  i2c_write_byte(MAX30102_ID, MAX30102_REG_FIFO_CONFIG, ...);  // 
FIFO-Rollover aktiviert, chipinterne Mittelwert-
                                //   bildung über 8 Werte je FIFO Wert
  i2c_write_byte(MAX30102_ID, MAX30102_REG_SPO2_CONFIG, ...);  //   18 
Bit Auflösung, 400 samples/s
                                //   (Mittelwert über 8 Werte entspricht 
50 FIFO Werte/s)
  i2c_write_byte(MAX30102_ID, MAX30102_REG_LED1_PA, ...);    //   LED 
Strom 6,2 mA, (bei schlechtem Signal erhöhen)
  i2c_write_byte(MAX30102_ID, MAX30102_REG_INT_EN, ...);    //   PPG_RDY 
Interrupt aktivieren
                                //   (wird für die Erkennung neuer Werte 
im FIFO benötigt)
}


int main(void)
{
  // Konfiguration USART für ausschließlichen Sendebetrieb mit 19200 
Baud
  uart_setup(..., ..., ...);

  // Interrupts global freigeben
  ...();

  // Konfiguration I2C Schnittstelle für MAX30102
  DDRE = 0b00001110;                      // PE0 (SDA1) INPUT, PE1 - PE3 
(SCL1, VIN, GND) OUTPUT
  PORTE = 0b00000110;                      // PE0 (SDA1) TRISTATE, PE1 
(SCL1) + PE2 (VIN) HIGH,
                                // PE3 (GND) auf LOW
  ...();                            // Initialisierung des I2C-Bus
  _delay_ms(1);                        // Initialisierungszeit 
(sicherheitshalber) abwarten
  sensor_init();                        // Initialisierung des 
PPG-Moduls für die Pulsmessung

  while (1)
  {
    // Prüfung ob "New FIFO Data Ready" (PPG_RDY) Interrupt Flag im 
Interrupt Status Register gesetzt wurde und somit ein neuer Wert 
bereitsteht
    if(i2c_read_byte(MAX30102_ID, ...) == ...)
    {  // Nur in diesem Fall ...
      // ... einen PPG-Wert per I2C vom Sensor lesen (3 Bytes, 
little-endian) ...
      i2c_read_n_bytes(MAX30102_ID, ..., ..., ...);

      // ... diesen 18-Bit ADC-Wert (rechtsbündig in 3 Bytes) in einen 
16-Bit Wert konvertieren ...
      //     (Nur die Bits [15:0] werden genutzt)
      ppg_raw = ...;

      // ... diesen in die gleitende Mittelwertbildung über 128 Stellen 
einbeziehen ...
      buffer_sum -= buffer[buffer_index];
      buffer[buffer_index] = ...;
      buffer_sum += ...;
      buffer_index = ...;
      ppg_avg = ...;

      // ... mit diesem als Referenz den Wechselanteil (AC-ANteil) des 
PPG-Signals ermitteln (kann positiv oder negativ sein) ...
      ppg_ac = ...;

      // ... und diesen dann abschließend als neuen Balken eines 
Balken-Diagramms aus Textzeichenketten über den USART Übertragen
      graph = (uint8_t)(...);                // Textzeichenzahl für 
positiven Wertebereich 0..31
                                // skalieren und ...
      for (uint8_t n = 0; n<graph; n++)
      {
        printf(...);                  // ... entsprechende Anzahl 
Zeichen ausgeben, dann ...
      }                          //     (Textzeichen für Stapel kann 
frei gewählt werden)
      printf(...);                    // ... Textzeile abschließen
    }
  }
}

von Falk B. (falk)


Lesenswert?

Tareq schrieb:
> Guten Tag liebe Community,

Bist du ein großer Britanier? In Teutonien spricht man eher von einer 
Gemeinde oder Gemeinschaft.

> dies ist mein erster Post,

Arbeitest du bei selbiger? Forumsteilnehmer der teutonischen Art 
schreiben Beiträg oder Fragen.

> deswegen entschuldige ich mich vorab bei
> falscher Formatierung.

Nö. Auch DU darfst und MUSST lesen

"Antwort schreiben
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"

> Hier habe ich nochmal den zu vervollständigenden Code reinkopiert.

Schlecht. U.a. weil die leicht angeschlagene Forensoftware da extra 
Umbrüche eingefügt hat.

Also bitte noch einmal als Anhang.

Ach so. Was ist denn eigentlich die Frage? Siehe Netiquette

Beitrag "Einheitlicher Umgang mit faulen Schülern etc.?"

: Bearbeitet durch User
von Tareq B. (tarek0000)


Angehängte Dateien:

Lesenswert?

Ich brauche Hilfe beim Schreiben des Codes!!

von Tareq B. (tarek0000)


Lesenswert?

Das Modul ist über vier Leitungen an den Port E des ATmega328PB 
angeschlossen. Der Interrupt-Ausgang des Moduls ist nicht mit dem 
Controller verbunden, so dass die Verfügbarkeit neuer Messwerte nur 
durch wiederholtes Abfragen des Interrupt-Status ("Polling"), ermittelt 
werden kann. Dafür muss der Interrupt des Moduls zuvor initial aktiviert 
werden.

Die Versorgungsspannung bezieht das Modul aus den Port-Pins des Port E. 
Dazu müssen initial die betreffenden Port-Pins PE3 als Masseanschluss 
(GND) in den Zustand OUTPUT LOW und PE2 als Versorgungsspannung (+5 V) 
in den Zustand OUTPUT HIGH versetzt werden. Da der Mikrocontroller als 
einziger I2C-Master am Bus fungiert, erfolgt die Taktversorgung für die 
Kommunikation über die SCL-Leitung an PE1 treibend durch ihn, so dass 
der betreffende Pin initial in den Leerlaufzustand OUTPUT HIGH versetzt 
werden kann . Der Kommunikationsanschluss SDA an PE0 sollte 
sicherheitshalber initial
in den rezeptiven Zustand INPUT TRISTATE versetzt werden, damit nach dem 
Einschalten der Spannungsversorgung durch unbestimmte Signalzustände 
keine ungewollten Schreib- Aktionen auftreten können.
. Zur Durchführung der Messung muss ein Finger ohne Andruck wie in 
Abbildung 11 gezeigt vollflächig auf die Aussparung des Gehäusedeckels 
gelegt werden, so dass der Finger die nach Aktivierung rot leuchtende 
LED des Moduls abdeckt.

von Tareq B. (tarek0000)


Angehängte Dateien:

Lesenswert?

Abbildung

von Klaus W. (mfgkw)


Lesenswert?

Tareq B. schrieb:
> Ich brauche Hilfe beim Schreiben des Codes!!

ok: ich vermnute, du sollst die mit ... markierten Bereiche sinnvoll 
ausfüllen.

von Tareq B. (tarek0000)


Lesenswert?

Ja genau

von Klaus W. (mfgkw)


Lesenswert?

Was bietet die Uni-Due dafür an Skripten, Unterlagen?

von Klaus W. (mfgkw)


Lesenswert?

Klaus W. schrieb:
> ok: ich vermnute, du sollst die mit ... markierten Bereiche sinnvoll
> ausfüllen.

Gut, vielleicht deutlicher: ich vermute, DU sollst die mit ... 
markierten Bereiche sinnvoll ausfüllen.

von Falk B. (falk)


Lesenswert?

Tareq B. schrieb:
> Ich brauche Hilfe beim Schreiben des Codes!!

Hmm, was ist denn unklar? Oder suchst du einfach nur einen Ghostwriter? 
Die liegen ja im Trend, nicht nur bei Software, auch bei Büchern ;-)

Ich sehe bei dir 0% Eigeninitiative.

Beitrag "Einheitlicher Umgang mit faulen Schülern etc.?"

Netiquette

von Klaus W. (mfgkw)


Lesenswert?

reinhard.viga@uni-due.de
martin.rosenkranz@uni-due.de

von Tareq B. (tarek0000)


Angehängte Dateien:

Lesenswert?

Sollten wir nur den Teil 1 als Hausaufgabe fertig machen

von Falk B. (falk)


Lesenswert?

Tareq B. schrieb:
> Abbildung

Merkwürdig. VIN und GND schließt man nicht an IOs an, sondern an die 
Stromversorgung und GND. Bei SCL und SDA fehlen Pull-Up Widerstände nach 
VCC. Dann muss man halt das Ding per I2C ansprechen, Dazu muss man 
diverse Sequenzen schreiben und lesen. Wie das per I21C geht, steht 
sicher im Datenblatt. Wenn nicht, kann man nach I2C googeln und das 
Grundprinzip erlernen. Bei direkten Fragen stehen wir gern zur 
Verfügung.

von Klaus W. (mfgkw)


Lesenswert?

Tareq B. schrieb:
> Sollten wir nur den Teil 1 als Hausaufgabe fertig machen

Das verstehe ich jetzt nicht.
Welchen Teil 1? Ist das nicht das Blinklicht?

Deine Frage oben ist doch Teil 4?

von Klaus W. (mfgkw)


Lesenswert?

Falk B. schrieb:
> Merkwürdig. VIN und GND schließt man nicht an IOs an, sondern an die
> Stromversorgung und GND.

Genau

Zumindest nicht, solange man nicht weiß wieviel Strom das angeschlossene 
Teil zieht, und wieviel Strom der Port am AVR liefern mag, bevor etwas 
abraucht.

Tareq B. schrieb:
> Abbildung

Wo ist denn die Abbildung her? Vom Dozenten so vorgegeben? Das kann ich 
kaum glauben.

von Falk B. (falk)


Lesenswert?

Tareq B. schrieb:
> Sollten wir nur den Teil 1 als Hausaufgabe fertig machen

Aha. Und was hat das mit deiner Überschrift zu tun?

1. Einführung
Kennenlernen der Hardware und
Entwicklungs-Umgebung
• Einführung
• Blinklicht in Assembler
• Sekundenzähler mit der 7-Segment-Anzeige in C

Das ein guter Einstieg für Anfänger. Dazu muss man aber mal ANFANGEN!

von Falk B. (falk)


Lesenswert?

Klaus W. schrieb:
> Das verstehe ich jetzt nicht.
> Welchen Teil 1? Ist das nicht das Blinklicht?
>
> Deine Frage oben ist doch Teil 4?

Er meint Versuch 4, Teil 1, Seite 11. Dort sieht man auch das 
fragwürdige Blockschaltbild.

von Falk B. (falk)


Lesenswert?

"Die Versorgungsspannung bezieht das Modul aus den Port-Pins des Port E. 
Dazu müssen initial die betreffenden Port-Pins PE3 als Masseanschluss 
(GND) in den Zustand OUTPUT LOW und PE2 als Versorgungsspannung (+5 V) 
in den Zustand OUTPUT HIGH versetzt werden. Da der Mikrocontroller als 
einziger I2C-Master am Bus fungiert, erfolgt die Taktversorgung für die 
Kommunikation über die SCL-Leitung an PE1 treibend durch ihn, so dass 
der betreffende Pin initial in den Leerlaufzustand OUTPUT HIGH versetzt 
werden kann (s. Abbildung 7)."

Ganz schöne Käse.

Die Stromversorgung sollte man nicht mit IOs machen, schon gar nicht bei 
GND, der wird fest angeschlossen. VCC KANN man ggf. per IO versorgen, 
wenn der Sensor nur wenige mA benötigt.

Wenn man schon I2C macht, dann bitte richtig! D.H. auch SCL wird immer 
nur aktiv LOW oder Tristate geschaltet, NIE aktiv HIGH, denn es ist ein 
Open Drain  Signal. Es kostet weder Geld noch Aufwand, es gleich richtig 
zu machen.

von Falk B. (falk)


Lesenswert?

Aber alles in Allem ist doch schon verdammt viel erklärt! Es werden auch 
ganz konkrete Teilaufgaben gestellt (I2C konfigurieren, UART 
konfigurieren etc.) Die muss man Schritt für Schritt abarbeiten und 
testen. Ja, das ist Aufwand und nicht in 1h erledigt! Schon gar nicht, 
wenn man das lernen will.

von Klaus W. (mfgkw)


Lesenswert?

Falk B. schrieb:
> Er meint Versuch 4, Teil 1, Seite 11. Dort sieht man auch das
> fragwürdige Blockschaltbild.

Danke, wollte im Skript nicht weiter lesen als der TO :-)

Ist aber ganz interessant zu lesen:
> Für die Beantwortung der nachfolgenden Fragen finden Sie alle
> notwendigen Informationen in den Unterlagen der
> Praktikumsversuche1 bis 4, im Datenblatt
> des ATmega328PB und im Datenblatt des MAX30102.

von Klaus W. (mfgkw)


Lesenswert?

Falk B. schrieb:
> Schon gar nicht,
> wenn man das lernen will.

Geht leider nicht. Du weißt doch, wegen Corona!

Wenn ich das Skript überfliege, finde ich das als Vorbereitung 
eigentlich gut gemacht (von der HW-Anbindung mal abgesehen - wenn es 
funktioniert, soll es so sein).

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.