Difference between revisions of "AN0502 - Connecting your GUI as a Modbus Slave"

From Serious Documentation
Jump to: navigation, search
 
(21 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
__TOC__
 
__TOC__
This application note covers the setup and initialization a SHIP GUI on a [[SIMs|SIM]] of a simple Modbus slave virtual device. For more information on Modbus, consult [[Modbus#References|this list of resources]].
+
GUIs developed in [[SHIPTide]] and running in [[SHIPEngine]] need to communicate with the outside world. Typically, your GUI needs to turn things on/off, find the status of things in the outside world, and generally exchange information.
  
UIs developed in [[SHIPTide]] and running in [[SHIPEngine]] need to communicate with the outside world. Typically, your GUI needs to turn things on/off, find the status of things in the outside world, and generally exchange information.
+
This application note covers the setup and initialization a SHIP GUI on a [[SIMs|SIM]] of a simple Modbus slave virtual device.
 +
== Required Reading ==
 +
Before proceeding with this applications note, ensure you have reviewed the following:
 +
* [[Modbus|Modbus Overview]]
 +
* [[SHIP:Communications|SHIP Communications Concepts]]
  
'''→[[Modbus:Overview|Read more about Modbus]]'''
+
For more information on Modbus, consult [[Modbus#References|this list of resources]].
  
'''→[[SHIP:Communications|Read more about SHIP communications concepts]]'''
+
== Binding the Protocol to the Hardware ==
 +
The first step in connecting as a Modbus slave device is to create a [[SHIP:Node:link|link]] node in the [[SHIP:Node:resourcesarea|Resources area]].
  
== Creating a Communications [[SHIP:Node:link|Link]] ==
+
In [[SHIPTide]], go to the [[SHIP:Node:resourcesarea|Resources area]] and right click on the "links" section and add a new [[SHIP:Node:link|link]] node.  This node will bind the Modbus slave protocol to a physical communications channel, so set up this new  [[SHIP:Node:link|link]] node with properties like this:
  
Communications links are described by a set of tree-structured nodes in the [[SHIP:Node:link|link]] [[SHIP:Node:resourcesarea|Resources area]]. The three main node types are:
+
[[File:SHIPTide-createNewModbusSlaveLink.jpg|600px|border|center|Creating the new Modbus Slave link]]
  
* the [[SHIP:Node:link|link]] node, which binds a protocol to a communications node, for instance the Modbus Master RTU protocol bound to the UART0 port,
+
Each channel in a platform may only be bound once to a single protocol. For example, UART0 can only be bound to a single protocol (e.g. [[Protocol:Modbus#RTU|MODBUS_SLAVE_RTU]]).
* the [[SHIP:Node:linkset|linkset]] node, which encompasses all the traffic between two endpoints in the[[SHIP:Node:link|link]], and,
 
* the [[SHIP:Node:linkvar|linkvar]] node, which describes a shared variable between the two endpoints in a[[SHIP:Node:linkset|linkset]].
 
  
=== [[SHIP:Node:link|link]] Nodes ===
+
=== Creating One or More Virtual Slave Devices ===
  
A [[SHIP:Node:link|link]] node binds a protocol to a physical communications channel. The properties of a link are:
+
Within a given [[SHIP:Node:link|link]], there may be one or more [[SHIP:Node:linkset|linkset]] nodes. Each [[SHIP:Node:linkset|linkset]] encompasses all the traffic between two endpoints in a [[SHIP:Node:link|link]]. On the slave side of master/slave protocols (for example the [[Protocol:Modbus#RTU|MODBUS_SLAVE_RTU]]), the GUI may be responding as one or more Modbus slaves. Even though the protocol is running on a single physical communications channel (e.g. UART0), each [[SHIP:Node:linkset|linkset]] within the [[SHIP:Node:link|link]] can act as one of a number of independent virtual slaves.
 
 
{| class="wikitable" style="margin: 1em auto 1em auto;"
 
! scope="col" | Property
 
! scope="col" | Description
 
|-
 
| name|| A unique [[SHIP:Node:link|link]] identifier
 
|-
 
| protocol || The [[SHIP:Protocols|protocol]] bound to the channel (e.g. [[Protocol:MODBUS_MASTER_RTU|MODBUS_MASTER_RTU]])
 
|-
 
| channel || A port name (e.g. UART0)
 
|}
 
 
 
For example, the following [[SHIP:Node:link|link]] binds a [[Protocol:MODBUS_SLAVE_ASCII|MODBUS_SLAVE_ASCII]] protocol to UART0 on a [[SIM110]]:
 
 
 
{| class="wikitable" style="margin: 1em auto 1em auto;"
 
! scope="col" | Property
 
! scope="col" | Value
 
|-
 
| name|| myModbusSlave
 
|-
 
| protocol || [[Protocol:MODBUS_SLAVE_ASCII|MODBUS_SLAVE_ASCII]]
 
|-
 
| channel || platform.UART0
 
|}
 
 
 
Each channel in a platform may only be bound once to a single protocol. For example, UART0 can only be bound to a single protocol (e.g. [[Protocol:MODBUS_MASTER_RTU|MODBUS_MASTER_RTU]]).
 
 
 
=== [[SHIP:Node:linkset|linkset]] Nodes ===
 
 
 
Within a given [[SHIP:Node:link|link]], there may be one or more [[SHIP:Node:linkset|linkset]] nodes. Each [[SHIP:Node:linkset|linkset]] encompasses all the traffic between two endpoints in a [[SHIP:Node:link|link]]. The properties of a [[SHIP:Node:linkset|linkset]] are:
 
 
 
{| class="wikitable" style="margin: 1em auto 1em auto;"
 
! scope="col" | Property Name
 
! scope="col" | Description
 
|-
 
| name|| A unique [[SHIP:Node:linkset|linkset]] name within the [[SHIP:Node:link|link]]
 
|-
 
| id || Some [[#Protocols|protocols]] require the endpoint to have an ID number assigned
 
|-
 
| channel || A port name (e.g. UART0)
 
|}
 
 
 
On the slave side of master/slave protocols (for example the [[Protocol:MODBUS_SLAVE_RTU|MODBUS_SLAVE_RTU]]), the [[SHIP:Node:link|link]] may be representing one or more Modbus slaves within the SHIPEngine environment. Even though the protocol is running on a single physical communications channel (e.g. UART0), each [[SHIP:Node:linkset|linkset]] within the [[SHIP:Node:link|link]] can act as one of a number of independent virtual slaves.
 
 
 
On the master side of master/slave protocols (for example [[Protocol:MODBUS_MASTER_ASCII|MODBUS_MASTER_ASCII]]) you may want to address multiple slaves on the channel. Each slave would be identified by a [[SHIP:Node:linkset|linkset]] with the slave ID set appropriately.
 
  
 
Adding two [[SHIP:Node:linkset|linkset]]s to our prior example might look like this:
 
Adding two [[SHIP:Node:linkset|linkset]]s to our prior example might look like this:
Line 71: Line 29:
 
In this example GUI, our SIM is acting as a Modbus slave attached to UART0, potentially one of many other Modbus slave devices on the physical network. This physical network (aka channel) could be, for instance, a multi-drop RS485 network with many slaves of which our [[SIMs|SIM]] is only one. Our GUI, because it has the two [[SHIP:Node:linkset|linkset]]s at ID #1 and #13 created, will respond as if it were two of those slaves on the network.
 
In this example GUI, our SIM is acting as a Modbus slave attached to UART0, potentially one of many other Modbus slave devices on the physical network. This physical network (aka channel) could be, for instance, a multi-drop RS485 network with many slaves of which our [[SIMs|SIM]] is only one. Our GUI, because it has the two [[SHIP:Node:linkset|linkset]]s at ID #1 and #13 created, will respond as if it were two of those slaves on the network.
  
=== [[SHIP:Node:linkvar|linkvar]] Nodes ===
+
=== Adding Shared Link Variables ===
 
The SHIP GUI communicates with a remote network device using the concept of ''link variables''. These are variables who's values are shared, nearly automatically, across the communications link.  One party must own the actual true value of the variable, other parties on the network merely need to get copies of the latest value in order to display, react, control, or otherwise act on that value.   
 
The SHIP GUI communicates with a remote network device using the concept of ''link variables''. These are variables who's values are shared, nearly automatically, across the communications link.  One party must own the actual true value of the variable, other parties on the network merely need to get copies of the latest value in order to display, react, control, or otherwise act on that value.   
  
Line 85: Line 43:
 
| name|| A unique variable name within the [[SHIP:Node:linkset|linkset]]
 
| name|| A unique variable name within the [[SHIP:Node:linkset|linkset]]
 
|-
 
|-
| datatype || The data type of this [[SHIP:Node:link|link]] variable; may be limited depending on the [[SHIP:Protocols|protocols]]
+
| datatype || The data type of this [[SHIP:Node:link|link]] variable; may be limited depending on the [[Protocols|protocols]]
 
|-
 
|-
| address || Most [[SHIP:Protocols|protocols]] require each variable to have a unique address/location/id number assigned
+
| address || Most [[Protocols|protocols]] require each variable to have a unique address/location/id number assigned
 
|-
 
|-
 
| direction || Most protocols need to understand if this is an ''input'' or ''output'' variable
 
| direction || Most protocols need to understand if this is an ''input'' or ''output'' variable
Line 96: Line 54:
 
The direction can be a bit confusing: it is always with respect to [[SHIPEngine]] and the GUI. So an ''output'' direction means the data is supplied by [[SHIPEngine]] to the device across the network on the remote end of the [[SHIP:Node:linkset|linkset]], regardless of whether the [[SHIP:Node:linkset|linkset]] is a master or slave in a master/slave environment. Similarly, an ''input'' direction means that the data is coming into the variable from the remote end of the [[SHIP:Node:linkset|linkset]]. Remember that "in" and "out" are with respect to your GUI in [[SHIPEngine]].
 
The direction can be a bit confusing: it is always with respect to [[SHIPEngine]] and the GUI. So an ''output'' direction means the data is supplied by [[SHIPEngine]] to the device across the network on the remote end of the [[SHIP:Node:linkset|linkset]], regardless of whether the [[SHIP:Node:linkset|linkset]] is a master or slave in a master/slave environment. Similarly, an ''input'' direction means that the data is coming into the variable from the remote end of the [[SHIP:Node:linkset|linkset]]. Remember that "in" and "out" are with respect to your GUI in [[SHIPEngine]].
  
The datatypes are [[SHIP:Protocols|protocol]] dependent, and, in the Modbus case, may be limited to the basic Modbus data types of {{DataType|Boolean}} and {{DataType|Short}}.
+
The datatypes are [[Protocols|protocol]] dependent, and, in the Modbus case, may be limited to the basic Modbus data types of {{DataType|Boolean}} and {{DataType|Short}}.
  
 
Expanding the example above with four [[SHIP:Node:linkvar|linkvar]]s looks like this:
 
Expanding the example above with four [[SHIP:Node:linkvar|linkvar]]s looks like this:
Line 111: Line 69:
  
 
== Events and Polling ==
 
== Events and Polling ==
 +
 +
[[Category:Communications App Notes]]

Latest revision as of 15:03, 2 November 2016

GUIs developed in SHIPTide and running in SHIPEngine need to communicate with the outside world. Typically, your GUI needs to turn things on/off, find the status of things in the outside world, and generally exchange information.

This application note covers the setup and initialization a SHIP GUI on a SIM of a simple Modbus slave virtual device.

Required Reading

Before proceeding with this applications note, ensure you have reviewed the following:

For more information on Modbus, consult this list of resources.

Binding the Protocol to the Hardware

The first step in connecting as a Modbus slave device is to create a link node in the Resources area.

In SHIPTide, go to the Resources area and right click on the "links" section and add a new link node. This node will bind the Modbus slave protocol to a physical communications channel, so set up this new link node with properties like this:

Creating the new Modbus Slave link

Each channel in a platform may only be bound once to a single protocol. For example, UART0 can only be bound to a single protocol (e.g. MODBUS_SLAVE_RTU).

Creating One or More Virtual Slave Devices

Within a given link, there may be one or more linkset nodes. Each linkset encompasses all the traffic between two endpoints in a link. On the slave side of master/slave protocols (for example the MODBUS_SLAVE_RTU), the GUI may be responding as one or more Modbus slaves. Even though the protocol is running on a single physical communications channel (e.g. UART0), each linkset within the link can act as one of a number of independent virtual slaves.

Adding two linksets to our prior example might look like this:

Example link with two linksets

In this example GUI, our SIM is acting as a Modbus slave attached to UART0, potentially one of many other Modbus slave devices on the physical network. This physical network (aka channel) could be, for instance, a multi-drop RS485 network with many slaves of which our SIM is only one. Our GUI, because it has the two linksets at ID #1 and #13 created, will respond as if it were two of those slaves on the network.

Adding Shared Link Variables

The SHIP GUI communicates with a remote network device using the concept of link variables. These are variables who's values are shared, nearly automatically, across the communications link. One party must own the actual true value of the variable, other parties on the network merely need to get copies of the latest value in order to display, react, control, or otherwise act on that value.

For example, if a device on a network has a motor RPM sensor, that device "owns" that value - perhaps represented as a 16-bit signed (for motor direction) RPM value. Other devices on the network that need to know that motor's RPM need to somehow get access to that devices "RPM variable" periodically. A SHIP GUI, for example, may need to update a value on the screen showing the motor RPM every second or even more frequently.

These shared network variables are represented in your SHIP GUI each as linkvar nodes describing these shared network variables within a given linkset. The linkvar properties available depend on the protocol selected.

The following are normal properties of a linkvar:

Property Name Description
name A unique variable name within the linkset
datatype The data type of this link variable; may be limited depending on the protocols
address Most protocols require each variable to have a unique address/location/id number assigned
direction Most protocols need to understand if this is an input or output variable
enabled Defaults to true, but can be set false in SHIPTide. Only enabled variables participate in polling (if applicable).

The direction can be a bit confusing: it is always with respect to SHIPEngine and the GUI. So an output direction means the data is supplied by SHIPEngine to the device across the network on the remote end of the linkset, regardless of whether the linkset is a master or slave in a master/slave environment. Similarly, an input direction means that the data is coming into the variable from the remote end of the linkset. Remember that "in" and "out" are with respect to your GUI in SHIPEngine.

The datatypes are protocol dependent, and, in the Modbus case, may be limited to the basic Modbus data types of Boolean and Short.

Expanding the example above with four linkvars looks like this:

Example linkset with four link variables (linkvars)

Our example here is, perhaps, a hypothetical GUI controlling a pump. Our GUI (in a Sail script) could turn on the pump by setting the pumpOnRequest output Boolean linkvar to "true". Since Modbus masters poll their slaves, the next time the master polls slave #1 address 0x4000 ("pumpOnRequest", a Boolean), it will read a "true" at that shared variable location, indicating to the master (the pump) to turn on. It may also poll slave #1 address 0x2000 ("pumpRPMRequest", a Short) to determine the requested RPM before turning the pump on. It may continue to poll these two locations to watch for a request to stop the pump or change the RPM. Also, as the pump turns on and off, and its actual RPM changes, it may send those values to slave#1 address 0x4001 ("pumpOn", a Boolean) and 0x2002 ("pumpRPM", a Short) respectively.

Note that just because the GUI "requests" that a remote device performs some action does not mean the remote device actually does it. The GUI (in a Sail script) might request the pump turn on, but it may not happen for whatever reason (the pump is overheated, for example). Timeouts and other mechanisms can be done in the GUI to watch for these conditions.

A good practice is to have visual indicators on the GUI reflect the actual remote state, rather than the requested state. For example, an RPM reading in the GUI should reflect the value of "pumpRPM", not "pumpRPMRequest".

Starting a Communications Link

Events and Polling