Seite 1 von 1

PZB 90 Leuchtmelderblock zu verkaufen

Verfasst: 14.10.2021 23:29:54
von Timo
BildBildBildBildBildBild


PZB 90 Leuchtmelderblock

Technische Daten
Maße: 72 x 84 x 29 mm
Lochmaß: 66 x 66 mm
Einbautiefe: 20 mm
Frontplattenstärke: 1 - 10 mm
LED: 3.2-3.6V 20mA
Wie wird der Würfel angesteuert?
Ich selbst kann den kleinen und preiswerten NodeMCU empfehlen.
Einfach die LEDs mit der Platine verbinden - es werden keine Widerstände benötigt.
Danach über ein USB Kabel mit dem PC das Programm aufspielen.
Im letzten Schritt verbindet sich der PZB Würfel über euer Wlan mit Zusi TCP - fertig!

Der Würfel kann auch in eine bestehende Steuerung integriert werden.
Dann sind abhängig von der Ausgangsspannung ggf. Widerstände nötig.

Werden Widerstände für die LEDs benötigt?
Das ist im Wesentlichen abhängig von der verwendeten Steuerung.
keine bei 3.4 Volt (z.B. NodeMCU)
80 ohm bei 5.0 Volt (z.B. Arduino)
320 ohm bei 9.0 Volt
460 ohm bei 12.0 Volt

Wie wird die Helligkeitsregulierung umgesetzt?
Softwareseitig lassen sich die LEDs sehr einfach über PWM fähige Ausgänge dimmen.
Beim NodeMCU bieten sich dafür alle Pins von D1 bis D8 an.
Arduino Nano über die Pins D3, D5, D6, D9, D10 und D11.
Arduino Mega über die Pins D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D44, D45, D46.

Ich kann nicht programmieren, wie gehe ich vor?
Gerne stelle ich den Programmcode für den NodeMCU zur freien Verfügung,
der wird in die kostenlose Arduino IDE kopiert und mit einem Klick zur Platine gesendet.
Wie man den NodeMCU korrekt mit deinem PC und der ArduinoIDE verbindet ist in vielen Tutorials nachzulesen.

Sind die Leuchtfelder aus bedrucktem Papier und anschließend laminiert?
Nein! Bedrucktes Papier eignet sich nicht für die Leuchtfelder. Das hat zwei wesentliche Gründe,
zum Einen verblasst der Druck zunehmend mit dem Monaten und zum Anderen leuchten die Farben nicht.
Deshalb wurde eigens für den Würfel eine beständige Folien aus dem Instrumentenbau angefertigt.

Sind die Leuchtmittel nicht normale LEDs?
Es kommen sehr helle LEDs zum Einsatz, die einen speziellen Abstrahlwinkel und eine gewisse Wellenlänge haben.
Die sind nicht einfach bei Conrad bestellbar und unterscheiden sich zu den normalen LEDs.

Was soll der Würfel kosten?
Leider lassen sich Arbeitsstunden, Material, Anfertigungen und Maschinen nur schwer gegenrechnen.
Grob überschlagen bin ich mit einem Betrag von um die 45 Euro jedenfalls zufrieden.
Jeder Verkauf unterstützt Projekte wie dieses oder zukünftig die Schalter-Nachbauten, Richtungswender...
Und wer mich einfach so unterstützen möchte darf mir gerne einen Kaffee spendieren.
Liebe Grüße aus Hessen,
Timo

Re: PZB 90 Leuchtmelderblock zu verkaufen - wieder verfügbar!

Verfasst: 25.06.2022 22:53:35
von Timo
Anbei noch der Programmcode für den NodeMCU zur drahtlosen Übertragung der Daten zwischen Zusi TCP und PZB Leuchtmelderblock.

Code: Alles auswählen

#include <ESP8266WiFi.h>

#define SendKey 0

const char *host = "192.168.178.80"; // Lokale IP vom Zusi TCP Server häufig 192.168.X.X
const uint16_t port = 1436;  // Port zum Server
//WiFiServer server(port);

//Server connect to WiFi Network
const char *ssid = "FRITZ!Box 7590";  // WiFi SSID (Netzwerkname)
const char *password = "xxxxxx";  // WiFi Passwort

// Byte Serie zum Verbindungsaufbau
uint8_t Anmeldung[] = { 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, 0x0, 0x2, 0x0, 0xA, 0x0,
             0x0, 0x0, 0x3, 0x0, 0x46, 0x61, 0x68, 0x72, 0x70, 0x75, 0x6C, 0x74, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x32, 0x2E, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
            };
