Deutsche Anleitung: I²C-Drucksensor an ESP32 (Arduino) Basierend auf der Herstelleranleitung (siehe mitgeliefertes PDF). ============================================================ 1) Überblick ============================================================ Der Sensor liefert kalibrierte digitale Messwerte über I²C: - Druck als 24‑Bit ADC-Wert (signed) aus den Registern 0x06, 0x07, 0x08 - Temperatur als 16‑Bit Wert (signed) aus den Registern 0x09, 0x0A - Messung wird über Register 0x30 gestartet; Fertig-Status über SCO-Bit (Bit 3) in 0x30 ============================================================ 2) Verdrahtung an ESP32 (WICHTIG: 3,3 V!) ============================================================ Kabelfarben → ESP32: - Braun → 3V3 (Versorgung +) - Blau → GND - Weiß → SDA - Schwarz→ SCL Pull-Ups: - Im Hersteller-Schaltbild sind 4,7 kΩ Pull-Ups eingezeichnet. - Laut Text sind Pull-Ups bereits integriert → normalerweise keine zusätzlichen Pull-Ups nötig. ESP32-Pins (Beispiel): - SDA = GPIO 21 - SCL = GPIO 22 Du kannst andere I²C-fähige GPIOs nehmen und im Code Wire.begin(SDA, SCL) setzen. ============================================================ 3) I²C-Adresse ============================================================ In der Hersteller-Bit-Tabelle ist A7..A1 = 1, danach W/R. Das ergibt eine 7‑Bit‑Adresse von 0x7F. Hinweis: 0x7F ist im I²C-Standard „speziell“/reserviert. Manche I²C‑Scanner finden ihn nicht. Im Zweifel den Sensor trotzdem direkt mit 0x7F ansprechen (siehe Beispielcode). ============================================================ 4) Messablauf (Register-Protokoll) ============================================================ 1) Messung starten: Schreibe 0x0A in Register 0x30 (Temp + Pressure acquisition) 2) Warten bis fertig: Lies Register 0x30. Wenn SCO (Bit 3) = 0, ist die Messung fertig. Alternativ kann man (laut Beispiel) ~50 ms warten. 3) Daten lesen: Lies 0x06..0x0A in einem Rutsch (5 Bytes): - 0x06,0x07,0x08: Druck (24-bit) - 0x09,0x0A: Temperatur (16-bit) ============================================================ 5) Umrechnung in Druck und Temperatur ============================================================ 5.1 Druck (24‑Bit signed, Fullscale nötig) Aus den drei Bytes: - m = (x << 16) + (y << 8) + z (x=0x06, y=0x07, z=0x08) Vorzeichenbehandlung: - Wenn m > 2^23: pressure = (m - 2^24) / 2^23 * Fullscale - sonst: pressure = m / 2^23 * Fullscale WICHTIG: Fullscale = Messbereich deines Sensors (z. B. 10 bar, 16 bar, 1.2 MPa, …) Den musst du im Code passend setzen. 5.2 Temperatur (16‑Bit signed, Skalierung /256) - n = (a << 8) + b (a=0x09, b=0x0A) Vorzeichen & Skalierung: - Wenn n > 2^15: tempC = (n - 2^16) / 256 - sonst: tempC = n / 256 ============================================================ 6) ESP32 Arduino-Beispielcode (Wire) ============================================================ WICHTIG: Setze FULLSCALE_BAR passend zu deinem Sensor! ```cpp #include // --- I2C-Konfiguration --- static constexpr uint8_t I2C_ADDR = 0x7F; // laut Hersteller-Tabelle (A7..A1 = 1) static constexpr uint8_t REG_CMD = 0x30; // Command/Status Register static constexpr uint8_t CMD_START = 0x0A; // Start: Temp + Pressure acquisition // Datenregister static constexpr uint8_t REG_DATA_START = 0x06; // 0x06..0x0A (5 Bytes) // ESP32 Pins (anpassen falls nötig) static constexpr int PIN_SDA = 21; static constexpr int PIN_SCL = 22; // --- Sensor-Messbereich (WICHTIG anpassen!) --- static constexpr float FULLSCALE_BAR = 16.0f; // Beispiel: 16 bar Fullscale // I2C: 1 Byte in Register schreiben bool i2cWriteReg(uint8_t addr, uint8_t reg, uint8_t value) { Wire.beginTransmission(addr); Wire.write(reg); Wire.write(value); return (Wire.endTransmission() == 0); } // I2C: 1 Byte aus Register lesen bool i2cReadReg(uint8_t addr, uint8_t reg, uint8_t &value) { Wire.beginTransmission(addr); Wire.write(reg); if (Wire.endTransmission(false) != 0) return false; // Repeated start if (Wire.requestFrom((int)addr, 1) != 1) return false; value = Wire.read(); return true; } // I2C: mehrere Bytes ab Startregister lesen bool i2cReadBytes(uint8_t addr, uint8_t startReg, uint8_t *buf, size_t len) { Wire.beginTransmission(addr); Wire.write(startReg); if (Wire.endTransmission(false) != 0) return false; // Repeated start int got = Wire.requestFrom((int)addr, (int)len); if (got != (int)len) return false; for (size_t i = 0; i < len; i++) buf[i] = Wire.read(); return true; } // Umrechnung nach Herstellerformeln float convertPressureBar(uint8_t b0, uint8_t b1, uint8_t b2) { uint32_t m = ((uint32_t)b0 << 16) | ((uint32_t)b1 << 8) | (uint32_t)b2; // Hersteller: wenn m > 2^23 => negativ, sonst positiv // 2^23 = 8388608, 2^24 = 16777216 float ratio; if (m > 8388608UL) { ratio = ((int32_t)m - 16777216.0f) / 8388608.0f; } else { ratio = (float)m / 8388608.0f; } return ratio * FULLSCALE_BAR; } float convertTempC(uint8_t b0, uint8_t b1) { uint16_t n = ((uint16_t)b0 << 8) | (uint16_t)b1; // Hersteller: wenn n > 2^15 => negativ // 2^15 = 32768, 2^16 = 65536, Skalierung /256 float t; if (n > 32768U) { t = ((int32_t)n - 65536.0f) / 256.0f; } else { t = (float)n / 256.0f; } return t; } bool readPressureAndTemp(float &pressureBar, float &tempC) { // 1) Messung starten (0x0A nach 0x30) if (!i2cWriteReg(I2C_ADDR, REG_CMD, CMD_START)) return false; // 2) Fertig abfragen (SCO = Bit3). Alternativ könnte man fix 50ms warten. // Wir machen: kurze Warte + Polling mit Timeout. const uint32_t t0 = millis(); while (true) { uint8_t st = 0; if (!i2cReadReg(I2C_ADDR, REG_CMD, st)) return false; bool scoBusy = (st & (1 << 3)) != 0; // SCO bit3 if (!scoBusy) break; if (millis() - t0 > 100) return false; // Timeout 100ms delay(5); } // 3) 5 Bytes lesen: 0x06..0x0A uint8_t data[5]; if (!i2cReadBytes(I2C_ADDR, REG_DATA_START, data, sizeof(data))) return false; pressureBar = convertPressureBar(data[0], data[1], data[2]); tempC = convertTempC(data[3], data[4]); return true; } void setup() { Serial.begin(115200); delay(200); Wire.begin(PIN_SDA, PIN_SCL); Wire.setClock(100000); // 100 kHz als solider Start Serial.println("I2C Drucksensor Start"); } void loop() { float pBar, tC; if (readPressureAndTemp(pBar, tC)) { Serial.print("Druck [bar]: "); Serial.print(pBar, 3); Serial.print(" | Temp [C]: "); Serial.println(tC, 2); } else { Serial.println("Sensor-Lesefehler (I2C/Timeout)."); } delay(200); } ``` ============================================================ 7) Typische Stolpersteine & Debug ============================================================ 1) Spannung wirklich 3,3 V? Der Hersteller zeigt 3,3 V im Wiring-Bild. 5 V können je nach Sensor/Board problematisch sein. 2) I²C-Adresse 0x7F „ungewöhnlich“ Wenn dein I²C-Scanner nichts findet: trotzdem den Sensor direkt mit 0x7F testen. 3) Kabelfarben prüfen Braun=V+, Blau=GND, Weiß=SDA, Schwarz=SCL. 4) Messbereich (Fullscale) falsch → Druckwerte falsch skaliert Beispiel: 16 bar statt 10 bar führt zu Faktor 1,6. 5) Lange Leitungen in der Maschine Bei Aussetzern: - I²C-Clock reduzieren (z. B. 50 kHz oder 10 kHz) - SDA/GND und SCL/GND verdrillen - saubere Masseführung Ende.