Milesight UC501: Multi-Interface-SDI-12-LoRaWAN-Controller

Milesight UC501 Multi-Interface-LoRaWAN-Controller: SDI-12, RS485 Modbus, Analog- und GPIO-Eingaenge, eigenes Decoder-Framework und ChirpStack-Integration.

Milesight UC501
UC501Controller
LoRaWAN
Class A / Class C, OTAA
SDI-12
Mehrere SDI-12-Sensoren
Feldbus
RS485 Modbus RTU
Eingaenge
GPIO (DI/DO/Zaehler) + Analog (4-20 mA / 0-10 V)
Gehaeuse
IP67, fuer den Aussenbereich
Stromversorgung
Batterie, Solar oder externe DC-Quelle
Konfiguration
NFC / USB (Milesight ToolBox)
Funktionen

Was kann der UC501?

SDI-12-Sensoren

Wetter-, Hydrologie- und Agrarsonden, als ASCII-String gelesen.

RS485 Modbus RTU

Energiezaehler, SPS und industrielle Modbus-Sensoren.

Analogeingaenge (AI)

4-20 mA / 0-10 V mit Min-, Max- und Durchschnittswert.

GPIO

Pro Kanal Digitaleingang, Digitalausgang oder Impulszaehler.

Verlaufsspeicher

Speichert Messwerte lokal und sendet sie nach einer Netzluecke erneut.

Daten ins Dashboard

Integration

Sensor / Controller

Misst oder steuert vor Ort und sendet LoRaWAN-Uplinks.

LoRaWAN-Gateway

Empfängt die Funkpakete und reicht sie an den Server weiter.

ChirpStack

Network-Server: verwaltet Sessions und decodiert das Payload.

ThingsBoard / Grafana

Dashboards, Alarme, Regeln und Reports.

ChirpStack v4 · decodeUplink
function decodeUplink(input) {
  var bytes = input.bytes;
  var data = { gpio: {}, analog: {}, sdi12: {}, modbus: {} };

  for (var i = 0; i < bytes.length; ) {
    var channel = bytes[i++];
    var type = bytes[i++];

    // Modbus: register id + package type, then 1/2/4 bytes by data type.
    // Checked before the 0xff device-info catch-all so the type byte 0x0e
    // is not swallowed by the generic 0xff branch (channel 0x80 or 0xff).
    if ((channel === 0x80 || channel === 0xff) && type === 0x0e) {
      var reg = bytes[i++] - 6;
      var dataType = bytes[i++] & 0x07;
      data.modbus["chn" + reg] = readModbusValue(bytes, i, dataType);
      i += modbusLen(dataType); continue;
    }

    // Device info (join / power-on): version, SN, class. Lengths are firmware-specific.
    if (channel === 0xff) { i += deviceInfoLen(type); continue; }

    // Battery (%)
    if (channel === 0x01 && type === 0x75) { data.battery = bytes[i]; i += 1; continue; }

    // GPIO as digital input / output: 1 byte (0/1)
    if ((channel === 0x03 || channel === 0x04) && (type === 0x00 || type === 0x01)) {
      data.gpio["ch" + channel] = bytes[i]; i += 1; continue;
    }

    // GPIO as pulse counter: UINT32 little-endian (4 bytes)
    if ((channel === 0x03 || channel === 0x04) && type === 0xc8) {
      data.gpio["ch" + channel] = readUInt32LE(bytes, i); i += 4; continue;
    }

    // Analog input: value + min + max + avg, four INT16 little-endian (8 bytes)
    if ((channel === 0x05 || channel === 0x06) && type === 0x02) {
      data.analog["ch" + channel] = {
        value: readInt16LE(bytes, i) / 1000,
        min: readInt16LE(bytes, i + 2) / 1000,
        max: readInt16LE(bytes, i + 4) / 1000,
        avg: readInt16LE(bytes, i + 6) / 1000
      };
      i += 8; continue;
    }

    // SDI-12: 1 byte sensor index + 36-byte ASCII string
    if (channel === 0x08 && type === 0xdb) {
      var idx = bytes[i++];
      data.sdi12["s" + (idx + 1)] = readString(bytes, i, 36); i += 36; continue;
    }

    break; // unknown channel: stop, payload layout is configuration-dependent
  }
  return { data: data };
}

function modbusLen(t) { return (t <= 1) ? 1 : (t <= 3) ? 2 : 4; }
function readModbusValue(b, i, t) {
  if (t <= 1) return b[i];
  if (t <= 3) return readUInt16LE(b, i);
  if (t === 5 || t === 7) return readFloatLE(b, i);
  return readUInt32LE(b, i);
}
function readInt16LE(b, i) {
  var v = (b[i + 1] << 8) | b[i];
  return v > 0x7fff ? v - 0x10000 : v;
}
function readUInt16LE(b, i) { return (b[i + 1] << 8) | b[i]; }
function readUInt32LE(b, i) {
  return ((b[i+3]<<24)|(b[i+2]<<16)|(b[i+1]<<8)|b[i]) >>> 0;
}
function readFloatLE(b, i) {
  var bits = readUInt32LE(b, i);
  var sign = (bits >>> 31) ? -1 : 1;
  var exp = (bits >>> 23) & 0xff;
  var frac = bits & 0x7fffff;
  if (exp === 0) return sign * frac * Math.pow(2, -149);
  if (exp === 0xff) return frac ? NaN : sign * Infinity;
  return sign * (1 + frac * Math.pow(2, -23)) * Math.pow(2, exp - 127);
}
function readString(b, i, len) {
  var s = "";
  for (var k = 0; k < len; k++) {
    if (b[i + k] === 0) break;
    s += String.fromCharCode(b[i + k]);
  }
  return s.replace(/[^\x20-\x7e]/g, "").trim();
}
function deviceInfoLen(type) {
  void type; // 0xFF segment lengths are firmware-specific; set per deployment
  return 1;
}

