You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 29 Next »



Multiple different Variants

There are different kinds of Pressure Probes that use very different kinds of communication. As a consequence there exist different Variants of our Hardware for using Pressure Probes. Please take care that you only install the correct Variant of firmware on your device.

Consider using the latest firmware on your hardware

Target Measurement / Purpose

Precise liquid level measurement, e.g. for tanks, via LoRaWAN.

Features

  • Cable length 15m
  • 0…15 mH2O (15m water level, 1.5 Bar)
  • Resolution: ± 0.5% FSO (Full Scale Output)
  • Waterproof IP66 Housing
  • Multi-year Battery life, ultra low power design

Order Information

  • Type: LOB-S-PR-LW-BOX
  • Articlenumber: 8000089

The (initial) configuration is normally done using our free Lobaro Maintenance Tool and the USB PC configuation adapter.

Beside this the configuration can also be changed or read remotely in the field using LoRaWAN downlink messages, see Downlinks description.

LoRaWAN Connection

Advanced Lobaro LoRaWAN Stack

Some of the features listed here (LoRaWAN 1.1, Remote Configuration, ...) are only implemented for recent versions of our firmware. For the Lobaro Sensor this starts with v0.2.1, for the Keller Sensor it starts with v0.3.0. If possible, you should update your devices to our most recent firmware.

The connection to the LoRaWAN network is defined by multiple configuration parameters. This need to be set according to your LoRaWAN network and the way your device is supposed to be attached to it, or the device will not be able to send any data.

For a detailed introduction into how this values need to be configured, please refer to the chapter LoRaWAN configuration in our LoRaWAN background article.

NameDescriptionTypeValues
OTAAActivation: OTAA or ABPbooltrue= use OTAA, false= use ABP
DevEUIDevEUI used to identify the Devicebyte[8]e.g. 0123456789abcdef
JoinEUIUsed for OTAA (called AppEUI in v1.0)byte[8]e.g. 0123456789abcdef
AppKeyKey used for OTAA (v1.0 and v1.1)byte[16]
NwkKeyKey used for OTAA (v1.1 only)byte[16]
SFInitial / maximum Spreading Factorint7 - 12
ADRUse Adaptive Data Ratebooltrue= use ADR, false= don't
TimeSyncDays after which to sync timeintdays, 0=don't sync time
RndDelayRandom delay before sendingintmax seconds
RemoteConfSupport Remote Configurationbooltrue=allow, false=deactivate
LostRebootDays without downlink before rebootintdays, 0=don't reboot

Operation

Configuration values defining the behaviour of the device. The Min and Max values will be preconfigured when receiving the device. In case of using "Restore Default" they will be reset to standard values and have to be set again using the values printed on the sensor or given separately.

namedescriptionexample value
sendCronCron expression defining when to read and send0 0/15 * * * * for every 15 minutes
rangeMinmin range in mh2oin most cases 0
rangeMaxmax range in mh2oin most cases 15
outputMinmin digital output value of the sensorin most cases 819
outputMaxmax digital output value of the sensorin most cases 11664


See also our Introduction to Cron expressions.

Payload Format

Data Message

Port: 1, Payload: 8 Bytes

Temperature is transmitted in 1/100°C, battery voltage in Millivolt and pressure in Bar.

PRESSURETemperatureBattery Voltage
float32float32float32float32int16int16int16int16
Byte 0Byte 1Byte 2Byte 3LSBMSBLSBMSB

Status message

Port: 64, Payload: 13 Bytes

The Status Message communicates information about the device itself (starting with firmware 0.3.0). It contains information like the internal temperature of the device and the reason for the latest reboot.

For instructions how to parse the status message, please take a look at the reference parser implementation.

Payload Parser

Element-IoT: https://github.com/ZennerIoT/element-parsers/blob/master/lib/lobaro_pressure26d.ex

The Things Network

