aldas / modbus-tcp-client

PHP client for Modbus TCP and Modbus RTU over TCP (can be used for serial)
Apache License 2.0
191 stars 55 forks source link

Question: Trying to retrieve simple data through modbus #127

Closed XavegX367 closed 1 year ago

XavegX367 commented 1 year ago

Hello, I just started working with Modbus and I am using a program called 'Advantech Adam/Apax' Here I am able to turn on a light and count the amount of times a button has been pressed. Currently I am trying to retrieve this count and controll the light in php. Do you have any idea what I am doing wrong?

I am working with the Laravel framework, here is the function:

public function index()
    {
        $connection = BinaryStreamConnection::getBuilder()
            ->setPort(502)
            ->setHost('192.168.250.50')
            ->build();

        $startAddress = 00001;
        $quantity = 1;

        $packet = new ReadCoilsRequest($startAddress, $quantity);

        try {
            $binaryData = $connection->connect()
                ->sendAndReceive($packet);

            $response = ResponseFactory::parseResponseOrThrow($binaryData);

            dd($response);
        } catch (Exception $exception) {
            dd($exception->getMessage() . PHP_EOL);
        } finally {
            $connection->close();
        }

    }

Here is what the modbus looks like in adam:

modbus

Location: 00001 with description DI 0 is the button Location: 00017 with description DO 0 is the light

I am only trying to retrieve the button count with the code above. But it only returns an array with a length of 8:

image

I am also curious about how I will be able to write to the coil so the light will turn on / off.

Thanks in advance.

aldas commented 1 year ago

Please log raw bytes as https://github.com/aldas/modbus-tcp-client/blob/master/examples/fc1.php does. It is easier to examplain when I see what was sent and received.

Only 1 "coil" is true because you asked for 1 coil $quantity = 1;. There are 8 coils in that printed class instance because FC1 response can at minimum respond with 1 byte (8 bits/coils) where coils 1-7 are 0 zeroed.

https://github.com/aldas/modbus-tcp-client/blob/master/src/Packet/ModbusFunction/ReadCoilsResponse.php This file has commend that describes FC1 response structure if you want to know the details.

You should create your request as $packet = new ReadCoilsRequest(0, 22); to get coils from 1 to 22

NB: in packet level modbus addresses are 0-based. So first address is actuall 0 but this depends sometimes how your device manual is written. But it mostly written 1 based and you need to adjust it to 0 based.

XavegX367 commented 1 year ago

So I followed the example and now location 00001 returns true, while I need it to return the times a button is pressed. Like shown in the image below:

image

This one should be under location DI[0] / DI 0. On the previous post it is shown on location 00001

image

I am also trying to get the state of a light this should be on DO[0 / DO 0 and this one should be on location 00017. But when I turn the light on and try to receive 00017 it shows false while in the program it returns 1 (true).

aldas commented 1 year ago

Did you try 0-based addresses? And please add sent/received packets as hex.

At the moment I understand that when you read coil 17 value you get 0. When using some other tool that coil 17 is shown as 1?

Do you use address as 17 or 16?

Please see https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf page 7 "4.4 MODBUS Addressing model"

XavegX367 commented 1 year ago

This is what it returns:

image

With this code:

image
XavegX367 commented 1 year ago

Did you try 0-based addresses? And please add sent/received packets as hex.

At the moment I understand that when you read coil 17 value you get 0. When using some other tool that coil 17 is shown as 1?

Do you use address as 17 or 16?

Please see https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf page 7 "4.4 MODBUS Addressing model"

Indeed, when I use the tool on my windows machine it says bit: 1 on 00017.

aldas commented 1 year ago

$startAddress = 1; means that you request second address to ninth address. As address 1 in modbus model is actually PDU address 0. This library uses PDU/0-based addresses. This depends on you device documentation - which addressing scheme it is using.

That response bytes explained:

aldas commented 1 year ago

If you are investigating address 0017 why do you request 8 coils starting from 0001? You probably should move start address or quantity to see from this library side what is in those addresses.

        $startAddress = 16;  // is 0-based address for 17
        $quantity = 1;
XavegX367 commented 1 year ago

Thanks, I didn't know I had to parse number 16 for address 17. It works! But how do I read the amount of clicks on a button through address 1?

aldas commented 1 year ago

I doubt you can read amount of clicks with coils. Coil is binary (0 or 1). You probably need to use Register functions for this purpose. FC3 maybe http://www.simplymodbus.ca/FC03.htm

XavegX367 commented 1 year ago

I doubt you can read amount of clicks with coils. Coil is binary (0 or 1). You probably need to use Register functions for this purpose. FC3 maybe http://www.simplymodbus.ca/FC03.htm

Yes, that works. I am getting the response in the last array. Thanks a lot!