// Byte Serie der angeforderten Daten, die der Server senden soll
uint8_t Abfrage[] = { 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0x0,
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0,  // Geschwindigkeit m/s
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0xA, 0x0,  // Zugkraft IST/Achse N
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0xC, 0x0,  // Zugkraft Soll/Achse N
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x13, 0x0, // Hauptschalter
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x17, 0x0, // AFB Soll m/s
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x20, 0x0, // LM Hochabbremsung Aus/Ein
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x64, 0x0, // SIFA
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x65, 0x0, // Zugsicherung
                      //0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x66, 0x0, // Türen
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF
                    };

int count=0;

WiFiClient client;

union //Datentyp zur Abfrage des Knotens
{
  byte b[4];
  int i;
} dataLng;

union 
{
  byte b[2];
  int16_t i;
} dataGroup;

int ebene = 0;
int16_t ebene1Status = 0;
int16_t ebene2Status = 0;
int16_t ebene3Status = 0;
int16_t ebene4Status = 0;

union 
{
  byte b[4];
  float f;
  int i;
  int16_t i16;
} nutzdata;

#define MAX_NUTZDATA 4

uint8_t clientForceRead()
{
  while (!client.available()) {}
  return client.read();
}

void(* resetFunc) (void) = 0;  

//=======================================================================
//                    Power on setup
//=======================================================================
void setup() 
{
   // Aus und Eingänge festlegen
   pinMode(15, OUTPUT); // Tacho
   pinMode(23, OUTPUT); // PIN23 Ausgang LM ZS Aus
   pinMode(24, OUTPUT); // PIN24 Ausgang LM HS Aus
   pinMode(25, OUTPUT); // PIN25 Ausgang LM TAV
   pinMode(26, OUTPUT); // PIN26 Ausgang LM SIFA
   pinMode(14, OUTPUT); // PIN27 Ausgang LM 55
   pinMode(28, OUTPUT); // PIN28 Ausgang LM 99
   pinMode(13, OUTPUT); // PIN29 Ausgang LM 70
   pinMode(30, INPUT);  // PIN30 Eingang Lampentest MFA
   pinMode(5, OUTPUT); // PIN31 Ausgang LM 85
   pinMode(32, INPUT);  // PIN32 Eingang Beleuchtung MFA heller
   pinMode(12, OUTPUT); // PIN33 Ausgang LM Befehl 40
   pinMode(34, INPUT);  // PIN34 Eingang Beleuchtung MFA dunkler
   pinMode(2, OUTPUT); // PIN35 Ausgang LM 500Hz
   pinMode(4, OUTPUT); // PIN37 Ausgang LM 1000Hz
  
  Serial.begin(115200);
  pinMode(SendKey,INPUT_PULLUP);
  Serial.println();
  
  WiFi.hostname("PZB 90 LM");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password); // Verbindung mit WiFi herstellen
 
  // Wait for connection  
  Serial.println("Verbindung herstellen zu ");
  Serial.println(ssid);
  while (WiFi.status() != WL_CONNECTED) {   
    delay(500);
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.print("Erfolgreich verbunden mit ");
  Serial.println(ssid);

  if(client.connect(host, port))
    {
      Serial.println("Verbunden mit Zusi TCP");
    } else {
      Serial.println("ERROR: Keine Verbindung zu Zusi TCP möglich!");
      delay(5000);
      return;
    }
    if(client.connected()){
        client.write (Anmeldung, sizeof(Anmeldung));
        delay(5000);
        client.write (Abfrage, sizeof(Abfrage)); 
    } 
}
//=======================================================================
//                    Loop
//=======================================================================

