2 Sensoren an I²C-Schnittstelle

Hallo an alle,

ich habe folgendes Problem:
Ich möchte gerne 3 Sensoren für die Überwachung der Vitalfunktionen Pulsfrequenz (Sensor: Max30105), Temperatur (Sensor: MLX90614) und Schweiß (GRV GSR SENS) an meinen Arduino (ESP-32 Dev Kit C, Datenblatt im Anhang) anschließen und mir die Werte anzeigen lassen.
Problematisch ist, dass die Sensoren für die Puls- und Temperaturmessung an die gleichen Pins des Arduinos (3V, GND, SDA und SCL) angeschlossen werden. Für SDL und SCL werden dabei die Pins G21 und G22 verwendet.
Wenn man nun das System startet werden die richtigen Werte für den Schweiß- und Pulssensor angezeigt, jedoch zeigt der Temperatursensor die ganze Zeit einen Wert von ca. 1700 Fahrenheit (was definitiv zu hoch und falsch ist) an. Schließt man nur den Temperatursensor und den Schweißsensor an, wird die richtige Temperatur angezeigt.
Ich habe schon ein paar Recherchen zu dem Thema angestellt und dabei herausgefunden, dass man auch beide I²C-Schnittstellen verwenden kann (siehe ESP32: Beide I²C-Schnittstellen verwenden – AZ-Delivery). Das Ganze habe ich versucht in meinen Code zu implementieren (siehe Anhang oder im weiteren Verlauf), jedoch werden mir jedes Mal nur vom Puls- und Schweißsensor die richtigen Werte angezeigt. So wie der Code im Moment vorliegt, zeigt er mir die Puls- und Schweißwerte an. Ich habe selber mal versucht weitere Pins zu implementieren (diese Stellen sind auskommentiert //). Die letzten Zeilen sind eigentlich uninteressant, da ich in diesem Schritt alle zu messenden Werte in ein Google Sheet eintragen lasse.

Vielleicht hat jemand eine Idee woran es liegen könnte, oder ob es eine bessere Lösung gibt.

Vielen Dank im Voraus

Code:

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include "MAX30105.h"
#include "heartRate.h"

//#define SDA1 21
//#define SCL1 22
//#define SDA2 17
//#define SCL2 16
//
//TwoWire I2Cone = TwoWire(0);
//TwoWire I2Ctwo = TwoWire(1);

MAX30105 particleSensor;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

//setup
const char * ssid = "xy"; // routername
const char * password = "yx"; // passwort
String GOOGLE_SCRIPT_ID = "AKfycbz2Vl3HJvYJ5SY8oIdmB4EJOuW-EXlOhQfly8G62KdYL4tAkiph"; // google script id
const int sendInterval = 996 *10; // in millis, 996 instead of 1000 is adjustment, with 1000 it jumps ahead a minute every 3-4 hours
const byte RATE_SIZE = 4; // increase this for more averaging. 
byte rates[RATE_SIZE]; // array of heart rates
byte rateSpot = 0;
long irValue = 0;
long lastBeat = 0; // time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
const int GSR=32;
int sensorValue=0;
int gsr_average=0;


const char * root_ca=\
"-----BEGIN CERTIFICATE-----\n" \
"MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\n" \
"A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\n" \
"Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\n" \
"MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\n" \
"A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\n" \
"hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\n" \
"v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\n" \
"eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\n" \
"tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\n" \
"C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\n" \
"zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\n" \
"mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\n" \
"V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\n" \
"bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\n" \
"3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\n" \
"J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\n" \
"291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\n" \
"ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\n" \
"AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\n" \
"TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n" \
"-----END CERTIFICATE-----\n";
 
WiFiClientSecure client;

TaskHandle_t taskUpdateDataOnline;

void setup()
{
  Serial.begin(115200);
//  I2Cone.begin(SDA1,SCL1,400000); // SDA pin 21, SCL pin 22 TTGO TQ
//  I2Ctwo.begin(SDA2,SCL2,400000); // SDA2 pin 17, SCL2 pin 16 
  Serial.println("Initializing...");

// Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
    Serial.println("MAX30105 was not found. Please check wiring/power. ");
    while (1);
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");

  particleSensor.setup(); //Configure sensor with default settings
  particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
  particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
  
  //connection
    xTaskCreatePinnedToCore(
      updateDataOnline,         // task funktion
      "updateDataOnline",       // name of task
      50000,                    // stack size of task
      NULL,                     // parameter of the task
      2,                        // priority of the task
      &taskUpdateDataOnline,    // task handle to keep track of created task
      0);                       // pin task to core 0
      delay(500);               // needed to start-up task1

  mlx.begin();  
}


void loop()
{
  // measuring of bpm
  irValue = particleSensor.getIR();
  
  if (checkForBeat(irValue) == true)
  {
    //sending beats
    long delta = millis() - lastBeat;
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);
    if (beatsPerMinute < 255 && beatsPerMinute > 20)
    {
      rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
      rateSpot %= RATE_SIZE; //Wrap variable

      //Take average of readings
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
        beatAvg /= RATE_SIZE;
    }
  }

  if (irValue < 50000)
    Serial.print(" No finger?");
    Serial.println();

  // measuring of GSR
  long sum=0;
    for(int i=0;i<10;i++)           //Average the 10 measurements to remove the glitch
    {
      sensorValue=analogRead(GSR);
      sum += sensorValue;
      delay(5);
    }
  gsr_average = sum/10;
  
  Serial.print("IR="); Serial.print(irValue);
  Serial.print(", BPM="); Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM="); Serial.println(beatAvg);
  Serial.print("Ambient="); Serial.print(mlx.readAmbientTempC()); Serial.print("*C");
  Serial.print(", Object="); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
  //  Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF()); Serial.println("*F");
  //  Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");
  Serial.print("GSR="); Serial.println(gsr_average);
}


