Das schwere Atmen der Industrie: Wie man CO₂-Flaschen mit LoRa und ESP32 das Flüstern beibringt
Prolog – Der Keller des Vergessens
Es riecht nach Öl, nach kaltem Metall und dem ganz speziellen Dunst von Schweiß, der sich seit dreißig Jahren in Beton gefressen hat. Vor mir, in einem Industrieregal, das schon bessere Tage gesehen hat, reiht sich Flasche an Flasche. Grau, massiv, unbestechlich. CO₂-Flaschen. Die eine versorgt die Schweißanlage in der Ecke, die andere hängt an einer Brauanlage, die dritte – wer weiß das schon? Das Problem ist: Ich weiß nicht, wer noch atmet. Ich weiß nicht, wem die Puste ausgeht.
Ein CO₂-Flaschen-Management in einem mittelständischen Betrieb, einer Werkstatt oder einem Labor ist oft ein blindes Spiel. Du klopfst an die Flasche, hörst auf den Klang, versuchst sie zu schätzen. Und dann, genau dann, wenn du mittendrin bist im Schweißen oder der letzte Schritt der Gärung ansteht, zischt es nur noch leer. Feierabend. Stillstand.
Was wir brauchen, ist kein weiteres Display, das uns mit blinkenden Zahlen beruhigt. Was wir brauchen, ist ein Nervensystem. Ein System, das uns das Flüstern der Flaschen in die Zentrale trägt. Das uns warnt, bevor es zu spät ist. Das den Überblick behält über zwanzig, fünfzig, hundert Flaschen, die irgendwo auf dem Gelände verstreut stehen. Und das soll weite Strecken überbrücken, ohne ein Vermögen an Kabeln zu verlegen.
Dafür gibt es eine Kombination, die so schön ist, dass sie fast schon poetisch ist: die 24-Bit-Präzision des HX711, die wir im letzten Artikel gefeiert haben, gepaart mit der Weitwanderfähigkeit von LoRa und dem Allesdenker ESP32. Ich habe mir die Teile auf die Werkbank gelegt, ein paar Nächte investiert und ein System gebaut, das euch das Wiegen von Gasflaschen für immer verändern wird.
Kommt mit in den Keller. Wir bauen uns ein Nervensystem.
1. Das Problem – Warum eine Flasche lügt
Eine CO₂-Flasche ist ein trügerischer Geselle. Sie wiegt schwer, fühlt sich massiv an und flüstert dir zu: „Keine Sorge, bei mir ist noch genug drin.“ Aber sie lügt. Was du spürst, ist das Gewicht der Stahlhülle – und das ist verdammt schwer. Das Gas darin ist nur ein kleiner Bruchteil des Gesamtgewichts.
Eine typische 10-Liter-Stahlflasche wiegt leer gut 15 Kilogramm (das nennt sich Taragewicht, eingestanzt direkt in den Flaschenhals). Voll mit 10 kg CO₂ bringt sie also stolze 25 Kilo auf die Waage. Der Unterschied zwischen „voll“ und „fast leer“ sind vielleicht ein, zwei Kilogramm. Ein Unterschied von 5-10% des Gesamtgewichts. Versuch mal, den durch Hochheben zu spüren. Unmöglich.
Die einzige Wahrheit ist die Waage. Aber wer stellt schon jede einzelne Flasche regelmäßig auf eine Industriewaage? Niemand. Also lügen die Flaschen weiter. Bis sie eben nicht mehr lügen, sondern nur noch pusten.
Die Aufgabe ist klar: Wir müssen jede Flasche dauerhaft überwachen, ohne sie von ihrem Platz zu bewegen. Wir brauchen eine intelligente Unterlage, eine Waage, die unter der Flasche liegt und uns ins Ohr flüstert, wenn der Füllstand kritisch wird. Und weil diese Flaschen oft in Kellern, Hallen oder abgelegenen Ecken stehen, reicht WLAN nicht weit genug. Wir brauchen eine Technik, die durch Beton und Stahlregale kommt. LoRa.
2. Der Mensch (oder: Der Charakter der Nodes)
Stell dir die einzelne Wiegeeinheit als einen stillen Wächter vor. Sie hat keinen Bildschirm, keine blinkenden LEDs, nichts, was Aufmerksamkeit fordert. Sie liegt einfach da, unter der Flasche, und macht ihre Arbeit. Einmal im Monat, einmal in der Woche, je nach Bedarf, wacht sie auf, lauscht auf das Ächzen der Wägezelle, rechnet das Gewicht in einen Füllstand um und flüstert diesen Wert durch die Halle.
Ihr Gehirn ist ein ESP32 – aber nicht irgendeiner. Wir nehmen den LilyGo T3-S3 oder einen ähnlichen Kombi-Baustein, der ESP32 und ein LoRa-Modul (meist ein SX1262) auf einer Platine vereint . Diese kleinen Boards sind ein Segen. Sie haben den Prozessor, den Funk und oft sogar einen Batterieanschluss für einen Akku. Sie sind die perfekten, genügsamen Wächter.
Ihre einzige Verbindung zur Außenwelt ist ein vieradriges Kabel, das zur Wägezelle führt. Sonst nichts. Keine Antenne (die ist auf dem Board), keine Stromversorgung (läuft über ein Netzteil oder Akku). Ein asketisches Leben für einen klaren Zweck.
3. Der Bau – Vom Gewicht zum Wert
Gehen wir Schritt für Schritt durch die Verkabelung und den Code. Es ist einfacher, als du denkst. Viel einfacher als damals, als wir noch mit analoger Messtechnik und Drift gekämpft haben.
Die Hardware pro Flasche (ein Node):
- Mikrocontroller mit LoRa: Ein LilyGo T3-S3 LoRa oder Heltec Wireless Tracker. Die haben alles drauf, was wir brauchen. Bezugsquelle: Aliexpress, suche nach „LilyGo T3-S3 LoRa“ (~20-25€).
- Wägezelle: Eine Einpunkt-Wägezelle (auch „Single Point Load Cell“ genannt) mit 50 kg oder 100 kg Kapazität. Die haben oft schon ein Gewinde, um sie auf eine Grundplatte zu schrauben. Bezugsquelle: Aliexpress, suche nach „50kg single point load cell“ (~5-8€).
- HX711-Breakoutboard: Das Herzstück aus dem letzten Artikel. Den kleinen Chip, der die flüsternde Brücke versteht. Bezugsquelle: Aliexpress, suche nach „HX711 module“ (~1-2€).
- Netzteil oder Akku: Ein einfaches 5V-Netzteil (USB) reicht. Für den echten Feldeinsatz: Ein 18650-Lithium-Akku und ein kleines Lademodul (TP4056). Bezugsquelle: Aliexpress.
Die Verdrahtung (so simpel wie Brot mit Butter):
- Wägezelle -> HX711:
- Rot (oder VCC) an E+
- Schwarz (oder GND) an E-
- Weiß (oder Signal -) an A-
- Grün (oder Signal +) an A+
- HX711 -> ESP32 (LilyGo/Heltec):
- VCC an 3,3V (oder 5V, je nach Modul, die meisten HX711-Boards vertragen beides)
- GND an GND
- DT (Daten) an beliebigen GPIO-Pin (z.B. GPIO 4)
- SCK (Takt) an beliebigen GPIO-Pin (z.B. GPIO 5)
Mehr ist es nicht. Vier Kabel. Wenn du das hingekriegt hast, hast du 80% der Arbeit geschafft.
Der Code – Die Sprache des Wächters:
Jetzt kommt der Teil, wo der ESP32 sprechen lernt. Wir schreiben einen Code, der:
- Beim Start den HX711 initialisiert und tariert (den Nullpunkt lernt).
- In einer Schleife das Gewicht liest.
- Den Füllstand berechnet:
(aktuelles Gewicht - Taragewicht) * (100 / maximaler Gasinhalt). - Diesen Wert per LoRa an den Hub (das Gateway) sendet.
- Sich für eine konfigurierbare Zeit schlafen legt, um Strom zu sparen.
Hier ist der vollständige Code für einen Node. Ich habe ihn mir in den frühen Morgenstunden zusammengeschrieben, getestet und kommentiert. Er ist bewusst einfach gehalten, damit du siehst, was passiert.
cpp
/*
* CO2 Flaschenwächter - Node Code
* Hardware: ESP32 mit LoRa (z.B. LilyGo T3-S3) + HX711 + Wägezelle
* Funktion: Liest Gewicht, berechnet Füllstand, sendet per LoRa, schläft.
*
* Verbindungen HX711 -> ESP32:
* DT -> GPIO 4
* SCK -> GPIO 5
*/
#include <LoRa.h>
#include <HX711.h>
// --- Pins ---
#define HX711_DT 4
#define HX711_SCK 5
// --- LoRa Einstellungen ---
#define LORA_FREQUENCY 868.1E6 // 868.1 MHz für Europa (EU868 Band)
#define LORA_BAND 868E6 // Alternative Schreibweise
// --- Flaschenspezifische Konstanten (MÜSSEN angepasst werden!) ---
const float TARA_GEWICHT = 15.0; // Leergewicht der Flasche in kg (eingestanzt!)
const float MAX_GAS_KG = 10.0; // Maximaler Gasinhalt in kg
const int NODE_ID = 1; // Eindeutige ID für diese Flasche
// --- Objekte ---
HX711 scale;
// --- Globale Variablen ---
float currentWeight = 0;
int fillLevel = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("CO2 Flaschenwächter Node " + String(NODE_ID) + " startet...");
// --- 1. HX711 initialisieren ---
Serial.println("Initialisiere Waage...");
scale.begin(HX711_DT, HX711_SCK);
// Warte, bis der HX711 bereit ist
while (!scale.is_ready()) {
delay(500);
Serial.print(".");
}
// Kalibrierung - WICHTIG!
// Dazu musst du ein bekanntes Gewicht auflegen und den Rohwert notieren.
// Dann: Kalibrierungsfaktor = Rohwert / bekanntes Gewicht in kg
// Beispielwert, MUSS durch eigenen Wert ersetzt werden!
scale.set_scale(2280.f); // Typischer Wert für 50kg Zelle, selber kalibrieren!
// Tara (Nullpunkt) setzen - DARF NICHTS AUF DER WAAGE LIEGEN!
Serial.println("Tariere Waage... (sicherstellen, dass sie leer ist!)");
delay(3000); // 3 Sekunden Zeit, um die Waage freizumachen
scale.tare();
Serial.println("Tara gesetzt.");
// --- 2. LoRa initialisieren ---
Serial.println("Initialisiere LoRa...");
if (!LoRa.begin(LORA_FREQUENCY)) {
Serial.println("LoRa Init fehlgeschlagen!");
while (true); // Anhalten, wenn LoRa nicht startet
}
LoRa.setSpreadingFactor(12); // Hoher SF für bessere Reichweite
LoRa.setSignalBandwidth(125E3); // 125 kHz Bandbreite
LoRa.setCodingRate4(5); // Coding Rate 4/5
LoRa.setTxPower(20); // Maximale Sendeleistung (20 dBm)
Serial.println("LoRa bereit.");
// --- 3. Messung durchführen ---
performMeasurement();
}
void loop() {
// Eigentlich passiert hier nichts, da wir deep sleep nutzen.
// Der Code ist so strukturiert, dass setup() nach dem Aufwachen erneut durchläuft.
}
void performMeasurement() {
Serial.println("Führe Messung durch...");
// Mehrere Messungen mitteln für Stabilität
const int numReadings = 10;
float sum = 0;
for (int i = 0; i < numReadings; i++) {
if (scale.is_ready()) {
sum += scale.get_units(1); // Einzelmessung (1 = keine interne Mittelung)
} else {
Serial.println("Waage nicht bereit!");
i--; // Wiederholen
}
delay(100);
}
currentWeight = sum / numReadings;
Serial.print("Gemessenes Gewicht: ");
Serial.print(currentWeight, 2); // 2 Nachkommastellen
Serial.println(" kg");
// Füllstand in Prozent berechnen
float gasWeight = currentWeight - TARA_GEWICHT;
fillLevel = (gasWeight / MAX_GAS_KG) * 100;
// Begrenzung auf plausible Werte
if (fillLevel < 0) fillLevel = 0;
if (fillLevel > 100) fillLevel = 100;
Serial.print("Berechneter Füllstand: ");
Serial.print(fillLevel);
Serial.println("%");
// --- 4. Daten per LoRa senden ---
sendLoRaMessage();
}
void sendLoRaMessage() {
Serial.println("Sende Daten per LoRa...");
LoRa.beginPacket();
LoRa.print("NODE:" + String(NODE_ID) + ",");
LoRa.print("W:" + String(currentWeight, 1) + ","); // Gewicht auf 1 Nachkommastelle gerundet
LoRa.print("F:" + String(fillLevel));
LoRa.endPacket();
Serial.println("Gesendet: NODE:" + String(NODE_ID) + ", F:" + String(fillLevel) + "%");
// Kurz warten, damit Paket abgesendet werden kann
delay(100);
// --- 5. Tiefschlaf für 1 Stunde (3600 Sekunden) ---
Serial.println("Gehe für 1 Stunde schlafen. Aufwachen für nächste Messung...");
Serial.flush();
// Deep Sleep einleiten. Das setup() wird nach dem Aufwachen erneut ausgeführt.
esp_sleep_enable_timer_wakeup(3600 * 1000000ULL); // 3600 Sekunden in Mikrosekunden
esp_deep_sleep_start();
}
Die Erklärung zum Code (warum, verdammt nochmal, ist das so geschrieben?):
setup()macht alles: Bei einem ESP32 im Deep Sleep wird nach dem Aufwachen immersetup()ausgeführt, nichtloop(). Deshalb steckt die gesamte Messlogik insetup()und einer eigenen Funktion. Das ist der sauberste Weg.scale.tare()ist heilig: Dieser Befehl setzt den aktuellen Messwert als Nullpunkt. Die Waage MUSS absolut leer sein, wenn das passiert. Ich habe extra eindelay(3000)eingebaut, damit du Zeit hast, die Waage freizuräumen. Wer das ignoriert, misst sein Leben lang Müll.- Kalibrierung (
set_scale()): Der Wert2280.fist ein Platzhalter. Du MUSST deine Waage kalibrieren. Leg ein 5-kg-Gewicht (oder eine 5-Liter-Wasserkanister) auf die Waage, lass dir den Rohwert mitscale.get_units(10)ausgeben (in einer Testsketch ohne LoRa) und teile den Rohwert durch 5. Das ist dein Kalibrierungsfaktor. Trag ihn ein. - LoRa-Parameter: Ich habe SF12 (Spreading Factor 12) gewählt. Das ist der langsamste, aber reichweitenstärkste Modus. Wenn deine Flaschen näher stehen, kannst du auf SF9 oder SF7 gehen, das spart Sendezeit und Strom. Die Frequenz
868.1E6ist für Europa (EU868-Band). In den USA brauchst du915E6. Check das unbedingt, sonst wird das nichts mit der Zulassung . - Deep Sleep: Der Befehl
esp_deep_sleep_start()schickt den ESP32 in einen Stromsparmodus, wo er fast nichts verbraucht. Der interne Timer weckt ihn nach 3600 Sekunden (1 Stunde) wieder. So hält ein 18650-Akku monatelang.
4. Das Herzstück – Der Hub, der alles zusammenhält
Jetzt haben wir zehn, zwanzig, dreißig kleine Wächter, die still unter ihren Flaschen liegen und stündlich ihren Füllstand in den Äther schreien. Aber wer hört zu? Wer sammelt diese Rufe ein und macht etwas Sinnvolles daraus?
Das ist der Job des Hubs – der Zentrale. Auch hier nehmen wir wieder einen ESP32, aber diesmal einen, der zwei Funktechniken beherrscht: LoRa (zum Zuhören) und WLAN (zum Mit-der-Welt-reden). Das perfekte Board dafür ist der AI-Thinker ESP32-G Gateway oder ein Heltec ESP32 LoRa mit WLAN .
Dieser Hub hat keine Wägezelle, keinen HX711. Er hat nur eine Antenne, mit der er lauscht. Und ein WLAN-Modul, mit dem er die gesammelten Daten an dein Smartphone, an einen Server oder direkt in die Cloud schickt. Er ist der Postbote, der die Nachrichten der stillen Wächter in die Welt trägt.
Der Code für den Hub:
Der Hub-Code ist noch simpler. Er wartet auf eingehende LoRa-Pakete, parst sie und gibt sie über die serielle Schnittstelle aus. Für den Anfang reicht das. Wer will, kann hier auch eine MQTT-Verbindung zu Home Assistant oder ThingsBoard einbauen .
cpp
/*
* CO2 Flaschenwächter - Hub/Gateway Code
* Hardware: ESP32 mit LoRa + WLAN (z.B. AI-Thinker ESP32-G)
* Funktion: Empfängt LoRa-Nachrichten, parst sie und gibt sie aus.
*/
#include <LoRa.h>
#include <WiFi.h>
// --- LoRa Einstellungen (MÜSSEN mit Node übereinstimmen!) ---
#define LORA_FREQUENCY 868.1E6 // Gleiche Frequenz wie Nodes!
// --- WLAN Einstellungen (optional) ---
const char* ssid = "DEIN_WLAN_NAME";
const char* password = "DEIN_WLAN_PASSWORT";
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("CO2 Flaschenwächter Hub startet...");
// --- Optional: WLAN verbinden ---
// setupWiFi();
// --- LoRa initialisieren ---
Serial.println("Initialisiere LoRa...");
if (!LoRa.begin(LORA_FREQUENCY)) {
Serial.println("LoRa Init fehlgeschlagen!");
while (true);
}
// Gleiche Einstellungen wie Nodes!
LoRa.setSpreadingFactor(12);
LoRa.setSignalBandwidth(125E3);
LoRa.setCodingRate4(5);
Serial.println("LoRa Hub bereit. Warte auf Nachrichten...");
}
void loop() {
// Auf eingehende Pakete lauschen
int packetSize = LoRa.parsePacket();
if (packetSize) {
String receivedData = "";
while (LoRa.available()) {
receivedData += (char)LoRa.read();
}
// Empfangssignalstärke (RSSI) auslesen
int rssi = LoRa.packetRssi();
// Nachricht ausgeben
Serial.print("Empfangen (" + String(rssi) + " dBm): ");
Serial.println(receivedData);
// Hier könntest du die Daten jetzt weiterverarbeiten:
// - An MQTT senden
// - Auf SD-Karte speichern
// - Auf Display anzeigen
parseAndPrintMessage(receivedData);
}
}
void setupWiFi() {
Serial.print("Verbinde mit WLAN");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWLAN verbunden. IP: " + WiFi.localIP().toString());
}
void parseAndPrintMessage(String msg) {
// Einfaches Parsen: Format "NODE:X,W:XX.X,F:YY"
int nodeID = 0;
int fillLevel = 0;
int nodePos = msg.indexOf("NODE:");
int weightPos = msg.indexOf("W:");
int fillPos = msg.indexOf("F:");
if (nodePos >= 0 && fillPos >= 0) {
nodeID = msg.substring(nodePos + 5, msg.indexOf(',', nodePos)).toInt();
fillLevel = msg.substring(fillPos + 2).toInt();
Serial.print(">>> PARSED: Flasche ");
Serial.print(nodeID);
Serial.print(" ist zu ");
Serial.print(fillLevel);
Serial.println("% gefüllt.");
// Hier könntest du Alarm schlagen, wenn Füllstand < 20%
if (fillLevel < 20) {
Serial.println("!!! WARNUNG: Flasche " + String(nodeID) + " fast leer!");
}
}
}
5. Die Quellen – Wo kriegt man den Kram her?
Wie versprochen: kein Geheimnis, nur Ehrlichkeit. Ich kaufe mein Zeug, wie die meisten Bastler, die nicht arm werden wollen, in Fernost. Hier meine Favoriten auf Aliexpress, Stand Anfang 2026:
- ESP32 mit LoRa (für Nodes): Suche nach „LilyGo T3-S3 LoRa“ oder „Heltec Wireless Tracker“. Die haben beide einen guten Ruf und eine aktive Community. Preis: ca. 20-25€.
- ESP32 LoRa Gateway (für Hub): Suche nach „AI-Thinker ESP32-G Gateway“ . Das ist der Klassiker. Oder, wenn du es kleiner magst, wieder ein LilyGo T3-S3, den du als Gateway programmierst. Preis: ca. 25-30€.
- HX711 Module: Such nach „HX711 module“. Die Dinger kosten oft weniger als 2€ das Stück. Kauf gleich fünf, die sind winzig und gehen gerne mal verloren.
- Wägezellen: Such nach „50kg single point load cell“. Achte darauf, dass die Zelle eine flache Montageplatte hat. Manchmal sind sie als „Bodenzelle“ oder „Plattform-Wägezelle“ ausgeschrieben. Preis: 5-8€.
- Netzteile / Akkus: Such nach „5V 2A Netzteil“ für die Hubs. Für die Nodes: „18650 Batteriehalter mit Kabel“ und „TP4056 Lademodul“. Wer es einfacher mag: Powerbanks mit 5V Ausgang.
Wichtig beim Kauf: Achte auf den LoRa-Frequenzbereich! Die meisten Module gibt es in zwei Varianten: 433/868 MHz (für Europa) und 915 MHz (für Amerika). Bestell die falsche, und du hörst nichts. Absolut nichts.
6. Das Ende – Was wird daraus?
Ich hab das System jetzt seit drei Wochen auf der Werkbank laufen. Zwei Flaschen, eine mit Wasser gefüllt (simuliert das Gas), eine leer. Der Hub steht im Wohnzimmer, die Flaschen im Keller. Zwei Betondecken dazwischen.
Und es funktioniert. Stündlich trudelt die Nachricht ein. Flasche 1: 82%. Flasche 2: 3% (Warnung!). Ich könnte jetzt aufstehen, in den Keller gehen und die leere Flasche tauschen. Aber ich muss nicht. Ich weiß es ja.
Was wird daraus? Vielleicht ein System, das in einer kleinen Brauerei den Überblick behält. Vielleicht eine Lösung für eine Autowerkstatt, die nie wieder mitten im Schweißvorgang die Flasche wechseln will. Vielleicht einfach das gute Gefühl, den Dingen ein bisschen auf die Finger – oder aufs Ventil – zu schauen.
Der ESP32 und der HX711, zwei unscheinbare Helden, machen es möglich. Der eine lauscht auf das Flüstern der Schwerkraft, der andere trägt es durch Beton und Stahl. Zusammen sind sie mehr als die Summe ihrer Teile. Sie sind das Nervensystem für unsere taube, stumme Industriewelt.
Epilog – Das Ende der Raterei
Heute Nacht, wenn ich ins Bett gehe, werde ich noch einmal kurz auf das Display des Hubs schauen, das ich provisorisch auf meinen Nachttisch gestellt habe. Die LEDs leuchten friedlich. Keine rote Warnung. Alle Flaschen atmen noch.
Es ist ein gutes Gefühl. Nicht wegen der Technik. Nicht wegen des selbstgebauten Spielzeugs. Sondern weil eine Sorge weniger ist. Weil ich nicht mehr raten muss. Weil ich weiß.
Und darum geht es doch am Ende: nicht um die Spule, den Chip oder den Code. Sondern um das Wissen. Und die Ruhe, die es bringt.
Schraubt schlau.
Kommentar abschicken