Implementiert nach der veröffentlichten Milesight-Byte-Spezifikation (Communication Protocol / User Guide).

Die UC501-Payload ist konfigurationsabhaengig: Sie spiegelt wider, welche Schnittstellen aktiviert sind (SDI-12, RS485 Modbus, Analog, GPIO) und wie die Register zugeordnet sind. SDI-12-Messwerte kommen als Sensorindex plus 36-Byte-ASCII-String, den Sie je Sonde parsen; Modbus-Werte kommen als Registernummer plus Datentyp, der die Laenge bestimmt (1/2/4 Byte). Das ist ein Framework, implementiert nach der veroeffentlichten Milesight-Byte-Spezifikation, kein fertiges Drop-in: Wir finalisieren den Decoder anhand eines echten Uplinks aus dem Einsatz. Die Analog- und Float-Skalierung unterscheidet sich je nach Hardware-/Firmware-Revision (etwa /1000 statt /100), pruefen Sie sie an Ihrem Geraet.

Aus der Praxis

Konfiguration & Stolpersteine

Schnittstellenauswahl

SDI-12, RS485, Analog und GPIO werden in der ToolBox aktiviert; die Payload enthaelt nur die eingeschalteten Kanaele, daher ist der Decoder geraetespezifisch.

SDI-12-Adressierung

Jede SDI-12-Sonde braucht eine eindeutige Busadresse und ein definiertes Messkommando. Dokumentieren Sie die Adress-zu-Sensor-Zuordnung, damit die ASCII-Strings nachvollziehbar bleiben.

Class-C-Stromverbrauch

Class C haelt das Empfangsfenster fuer Downlinks offen und braucht mehr Strom; fuer SDI-12-Feldstandorte auf Batterie oder Solar passt Class A mit geplantem Reporting meist besser.

Verlauf-Nachuebertragung

Die UC501 puffert Messwerte lokal und sendet sie nach einer Netzluecke erneut, daher sollten Dashboards Verlaufsframes gegen Live-Uplinks entdoppeln.

Dein Partner

So unterstützt dich merkaio beim UC501

Von der Beschaffung bis zum laufenden Betrieb, alles aus einer Hand und auf eigener europäischer Infrastruktur.

Pre-Staging & Provisioning

Wir konfigurieren den UC501, setzen Keys, Intervalle und Alarme und liefern einsatzbereit aus.

Eigener Decoder

Payload-Codec für ChirpStack v4 und ThingsBoard, nach der Milesight-Spezifikation implementiert.

Integration ins Dashboard

Die Daten landen in deinem ThingsBoard oder Grafana, inklusive Alarmen und Reports.

Betrieb & Monitoring

Wir betreiben LoRaWAN-Stack und Dashboards auf europäischer Infrastruktur, du nutzt nur die Daten.

Häufige Fragen

Ja. Es ist ein Standard-LoRaWAN-Geraet, kein Milesight-Gateway oder Cloud noetig. Sie fuegen den Codec ins Device-Profil ein und provisionieren das Geraet per OTAA.
Ja, implementiert nach der veroeffentlichten Milesight-Byte-Spezifikation. Da die Payload davon abhaengt, welche Schnittstellen Sie aktivieren, liefern wir ein Decoder-Framework und finalisieren es anhand eines echten Uplinks aus Ihrem Einsatz.
Die Payload enthaelt nur die aktivierten Kanaele (SDI-12, RS485 Modbus, Analog, GPIO) und spiegelt Ihre Register- und Adresszuordnung wider, daher wird der Decoder fuer Ihre genaue Konfiguration gebaut und validiert statt als festes Drop-in ausgeliefert.
SDI-12 fuer Umweltsonden, RS485 Modbus RTU, Analogeingaenge fuer 4-20 mA oder 0-10 V sowie GPIO, das als Digitaleingang, Digitalausgang oder Impulszaehler arbeiten kann.
Ja. Sie unterstuetzt Batterie, Solar und externe DC-Versorgung, und das IP67-Gehaeuse eignet sich fuer Aussenstandorte. Auf Batterie oder Solar verlaengert Class A mit geplantem Reporting-Intervall die Laufzeit.
Jeder SDI-12-Kanal wird als Sensorindex plus 36-Byte-ASCII-String mit dem Rohmesswert gesendet. Der Decoder extrahiert den String je Sonde; die Felder parsen Sie dann gemaess dem SDI-12-Antwortformat Ihres Sensors.
Aus derselben Serie

Verwandte Geräte

Sprechen wir über Ihre Infrastruktur. Digital und vor Ort.

Ob IoT-Plattformentwicklung, Hardwareauswahl, Managed Hosting für ChirpStack, ThingsBoard, Grafana oder NetBird VPN, oder Migration von einem Self-Hosted-Setup - wir finden die passende Lösung für Ihren Anwendungsfall. Buchen Sie ein kostenloses 30-Minuten-Gespräch, unverbindlich.

Timo Wevelsiep

Ihr Ansprechpartner

Timo Wevelsiep

Gründer, merkaio

15 Minuten, unverbindlich, direkt mit Timo.

Mit dem Absenden stimmen Sie unserer Datenschutzerklärung zu.

Decoder für ChirpStack v4. merkaio ist unabhängiger Integrator und nicht mit Milesight affiliiert.