Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Praktische Anwendungen (Showcase)
  4. LoRaWAN MakerFab Bewässerungssensor

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    16
    1
    1.5k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    843

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.1k

LoRaWAN MakerFab Bewässerungssensor

Geplant Angeheftet Gesperrt Verschoben Praktische Anwendungen (Showcase)
3 Beiträge 2 Kommentatoren 602 Aufrufe 3 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • B Offline
    B Offline
    bloop
    schrieb am zuletzt editiert von
    #1

    Liebe Community,

    Ich würde gerne meine gesammelte Erfahrung mit den Bodenfeuchtigkeitssensoren von MakerFab mit euch teilen.
    Ziel dieses Projektes war es die Sensoren für meine Bewässerungsanlage zu verwenden und in den sprinkelcontrol Adapter einzubinden. Die zu bewässernden Pflanzen stehen leider außerhalb der Reichweite meines Netzwerkes. Wodurch ich mich auf die Suche nach einer möglichen Alternative gemacht habe. Für mich ergab sich so ein etwas holpriger Einstieg in die LoRaWAN Welt.

    LoRa Bodenfeuchtigkeitssensoren V3 Kostenpunkt €19,90
    2023-06-02 23.31.03.jpg
    Ich hab mich für die Sensoren entschieden, da ich ansonsten leider nichts ähnliches in dieser Preisklasse finden konnte.
    Allerdings sind die Sensoren nicht LoRaWAN fähig und für den Betrieb mit einem selbst gebauten Lora Gateway gedacht. Diese Mühe wollte ich mir eigentlich sparen. So habe ich mich auf die Suche nach einer Möglichkeit zur Integration ins LoRaWAN Netzwerk TTN (TheTingsNetwork) gemacht. Die Verarbeitung der Sensoren ist recht ok, Sie sind über die gesamte Platinenfläche und den Sensor mit einem Lack überzogen. Nur das Gehäuse lässt etwas zu wünschen übrig.

    Tip: Ich habe mich leider bei der Wahl der Sensoren etwas vergriffen, in der Zwischenzeit gibt es bereits Sensoren die LoRaWan unterstützen.So könnte das Flashen der Firmware nicht nötig sein. LoRaWan Sensoren

    Wichtige Links:
    USB-Serial Converter: CP2104

    Anleitung: Makerfabs Soil Moisture Sensor v3
    Firmware: LORAWAN SOIL MOISTURE SENSOR (Die 3 Files weiter unten im Blog)

    Arduino IDE: Download

    Erfahrungen:

    • Das Aufspielen des Sketch hat mir große Schwierigkeiten gemacht. Es müssen genau die richtigen Version von Biblioteken in Arduino IDE installiert werden. Welche hierfür benötigt werden ist in der Anleitung angegeben. Ebenso muss in der Konfigurationsdatei von MCCI LoRaWAN Library folgender Code eingegeben werden um die richtige Region der Library einzustellen. Ansonsten erhaltet ihr immer die Nachricht das der Sketch zu groß ist und nicht auf den Sensor geflashed werden kann.
    #define CFG_eu868 1
    //define CFG_us915 1
    //#define CFG_au915 1
    //#define CFG_as923 1
    // #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP	/* for as923-JP */
    //#define CFG_kr920 1
    //#define CFG_in866 1
    #define CFG_sx1276_radio 1
    //#define LMIC_USE_INTERRUPTS
    
    #define DISABLE_PING
    #define DISABLE_BEACONS
    #define LMIC_DEBUG_LEVEL 0
    #define USE_IDEETRON_AES
    
    • Nachdem ich verstanden habe was in dem Sketch angegeben und gemeint ist, hat das eintragen der EUI aus TTN erstaunlich gut funktioniert. Hier ist lediglich zu beachten, dass diese auch im richtigen Format eingetragen werden. In TTN lassen sich die aber direkt im passenden Format anzeigen und kopieren.
    // This EUI must be in little-endian format, so least-significant-byte
    // first. When copying an EUI from ttnctl output, this means to reverse
    // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
    // 0x70.
    // APPEUI can be left with ceros
    static const u1_t PROGMEM APPEUI[8]={ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
    void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
    
    // This should also be in little endian format, see above.
    static const u1_t PROGMEM DEVEUI[8]={ TTN_DEVEUI };
    void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
    
    // This key should be in big endian format (or, since it is not really a
    // number but a block of memory, endianness does not really apply). In
    // practice, a key taken from ttnctl can be copied as-is.
    static const u1_t PROGMEM APPKEY[16] = { TTN_APPKEY };
    void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}
    
    
    • Leider hat mir das Flashen immer wieder Schwierigkeiten gemacht, worauf hin ich den Bootloader der Sensoren mit einem Arduino Nano neu programmiert habe. Entsprechende Anleitungen lassen sich leicht finden. Hierfür habe ich den Lack auf den 6 Pins abgekratzt und Kabel angelötet und mit dem Nano verbunden. Aufpassen das beim Flashen des Arduino Nano der Sensor nicht angeschlossen ist.

    • Nachdem ich die Sensoren dann endlich im TTN angezeigt bekommen habe, musste ich noch den Payload Formater passend konfigurieren. Dieser ist bei Device unter Payload formatters / Uplink / Custom Javascript formatter einzutragen.

    // TTNV3 Payload Formatter Uplink V0.1
    function decodeUplink(input) {
    
    if ((input.fPort > 0) && (input.fPort < 223))
    {
      var decodedTemp = 0;
      var decodedHumi = 0;
      var decodedBatt = 0;
    
    // seperate raw data from payload
      var rawSoil = input.bytes[0] + input.bytes[1] * 256;
      var rawTemp = input.bytes[2] + input.bytes[3] * 256;
      var rawHumi = input.bytes[4] + input.bytes[5] * 256;
      var rawBatt = input.bytes[6] + input.bytes[7] * 256;
    
    // decode raw data to values
      decodedTemp = sflt162f(rawTemp) * 100; // value calculated to range -1..x..+1 by dividing /100
      decodedHumi =  sflt162f(rawHumi) * 100; // value calculated to range -1..x..+1 by dividing /100
      if (rawBatt !== 0) decodedBatt =   rawBatt / 1000; // batterie voltage ist transmitted in mV, recalculate in V
    
    // definition of the decimal places
      decodedTemp = decodedTemp.toFixed(2);
      decodedHumi = decodedHumi.toFixed(2);
      decodedBatt = decodedBatt.toFixed(2);
    
    // return values
      return {
        data: {
          Feuchtigkeit: rawSoil,
          Temperatur: decodedTemp,
          Luftfeuchtigkeit: decodedHumi,
          Batterie: decodedBatt
              },
        warnings: [],
        errors: []
      };
    }
    else {
        return {
          data: {},
          warnings: [],
          errors: ["Invalid data received"]
        };
      
    }
    }
    
    function sflt162f(rawSflt16)
    	{
    	// rawSflt16 is the 2-byte number decoded from wherever;
    	// it's in range 0..0xFFFF
    	// bit 15 is the sign bit
    	// bits 14..11 are the exponent
    	// bits 10..0 are the the mantissa. Unlike IEEE format, 
    	// 	the msb is transmitted; this means that numbers
    	//	might not be normalized, but makes coding for
    	//	underflow easier.
    	// As with IEEE format, negative zero is possible, so
    	// we special-case that in hopes that JavaScript will
    	// also cooperate.
    	//
    	// The result is a number in the open interval (-1.0, 1.0);
    	// 
    	
    	// throw away high bits for repeatability.
    	rawSflt16 &= 0xFFFF;
    
    	// special case minus zero:
    	if (rawSflt16 == 0x8000)
    		return -0.0;
    
    	// extract the sign.
    	var sSign = ((rawSflt16 & 0x8000) !== 0) ? -1 : 1;
    	
    	// extract the exponent
    	var exp1 = (rawSflt16 >> 11) & 0xF;
    
    	// extract the "mantissa" (the fractional part)
    	var mant1 = (rawSflt16 & 0x7FF) / 2048.0;
    
    	// convert back to a floating point number. We hope 
    	// that Math.pow(2, k) is handled efficiently by
    	// the JS interpreter! If this is time critical code,
    	// you can replace by a suitable shift and divide.
    	var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15);
    
    	return f_unscaled;
    	}
    
    • Der nächste Schritt das übertragen zu iobroker per MQTT ging ganz leicht. Hierfür eine neue Instanz anlegen und die unter Integrations / MQTT angegebenen Verbindungskonfigurationen eingeben.

    • So habe ich es endlich geschafft die Sensordaten in den iobroker zu integrieren. Diese werden als JSON an einen Datenpunkt geschickt. Mit folgendem Skript lasse ich mir diese in Datenpunkte ablegen.

    const soilup = "mqtt.1.v3.030374@ttn.devices.eui-70b3d57ed005e017.up";
    const path = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017';
    const idBat = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Batterie';
    const idMoist = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Feuchtigkeit';
    const idAir = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Luftfeuchtigkeit';
    const idTemp = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Temperatur';
    
    if(!existsState(idBat)) { // Datenpunkte erzeugen
        createState(idBat, '0', {type: 'number', unit: 'V'});
        createState(idMoist, '0', {type: 'number', unit: '%'});
        createState(idAir, '0', {type: 'number', unit: 'rF'});
        createState(idTemp, '0', {type: 'number', unit: '°C'});
    };
    
    on(soilup, function(dp) { // triggert bei Wertänderung
        let obj = JSON.parse(dp.state.val).uplink_message.decoded_payload;
        setState(idBat, obj.Batterie, true);
        setState(idMoist, parseFloat(obj.Feuchtigkeit), true);
        setState(idAir, parseFloat(obj.Luftfeuchtigkeit), true);
        setState(idTemp, parseFloat(obj.Temperatur), true);
    });
    

    2b0741fa-2e08-45cd-8351-15e0f30a1988-image.png

    Ich hoffe ich kann jedem der auf eine ähnliche Idee kommt mit meinen Tipps etwas helfen!

    O 1 Antwort Letzte Antwort
    1
    • B bloop

      Liebe Community,

      Ich würde gerne meine gesammelte Erfahrung mit den Bodenfeuchtigkeitssensoren von MakerFab mit euch teilen.
      Ziel dieses Projektes war es die Sensoren für meine Bewässerungsanlage zu verwenden und in den sprinkelcontrol Adapter einzubinden. Die zu bewässernden Pflanzen stehen leider außerhalb der Reichweite meines Netzwerkes. Wodurch ich mich auf die Suche nach einer möglichen Alternative gemacht habe. Für mich ergab sich so ein etwas holpriger Einstieg in die LoRaWAN Welt.

      LoRa Bodenfeuchtigkeitssensoren V3 Kostenpunkt €19,90
      2023-06-02 23.31.03.jpg
      Ich hab mich für die Sensoren entschieden, da ich ansonsten leider nichts ähnliches in dieser Preisklasse finden konnte.
      Allerdings sind die Sensoren nicht LoRaWAN fähig und für den Betrieb mit einem selbst gebauten Lora Gateway gedacht. Diese Mühe wollte ich mir eigentlich sparen. So habe ich mich auf die Suche nach einer Möglichkeit zur Integration ins LoRaWAN Netzwerk TTN (TheTingsNetwork) gemacht. Die Verarbeitung der Sensoren ist recht ok, Sie sind über die gesamte Platinenfläche und den Sensor mit einem Lack überzogen. Nur das Gehäuse lässt etwas zu wünschen übrig.

      Tip: Ich habe mich leider bei der Wahl der Sensoren etwas vergriffen, in der Zwischenzeit gibt es bereits Sensoren die LoRaWan unterstützen.So könnte das Flashen der Firmware nicht nötig sein. LoRaWan Sensoren

      Wichtige Links:
      USB-Serial Converter: CP2104

      Anleitung: Makerfabs Soil Moisture Sensor v3
      Firmware: LORAWAN SOIL MOISTURE SENSOR (Die 3 Files weiter unten im Blog)

      Arduino IDE: Download

      Erfahrungen:

      • Das Aufspielen des Sketch hat mir große Schwierigkeiten gemacht. Es müssen genau die richtigen Version von Biblioteken in Arduino IDE installiert werden. Welche hierfür benötigt werden ist in der Anleitung angegeben. Ebenso muss in der Konfigurationsdatei von MCCI LoRaWAN Library folgender Code eingegeben werden um die richtige Region der Library einzustellen. Ansonsten erhaltet ihr immer die Nachricht das der Sketch zu groß ist und nicht auf den Sensor geflashed werden kann.
      #define CFG_eu868 1
      //define CFG_us915 1
      //#define CFG_au915 1
      //#define CFG_as923 1
      // #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP	/* for as923-JP */
      //#define CFG_kr920 1
      //#define CFG_in866 1
      #define CFG_sx1276_radio 1
      //#define LMIC_USE_INTERRUPTS
      
      #define DISABLE_PING
      #define DISABLE_BEACONS
      #define LMIC_DEBUG_LEVEL 0
      #define USE_IDEETRON_AES
      
      • Nachdem ich verstanden habe was in dem Sketch angegeben und gemeint ist, hat das eintragen der EUI aus TTN erstaunlich gut funktioniert. Hier ist lediglich zu beachten, dass diese auch im richtigen Format eingetragen werden. In TTN lassen sich die aber direkt im passenden Format anzeigen und kopieren.
      // This EUI must be in little-endian format, so least-significant-byte
      // first. When copying an EUI from ttnctl output, this means to reverse
      // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
      // 0x70.
      // APPEUI can be left with ceros
      static const u1_t PROGMEM APPEUI[8]={ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
      void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
      
      // This should also be in little endian format, see above.
      static const u1_t PROGMEM DEVEUI[8]={ TTN_DEVEUI };
      void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
      
      // This key should be in big endian format (or, since it is not really a
      // number but a block of memory, endianness does not really apply). In
      // practice, a key taken from ttnctl can be copied as-is.
      static const u1_t PROGMEM APPKEY[16] = { TTN_APPKEY };
      void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}
      
      
      • Leider hat mir das Flashen immer wieder Schwierigkeiten gemacht, worauf hin ich den Bootloader der Sensoren mit einem Arduino Nano neu programmiert habe. Entsprechende Anleitungen lassen sich leicht finden. Hierfür habe ich den Lack auf den 6 Pins abgekratzt und Kabel angelötet und mit dem Nano verbunden. Aufpassen das beim Flashen des Arduino Nano der Sensor nicht angeschlossen ist.

      • Nachdem ich die Sensoren dann endlich im TTN angezeigt bekommen habe, musste ich noch den Payload Formater passend konfigurieren. Dieser ist bei Device unter Payload formatters / Uplink / Custom Javascript formatter einzutragen.

      // TTNV3 Payload Formatter Uplink V0.1
      function decodeUplink(input) {
      
      if ((input.fPort > 0) && (input.fPort < 223))
      {
        var decodedTemp = 0;
        var decodedHumi = 0;
        var decodedBatt = 0;
      
      // seperate raw data from payload
        var rawSoil = input.bytes[0] + input.bytes[1] * 256;
        var rawTemp = input.bytes[2] + input.bytes[3] * 256;
        var rawHumi = input.bytes[4] + input.bytes[5] * 256;
        var rawBatt = input.bytes[6] + input.bytes[7] * 256;
      
      // decode raw data to values
        decodedTemp = sflt162f(rawTemp) * 100; // value calculated to range -1..x..+1 by dividing /100
        decodedHumi =  sflt162f(rawHumi) * 100; // value calculated to range -1..x..+1 by dividing /100
        if (rawBatt !== 0) decodedBatt =   rawBatt / 1000; // batterie voltage ist transmitted in mV, recalculate in V
      
      // definition of the decimal places
        decodedTemp = decodedTemp.toFixed(2);
        decodedHumi = decodedHumi.toFixed(2);
        decodedBatt = decodedBatt.toFixed(2);
      
      // return values
        return {
          data: {
            Feuchtigkeit: rawSoil,
            Temperatur: decodedTemp,
            Luftfeuchtigkeit: decodedHumi,
            Batterie: decodedBatt
                },
          warnings: [],
          errors: []
        };
      }
      else {
          return {
            data: {},
            warnings: [],
            errors: ["Invalid data received"]
          };
        
      }
      }
      
      function sflt162f(rawSflt16)
      	{
      	// rawSflt16 is the 2-byte number decoded from wherever;
      	// it's in range 0..0xFFFF
      	// bit 15 is the sign bit
      	// bits 14..11 are the exponent
      	// bits 10..0 are the the mantissa. Unlike IEEE format, 
      	// 	the msb is transmitted; this means that numbers
      	//	might not be normalized, but makes coding for
      	//	underflow easier.
      	// As with IEEE format, negative zero is possible, so
      	// we special-case that in hopes that JavaScript will
      	// also cooperate.
      	//
      	// The result is a number in the open interval (-1.0, 1.0);
      	// 
      	
      	// throw away high bits for repeatability.
      	rawSflt16 &= 0xFFFF;
      
      	// special case minus zero:
      	if (rawSflt16 == 0x8000)
      		return -0.0;
      
      	// extract the sign.
      	var sSign = ((rawSflt16 & 0x8000) !== 0) ? -1 : 1;
      	
      	// extract the exponent
      	var exp1 = (rawSflt16 >> 11) & 0xF;
      
      	// extract the "mantissa" (the fractional part)
      	var mant1 = (rawSflt16 & 0x7FF) / 2048.0;
      
      	// convert back to a floating point number. We hope 
      	// that Math.pow(2, k) is handled efficiently by
      	// the JS interpreter! If this is time critical code,
      	// you can replace by a suitable shift and divide.
      	var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15);
      
      	return f_unscaled;
      	}
      
      • Der nächste Schritt das übertragen zu iobroker per MQTT ging ganz leicht. Hierfür eine neue Instanz anlegen und die unter Integrations / MQTT angegebenen Verbindungskonfigurationen eingeben.

      • So habe ich es endlich geschafft die Sensordaten in den iobroker zu integrieren. Diese werden als JSON an einen Datenpunkt geschickt. Mit folgendem Skript lasse ich mir diese in Datenpunkte ablegen.

      const soilup = "mqtt.1.v3.030374@ttn.devices.eui-70b3d57ed005e017.up";
      const path = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017';
      const idBat = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Batterie';
      const idMoist = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Feuchtigkeit';
      const idAir = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Luftfeuchtigkeit';
      const idTemp = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Temperatur';
      
      if(!existsState(idBat)) { // Datenpunkte erzeugen
          createState(idBat, '0', {type: 'number', unit: 'V'});
          createState(idMoist, '0', {type: 'number', unit: '%'});
          createState(idAir, '0', {type: 'number', unit: 'rF'});
          createState(idTemp, '0', {type: 'number', unit: '°C'});
      };
      
      on(soilup, function(dp) { // triggert bei Wertänderung
          let obj = JSON.parse(dp.state.val).uplink_message.decoded_payload;
          setState(idBat, obj.Batterie, true);
          setState(idMoist, parseFloat(obj.Feuchtigkeit), true);
          setState(idAir, parseFloat(obj.Luftfeuchtigkeit), true);
          setState(idTemp, parseFloat(obj.Temperatur), true);
      });
      

      2b0741fa-2e08-45cd-8351-15e0f30a1988-image.png

      Ich hoffe ich kann jedem der auf eine ähnliche Idee kommt mit meinen Tipps etwas helfen!

      O Offline
      O Offline
      oxident
      schrieb am zuletzt editiert von
      #2

      @bloop Sehr interessantes Projekt!

      Ich muss mal ganz blöd fragen: Braucht man dafür nicht eon eigenes LoRaWAN-Gateway für?

      B 1 Antwort Letzte Antwort
      0
      • O oxident

        @bloop Sehr interessantes Projekt!

        Ich muss mal ganz blöd fragen: Braucht man dafür nicht eon eigenes LoRaWAN-Gateway für?

        B Offline
        B Offline
        bloop
        schrieb am zuletzt editiert von
        #3

        @oxident
        Nicht unbedingt!
        Wenn in in deiner Region bereits ein Gateway vorhanden ist wird dieses verwendet.
        Auf TTN kannst du vorab checken ob die Region abgedeckt ist.

        1 Antwort Letzte Antwort
        1
        Antworten
        • In einem neuen Thema antworten
        Anmelden zum Antworten
        • Älteste zuerst
        • Neuste zuerst
        • Meiste Stimmen


        Support us

        ioBroker
        Community Adapters
        Donate

        742

        Online

        32.6k

        Benutzer

        82.1k

        Themen

        1.3m

        Beiträge
        Community
        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
        ioBroker Community 2014-2025
        logo
        • Anmelden

        • Du hast noch kein Konto? Registrieren

        • Anmelden oder registrieren, um zu suchen
        • Erster Beitrag
          Letzter Beitrag
        0
        • Home
        • Aktuell
        • Tags
        • Ungelesen 0
        • Kategorien
        • Unreplied
        • Beliebt
        • GitHub
        • Docu
        • Hilfe