PLCnext on LinkedInPLCnext on Instagram  PLCnext on YouTube Github PLCnext CommunityStore PLCnext Community

  1. jon_diller
  2. PLCnext Technology & PLCnext Controls
  3. Tuesday, 18 June 2019

I would like to connect our PLCs (AXC F 2152) with our EMpro smart meters (EEM-MA600) so that the PLC can run through various logic routines based on information from the smart meters. Our smart meters each have an EEM-ETH-MA600 module on them.

Can we do this by simply setting the smart meter as a slave device and connecting to it in PLCnext Engineer as a Profinet device or do we need a bus coupler to connect the two devices? Or do we need to do this via Modbus?

Where can we find more information on how to setup this configuration? The user manual for the PLC talks about setting up Profinet devices but does not explain how to work with devices with Modbus.

 

Thanks,

-Jon

Accepted Answer
jon_diller Accepted Answer Pending Moderation
0
Votes
Undo

Hi Martin,

Thank you. You were correct, I wasn't calling the functions. When I added those lines to my code I still wasn't able to communicate with the smart meters, but after spending sometime changing a few things around I was able to establish communication using the following code:

/*
Simple version of Modbus_Comms
Connects to EMpro smart meter and retrieves register information.
*/
CASE iState OF
    0: (* Wait to state *)
        IF xStart = TRUE THEN
            iState := 10;
        END_IF;
        
    10: (* Initialization of client and FC3 function block *)
        (* Client *)
        tcpClient.xActivate := FALSE;
        tcpClient.xAutoAck := FALSE;                //Do not Auto-Acknowledge errors
        tcpClient.strServer_IP := '192.168.1.21';   //Device IP address
        tcpClient.iPort := 502;                     //Default TCP port
        
        (* FC3 function block *)
        tcpMB_FC3.xActivate := FALSE;
        tcpMB_FC3.iMT_ID := 1;
        tcpMB_FC3.uiQuantityOfRegisters := UINT#4;
        tcpMB_FC3.wStartRegister := WORD#57616;     //IP Address
        
        tcpClient.xActivate := TRUE;
        
        iState := 100;
        
    100: (* If client function block is active, then start FC3 block *)
        IF (tcpClient.xError = TRUE) THEN
            iState := 1001;
        ELSIF (tcpClient.xActive = TRUE) THEN
            tcpMB_FC3.xActivate := TRUE;
            iState := 500;
        END_IF;
        
    (** Read registers **)
    
    500: (* Now activate FC3 function block and set inputs *)
        IF ((tcpMB_FC3.xActive = TRUE) AND (tcpMB_FC3.xError = FALSE)) THEN
            wRegVal1 := tcpMB_FC3.arrRegisterValue[1];
            wRegVal2 := tcpMB_FC3.arrRegisterValue[2];
            wRegVal3 := tcpMB_FC3.arrRegisterValue[3];
            wRegVal4 := tcpMB_FC3.arrRegisterValue[4];
        ELSIF (tcpMB_FC3.xError = TRUE) THEN
            iState := 1001;
        END_IF;
        
        IF xStart = FALSE THEN
            iState := 1000;
        END_IF;

    (* Stopping comms and handling errors *)
    
    1000: (* Finish *)
        (* Deactivate client and FC3 function block *)
        tcpClient.xActivate := FALSE;
        tcpMB_FC3.xActivate := FALSE;
        iState := 0;
        
    1001: (*An Error has occured*)
        wClientError := tcpClient.wDiagCode;
        wClientAddErr := tcpClient.wAddDiagCode;
        tcpClient.xAcknowledge := TRUE;
        tcpMB_FC3.xAcknowledge := TRUE;
        
        iState := 10;
        
END_CASE;

tcpClient(udtTCP_ComData := tComData);
tcpMB_FC3(udtTCP_ComData := tComData);

 

Thanks for the help,

-Jon

Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo

Hi Jon,

Using the EEM-ETH-MA600 module, you need to communicate using Modbus/TCP.

The AXC F 2152 currently doesn't include Modbus/TCP as a "native" driver, so you need to implement this protocol in your own application. Fortunately, there are libraries that can help.

Can you tell us if you will be doing your logic routines in a PLCnext Engineer program using an IEC 61131 language, or in a C++ application, or in an application written in another language? There are solutions for each of these on PLCnext Control ... but if I just describe the one you want, I might finish the description before the Australia/Jamaica football match starts.    :-)

Martin.

Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support

jon_diller Accepted Answer Pending Moderation
0
Votes
Undo

Hi Martin,

For now we will be using IEC 61131 Structured Text in PLCnext Engineer but eventually plan to switch to MATLAB with Simulink. For now, if we could setup communication and write algorithms in Structured Text that would be great, then maybe later on we could start a new thread on how to address this with MATLAB.

-Jon

Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo

Hi Jon,

In this case you will need to download the Modbus/TCP library from the PLCnext Store. The documentation for this library will help. You will be using the MB_TCP_Client function block, since the EMPRO comms module is a Modbus/TCP server.

Once you install this library on your PC and import it as a User Library into PLCnext Engineer, you can just drag and drop the MB_TCP_Client FB on to your ST code sheet to create an instance of the FB.

The documentation describes each of the FB parameters.

After establishing a connection with MB_TCP_Client FB instance, you will then need to read registers using one of the MB_TCP_FC.. function blocks, probably MB_TCP_FC3 to start with.