void updateDataOnline( void * parameter )
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("Started");
  Serial.print("Connecting");
    while (WiFi.status() != WL_CONNECTED)
    {
      delay(500);
      Serial.print(".");
      Serial.println("Ready to go");
    }
  Serial.println("Initializing...");
  
    while(1)
    {
      delay(sendInterval);
      sendData("IR="+String(irValue)+"&BPM="+String(beatsPerMinute)+"&Avg="+String(beatAvg)+"&AmbientTempC="+String(mlx.readAmbientTempC())+"&ObjectTempC="+String(mlx.readObjectTempC())+"&GSR="+String(gsr_average));
    }
}


void sendData(String params)
{
    HTTPClient http;
     String url = "https://script.google.com/macros/s/"+GOOGLE_SCRIPT_ID+"/exec?"+params;
    //Serial.print(url);
    //Serial.print("Making a request");
    http.begin(url, root_ca); //Specify the URL and certificate
    int httpCode = http.GET();  
    http.end();
    //Serial.println(": done "+httpCode);
}

Arduino_Code.txt (6.29 KB)

ESP32 Development Board_V2 (1).pdf (542 KB)

(deleted)

esp32devkit:
Ich möchte gerne 3 Sensoren für die Überwachung der Vitalfunktionen Pulsfrequenz (Sensor: Max30105), Temperatur (Sensor: MLX90614) und Schweiß (GRV GSR SENS) an meinen Arduino (ESP-32 Dev Kit C, Datenblatt im Anhang) anschließen

Problematisch ist, dass die Sensoren für die Puls- und Temperaturmessung an die gleichen Pins des Arduinos (3V, GND, SDA und SCL) angeschlossen werden. Für SDL und SCL werden dabei die Pins G21 und G22 verwendet.
Wenn man nun das System startet werden die richtigen Werte für den Schweiß- und Pulssensor angezeigt, jedoch zeigt der Temperatursensor die ganze Zeit einen Wert von ca. 1700 Fahrenheit (was definitiv zu hoch und falsch ist) an. Schließt man nur den Temperatursensor und den Schweißsensor an, wird die richtige Temperatur angezeigt.

Das Zertifikat und den Script-ID aus dem geposteten Code.

Was hast Du für einen Temp-Sensor?
Es gibt einen mit 3V und einen mit 5V.
Neben MLX90614 muss noch draufstehen E oder K sowie SF und dann ein Code aus drei Zeichen. Das erste Zeichen
A ware 5V
B wäre 3V

Was passiert, wenn Du alle Sensoren dran hast und dann das Example aus der Bibliothek zur Temp-Messung nimmst?

Wie bereits erwähnt wurde, werden die I2C-Sensoren alle parallel an SCL und SDA angeschlossen.
Pullup-Widerstände wurden auch schon erwähnt.
Jeder Sensor (jedes Device) braucht eine eigene Adresse. Oft ist die Adresse einstellbar (z.B. durch Verbinden von Lötbrücken).

Falls es keine Möglichkeit gibt die Adresse einzustellen, kannst du einen I2C-Multiplexer verwenden, z.B. PCA9547, PCA9548, TCA9544A oder TCA9548A 1-to-8 I2C multiplexer (Link = Tutorial). An letzteren können bis zu 8 I2C-Geräte angeschlossen werden. Die Adresse des Multiplexers liegt im Bereich 0x70 bis 0x77 (und keines der anderen Geräte darf dieselbe Adresse wie der Multiplexer haben).
Zuerst wird der Multiplexer angesprochen und eine Zahl zwischen 0 und 7 geschickt. Dadurch schaltet der Multiplexer zum gewünschten "Kanal". Danach wird "ganz normal" das Gerät an diesem Kanal angesprochen, also mit Adresse etc. (z.B. Sensoren, DAC, Displays). Die Adressen der angeschlossenen Geräte dürfen gleich oder verschieden sein (nur die Adresse des Multiplexers selbst darf nicht vorkommen).
Habe ich selbst schon oft verwendet, zuletzt z.B. beim Ansprechen von . 8 I2C-ADCs 8 I2C-DACs. Funktioniert problemlos. :slight_smile:

