Paine-eron mittaus ESPHomella
Tällä sivulla tehdään nopea käytännön vertailu kahden eri paineanturiratkaisun välillä: halpa HX711/HX710-tyyppinen moduuli ja Sensirion SDP810. Molemmilla voi saada numeroita ruudulle, mutta vain toinen on järkevä valinta pienten paine-erojen mittaamiseen.
!secret-muuttujia tai vaihda avaimet ennen julkaisua.
1. Mitä tässä oikeasti mitataan?
Kun tässä puhutaan ilmanpaineen mittauksesta, kyse ei ole sääaseman absoluuttisesta ilmanpaineesta. Tässä mitataan paine-eroa: eli kahden pisteen välistä eroa.
Paine-eroa voidaan mitata esimerkiksi suodattimen yli, ilmanvaihtokanavasta, 3D-tulostimen kotelosta, puhaltimen aiheuttamasta imusta tai pienestä ylipaineesta. Yksikkönä käytetään yleensä pascaleita, eli Pa.
2. Anturien erot lyhyesti
Halpa HX711/HX710-tyyppinen moduuli
Tämä sopii hyvin kokeiluun ja periaatteen näyttämiseen. Sen avulla voidaan nähdä, että paine muuttuu, mutta lukeman muuttaminen luotettavaksi pascal-arvoksi vaatii kalibrointia.
Paras käyttötapa: “muuttuuko paine johonkin suuntaan?”
Sensirion SDP810
Sensirion SDP810 on tehty nimenomaan pienille paine-eroille. Esimerkiksi ±125 Pa versio sopii hyvin ilmanvaihdon, suodattimien ja pienten puhaltimien mittauksiin.
Paras käyttötapa: “paljonko paine-ero oikeasti on?”
| Ominaisuus | Halpa HX711/HX710-tyyppinen moduuli | Sensirion SDP810 |
|---|---|---|
| Hinta | Erittäin halpa | Selvästi kalliimpi |
| Mittausalue | Usein suuri tai epäselvästi ilmoitettu | Pieni ja tähän käyttöön sopiva, esimerkiksi ±125 Pa |
| Käyttöönotto | Vaatii usein raakadataa ja kalibrointia | I2C-väylällä siisti ja suora lukeminen |
| Luotettava pieni paine-ero | Hankala | Hyvä valinta |
| ProtoBoksi-suositus | Kokeiluun | Oikeaan mittaukseen |
3. Kytkennät
Sensirion SDP810 D1 minillä
| Sensirion | D1 mini / ESP8266 |
|---|---|
| VCC | 3.3 V |
| GND | GND |
| SDA | D1 |
| SCL | D2 |
Halpa moduuli ESP32:lla
| Moduuli | ESP32 |
|---|---|
| VCC | 3.3 V tai moduulin vaatima käyttöjännite |
| GND | GND |
| DOUT / DATA | GPIO19 |
| SCK / CLK | GPIO18 |
Tarkista aina oman moduulin merkinnät. Halvoissa moduuleissa nimeäminen voi vaihdella.
4. Halvan HX711/HX710-tyyppisen moduulin ESPHome-koodi
Tässä esimerkissä halpa paineanturimoduuli luetaan ESPHomessa hx711-alustalla. Koodissa raakadata muutetaan prosentiksi kahden kalibrointipisteen avulla: tyhjä ja täysi.
Tämä esimerkki on tehty IBC-säiliön mittausajatuksella, mutta sama periaate sopii myös opetusvideolle: ensin luetaan raakadata, sitten muutetaan se käyttökelpoisempaan muotoon.
raw_empty ja raw_full ovat esimerkkiarvoja. Ne pitää mitata omasta anturista ja omasta rakenteesta. Muuten prosentti- ja litralukemat eivät pidä paikkaansa.
esphome:
name: paine-halpa
friendly_name: Paine halpa anturi
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Paine Halpa Fallback"
password: !secret fallback_password
captive_portal:
substitutions:
tank_liters: "1000.0"
tank_height_cm: "100.0"
# Vaihda nämä oman mittauksen mukaan.
raw_empty: "8500"
raw_full: "26500"
i2c:
sda: 21
scl: 22
scan: true
font:
- file: "gfonts://Roboto"
id: font_small
size: 12
- file: "gfonts://Roboto"
id: font_big
size: 26
sensor:
# Esimerkkinä mukana myös TOF-etäisyysanturi OLED-näyttöä varten.
- platform: vl53l0x
name: "Etäisyys"
id: tof_distance
address: 0x29
update_interval: 300ms
long_range: true
# Halvan paineanturimoduulin raakadata.
- platform: hx711
id: ibc_raw
name: "IBC raakadata"
dout_pin: GPIO19
clk_pin: GPIO18
gain: 128
update_interval: 2s
filters:
- sliding_window_moving_average:
window_size: 10
send_every: 1
# Raakadatan muunnos prosenteiksi.
- platform: template
id: ibc_percent
name: "IBC täyttöaste"
unit_of_measurement: "%"
accuracy_decimals: 1
update_interval: 2s
lambda: |-
float raw = id(ibc_raw).state;
float empty = atof("${raw_empty}");
float full = atof("${raw_full}");
if (full == empty) return NAN;
float percent = (raw - empty) / (full - empty) * 100.0;
if (percent < 0.0) percent = 0.0;
if (percent > 100.0) percent = 100.0;
return percent;
- platform: template
id: ibc_liters
name: "IBC litraa jäljellä"
unit_of_measurement: "L"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
return id(ibc_percent).state / 100.0 * atof("${tank_liters}");
- platform: template
id: ibc_height
name: "IBC veden korkeus"
unit_of_measurement: "cm"
accuracy_decimals: 1
update_interval: 2s
lambda: |-
return id(ibc_percent).state / 100.0 * atof("${tank_height_cm}");
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
update_interval: 200ms
lambda: |-
static uint32_t last_switch = 0;
static bool page_ibc = false;
if (millis() - last_switch > 4000) {
page_ibc = !page_ibc;
last_switch = millis();
}
if (!page_ibc) {
it.printf(0, 0, id(font_small), "ProtoBoksi");
if (id(tof_distance).has_state()) {
float mm = id(tof_distance).state * 1000.0;
it.printf(0, 20, id(font_big), "%.0f mm", mm);
it.printf(0, 50, id(font_small), "%.1f cm", mm / 10.0);
} else {
it.printf(0, 20, id(font_big), "--- mm");
}
} else {
it.printf(0, 0, id(font_small), "IBC tankki");
if (id(ibc_liters).has_state()) {
it.printf(0, 16, id(font_big), "%.0f L", id(ibc_liters).state);
it.printf(0, 40, id(font_small), "Taytto: %.1f %%", id(ibc_percent).state);
it.printf(0, 54, id(font_small), "Korkeus: %.1f cm", id(ibc_height).state);
} else {
it.printf(0, 20, id(font_big), "--- L");
}
}
Miten halpa anturi kalibroidaan?
- Kokoa anturi ja katso Home Assistantista
IBC raakadata. - Mittaa arvo, kun säiliö tai mittauskohta on tyhjä. Laita se arvo kohtaan
raw_empty. - Mittaa arvo, kun säiliö tai mittauskohta on täysi. Laita se arvo kohtaan
raw_full. - Jos prosentti toimii väärinpäin, vaihda
raw_emptyjaraw_fullkeskenään.
5. Sensirion SDP810 ESPHome-koodi
Tässä Sensirion SDP810 luetaan suoraan I2C-väylältä. Koodi käynnistää anturin jatkuvan paine-eromittauksen, lukee paineen, lämpötilan ja scale factorin sekä tarkistaa CRC:n.
Tämän etu halpaan moduuliin verrattuna on se, että lopputuloksena saadaan suoraan pascaleina järkevä paine-erolukema.
esphome:
name: sensirion
friendly_name: Sensirion SDP810
libraries:
- Wire
esp8266:
board: d1_mini
logger:
level: DEBUG
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Sensirion Fallback Hotspot"
password: !secret fallback_password
captive_portal:
i2c:
sda: D1
scl: D2
scan: true
frequency: 50kHz
globals:
- id: sdp_started
type: bool
restore_value: no
initial_value: "false"
sensor:
- platform: template
id: sdp_paine_ero
name: "SDP paine-ero"
unit_of_measurement: "Pa"
accuracy_decimals: 2
state_class: measurement
icon: mdi:gauge
- platform: template
id: sdp_lampotila
name: "SDP lampotila"
unit_of_measurement: "°C"
accuracy_decimals: 2
state_class: measurement
device_class: temperature
- platform: template
id: sdp_scale_factor
name: "SDP scale factor"
accuracy_decimals: 0
state_class: measurement
interval:
- interval: 2s
then:
- lambda: |-
auto crc8 = [](const uint8_t *data, uint8_t len) -> uint8_t {
uint8_t crc = 0xFF;
for (uint8_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t b = 0; b < 8; b++) {
if (crc & 0x80) {
crc = (crc << 1) ^ 0x31;
} else {
crc <<= 1;
}
}
}
return crc;
};
const uint8_t addr = 0x25;
// Käynnistä jatkuva paine-eromittaus vain kerran.
if (!id(sdp_started)) {
Wire.beginTransmission(addr);
Wire.write(0x36);
Wire.write(0x15);
uint8_t err = Wire.endTransmission();
if (err != 0) {
ESP_LOGW("sdp", "Start command failed, Wire error=%u", err);
return;
}
id(sdp_started) = true;
ESP_LOGI("sdp", "SDP continuous measurement started");
delay(10);
}
// Lue 9 tavua:
// pressure(2)+crc, temperature(2)+crc, scale factor(2)+crc
uint8_t need = 9;
uint8_t got = Wire.requestFrom((int) addr, (int) need);
if (got != need) {
ESP_LOGW("sdp", "Expected %u bytes, got %u", need, got);
return;
}
uint8_t buf[9];
for (int i = 0; i < 9; i++) {
if (!Wire.available()) {
ESP_LOGW("sdp", "Wire underrun at byte %d", i);
return;
}
buf[i] = Wire.read();
}
if (crc8(buf, 2) != buf[2]) {
ESP_LOGW("sdp", "CRC fail pressure");
return;
}
if (crc8(buf + 3, 2) != buf[5]) {
ESP_LOGW("sdp", "CRC fail temperature");
return;
}
if (crc8(buf + 6, 2) != buf[8]) {
ESP_LOGW("sdp", "CRC fail scale");
return;
}
int16_t dp_raw = (int16_t)((buf[0] << 8) | buf[1]);
int16_t temp_raw = (int16_t)((buf[3] << 8) | buf[4]);
uint16_t scale = (uint16_t)((buf[6] << 8) | buf[7]);
if (scale == 0) {
ESP_LOGW("sdp", "Scale factor was 0");
return;
}
float pressure = (float) dp_raw / (float) scale;
float temperature = (float) temp_raw / 200.0f;
id(sdp_paine_ero).publish_state(pressure);
id(sdp_lampotila).publish_state(temperature);
id(sdp_scale_factor).publish_state(scale);
ESP_LOGD("sdp", "raw=%d temp_raw=%d scale=%u -> %.3f Pa, %.2f C",
dp_raw, temp_raw, scale, pressure, temperature);
Home Assistant -kortti Sensirionille
Tällä kortilla lukemat saa nopeasti näkyviin Home Assistantin dashboardille.
type: entities
title: Sensirion SDP810
entities:
- entity: sensor.sdp_paine_ero
name: Paine-ero
- entity: sensor.sdp_lampotila
name: Anturin lämpötila
- entity: sensor.sdp_scale_factor
name: Scale factor
Graafi paine-erolle
Graafi tekee paine-erosta paljon helpommin ymmärrettävän kuin pelkkä numero.
type: custom:apexcharts-card
header:
show: true
title: Paine-ero
show_states: true
colorize_states: true
graph_span: 10min
series:
- entity: sensor.sdp_paine_ero
name: Paine-ero
type: line
stroke_width: 2
unit: Pa
6. Mihin tätä voi käyttää?
Paine-eron mittaus muuttuu kiinnostavaksi heti, kun mittaus laitetaan kiinni oikeaan paikkaan.
- Ilmanvaihdon suodatin: paine-ero kasvaa, kun suodatin alkaa tukkeutua.
- 3D-tulostimen kotelo: voi mitata, syntyykö koteloon pieni alipaine, kun kanavapuhallin vie ilmaa ulos.
- Puhaltimien vertailu: näkee, kumpi puhallin saa aikaan suuremman paine-eron.
- Vanhan talon vedot: voi kokeilla, miten ilmanvaihto, tuuli tai ovien avaaminen vaikuttaa paine-eroon.
- IBC- tai säiliöprojekti: raakadata voidaan kalibroida prosentiksi, litroiksi tai korkeudeksi.
7. Vianhaku
I2C-laite ei löydy
Tarkista SDA, SCL, käyttöjännite ja maa. ESPHome-logissa scan: true näyttää löytyykö laite väylältä. Sensirion SDP810 käyttää tässä esimerkissä osoitetta 0x25.
Lukema on väärinpäin
Vaihda letkut toisin päin tai käsittele arvo ohjelmassa miinusmerkillä. Paine-eroanturissa suunnalla on merkitystä.
Halvan anturin arvo vaeltaa
Se on tavallista halvoissa raakadataan perustuvissa ratkaisuissa. Käytä keskiarvosuodatusta, anna anturin lämmetä, tee nollaus ja muista, että raakadata ei ole sama asia kuin luotettava pascal-lukema.
Sensirion antaa CRC-virheitä
Kokeile lyhyempiä johtoja, matalampaa I2C-taajuutta ja varmista, että anturi saa oikean käyttöjännitteen. Tässä esimerkissä I2C-taajuus on laskettu arvoon 50kHz, koska se voi auttaa epävarmoissa johdotuksissa.