But before you try to get the PLC communicating with the EMPRO, I suggest that you follow the Modbus guide in the EMPRO User Manual to test the Modbus comms. In particular:

  • Download the "Modbus Poll" software that is recommended in section 10.1.5 of the EMPRO User Manual. Use this software to check that you can read the data you need from the EMPRO using the Modbus/TCP protocol. Follow the description in the "Modbus RTU" section of the EMPRO User Manual, but instead of choosing "Serial Port" in the "Connection" box, choose "Modbus TCP/IP" and enter the IP address of the EMPRO comms module. Other than that, all the Modbus register addresses etc. should be exactly the same for Modbus RTU and Modbus TCP (Modbus TCP is just the "Ethernet" version of the serial RTU protocol).
  • Chapter 11 of the EMPRO User Manual contains the list of Registers that are available via Modbus. I guess you will be choosing a sub-set of these registers for your application.

Once you are reading data from EMPRO registers correctly using the "Modbus Poll" software tool, you can then switch to PLCnext Engineer and set up the MB_TCP_Client and MB_TCP_FC3 Function Blocks to read the same registers from the EMPRO.

If you are considering switching to Matlab Simulink in future, then I suggest building your ST code to read the Modbus registers, and then write them to OUT ports in your ST program. Your Simulink program can then define IN ports to receive the EMPRO data, and it will just be a matter of linking the OUT and IN port variables together in PLCnext Engineer. Until you have Simulink, you can write a second IEC program (a "Simulink Simulator", if you like) to do the calculations that Simulink will eventually do. Again, you can pass data from your ST program (data collector) to the Simulink Simulator, via OUT and IN ports. This will make the switch to Simulink, seamless.

Good luck!

Martin.

 

Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support

jon_diller Accepted Answer Pending Moderation
0
Votes
Undo

Hi Martin,

We are having some issues connecting to the EMpro meters using the Modbus/TCP library. We're using the following code (which is a modified version of the example from the library documentation) as a test to establish communication. The code should be reading the Ethernet IP address CL. A register in the EMpro (E110). We were able to read this register using the Modbus Poll tool, but when our code runs we get stuck in state 100.

CASE iState OF
    0: (* Wait for start of Example program *)
        IF xStart = TRUE THEN
            iState := 10;
        END_IF;
        
    10: (* Initialization of client and FC3 function block *)
        (* Client *)
        tcpClient.xActivate := FALSE;
        tcpClient.xAutoAck := FALSE;                //Ignor errors
        tcpClient.strServer_IP := '192.168.1.21';   //Device IP address
        tcpClient.iPort := 502;                     //Default TCP port
        tcpClient.xUDP_Mode := FALSE;               //Using TCP, not UDP
        tcpClient.tReconnectDelay := TIME#3000ms;   //Delay between connection attempts
        tcpClient.tTimeout := TIME#10s;             //Timeout period, using 10s
        
        (* FC3 function block *)
        tcpMB_FC3.xActivate := FALSE;
        tcpMB_FC3.iMT_ID := 1;
        
        iState := 100;
        
    100: (* Start client function block first and wait for xActive *)
        tcpClient.xActivate := TRUE;
        IF (tcpClient.xActive = TRUE) THEN
            iState := 500;
        END_IF;
        
        IF (tcpClient.xError = TRUE) THEN
            wClientError := tcpClient.wDiagCode;
            wClientAddErr := tcpClient.wAddDiagCode;
        END_IF;
        
    (** Read min. number of registers **)
    
    500: (* Now activate FC3 function block and set inputs *)
        tcpMB_FC3.xActivate := TRUE;
        tcpMB_FC3.wStartRegister := WORD#16#E110;
        tcpMB_FC3.uiQuantityOfRegisters := UINT#1;
        
        (* Wait for xActive of FC3 function block *)
        IF (tcpMB_FC3.xActive = TRUE) THEN
            iState := 1000;
        END_IF;    

    1000: (* Check value of read *)
        IF (tcpMB_FC3.xError = FALSE) THEN
            wRegVal := tcpMB_FC3.arrRegisterValue[1];
            iState := 3000;
        END_IF;
         
    3000: (* Finish *)
        (* Deactivate client and FC3 function block *)
        tcpClient.xActivate := FALSE;
        tcpMB_FC3.xActivate := FALSE;
        IF (tcpMB_FC3.xActive = FALSE AND tcpClient.xActive = FALSE) THEN
            IF xStart = FALSE THEN
                iState := 0;
            END_IF;
        END_IF;
END_CASE;

Here are our variable declarations:

 

vars

 

There are no errors in tcpClient, the PLC just gets stuck in state 100 and never continues through the rest of the code. Any ideas on what we are doing wrong?

Thanks,

-Jon

jon_diller Accepted Answer Pending Moderation
0
Votes
Undo

UPDATE:

I realized after posting that we are not acknowledging errors so I changed the line

tcpClient.xAutoAck := FALSE;    // Ignor errors

to

tcpClient.xAutoAck := TRUE;    //Acknowledge errors.

Nothing changes though. The PLC is still getting stuck at state 100 and there are no errors being reported.

-Jon

Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo

Hi Jon,

Unless you've left out some code from your listing, I see one major problem ... while you are setting the inputs and reading the outputs of the two function block instances, you're not actually calling the functions ... which would explain why none of the outputs are changing, and the state machine isn't being bumped out of state 100.

Add two lines at the end, after the END CASE statement, something like:

tcpClient();
tcpMB_FC3();

... and this should do the trick.

Martin.

Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support

  • Page :
  • 1


There are no replies made for this post yet.
However, you are not allowed to reply to this post.