Forum Replies Created

Viewing 25 posts - 1 through 25 (of 34 total)
  • Author
    Posts
  • in reply to: TrixBrix Servos Defekt #3135
    Matthias EnderMatthias Ender
    Participant

    Ich habe jetzt die Servos mit dem Papierstreifen eingestellt. Das geht wunderbar und man kann sehr gut vermeiden, dass die Servos gegen die Wand drücken. Vorher habe ich die Servos anhand der Stellung der Weichen eingestellt. Das hat dazugeführt, dass ich fast alle Servos habe blockieren lassen. Dass dürfte dazu geführt haben, dass mir viele Servos kaputt gegangen sind und auch dass meine Batterien schnell leer waren.

    Ich kann diese Papierstreifenmethode nur dringend empfehlen!

    Ausserdem habe ich die Servos jetzt mir einem PCA9685 angesteuert. Das die Servos nur beim Schalten mit Strom versorgt werden, war dabei der ausschlaggebene Punkt. Nach meinen Messungen ändert sich zwar der Stromverbrauch nicht, allerdings dürfte die Lebenszeit der Servos deutlich erhöht werden.

    in reply to: Integrationsbericht #3106
    Matthias EnderMatthias Ender
    Participant

    e6facbc3-a7ff-4116-ba91-8a139c8255df

    Viel Besser… Funktioniert wunderbar. Genauer Bericht folgt mit dem Einbau.

    in reply to: MTC4PU – MattzoTrainController for Powered Up #3103
    Matthias EnderMatthias Ender
    Participant

    Bei mir läuft die V0.4 wunderbar. Die V0.4.1 habe ich noch nicht getestet.

    in reply to: TrixBrix Servos Defekt #3065
    Matthias EnderMatthias Ender
    Participant

    das werde ich auch mal tun..

    in reply to: MTC4PU – MattzoTrainController for Powered Up #3064
    Matthias EnderMatthias Ender
    Participant

    You need an password protected network. could you try it with the reset button on the board? an try an other network?

    in reply to: TrixBrix Servos Defekt #3060
    Matthias EnderMatthias Ender
    Participant

    Erstmal vielen dank Dirk für dein ausführliches Feedback. Ich werde mir das mit dem PCA mal ansehen.

    @Kevin
    , wie ich die Dinger anschließe, habe ich ja in nem anderen Thread beschrieben, ja, ich schalte die Servos nicht ab. Das werde ich mir nochmal ansehen.

    in reply to: Projekt: Layout Statusanzeige #2971
    Matthias EnderMatthias Ender
    Participant

    Sollte jemand von euch das Projekt so, oder so ähnlich nachbauen würde ich mich freuen, wenn ihr davon berichtet.

    in reply to: Projekt: Layout Statusanzeige #2970
    Matthias EnderMatthias Ender
    Participant

    3. Displaybau

    Nun kommt der komplizierteste Part.

    Dabei sind die Bauteile recht einfach:
    – Display
    – Controller(Der selbe wie die LayoutController)
    – Batteriebox
    – Akkus
    Und gelötet werden muss auch nicht 😀

    Meine Quellen waren:
    Youtube
    Fontgenerator fürs Display
    JSON Assistent
    Pinger für ESP8266

    Im Prinzip habe ich gemacht, was in dem Youtube Video erklärt wird:
    – zunächst von https://nextion.tech/ den Nextion Editor geladen und installiert.
    – dann mit dem Fontgenerator eine Schrift erstellt:
    font
    – Im Editor habe ich dann ein Template für das Display erstellt:
    nextion
    Dabei sind im Hintergrund als Bild die ganzen Texte.
    Die Elemente hub1-hub6 und train1-train4 sind Bilder. Hier wechsel ich das Bild von leer zu offline oder online.
    Die Elemente hub3v-hub6v und train1v-train4v sind Textboxen, da schreibe ich die Spannung oder den Status jeweils rein.
    Das Element status ist ebenfalls eine Textbox.
    Das Element process ist eine Progressbar.

    Jetzt das ganze Ding speichern und dann mit einer MicroSD Karte auf das Display übertragen. Wie das geht wird im Video ja erklärt.

    Wie das Angeschlossen wird, wird auch im Video erklärt. Ist nich kompliziert. Hier ist nur zubeachten, dass man kein Programm auf den Kontroller spielen kann, wenn das Display angeschlossen ist.

    Und dann der Quellcode für den Kontroller:

    #include <ESP8266WiFi.h>
    #include <Pinger.h>
    #include <ESP8266HTTPClient.h>
    #include <ArduinoJson.h>
    
    extern "C"
    {
      #include <lwip/icmp.h> // needed for icmp packet definitions
    }
    
    Pinger rocPinger;
    
    char ssid[] = "WLANN SSID";
    char pass[] = "WLAN PASSWORT";
    WiFiServer server(80);
    IPAddress ip(192, 168, 178, 80);
    IPAddress gateway(192, 168, 178, 1);
    IPAddress subnet(255, 255, 255, 0);
    
    void setup() {
      Serial.begin(9600);
      resetDisplay();
      sendstring("status.txt","OFFLINE");
      sendint("status.pco",63650);
      WiFi.config(ip, gateway, subnet);
      WiFi.begin(ssid, pass);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
      server.begin();
      sendstring("status.txt","ONLINE");
      sendint("status.pco",5248);
    
      rocPinger.OnReceive([](const PingerResponse& response)
      {
        if (response.ReceivedResponse){
          sendint("hub1.pic",2);
        }else{
          sendint("hub1.pic",3);
        }
        return true;
      });
    }
    
    String data;
    bool pingResult;
    
    void loop() {
      HTTPClient http;
      StaticJsonDocument<512> doc;
      DeserializationError error;
      int httpCode;
      String json;
      float batLevel;
        
      //RocRailServer 192.168.178.93
      rocPinger.Ping("192.168.178.93",1);
      sendint("process.val",16);
    
     //TrainServer 192.168.178.103
      http.begin("http://192.168.178.103/?rand=2222");
      httpCode = http.GET();
     
      if (httpCode > 0) {
        json = http.getString();
        error = deserializeJson(doc, json);
        
        if (error) {
          sendint("hub2.pic",3);
        }else{
          JsonArray Hubs = doc["Hubs"];
          if(Hubs[0]["CityExpress"]["isConnected"]==1){
            sendint("train1.pic",2);
            sendstring("train1v.txt",Hubs[0]["CityExpress"]["batteryLevel"]);
          }else{
            sendint("train1.pic",3);
            sendstring("train1v.txt","");
          }
    
          if(Hubs[1]["CityCargo"]["isConnected"]==1){
            sendint("train2.pic",2);
            sendstring("train2v.txt",Hubs[1]["CityCargo"]["batteryLevel"]);
          }else{
            sendint("train2.pic",3);
            sendstring("train2v.txt","");
          }
          
          if(Hubs[2]["BR23"]["isConnected"]==1){
            sendint("train3.pic",2);
            sendstring("train3v.txt",Hubs[2]["BR23"]["batteryLevel"]);
          }else{
            sendint("train3.pic",3);
            sendstring("train3v.txt","");
          }
    
          if(Hubs[3]["Krokodil"]["isConnected"]==1){
            sendint("train4.pic",2);
            sendstring("train4v.txt",Hubs[3]["Krokodil"]["batteryLevel"]);
          }else{
            sendint("train4.pic",3);
            sendstring("train4v.txt","");
          }
    
          sendint("hub2.pic",2);
        }
      }else{
        sendint("hub2.pic",3);
      }
     
      http.end();
      sendint("process.val",33);  
    
      //Layout Server 1 192.168.178.117
      http.begin("http://192.168.178.117/?rand=2222");
      httpCode = http.GET();
     
      if (httpCode > 0) {
        json = http.getString();
        error = deserializeJson(doc, json);
        
        if (error) {
          sendint("hub3.pic",3);
        }else{
          sendstring("hub3v.txt",doc["batLevel"]);
          sendint("hub3.pic",2);
        }
      }else{
        sendint("hub3.pic",3);
      }
     
      http.end();
      sendint("process.val",50);
    
      //Layout Server 2 192.168.178.104
      http.begin("http://192.168.178.104/?rand=2222");
      httpCode = http.GET();
     
      if (httpCode > 0) {
        json = http.getString();
        error = deserializeJson(doc, json);
        
        if (error) {
          sendint("hub4.pic",3);
        }else{
          sendstring("hub4v.txt",doc["batLevel"]);
          sendint("hub4.pic",2);
        }
      }else{
        sendint("hub4.pic",3);
      }
     
      http.end();
      sendint("process.val",66);
      
      //Layout Server 3 192.168.178.107
      http.begin("http://192.168.178.107/?rand=2222");
      httpCode = http.GET();
     
      if (httpCode > 0) {
        json = http.getString();
        error = deserializeJson(doc, json);
        
        if (error) {
          sendint("hub5.pic",3);
        }else{
          sendstring("hub5v.txt",doc["batLevel"]);
          sendint("hub5.pic",2);
        }
      }else{
        sendint("hub5.pic",3);
      }
     
      http.end();
      sendint("process.val",83);
      
      //Layout Server 4 192.168.178.109
      http.begin("http://192.168.178.109/?rand=2222");
      httpCode = http.GET();
     
      if (httpCode > 0) {
        json = http.getString();
        error = deserializeJson(doc, json);
        
        if (error) {
          sendint("hub6.pic",3);
        }else{
          sendstring("hub6v.txt",doc["batLevel"]);
          sendint("hub6.pic",2);
        }
      }else{
        sendint("hub6.pic",3);
      }
     
      http.end();
      sendint("process.val",100);
      
    }
    
    void resetDisplay(){
      sendstring("status.txt","");
      sendint("process.val",0);
      sendint("hub1.pic",1);
      sendint("hub2.pic",1);
      sendint("hub3.pic",1);
      sendint("hub4.pic",1);
      sendint("hub5.pic",1);
      sendint("hub6.pic",1);
      sendint("train1.pic",1);
      sendint("train2.pic",1);
      sendint("train3.pic",1);
      sendint("train4.pic",1);
    }
    
    void sendstring(String field, String value){
      data = field + "=\"" +value + "\"";
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.println();
    }
    
    void sendint(String field, int value){
      data = field + "=" +value + "";
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.println();
    }

    In den Code müsst ihr euch leider etwas einarbeiten:
    Die Bibliotheken Pinger.h, ESP8266HTTPClient.h und ArduinoJson.h installieren.
    Die Funktionen sendstring() und sendint() senden die Steuersigale an das Display zum Ändern der Bilder bzw. Texte.
    Der Pinger ist dafür da, den RocRailServer anzupingen.
    Mit dem ArduinoJson müsst ihre euch etwas beschäftigen. Ist ziemlich komplex.
    Im Prinzip resettet das Programm am Anfang das Display und dann werden der Reihe nach alle Kontroller abgefragt und die Anzeige entsprechend ans Display gesendet. Wenn alle Abgefragt wurden, gehts von vorne los.

    Jetzt noch etwas Lego und fertig ist die Kontrolleinheit.
    ff858281-3dc4-4d52-8b42-ca005d67c7b1

    in reply to: Projekt: Layout Statusanzeige #2969
    Matthias EnderMatthias Ender
    Participant

    Jetzt funktioniert die HTML Seite:

    <!DOCTYPE html>
    <html lang="de">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Status Mattzo Controller</title>
    	<script>
    		var controllers = {
    			"RocRailServer":"192.168.178.93",
    			"Train Controller":"192.168.178.103",
    			"LayoutController 1":"192.168.178.117",
    			"LayoutController 2":"192.168.178.104",
    			"LayoutController 3":"192.168.178.107",
    			"LayoutController 4":"192.168.178.109"
    		}
    	
    		var siteBuild=false;
    		
    		function ping(ip,fieldName) {
    		
    			if(!siteBuild){
    				document.getElementById(fieldName).innerHTML = "";
    			}
    
    			url = "http://" + ip + "/?rand=" + Math.random().toString(36).substring(7);
    
    			var httpRequest = new XMLHttpRequest();
    		
    			httpRequest.onreadystatechange = function() {
    
    				if (httpRequest.readyState == 4) {
    					if (httpRequest.status == 200) {
    						var jsonArray = JSON.parse(httpRequest.responseText);
    						decodeJson(fieldName,jsonArray);
    					}else{
    						document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
    					}
    				}
    			}
    
    			httpRequest.ontimeout = function() {
    				document.getElementById(fieldName).innerHTML = "<span style='color:red'>OFFLINE</span>";
    				document.getElementById(fieldName + "2").innerHTML = "";
    			}
    			
    			httpRequest.timeout = 5000;
    			httpRequest.open("GET", url, true);
    			httpRequest.send();
    		}
    		
    		function setTrains(hubs){
    			var out = "<table><tr><th>Zug</th><th>Status</th><th>Battery</th></tr>"
    			hubs.forEach(hub => 
    				Object.keys(hub).forEach(key => {
    					out += "<tr>";
    					out += "<td>" + key + "</td>";
    					out += "<td>";
    					if(hub[key]["isConnected"]==1){
    						out += "<span style='color:green'>ONLINE</span>";
    					}else{
    						out += "<span style='color:red'>OFFLINE</span>";
    					}
    					out += "</td>";
    					out += "<td>";
    					out += hub[key]["batteryLevel"]
    					out += "</td>"
    					out += "</tr>";
    				})
    			);
    			out += "</table>";
    			document.getElementById("trains").innerHTML = out;			
    		}
    		
    		function decodeJson(fieldName,jsonArray){
    			if("type" in jsonArray){
    				switch (jsonArray["type"]) {
    				  case "layout":
    					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
    					document.getElementById(fieldName + "2").innerHTML = jsonArray["batLevel"];
    					break;
    				  case "train":
    					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
    					setTrains(jsonArray.Hubs);
    					break;
    				  default:
    					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
    					break;
    				}
    			}
    		};
    		
    		function test(){
    			var out = "<table><tr><th>System</th><th>Status</th><th>Volt</th></tr>";
    			console.log(controllers);
    			var i = 0;
    			Object.keys(controllers).forEach(key => {
    				i++;
    				out += "<tr>";
    				out += "<td>" + key + "</td>";
    				out += "<td id=\"controller" + i + "\">";
    				out += "</td>";
    				out += "<td id=\"controller" + i + "2\">";
    				out += "</td>";
    				out += "</tr>";
    			});
    			out += "</table>";
    			if(!siteBuild){
    				document.getElementById("controller").innerHTML = out;
    				siteBuild=true;
    			}
    			
    			
    			i = 0;
    			Object.keys(controllers).forEach(key => {
    				i++;
    				ping(controllers[key],"controller" + i); 
    			});
    		};
    	</script>
      </head>
      <body onload="test();">
    	<div style="float: left;margin:20px;margin-right: 50px;">
    	  <div id="controller"></div>
    	  <div style="margin-top:20px;">
    		<input type="submit" value="Reload" onclick="test()"> 
    	  </div>
    	</div>	
    	<div id="trains" style="padding:20px"></div>
      </body>
    </html>
    
    in reply to: Projekt: Layout Statusanzeige #2968
    Matthias EnderMatthias Ender
    Participant

    2. Anpassung der MTC4PU

    Die Layoutcontroller waren noch einfach, jetzt wird es etwas Komlizierter:

    Zunächst muss die Klasse MattzoPUHub angepasst werden:
    Das Abrufen des Batterylevels kann zwar schon ausgeführt werden, bisher wird das aber nicht gespeichert. Deshalb bekommt die Klasse zunächst einen neuen Parameter:
    String batteryLevel = "0";
    Dann brauche ich zwei neue Zugriffe auf Parameter:

    
    String getName() {
      return _hubName;
    }
    
    String getAddress() {
      return _macAddress;
    }
    

    Es muss die Konfigration des MTC4PU angepasst werden.
    1. Soll der MTC4PU das Batterylevel auslesen und das auch alle 10 Sekunden:

    
    const bool REPORT_BATTERYLEVEL = true;          // set to true or false to allow or omit battery level reports
    const int SEND_BATTERYLEVEL_INTERVAL = 10000;
    

    ^^ Diese Zeilen werden nur abgeändert.

    Um den Log nicht zuzumüllen entferne ich das Logging des Batterylevel aus der requestPoweredUpBatteryLevel() Funktion:

    
    //mcLog2("Requesting battery level for hub " + String(nextBatteryLevelReportingHub), LOG_DEBUG);
    

    Die Funktion hubPropertyChangeCallback() habe ich so angepasst, dass sie erstens nichts mehr ins Log schreibt und zweitens das Batterylevel im MattzoPUHub Objekt abspeichert:

    
    void hubPropertyChangeCallback(void* hub, HubPropertyReference hubProperty, uint8_t* pData)
    {
      Lpf2Hub* myHub = (Lpf2Hub*)hub;
      String hubAddress = myHub->getHubAddress().toString().c_str();
      //mcLog("PU Message received from " + hubAddress + ", hub property " + String((byte)hubProperty, HEX));
    
      for (int i = 0; i < NUM_HUBS; i++) {
        if(myHubs[i].getAddress()==hubAddress){
          //mcLog("Hub found!!");
          if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE){
            myHubs[i].batteryLevel=String(myHub->parseBatteryLevel(pData), DEC);
            mcLog(myHubs[i].getName() + " BatteryLevel: " + myHubs[i].batteryLevel);
          }
        }
      }
    
      if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE)
      {
        //mcLog("BatteryLevel: " + String(myHub->parseBatteryLevel(pData), DEC));
        sendMQTTMessage("roc2bricks/battery", hubAddress + " " + myHub->parseBatteryLevel(pData));
        return;
      }
    
      if (hubProperty == HubPropertyReference::BUTTON)
      {
        //mcLog("Button: " + String((byte)myHub->parseHubButton(pData), HEX));
        sendMQTTMessage("roc2bricks/button", hubAddress + " button pressed.");
        return;
      }
    }
    

    Nun kommt der HTTP Response so ähnlich wie beim LayoutController. Die JSON ist etwas komplexer aber sonst ist das ziemlich ähnlich:

    WiFiServer server(80);
    bool globalLastKnownWifiConnectedStatus = false;
    
    void webpage(WiFiClient client){
       client.println("HTTP/1.1 200 OK");
       client.println("Access-Control-Allow-Origin: *");   
       client.println("Access-Control-Allow-Methods: GET");
       client.println("Content-Type: application/json");
       client.println("");
       client.print("{\"type\":\"train\",\"status\":true, \"Hubs\":["); 
       for (int i = 0; i < NUM_HUBS; i++) {
          client.print("{\"" + myHubs[i].getName() + "\": ");
            client.print("{\"isConnected\": " + String(myHubs[i].isConnected()) + ", \"batteryLevel\": \"" + myHubs[i].batteryLevel + "\"}");   
          client.print("}");
          if(i+1<NUM_HUBS){
            client.print(",");
          }
       }
       client.println("]}"); 
    }
    
    void HTTPLoop(){
      WiFiClient client = server.available();
      if (!client) {
        return;
      }
      client.flush();
      webpage(client);
    }
    
    void checkHTTPServerStart() {
      if (WiFi.status() != WL_CONNECTED && globalLastKnownWifiConnectedStatus) {
        globalLastKnownWifiConnectedStatus = false;
      }
      else if (WiFi.status() == WL_CONNECTED && !globalLastKnownWifiConnectedStatus) {
        globalLastKnownWifiConnectedStatus = true;
        server.begin();
        Serial.println("HTTP Server started");
      }
      if (WiFi.status() == WL_CONNECTED) {
        HTTPLoop();
      }
    }

    Dieser Code gehört vor die loop() Funktion und auch hier wird die LoopFunktion angepasst:

    
    void loop() {
      loopMattzoController();
    
      checkHTTPServerStart();
      
      sendDiscoveredHub2mqtt();
      connectPoweredUpHubs();
      requestPoweredUpBatteryLevel();
      accelerateTrainSpeed();
      setLights();
    
      debugInfo();
    }

    Nun antwortet auch der Traincontroller, so wie er es soll.

    Nochmal zusammengefasst:

    Anpassung der Klasse:
    klasse

    Anpassung der Konfig:
    konfig

    Die Funktionen:
    funktionen

    und der Response:
    response

    in reply to: Projekt: Layout Statusanzeige #2967
    Matthias EnderMatthias Ender
    Participant

    Die Realisierung besteht nun also aus 3 Teilen.
    1. Anpassung der MattzoLayoutController
    2. Anpassung der MTC4PU
    3. Displaybau

    1. Teil MattzoLayoutController

    Hier wiederum habe ich 2 Anpassungen gemacht.
    1.1. Spannung Messen
    1.2. HTTP Response

    1.1. Spannung Messen
    Ich habe mich an folgende Anleitung gehalten um die Spannung zu messen:
    Quelle

    Als erstes wird die Kontrollerspannung mit dem A0 verbunden:
    d867b6d4-3d7e-4fbc-9cba-afdc17e765bf

    und dann kann man mit folgenden Zeilen Code die Spannung auslesen:
    <a href="https://ibb.co/ZBmctMX"><img src="https://i.ibb.co/ZBmctMX/d867b6d4-3d7e-4fbc-9cba-afdc17e765bf.jpg" alt="d867b6d4-3d7e-4fbc-9cba-afdc17e765bf" border="0" /></a>

    Also wenn die Funktion checkVoltage() aufruft ist dannach die aktuelle Spannung als String in Ubatt gespeichert.

    1.2. HTTP Response

    Um den HTTP Response zu erzeugen muss zunächst ein WIFI Server initialisiert werden
    WiFiServer server(80);

    Dieser wird gestartet, wenn das WIFI verbunden ist:
    server.begin();

    Dann gibt es ein Funktion, welche in der loop() Funktion aufgerufen wird und prüft ob eine Anfrage reinkommt:

    void HTTPLoop(){
      WiFiClient client = server.available();
      if (!client) {
        return;
      }
      client.flush();
      webpage(client);
    }

    Diese Funktion ruft die Funktion webpage auf, wenn eine Antwort gesendet wird.

    Die Funktion “webpage” prüft zunächst die Spannung und baut dann die JSON Antwort zusammen:

    void webpage(WiFiClient client){/* function webpage */ 
       checkVoltage();
       client.println("HTTP/1.1 200 OK");
       client.println("Access-Control-Allow-Origin: *");   
       client.println("Access-Control-Allow-Methods: GET");
       client.println("Content-Type: application/json");
       client.println("");
       client.println("{\"type\":\"layout\",\"status\":true,\"batLevel\":" + Ubatt + "}"); 
    }

    Der gesamte Code ist dann hier:

    
    WiFiServer server(80);
    bool globalLastKnownWifiConnectedStatus = false;
    String Ubatt = "";
    ADC_MODE(ADC_VCC);
    
    void checkVoltage(){
      uint16_t my_getVcc_Voltage = ESP.getVcc();
      float_t my_Voltage_calculated = ((float)my_getVcc_Voltage/1024.0f);
      Ubatt = String(my_Voltage_calculated, 3);
    }
    
    void webpage(WiFiClient client){/* function webpage */ 
       checkVoltage();
       client.println("HTTP/1.1 200 OK");
       client.println("Access-Control-Allow-Origin: *");   
       client.println("Access-Control-Allow-Methods: GET");
       client.println("Content-Type: application/json");
       client.println("");
       client.println("{\"type\":\"layout\",\"status\":true,\"batLevel\":" + Ubatt + "}"); 
    }
    
    void HTTPLoop(){
      WiFiClient client = server.available();
      if (!client) {
        return;
      }
    //  while(!client.available()){
    //    delay(1);
    //    Serial.println("HTTP Server ERROR");
    //  }
      client.flush();
      webpage(client);
    }
    
    void checkHTTPServerStart() {
      if (WiFi.status() != WL_CONNECTED && globalLastKnownWifiConnectedStatus) {
        globalLastKnownWifiConnectedStatus = false;
      }
      else if (WiFi.status() == WL_CONNECTED && !globalLastKnownWifiConnectedStatus) {
        globalLastKnownWifiConnectedStatus = true;
        server.begin();
        Serial.println("HTTP Server started");
      }
      if (WiFi.status() == WL_CONNECTED) {
        HTTPLoop();
      }
    }

    Dieser Code wird vor die “void loop()” Funktion koppiert und innerhalb der loop-Funktion aufgerufen:

    void loop() {
      loopMattzoController();
    
      checkHTTPServerStart();
        
      checkEnableServoSleepMode();
      monitorSensors();
      levelCrossingLoop();
      basculeBridgeLoop();
    }

    Nun antworten die LayoutController auf einen HTTP Request wie benötigt. Es lässt sich über den Aufruf der IP im Browser testen.

    in reply to: Projekt: Layout Statusanzeige #2966
    Matthias EnderMatthias Ender
    Participant

    Ok, dann versuche ich mich mal im Erklären:

    Zunächst das Prinzip:
    prinzip

    Der RocRailServer wird von mir im Moment nur angepingt. Damit weiß ich zwar nicht ob die Serversoftware wirklich läuft, allerdings weiß ich ob der Rechner an ist und ob er mit dem WLAN verbunden ist.

    Die MattzoController werden allerdings mit einem HTTP Request angefragt. Als Antwort kommt ein JSON zurück. Diese JSON Daten geben mir dann etwas mehr Informationen.
    Wenn ich also in den Browser die IP Adresse vom TrainServer eingebe, kommt folgende Antwort:
    Die Rohdaten sehen so aus:
    json2

    Und wenn man das etwas sauberer aufschreibt, sieht das so aus:

    json1
    Dabei ist das “isConnected” 0 wenn der Zug Offline ist und 1 wenn der Zug verbunden ist. Ausserdem wird dann bei batteryLevel eine Zahl zwischen 0 und 100 übertragen, was das BatteryLevel darstellt.

    Bei den LayoutControllern sieht das etwas einfacher aus:
    json3

    json4

    Man könnte auch eine komplette HTML Seite anzeigen, aber das wäre schwer maschinell zu lesen. Deshalb verwende ich dort diese JSONs.

    in reply to: Projekt: Layout Statusanzeige #2948
    Matthias EnderMatthias Ender
    Participant

    Nicht ganz einfach, aber auch keine Raketenwissenschaft:

    c34f7418-cf22-4eb2-8143-a1a34f749e9b

    Wie gesagt, wenn jemand interessiert wie ich das realisiert habe, dann meldet euch hier.

    in reply to: Einsteiger Tutorial Einrichten Microcontroller #2947
    Matthias EnderMatthias Ender
    Participant

    Was war denn das Problem?

    in reply to: Projekt: Layout Statusanzeige #2924
    Matthias EnderMatthias Ender
    Participant

    2 Stunden später:
    statusV2

    in reply to: Projekt: Layout Statusanzeige #2923
    Matthias EnderMatthias Ender
    Participant

    So, das ganze geht vorwärts:
    status

    Jetzt habe ich irgendeine Spannung bei den LayoutControllern und meine Züge. Nun muss ich mal die Spannung beobachten und schauen wie ich an den Batteriestatus bei den Zügen rankomme.

    Die werden ja regelmäßig abgefragt und dann ins Log geschrieben. Ich muss die irgendwie Speichen ums sie dann beim HTTP Request abzurufen.

    Dann mal schauen, wie ich euch den Quellcode teilen kann, wenn das jemanden interessiert.

    EDIT:
    Achso, diese HTML Seite ist natürlich nur ein Zwischenschritt. Am Ende soll ein Arduino mit Bildschirm den Status der Kontroller und Züge anzeigen.

    in reply to: Integrationsbericht #2922
    Matthias EnderMatthias Ender
    Participant

    Hier einmal der MattzoLayoutController 3:
    – 4 Reedsensoren für 4 Bahnhofsgleise
    – 2 Weichen
    (Die Signale sind nicht beleuchtet, dass ist irgendwann, viel später geplant)

    Ich habe das Modul gerade neu gebaut, weil ich zunächst zu wenig Abstand zwischen Weichen und Sensoren hatte. Jetzt sind es ca. 20 Noppen. Diesen Abstand solltet ihr unbedingt einhalten.

    b154d6ab-2dce-4fb4-a5a1-1b7f5e5098a3

    Die Züge bremsen bei mir nach dem ENTERSENSOR auf Minimalgeschwindigkeit, um dann beim INSENSOR sofort zu halten. Durch die Verzögerung im Funk kann es trotzdem ein paar Noppen dauern, bis der Zug steht: 5-15 Noppen..

    7448f7de-be7c-4ba4-9cda-faf694841383
    Ich bin noch mit dem Grundaufbau beschäftigt. Deko kommt später

    Kabelsalat und Reedsensor:
    6346cc99-94b6-498c-9ae5-92f5d63611b8

    Gehäsue für Kontroller und Batteriebox:
    45773d97-eb20-420e-9ad1-0b47a6468089

    10ade1f3-ac3b-4c8a-bf22-717ce1789291

    EIN-AUS-Schalter:
    7d5ec200-f4e0-4e7e-addd-83c53e402011

    in reply to: Projekt: Layout Statusanzeige #2920
    Matthias EnderMatthias Ender
    Participant

    Um das ganze zu erweitern möchte ich jetzt die Kontroller so erweitern, dass diese mir ein Statusfeedback geben. D.h. die MattzoLayoutController sollen mir bei einem GET Request das Batterielevel zurückgeben und der MTC4PU soll mir sagen, welche Züge aktuell verbunden sind. Ggf. gerne auch mit dem Batterielevel der Züge.

    Hat da jemand von euch Ahnung, wie ich sowas programmiere?

    in reply to: Integrationsbericht #2912
    Matthias EnderMatthias Ender
    Participant

    @Zoltan, ich habe die Modelle bei Bricklink komplett freigeschaltet, allerdings wird das erst nach einem Review sichtbar. Das dauert ein paar Tage. Aber dann ist dort die komplette Teileliste und Model und Anleitung etc. zu sehen

    @Max: Ich habe schon ein paar hundert davon 😀

    in reply to: Integrationsbericht #2906
    Matthias EnderMatthias Ender
    Participant

    HTML Seite zum Prüfen, ob die Server und Kontroller online sind:

    Server-Test

    Mehr Infos:

    Layout Statusanzeige

    in reply to: Integrationsbericht #2900
    Matthias EnderMatthias Ender
    Participant

    Beim Ansteuern der Weichen und Sensoren geht es leider nicht mehr ganz ohne Kabel. Allerdings habe ich auch hier versucht die Kabel soweit es geht zu vermeiden.

    Dem entsprechend habe ich eine Reihe von Batteriebetriebenen MattzoLayoutkontrollern auf der Anlage verteilt.

    Hier der Baubericht:

    Benötigtes Werkzeug:
    – Lötkolben
    – Crimpzange
    – Heißklebepistole
    – Abisolierzange

    Bauteile:
    – LayoutController
    – Servokabel
    – Batteriebox
    – Akkus

    Anleitung:
    Zunächst habe ich aus dem Crimpkoffer diese Anschlussleisten abgeschnitten
    3870dd21-e869-4ea4-a92b-0072344ed80c

    Mit ein paar Servokabeln kann man die Dinger am Board befestigen
    8c46a356-7ba0-497f-b71d-3fe3d5f50fca

    Dann ein Kabel abisoliert und mit Lötzin überzogen
    88e05be3-ce51-4dc7-bb73-8cdfb21e36b7

    Das Kabel dann an die Kontakte gelötet
    22e076ab-c39e-4ebb-920e-4a5115ab8d8d

    Am Ende müssen zwei solcher Kabel über die Anschlussleisten gelötet werden
    2108d10b-752c-4b90-877c-b0a77ecb9b07
    Es ist sinnvoll den Kontakt mit einem Multimeter zu prüfen

    Wenn das funktioniert können die Anschlüsse per Heißkleber fixiert werden.

    Nun wird ein Kabel benötigt um die Anschlüsse G und VIN mit der Leiste zu verbinden
    Um das Kabel zu erstellen habe ich eins der Servokabel verwendet und an der anderen Seite die einzelnen Anschluss drangecrimpt
    beb2065d-e707-417b-9402-6357cdd73f62

    Auch an die Batteriebox muss ein Anschluss drangecrimpt werden
    8f783f15-adaa-4d01-a033-52dbf4de045d

    Die Reedsensoren werden aus den Servokabeln wie folgt zusammengelötet
    5dc8c217-6456-4dc4-afb2-fc5b5ab9ed8e

    Das wars dann schon mit löten und Crimpen
    Wenn man das Zeug wie folgt anschließt, kann man den Kontroller per PC mit Firmware bespielen:
    7482dd4a-05a1-4dfd-b07f-097e41b2da7c
    Hier wird nur das braune Kabel mit dem Board verbunden. Der Kontroller bekommt seinen Strom also nicht aus der Batteriebox, sondern vom PC.

    Am Ende wird das USB Kabel entfernt und der rote Stecker an VIN Angeschlossen. Nun läuft alles per Batterie.
    505c880c-54d2-4545-b325-0246d5052a35

    Es können nun 8-9 Sensoren, Weichen oder Signale an den Layoutkontroller angesteckt werden.

    Nun kann man das ganze noch mit etwas Lego verstecken.
    Sensor-Shield-V3

    Bricklink

    Am Ende hat man dann eine Reihe von Funktionseinheiten, welche man verbauen kann.
    9bf86fdf-2f50-4607-be67-0751fe2e1e7b
    Diese Einheiten kann ich dann am Schreibtisch komplett testen und mit RocRail verbinden. Alles Einstellen und Pürfen. Erst dann gehts damit an die Anlage.

    Kleiner Tweak:
    Ich habe die Reedsensoren mit diesen 4×1 CurvedSlopes an den Schienen befestigt:
    Sensor-Shield-V3-3

    in reply to: Reichweite Reedsensoren #2885
    Matthias EnderMatthias Ender
    Participant

    ich habe gerade bei wikipedia nochmal nachgesehen. danach ist es egal ob oben oder unten ..

    was wie gesagt auch mit meiner beobachtung zusammen passt

    https://de.wikipedia.org/wiki/Reedschalter

    Das magnetfeld muss parallel zum reedsensor verlaufen, sodass die feld durch die metalldinger fließt.. dann ziehen sich diese beiden an, und der reedschalter schaltet. ob die nun von oben nach untern oder links und rechts schalten ist dabei egal..
    der reedsensor muss nur von links nach rechts in den schienen liegen und genauso müssen die magneten von links nach rechts eingebaut werden.

    in reply to: Reichweite Reedsensoren #2884
    Matthias EnderMatthias Ender
    Participant

    stimmt das mit der empfindlichkeit? ich habe mir sowas ausgedacht. Aber glaube gelesen zu haben dass es nicht so ist und bisher habe ich auch nicht beobachten können, dass es da unterschiede gibt.

    in reply to: Einsteiger Tutorial Einrichten Microcontroller #2875
    Matthias EnderMatthias Ender
    Participant

    na ich würde sie nicht löschen, aber eine umbennenen in servo.bac.

    in reply to: MattzoBricks Integration #2868
    Matthias EnderMatthias Ender
    Participant

    My plan for a sensorunit:

    Sensor-Shield-V3

    The idea with the battery box was great!!! Works better then with usb cable.

Viewing 25 posts - 1 through 25 (of 34 total)