Nur zur Info:
Der ESP32 ist kein Arduino, auch wenn du ihn mit der Arduino IDE programmieren kannst.
Und am besten mal Hyperlinks der verwendeten Sensoren posten, dann sehen wir mehr.

@ HotSystems
Ich bekomme Angst Ihr vertretet mich zu gut. :wink: :wink: :wink:
Grüße Uwe

uwefed:
@ HotSystems
Ich bekomme Angst Ihr vertretet mich zu gut. :wink: :wink: :wink:
Grüße Uwe

Keine Bange, wir versuchen dich nur zu unterstützen.

Und das machen wir gern.

HotSystems:
Keine Bange, wir versuchen dich nur zu unterstützen.

Und das machen wir gern.

Da man jedes Problem optimieren kann, sage ich:
Die Angst verdrängt zu werden ist berechtigt.

:o :o :o :o :o :o

Die Angst verdrängt zu werden ist berechtigt.

? ** Verwundert guck ** ???
Uwe bleibt Uwe, auch wenn er das hier einfach mal laufen lässt und lieber Äpfel erntet.

Sein 40.000 Posts Rekord ist in diesem Teil des Forums vorerst ungefährdet.
Und selbst das wäre keine Verdrängung von seiner Rolle hier.

Was bedeutet übrigens "Ein Problem optimieren" , combie?

Was bedeutet übrigens "Ein Problem optimieren" , combie?

Erst wollte ich die Frage noch nicht einmal ignorieren......

"Ein Problem optimieren"
Heißt: Das Maximum aus einem gegebenen Problem herausholen.

Beispiel: Auf einem Irrweg vorwärtsstürmen.
Oder: Irrtümer (Steigerung: unaufgefordert) rechtfertigen.

Angst:
Eine recht intensive Emotion, welche sich recht leicht steigern lässt, also viel Optimierungspotential bietet.
Und dann auch gerne interessante "Blüten treibt"

Selber bin ich leider zu doof, oder zu naiv, um z.B. im dunklen Angst zu haben.
Blicke also mit ein wenig Neid auf Leute, welche das auskosten können.

Erst einmal vielen Dank für die vielen Antworten!

Ich bin leider absolut neu in diesem Thema und kann daher nicht alle Fragen auf Anhieb beantworten, aber ich gebe mein bestes.

Ich habe mal ein paar Fotos von dem Gesamtaufbau angehangen. Eigentlich müssten die Sensoren parallel verschaltet sein. Auf den Bildern habe ich aus Gründen der Übersichtlichkeit den GSR-Schweißsensor rausgenommen, da dieser sowieso nur direkt an den ESP32 angeschlossen wird und keinerlei Probleme verursacht. Das Problem ist halt sobald beide I²C-Sensoren angeschlossen werden. Ziehe ich den Herzfrequenz-Sensor Max30105 ab, funktioniert der Temperatur-Sensor wieder einwandfrei (mit 3V).

Im Folgenden sind alle verwendeten Sensoren sowie die dazugehörigen Datenblätter aufgelistet:

Herzfrequenz-Sensor: https://eckstein-shop.de/Pimoroni-MAX30105-Breakout-Heart-Rate-Oximeter-Smoke-Sensor

Datenblatt Herzfrequenz-Sensor: https://cdn.sparkfun.com/assets/learn_tutorials/5/7/7/MAX30105_3.pdf

Temperatur-Sensor: https://www.ebay.de/itm/GY-906-MLX-90614-Infrarot-Thermometer-Kontaktloses-Temperatursensor-letz-Artikel/324183973745?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

Datenblatt Temperatur-Sensor: https://www.sparkfun.com/datasheets/Sensors/Temperature/MLX90614_rev001.pdfhttps://www.sparkfun.com/datasheets/Sensors/Temperature/MLX90614_rev001.pdf

GSR-Sensor: Grove - GSR Sensor | Seeed Studio Wiki

Ob die Sensoren Abschlusswiderstände mitbringen oder nicht kann ich leider nicht genau sagen. Wo kann ich das denn erkennen?

Und wie genau verteilt man denn eine eigene Adresse bzw. woran erkenne ich ob das überhaupt möglich ist? Ich würde nämlich gerne auf I²C-Multiplexer verzichten wenn das geht.

Falls noch weitere Informationen benötigt werden, lasst es mich ruhig wissen.

Wenn auf der I2C-Schnittstelle was nicht funktioniert, verwende ich gerne einen I2C-Scanner, wo mir die gefundenen Adressen angezeigt werden. Haben zwei Sensoren die selbe Adresse, kann man bei manchen die Adresse beispielsweise mit Lötbrücken oder über Konfigurationsbefehle ändern.

Beim Temperatursensor lese ich etwas von SMBus, nicht aber I2C.

Beim Temperatursensor lese ich etwas von SMBus, nicht aber I2C.
Ist weitgehend kompatibel.
Grüße Uwe