Einstiegshilfe modBus

Hallo,

ich brauche mal eine Einstiegshilfe modbus.
Ich will ein 8-Kanalrelais-Module (waveshare Modbus POE ETH Relay) ansteuern. Über das vom waveshare verlinke tool (SSCOM) habe ich mit viel Gefummel erreichen können, das die ein Relais via modbus TCP schalten kann.

Nun wollte ich das mal „auf die Schnelle“ in IPS umsetzen, scheitere jedoch kläglich.

Kann mir da bei der grundlegenden modbus-Nutzung in IPS jemand Hilfe leisten?

Die Einstellungen am Geräte (via virCom) sehen wie folgt aus:


Mit dem tool (mit dem ich es hinbekomme zu schalten) sieht es so aus:

In Symcon habe ich nun folgendes ohne Erfolgt (im Debugfenster kommt auch nichts an versucht:
Screenshot IPS 1

Im Wiki von waveshare steht folgendes:

Gruß hardlog

Nach viel Probieren komme ich der Sache selbst näher:

  1. der Modus war falsch (nicht RTU über TCP) sondern „einfach“ Modbus TCP …

Jetzt lassen sich die Relais schonmal mit Modbus Coil schalten:

hardlog

Lesen könnte auch nicht schaden :wink:
Edit:
Damit keine Missverständnisse entstehen: Lesen per Modbus Instance war gemeint, nicht die Augen :wink:

1 „Gefällt mir“

Danke.
Geht alles!

Gruß Hardlog

Hallo,

ich mache meine ersten Schritte in Modbus TCP. Ich will eine 8-Kanal-Relaiskarte (waveshare) steuern. Soweit so gut. Einzelne Relais per Instanz WriteSingleCoil bekomme ich hin. Hab ich aber auch die Möglichkeit per „MultipeCoil“ z.B. die Relais 1,3,5 und 7 gleichzeitig einzuschalten?

$startAddress = 0; // Startadresse für Relais
$numberOfCoils = 4; // Anzahl der zu schaltenden Relais
$data = chr(0x55); // Daten für Relais 1, 3, 5 und 7 ein

Gruß hardlog

Abend,

du kannst mit dem Functionscode 15 nur zusammenhängende Blöcke schreiben.

Wenn du Relais 1,3,5 und 7 schalten willst musst du 4 und 6 mit senden.
Wenn du diese nicht benutzt kannst du sie einfach auf 0 senden.

Mfg
Paul

Für Michael: Glaube nicht, dass das in die Modbus Einsteighilfe passt…

Also, da Modbus Multiple Coils (15) zwar angeboten wird, aber kein Feld für die Nachfolgenden Coil da sind, gehe ich davon aus, dass das ein Fake ist. Angefragt hatte ich es schon…
Ich habe mal das Prg qModbus Master gestartet und auf mein Pokeys57E die Funktion Modbus Multiple Coils (15) geschrieben.
Im Debug Fenster habe ich mir dann die Hex Codes raus geschrieben und in ein PHP Script gepackt.


 $str=chr(0x00).chr(0x0C).chr(0x00).chr(0x00).chr(0x00).chr(0x08).chr(0x01).chr(0x0F).chr(0x00).chr(0x12).chr(0x00).chr(0x08).chr(0x01).chr(0xA7); 
 
CSCK_SendText (14098,$str);

Warum? Geht doch noch immer um die gleiche Hardware.

Michael

Ein wenig Recht gebe ich Dir, eigentlich ist es eine Frage, die in Anleitungen gehört.
Aber schau Dir den Ordner an
Anleitungen sind überall zu finden in den Fragen und Antworten von Usern.
Irgendwie unbefriedigend, wo fragt man gezielt was zu einer Funktion, gib mal ein Tip

Hallo, ich traue mich kaum noch mal nachzufragen, aber wie könnte es gehen?

Welche Instanz ist dann die 14098 bei Dir?? bzw wie nutze ich in der ModbusCoil - Instanz die Funktion 15?

Trau Dich :wink:

Das ist die Client Socket Instanz ( i/O ) an der Dein Relais-Gerät hängt.
Nutzen… das Problem ist, ich weiß nicht wie man die CRC-Prüfsumme am Schluss berechnet.
Wenn mir jemand das aufzeigt, könnte ich Dir den Befehlsstring besser aufdrösseln.
Bin nun mal ein Copy and Paste Typ.

Hallo Helmut,

ich habe mal die „KI“ gefragt und die hat mir zum berechnen der Checksumme folgenden PHP-Schnipsel vorgeschlagen.

<?php
function calculate_crc($data) {
    $crc = 0xFFFF; // Initialwert für CRC

    // Durchlaufe jedes Byte im Datenarray
    for ($i = 0; $i < strlen($data); $i++) {
        $crc ^= ord($data[$i]); // XOR mit dem aktuellen Byte

        // Verarbeite jedes Bit des aktuellen Bytes
        for ($j = 0; $j < 8; $j++) {
            if ($crc & 0x0001) { // Prüfe, ob das niederwertigste Bit gesetzt ist
                $crc = ($crc >> 1) ^ 0xA001; // Rechtsverschiebung und XOR mit Polynom
            } else {
                $crc >>= 1; // Nur Rechtsverschiebung
            }
        }
    }

    return $crc;
}

// Beispiel: Modbus-Daten als String (ohne Checksumme)
//$data = "\x01\x0F\x00\x13\x00\x0A\x02\xCD\x01"; // Beispiel-Daten (Slave-Adresse, Funktion, usw.)
$data = "\x00\x00\x00\x00\x00\x06\x01\x03\x80\x00\x00\x01"; //

// CRC berechnen
$crc = calculate_crc($data);

// CRC in Low- und High-Byte aufteilen
$lowByte = $crc & 0xFF;
$highByte = ($crc >> 8) & 0xFF;

echo "CRC Low Byte: " . dechex($lowByte) . PHP_EOL;
echo "CRC High Byte: " . dechex($highByte) . PHP_EOL;
?>

Mit den Beispielen auf der Wiki von waveshare (https://www.waveshare.com/wiki/Modbus_POE_ETH_Relay#Modbus_TCP_Development_Protocol) scheint es zu stimmen. Ich kann damit trotzdem nicht soviel anfangen. Kannst du mir damit weiterhelfen?

Gruß
Florian

Im Moment nicht, aber ich setze mich heute Abend mal hin.

Super, 1000 Dank!

Florian

Wie gesagt, ich bin eher der Copy and Paste.
Ich habe noch einen Fehler: der Wert „$AlleRelays“ bringt nicht die richtigen Bit Zuweisung.
Finde den Fehler nicht, Es solten die Bit0 bis Bit 7 gesetzt werden, nach dem Muster:
Bit stelle wird mit dem ganz rechtem Hex Wert gesetzt
Bit …hier
0000 0000[TCP]>Tx > 20:31:28:320 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 00
0000 0001[TCP]>Tx > 20:24:29:253 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 80
0000 0010[TCP]>Tx > 20:24:45:472 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 40
0000 0100[TCP]>Tx > 20:27:08:874 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 60
0000 1000[TCP]>Tx > 20:27:58:644 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 10
0001 0000[TCP]>Tx > 20:28:31:419 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 08
0010 0000[TCP]>Tx > 20:29:38:692 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 04
0100 0000[TCP]>Tx > 20:30:13:762 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 06
1000 0000[TCP]>Tx > 20:30:50:973 - 00 01 00 00 00 08 01 0F 00 11 00 08 01 01

Hier mein Script, der fast fertig ist, die Relays sind im Code fest, zum Test

<?php
function calculate_crc($data) {
    $crc = 0xFFFF; // Initialwert für CRC

    // Durchlaufe jedes Byte im Datenarray
    for ($i = 0; $i < strlen($data); $i++) {
        $crc ^= ord($data[$i]); // XOR mit dem aktuellen Byte

        // Verarbeite jedes Bit des aktuellen Bytes
        for ($j = 0; $j < 8; $j++) {
            if ($crc & 0x0001) { // Prüfe, ob das niederwertigste Bit gesetzt ist
                $crc = ($crc >> 1) ^ 0xA001; // Rechtsverschiebung und XOR mit Polynom
            } else {
                $crc >>= 1; // Nur Rechtsverschiebung
            }
        }
    }

    return $crc;
}

//$Relay1 = GetValueBoolean(39702);  
$Relay1 = 1;
//$Relay2 = GetValueBoolean(59657);
$Relay2 = 1;
//$Relay3 = GetValueBoolean(17035);
$Relay3 = 1;
//$Relay4 = GetValueBoolean(51025);
$Relay4 = 1;

//$Relay5 = GetValueBoolean(31769);
$Relay5 = 1;
//$Relay6 = GetValueBoolean(47090);
$Relay6 = 1;
//$Relay7 = GetValueBoolean(46043);
$Relay7 = 1;
//$Relay8 = GetValueBoolean(49724);
$Relay8 = 1; 
$Low = (($Relay4 <<= 3) +  ($Relay3 <<= 2) +  ($Relay2 <<1) + $Relay1);
$Low = dechex($Low);
echo " Low ". $Low;
$High = (($Relay8 <<= 3) +  ($Relay7 <<= 2) +  ($Relay6 <<1) + $Relay5);
$High = dechex($High);
echo " High ". $High;

$AlleRelays = ($High . $Low);
echo " Alle Relays ".$AlleRelays;



 $data = chr(0x00).chr(0x01).chr(0x00).chr(0x00).chr(0x00).chr(0x08).chr(0x01).chr(0x0F).chr(0x00).chr(0x10).chr(0x00).chr(0x08).chr(0x01).$AlleRelays; ///dechex($High).dechex($Low );   //.chr(0x18);


// CRC berechnen
$crc = calculate_crc($data);

// CRC in Low- und High-Byte aufteilen
$lowByte = $crc & 0xFF;
$highByte = ($crc >> 8) & 0xFF;

echo " CRC Low Byte: " . dechex($lowByte) . PHP_EOL;
echo " CRC High Byte: " . dechex($highByte) . PHP_EOL;

 //$data = chr(0x00).chr(0x01).chr(0x00).chr(0x00).chr(0x00).chr(0x08).chr(0x01).chr(0x0F).chr(0x00).chr(0x11).chr(0x00).chr(0x08).chr(0x01).chr(0x80).$highByte.$lowByte;
CSCK_SendText (14098, $data);

//*//$data = hexToStr ($data); //. hexToStr($highByte) . hexToStr($lowByte) ;
 // $str = dechex($hexNum);

//echo $data;
?>