Initiale Bereitstellung
Initiale Bereitstellung der aktuellen Version auf Gitea
This commit is contained in:
@@ -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 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 <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.
|
||||
Reference in New Issue
Block a user