void loop() 
{ 
  if (client.available()) {
 
   dataLng.b[0] = clientForceRead();
   dataLng.b[1] = clientForceRead();
   dataLng.b[2] = clientForceRead();
   dataLng.b[3] = clientForceRead();

   Serial.println(dataLng.b[0]);
   Serial.println(dataLng.b[1]);
   Serial.println(dataLng.b[2]);
   Serial.println(dataLng.b[3]);

   
   if (dataLng.i == 0) { //BEGINN KNOTEN
      ebene++;
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      if (ebene == 1) {
         ebene1Status = dataGroup.i;
      } else if (ebene == 2) {
         ebene2Status = dataGroup.i;
      } else if (ebene == 3) {
         ebene3Status = dataGroup.i;
      } else if (ebene == 4) {
         ebene4Status = dataGroup.i;
      }
      
   } else if (dataLng.i == -1) { //ENDE KNOTEN
      ebene--;
      
      if (ebene < 0) { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
      }
   } else if (dataLng.i == 1)  { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
      
   } else { //ATTRIBUT
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      nutzdata.i = 0;                           //Löschen der Nutzdaten Variable
      for(int i = 0; i < dataLng.i - 2; i++) {  //Schleife zum Auslesen der Nutzdaten
         byte b = clientForceRead();                
         if (i < MAX_NUTZDATA) {
            nutzdata.b[i] = b;
         }
      }
      
      //AUSWERTUNG
      if ((ebene >= 1) && (ebene1Status == 0x0001)) { // VERBINDUNGSAUFBAU
      } else if ((ebene >= 1) && (ebene1Status == 0x0002)) { // FAHRPULT
         if ((ebene >= 2) && (ebene2Status == 0x000A)) { // FST-DATA
            if ((ebene >= 3) && (ebene3Status == 0x0022)) { // NBÜ-DATA
            } else if ((ebene >= 3) && (ebene3Status == 0x0064)) { // SIFA
               if (ebene == 3) {
                  if (dataGroup.i == 0x0002) { // Status Sifa-Leuchtmelder
                     if (nutzdata.b[0] == 1) {digitalWrite(26, HIGH);}    // SIFA Leuchtmelder einschalten
                     if (nutzdata.b[0] == 0) {digitalWrite(26,LOW);}      // SIFA Leuchtmelder ausschalten
                  } else if (dataGroup.i == 0x0003) { // Status Sifa-Hupe
                     if (nutzdata.b[0] == 2) Serial.println("SIFA Hupe Zwangsbremsung");
                     if (nutzdata.b[0] == 1) Serial.println("SIFA Hupe Warnung");
                     if (nutzdata.b[0] == 0) Serial.println("SIFA Hupe aus");
                  }
               }
            } else if ((ebene >= 3) && (ebene3Status == 0x0065)) { // PZB
               if ((ebene >= 4) && (ebene4Status == 0x0003)) { // Indusi-Betriebsdaten
                  if (ebene == 4) {
                     if (dataGroup.i == 0x0005) { // Melder 1000 Hz
                        if (nutzdata.b[0] == 1) {digitalWrite(4, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(4, LOW);}
                     } else if (dataGroup.i == 0x0006) { // Melder U
                        if (nutzdata.b[0] == 1) {digitalWrite(14, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(14, LOW);}
                     } else if (dataGroup.i == 0x0007) { // Melder M
                        if (nutzdata.b[0] == 1) {digitalWrite(13, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(13, LOW);}
                     } else if (dataGroup.i == 0x0008) { // Melder O
                        if (nutzdata.b[0] == 1) {digitalWrite(5, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(5, LOW);}
                     } else if (dataGroup.i == 0x000A) { // Melder 500 Hz
                        if (nutzdata.b[0] == 1) {digitalWrite(2, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(2, LOW);}
                     } else if (dataGroup.i == 0x000B) { // Melder Befehl
                        if (nutzdata.b[0] == 1) {digitalWrite(12, HIGH);}
                        if (nutzdata.b[0] == 0) {digitalWrite(12, LOW);}
                     }
                  }
               }
            } else if ((ebene >= 3) && (ebene3Status == 0x0066)) { // Türsystem
            } else if (ebene == 2) {
               if (dataGroup.i == 0x0001) {          // Geschwindigkeit Meter/Sekunde
                  byte Geschw = nutzdata.f * 3.6;
                  byte tacho = Geschw * 2.125; // Umrechnen für den Tacho
                  //Serial.print("A");
                  //Serial.println(Geschw);
                  analogWrite(15, tacho);
               } else if (dataGroup.i == 0x000A) {   // Zugkraft Ist/Achse in Newton
                  byte Zugkraft_ist = nutzdata.f;
                  //Serial.println(Zugkraft_ist);
               } else if (dataGroup.i == 0x000C) {   // Zugkraft Soll/Achse in Newton
                  byte Zugkraft_soll = nutzdata.f;
                  //Serial.println(Zugkraft_soll);
               } 
            }
         }
      }
   }
 }
 
 // wenn der Server getrennt wird, stoppt der Client und gibt seriell eine Meldung ab:
 if (!client.connected()) {
  Serial.println();
  Serial.println("Die Verbindung mit Zusi TCP wurde getrennt!");
  client.stop();
  // mache nichts:
  while (true);
  //resetFunc ();
 }
}
Liebe Grüße aus Hessen,
Timo