Initiale Bereitstellung

Initiale Bereitstellung der aktuellen Version auf Gitea
This commit is contained in:
raw-designs
2026-07-10 18:13:43 +02:00
commit 453644816f
4952 changed files with 2613188 additions and 0 deletions
+236
View File
@@ -0,0 +1,236 @@
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 24Bit ADC-Wert (signed) aus den Registern 0x06, 0x07, 0x08
- Temperatur als 16Bit 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 7BitAdresse von 0x7F.
Hinweis:
0x7F ist im I²C-Standard „speziell“/reserviert. Manche I²CScanner 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 (24Bit 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 (16Bit 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 <Wire.h>
// --- 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.