Marquee control from HMI
H ave you ever wanted to configure and control your marquee within your HMI package? Not just sending messages from your HMI to a marquee, but having a whole bank of marquee displays with the ability to send a fully configurable, unique message to each of them?
I recently ran into this challenge. Our customer has a group of marquees that they wanted to control. The marquee manufacturer supplied a driver application that exercised full control over the marquee. This application worked well in the lab, but using their driver application meant more software to install and another interface for their operators to learn. The customer contacted us for help. The basic requirements included that configuration and control was to be within a Cimplicity HMI (version 5.0) project. We decided to use a combination of Cimplicity's DEVCOM toolkit and Point Management API to orchestrate the solution. Both the toolkit and API are used within a C programming environment.
With our solution, the end user configures a device (or rather a hub) from which multiple marquees are connected. They also configure points for each marquee. There is one device point for every marquee connected to a hub. The address the hub uses to identify a particular marquee connected to it is entered as the device point address. The rest of the points are virtual points. Message configuration is accomplished via on screen selections. Text for the marquee and attribute data for the message is stored in points for future use. A message is sent to the marquee by toggling the trigger point (read device point) connected to a particular marquee.
Since the user wanted to control any number of marquees from the project, we used the DEVCOM toolkit to handle the communications with the various marquees. The DEVCOM toolkit has access to device information that the Point Management API does not have. The information provided in the device configuration provides the IP address location to a hub from which numerous marquees could connect.
Since a number of these hubs could be attached to a project it was important to know which hub a particular set of message data was intended to go. The DEVCOM is also responsible to catch the 'send' request to write the message and its configuration to the marquee. The send request is no more that the changing of the device point associated with a specific marquee and hub. Once the DEVCOM knew which hub and marquee to talk to, it can query the Point Management API for the message configuration data and then send the message to the marquee via the manufactures supplied library (.dll).
Message configuration data is retrieved from the point database through the use of the Point Management API. A well thought out point naming convention made this job fairly easy. The root name of the trigger point is used to formulate the message parameter point names. For instance, MARQUEE_1_TRIGGER is truncated to MARQUEE_1. The root name is then used to make the configuration point names like MARQUEE_1_BLINK and MARQUEE_1_ALIGNMENT.
To facilitate the creation of the point names, gathering point attributes values, and to aid in code maintenance; I defined some constants that had the same names as the point attributes.
#define _BOLD 0
#define _ALIGNMENT 1
#define _BLINK 2
I use the constants value as an offset to retrieve data from two global arrays that hold point names and point values. Point names in the point name array are used to retrieve point data for the point values array. In addition to using the constants value as an array offset, I created a macro that would take the constants' name and create point names from them.
#define setupPointNames(x, ptNameArray) strcpy(ptNameArray[x], strinc(#x));
Calling the macro:
setupPointNames( _ALIGNMENT, ptNames)
Expansion of the macro based on the call above:
To accomplish this the macro uses the 'stringizing' operator (#). This operator converts the passed constant to a string. Once converted to a string, the constant name is copied into the point name array. The position in the array is determined by the value of the passed constant. This method allows me to define the name of the attributes in one place, but use them in many places and for many functions.
Once the point names are assembled, the values for those points are retrieved from the point database and used to configure the command to send to the actual marquee.
In addition to the macro, I abstracted the Point Management API functions to ease the gathering of point values. The Point Management API contains many functions that allow full control over the point database but make it tedious to get just one value. By combining functions I was able to retrieve the value of the point by simply passing the point name to one function. This made development much simpler and abstracted the details of the point management API.
If required, marquee status values could be obtained via a read request in the DEVCOM or set in the Point Management API with the return code from the function used to send the message to the marquee.
In the end, the solution is a simple merging of technologies that already existed. Merging that was necessitated by the data to which each piece had access. And merging that gives our client the full control over the marquees in their arsenal. control.
Jeffrey Hadley is a software developer for NEDDAM Software Technologies. For more information, visit the NEDDAM web site at www.neddam.com .