/* Helper functions used by this parser */
function signed(val, bits) {
    if ((val & 1 << (bits-1)) > 0) { // value is negative (16bit 2's complement)
        val = (~val & ((1 << bits) - 1)) + 1; // invert all bits & add 1 => now positive value
        val = val * -1;
    }
    return val;
}
function uint40_BE(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    return bytes[0] << 32 |
        bytes[1] << 24 | bytes[2] << 16 | bytes[3] << 8 | bytes[4] << 0;
}
function uint32_BE(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3] << 0;
}
function uint16_BE(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    return bytes[0] << 8 | bytes[1] << 0;
}
function uint32_LE(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    return bytes[0] << 0 | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24;
}
function uint16_LE(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    return bytes[0] << 0 | bytes[1] << 8;
}
function int40_BE(bytes, idx) {
    return signed(uint40_BE(bytes, idx), 40);
}
function int32_BE(bytes, idx) {
    return signed(uint32_BE(bytes, idx), 32);
}
function int16_BE(bytes, idx) {
    return signed(uint16_BE(bytes, idx), 16);
}
function int32_LE(bytes, idx) {
    return signed(uint32_LE(bytes, idx), 32);
}
function int16_LE(bytes, idx) {
    return signed(uint16_LE(bytes, idx), 16);
}
function float32(bytes) {
    var sign = (bytes & 0x80000000) ? -1 : 1;
    var exponent = ((bytes >> 23) & 0xFF) - 127;
    var significand = (bytes & ~(-1 << 23));
    if (exponent === 128)
        return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
    if (exponent === -127) {
        if (significand === 0) return sign * 0.0;
        exponent = -126;
        significand /= (1 << 22);
    } else significand = (significand | (1 << 23)) / (1 << 23);
    return sign * significand * Math.pow(2, exponent);
}
function readVersion(bytes, i) {
    if (bytes.length < 3) {
        return null;
    }
    return "v" + bytes[i] + "." + bytes[i + 1] + "." + bytes[i + 2];
}

/* Port 1: Data */
function Decoder_Data(bytes) {
    return {
        pressure: float32(int32_LE(bytes, 0)),
        temp: int16_LE(bytes,4) / 100,
        voltage: int16_LE(bytes,6) / 1000,
    }
}

/**
 * Decode status/error codes from GPS-Tracker to human readable tags.
 */
function decode_status_code(code) {
    switch (code) {
        case 0:
            return "OK";
        case 101:
            return "PROBE_ERROR";
        default:
            return "UNKNOWN";
    }
}

/**
 * Decode reboot reason explaining last reboot of device.
 */
function decode_reboot_reason(code) {
    // STM reboot code from our HAL:
    switch (code) {
        case 1:
            return "LOW_POWER_RESET";
        case 2:
            return "WINDOW_WATCHDOG_RESET";
        case 3:
            return "INDEPENDENT_WATCHDOG_RESET";
        case 4:
            return "SOFTWARE_RESET";
        case 5:
            return "POWER_ON_RESET";
        case 6:
            return "EXTERNAL_RESET_PIN_RESET";
        case 7:
            return "OBL_RESET";
        default:
            return "UNKNOWN";
    }
}

/* Port 64: Status */
function Decoder_Status(bytes) {
    var firmware = String.fromCharCode.apply(null, bytes.slice(0, 3));
    var version = readVersion(bytes, 3);
    var status_code = bytes[6];
    var status_text = decode_status_code(status_code);
    var reboot_code = bytes[7];
    var reboot_reason = decode_reboot_reason(reboot_code);
    var final_code = bytes[8];
    var vcc = (int16_BE(bytes, 9) / 1000) || 0.0;
    var temp = (int16_BE(bytes, 11) / 10) || -0x8000;
    var app_data = bytes.slice(13);

    return {
        "firmware": firmware,
        "version": version,
        "status_code": status_code,
        "status_text": status_text,
        "reboot_code": reboot_code,
        "reboot_reason": reboot_reason,
        "final_code": final_code,
        "temperature": temp,
        "voltage": vcc,
        "app_data": app_data
    };
}

// TTN compatible decoder function:
function Decoder(bytes, port) {
    // Decode an uplink message from a buffer
    // (array) of bytes to an object of fields
    switch (port) {
        case 1:
            // date message:
            return Decoder_Data(bytes);
        case 64:
            // lobaro unified status telegram
            return Decoder_Status(bytes);
        case 128:
        case 129:
        case 130:
        case 131:
            // remote config responses
            return {};
        default:
            // unsupported port:
            return null;
    }
}

function UpdateDevice(decoded) {
    if (!Device || !Device.setProperty) {
        // not in Lobaro Platform parser
        return;
    }
    var keys = ["firmware", "version", "status_code", "status_text", "reboot_code", "reboot_reason",
            "final_code", "final_words", "app_data", "temperature", "voltage"];
    for (var i=0; i< keys.length; i++) {
        var key = keys[i];
        if (decoded[key]) {
            Device.setProperty(key, decoded[key]);
        }
    }
}

// Wrapper for Lobaro Platform (not used in TTN)
function Parse(input) {
    // Decode an incoming message to an object of fields.
    var b = bytes(atob(input.data));
    // use TTN decoder:
    var decoded = Decoder(b, input.fPort);
    // Update values in device properties
    UpdateDevice(decoded);
    return decoded;
}

Device & Probe Dimensions

CE Declaration of Conformity

CE Declaration of Conformity (pdf).

Disposal / WEEE / Entsorgung

Information about the disposal of the Device.

  • No labels