Unser WLAN Funkmodul für Messuhren und andere Handmessmittel wie Bügelmessschraube oder Messschieber kann mit dem Funkmodul M8 für Verbindungen über WebSockets verwendet werden. Meist werden unsere Datenübertragungsmodule im MQTT Modus eingesetzt. Es gibt jedoch Anwendungsfälle, in denen eine Verbindung über Websockets zweckmäßiger ist. Z.B. wenn aus einer Web-Anwendung oder einem Web-Browser heraus direkt auf ein einzelnes Messgerät zugegriffen werden soll.

Dieses Praxisbeispiel soll zeigen, wie eine WebSocket-Verbindung zum Messgerät hergestellt werden kann.

Das Beispiel besteht aus einer einfachen Webseite / Webanwendung in HTML und Javascript. Über diese einfachen Techniken ist es möglich, direkt auf das Funkmodul zuzugreifen und den aktuellen Messwert sowie Statusinformationen aus der Funk-Messuhr auszulesen. Dies ist im Vergleich zu MQTT ohne zusätzliche Infrastruktur eines Brokers möglich und somit vor allem für kleine, lokale Anwendungen eventuell einfacher umzusetzen als eine MQTT Abfrage.

Web-Oberfläche der Beispielanwendung

Der Quelltext der einfachen Anwendung:

<!DOCTYPE HTML>
<html>
<head>
  <meta name="websocket_test">
  <meta charset="UTF-8"/>
  <style>button{width:140px;height:50px}body{background: #f48f0d;}</style>
  <style>table, th, td { border-collapse: collapse;}</style>
<title>websocket to iot test</title>
</head>
<body style="font-family: arial, sans-serif;">
    <div style="width:500px;border:1px solid black;align:left">
        <form onsubmit="return false">
            Client name (informal): <input type="text" id="txtName" value="Client_1"><br>
            Server: <input type="text" id="txtServer" value="192.168.1.119">
        </form>
        <form onsubmit="return false">
            <button type="submit" id="btnConnect">Connect to IoT device</button>
            <input type="checkbox" id="cbxSsl" name="ssl" checked>
            <label for="cbxSsl">SSL</label>
            <input type="checkbox" id="cbxRaw" name="raw" checked>
            <label for="cbxRaw">Raw</label>
        </form>
        <form onsubmit="return false">
            <button type="submit" id="btnConfigSet" disabled>Set configuration</button>
        </form>
        <form onsubmit="return false">
        <table>
        <tr><td>
            <button type="submit" id="btnRequestMeas" disabled>Request measurements</button>
            </td><td>
            Repeat count:<input style="width:80px;" size="3" type="number" id="txtRepCnt" value="3"><br>
            Interval:<input style="width:80px;" size="6" type="number" id="txtRepMs" value="200">
            </td>
        </tr></table>
        </form>
        <form onsubmit="return false">
            <button type="submit" id="btnRequestMeta" disabled>Request device info</button>
        </form>
        <!-- output form -->
        <form onsubmit="return false">
            <div style="overflow:scroll;height:400px;word-break:break-all" id="divOut">Not connected...</div>
        </form>
        <!-- clear -->
        <form onsubmit="return false">
            <button type="submit" id="btnClear">Clear</button>
        </form>
    </div>
    <script type="text/javascript">
        const elem = id => document.getElementById(id);
        const txtName = elem("txtName");
        const txtServer = elem("txtServer");
        const txtRepCnt = elem("txtRepCnt");
        const txtRepMs = elem("txtRepMs");
        const btnConnect = elem("btnConnect");
        const cbxSsl = elem("cbxSsl");
        const cbxRaw = elem("cbxRaw");
        const btnConfigSet = elem("btnConfigSet");
        const btnRequestMeas = elem("btnRequestMeas");
        const btnRequestMeta = elem("btnRequestMeta");
        const btnClear = elem("btnClear");
        const divOut = elem("divOut");

        class Mdevice {
            constructor() {
                this.connecting = false;
                this.connected = false;
                this.name = "";
                this.ws = null;
            }
            connect() {
                if (this.ws === null) {
                    this.connecting = true;
                    txtName.disabled = true;
                    this.name = txtName.value;
                    btnConnect.innerHTML = "Connecting...<br>"+txtServer.value+"<br>ssl "+
                      cbxSsl.value+": "+(cbxSsl.checked?"on":"off");
                    this.ws = new WebSocket("ws"+(cbxSsl.checked?"s":"")+"://"+txtServer.value+"/"+(cbxRaw.checked?"raw1":"dev1"));
//                    this.ws = new WebSocket("wss://192.168.1.119/dev1");
                    this.ws.onopen = e => {
                        this.connecting = false;
                        this.connected = true;
                        divOut.innerHTML += "<br><p>Connected.</p>";
                        btnConnect.innerHTML = "Disconnect";
                        btnConfigSet.disabled=false;
                        btnRequestMeas.disabled=false;
                        btnRequestMeta.disabled=false;
                        // optional: send something through the websocket 
                        // this.ws.send(this.name + " connected!");
                    };
                    this.ws.onmessage = e => {
                        divOut.innerHTML+="<p>"+e.data+"</p>";
                        divOut.scrollTo(0,divOut.scrollHeight);
                    }
                    this.ws.onclose = e => {
                        this.disconnect();
                    }
                }
            }
            disconnect() {
                if (this.ws !== null) {
                    // optional: send something through the websocket 
                    // this.ws.send(this.name + " disconnect!");
                    this.ws.close();
                    this.ws = null;
                }
                if (this.connected) {
                    this.connected = false;
                    btnConfigSet.disabled=true;
                    btnRequestMeas.disabled=true;
                    btnRequestMeta.disabled=true;
                    txtName.disabled = false;
                    divOut.innerHTML+="<p>Disconnected.</p>";
                    btnConnect.innerHTML = "Connect";
                }
            }
            sendMessage(msg) {
                if (this.ws !== null) {
                    this.ws.send(msg);
                }
            }
        };
        let mdevice = new Mdevice();
        btnClear.onclick = () => {
            divOut.innerHTML ="";
        }
        btnConnect.onclick = () => {
            if (mdevice.connected) {
                mdevice.disconnect();
            } else if (!mdevice.connected && !mdevice.connecting) {
                mdevice.connect();
            }
        }
        btnConfigSet.onclick = () => {
            mdevice.sendMessage("{\"cmd\":\"config\",\"sleep_sec\":13698,\"display_text\":\"MESSAGE\"}");
            divOut.focus();
        }
        btnRequestMeas.onclick = () => {
            if (cbxRaw.checked) {
               mdevice.sendMessage("meas"); // -- opt: csv instead json
            } else {
              mdevice.sendMessage("{\"client\":\""+this.name+"\",\"cmd\":\"meas\",\"rep_cnt\":"+
                txtRepCnt.value+",\"rep_ms\":"+txtRepMs.value+"}");
            }
            divOut.focus();
        }
        btnRequestMeta.onclick = () => {
            // mdevice.sendMessage("1|info|*");
            mdevice.sendMessage("{\"client\":\""+this.name+"\",\"cmd\":\"info\"}");
            divOut.focus();
        }
    </script>
</body>
</html>

Der Quellcode dieses Programmbeispiels kann hier heruntergeladen werden. Dieser Quelltext kann gerne frei verwendet werden (Freeware, OpenSource, Public domain) – allerdings übernehmen wir keine Haftung für die Fehlerfreiheit des Quellcodes oder der Software.

Aufgabenstellung

Eine klassische Messvorrichtung soll die gemessenen Daten per Funk an ein verarbeitendes System übertragen. Die Vorrichtung wurde durch den Vorrichtungsbau bereits erstellt und ist bereits mit präzisen Mitutoyo Messuhren ausgestattet. Die Prüfvorrichtung soll Mobil eingesetzt werden. Es ist daher eine kabellose Lösung mit unabhängiger Stromversorgung erforderlich.

Durch die automatische Übertragung per Funk sollen Ablesefehler vermieden werden. Eine Übertragung mit Bluetooth oder anderen gängigen Funkprotokollen von Funkmessuhren ist nicht sinnvoll da die Vorrichtung an unterschiedlichen Stellen im Betrieb eingesetzt werden soll. Eine Kopplung der Funkmodule mit einem Rechner vor jeder Messung ist zudem zu aufwändig und generell problematisch.

Die Messungen sollen Ferngesteuert aus der Ferne ausgelöst werden.

Die Messung mit den Messuhren soll praktisch zeitsynchron in einem sehr engen Zeitfenster (wenige Millisekunden) durchgeführt werden.

Lösung der Aufgabe

Die vorhandenen Messuhren werden mit rAAAreware Funkmodulen M4 ausgestattet. Die Module können einfach auf der Rückseite der Messuhren montiert werden. Auf die Module wird ein leistungsstarker Lithium-Ionen Akku aufgeschoben. Dieser ermöglicht einen langen unabhängigen und kabellosen Betrieb der Funkmodule auf der Vorrichtung. Ein notwendiger baldiger Akkuwechsel wird rechtzeitig sowohl vom Modul als auch über MQTT angezeigt.

Messvorrichtung mit 6 Messuhren welche mit WLAN-Funkmodulen ausgestattet sind.
Ansicht der Messvorrichtung mit 6 Messuhren und den WLAN-Funkmodulen
(Modell M4 mit Akku)

Die WLAN Messuhr-Module werden über das offene und frei verfügbare MQTT Protokoll angesteuert. Somit kann über einen Leitrechner oder einen anderen MQTT Client eine Messung ferngesteuert getriggert werden. Die Ergebnisse werden dann direkt vom MQTT Broker übernommen und können direkt weiterverarbeitet werden. Als Bedienung an der Messvorrichtung ist nur das Einschalten der Messuhren und das Einschalten der Funkmodule über einen Schiebeschalter erforderlich.

Durch die gleichzeitige Messung und Übertragung der Messergebnisse wird ein Qualitätsgewinn und eine Zeitersparnis bei der Durchführung der Messaufgabe erreicht. Die Gesamtmessung ist in sehr kurzer Zeit bei minimaler Fehlermöglichkeit durchführbar.

Alternative Lösungsansätze

Ein alternativer Lösungsansatz ist über eine zentrale Stromversorgung der Funkmodule realisierbar. Wenn z.B. der Platz hinter den Messuhren nicht für das Funkmodul ausreicht können diese an anderer Stelle der Messvorrichtung angebracht werden. Die Verbindung zur Messuhr erfolgt dann nur über das Digimatic Kabel. Die extern auf der Vorrichtung angebrachten Module können dann über einen zentralen Ein-/Ausschalter mit einer zentralen Stromversorgung verbunden werden. Diese zentrale Energieversorgung kann dann ein industrielles Akku-Pack sein oder auch eine gewöhnliche 5V Powerbank. Durch die zentrale Spannungsversorgung der Module wird die Bedienung weiter vereinfacht, da alle Messuhren gleichzeitig und zentral ein- und ausgeschaltet werden können.

Dieser Ansatz wurde bereits bei anderen Prüfvorrichtungen erfolgreich umgesetzt. Auch andere Messuhren oder auch andere Messgeräte sind so über ein serielles Kabel an ein extern montiertes Funkmodul anbindbar.

Kontaktieren Sie uns wenn Sie weitere Informationen zu dieser Aufgabenstellung aus dem Bereich der Längenmesstechnik wünschen.

Für unseren Kunden capricorn group entwickelten wir Komponenten für eine Mess- & Prüfaufnahme.

Prüfaufnahme für ein Carbon Bauteil mit Messuhr und elektrischem Anheber der Messuhr.
Bedienteil der Messuhr-Anheber sowie Messwert-Anzeige der Mitutoyo-Messuhren

Das Projektbeispiel zeigt die Vorrichtung einer Mess- & Prüfaufnahme für ein Carbon Dach.
Die elektrisch gesteuerte Anhebung und Absenkung der Messuhren stellt eine schnelle und exakte Positionierung der Dächer in Fahrzeuglängsrichtung auf der Vorrichtung sicher.
Gegenüber einem manuellen Einmessen ergibt sich dadurch bei jedem Bauteil eine deutliche Zeitersparnis und Fehler werden sofort erkannt.
Die digital erfassten Daten lassen sich in nachgelagerten Systemen zur Qualitätssicherung protokollieren und archivieren.

Über Capricorn

Die capricorn GROUP ist ein Entwicklungsdienstleister mit dem Schwerpunkt Automobilindustrie und Motorsport.

Copyright Hinweise

Für die 4 gezeigten Bilder der Vorrichtung gilt: Diese unterliegen dem Copyright © capricorn. Eine Reproduktion oder Wiedergabe des Ganzen oder von Teilen ist ohne die schriftliche Genehmigung capricorns nicht gestattet.