Modbus TCP function for PHP

V

Thread Starter

Volzon

I'm making PLC programs for controlling micro hydro power plants. Now my customers want to have the possibility to access a webpage for status and look at trends in water level and so on.

The PLCs are Unitronics Vision 570 with Ethernet and Modbus TCP.

I'm familiar with use of PHP and MySQL on Linux with Apache.

Is there a function or anything that can be used for this with minor modifications?

I do not really need to use the PHPscript for reading. But I have to place the data in a MySQL database.

I do also need the possibility to write to the PLC, for changing setpoints.

Does someone have experience with this?
Thank you.
 
M

Michael Griffin

Is the web server going to be located at the PLC, or is it supposed to be located somewhere else and contact it remotely on a regular basis? This is probably the first question that you have to resolve.

If you are going to locate it with the PLC, then there are 4 different things you need.

1) The web pages to do the reports. These would simply pull the data out of the database on demand and display reports. There are PHP modules for turning data sets into graphs in order to display trends, if you want to do this. This is very conventional web site programming, so I won't go into more detail on this.

2) Web page forms to allow the user to enter new setpoints. Again, this is very conventional web site programming. The one difference from normal would be the need to get the existing setpoints from the PLC instead of from a database. These pages will need to be password protected of course.

3) A program which runs in the background, collects data from the PLC, and stuffs it into the database. For a communications protocol, the manufacturer's web page says it supports Modbus (over both RS-232 and Ethernet). There are a number of free Modbus drivers for Linux you could use (try Google for a list of these). I have seen free Modbus drivers in C, Java, and even Python.

Alternatively, the PLC may support exchanging raw data without using any special protocol. This is sometimes easier than using Modbus (or other similar protocols) if you are just connecting two points directly together and exchanging a limited amount of data.

This program could be written in whatever language you feel comfortable using. If you are using Modbus though, you will want to use a language that interfaces with the appropriate library easily.

In either case, the program would spend most of its time sleeping, and occasionally waking up to collect more data. If the program needs to collect data frequently (e.g. every few minutes), you might have a program which runs continuously (using "sleep()" when it is idle). If it only needs to collect data infrequently (e.g. once every few hours), then you might run it as a cron (or anacron) task, where it collects data immediately and then exits until run again.

4) Finally, you need a program to exchange setpoints between the PC and PLC. This would be similar to the data collector, except it would only run on demand when called from the PHP script. This could use a PHP "exec()" (or something similar). It would be called with parameters which hold the data or commands you want to send to the PLC, and would return the data from the PLC as return parameters.

Be *very* careful doing something like this though. Make sure any data the user is sending is thoroughly filtered and sanitised, as otherwise someone could enter data in a field which could be interpreted as an operating system command instead of passed as data to the setpoint communications program. This potential problem is similar in concept to how you have to guard against SQL injection problems in user data.

If you are comfortable writing PHP extensions, then you might do this function as a PHP extension instead of an external program.

Alternatively, if you can do simple socket communications with the PLC (I don't know the Unitronics well enough to say if this is possible), and you decide to do that instead of using Modbus, then you can do direct Ethernet socket programming with PHP. This would allow you to communicate directly with the PLC from a PHP script.

If the web server PC is located in a different place from the PLC, then you have to decide how to connect the PLC and the server. If you have a telephone line to each site, then you could put a modem in and have the PC dial up the PLC and collect accumulated data on a regular basis. If you don't have a telephone line, the manufacturer states that they support GPRS wireless data transmission. You would need to ask someone other than me for more details on these options.

If you only have a few installations for this, you might consider using an off the shelf SCADA package that supports a web interface for this. The disadvantage of this approach is the per unit licensing costs if are selling a large number of units. The advantage is that it may take you less time to get a simple system working (once you've learned the SCADA software of course). If you use a SCADA package, make sure you research how they've done their security, as many of them are not secure enough to operate on the internet.

The advantages of the LAMP approach of course is the zero per unit software license cost to you, plus the ability to tailor it exactly to your needs. The disadvantage is the amount of work that goes into the first system.

I don't know enough about your situation to make a recommendation either way, but it is something you might want to think about. For that matter, you might satisfy your immediate customers with a commercial SCADA system while you develop your own application once you have a better idea of the size of the market and the features needed.
 
Thank you for the reply.

The Web server is located at my location. Each PLC is connected through internet with a secure VPN connection to my server network. Only the Web server's port 80 will be available from internet.

Each PLC is connected permanently to internet through different ways of broadband connections, so they are permanently connected to the server through the VPN.

The plan is that the server should read the values from the PLC every few (1 or 5) minutes.

The user should be able to do three things:
1. Look at at reasonable presentation of logged values. (This I can manage).
2. Read and change the water level setpoint.
3. Give a start command, which is to change a value in the PLC registry, like changing setpoint.

I guess the best solution for me will be to learn some basic Perl or Python programming and do like you suggested. Having a program running in the background collecting the values and injecting them in the MySQL database. And just use one of the available Modbus TCP drivers.
 
J

Juan Jose Denis Corrales

We have a working system that comunicates Linux PCs with different PLCs via Ethernet and Modbus PLC, stores data in MySQL, and serves it via PHP.

The system is developed in Python, and released as free software.

It also generates daily PNG graphs of the stored values and sends them by email.

It is called "likindoy", and we are building a Web page to show its functionality.

The developer of the system is Juan Miguel Taboada, and its email [email protected].

We believe open standards and open source (Ethernet, Modbus, PHP, Python, MySQL, Linux...) are the future of the control systems.
 
M

Michael Griffin

It appears that you are planning on hosting the data for all your clients on your own web site. I had not considered that option, but it would appear to be a very good idea. In this case I would recommend the LAMP stack over a conventional SCADA because I think it would be more suited to what you are considering.

With that said, I think some things you have to nail down are:

First, can you afford to lose any data if the communications (or the server) is down? If not, then you will have to buffer the data together with a time stamp in the PLC until it is collected. This is a bit more complicated than just calling up and taking a reading. If you can afford to miss readings, then the programming (PLC and server) is simpler.

Second, how frequently do you really need to take a set of readings? How fast do the physical things you are measuring change? If you need to take a set of readings every minute, that is more complicated than a set of readings every hour. For example, if you are collecting data once per minute from 60 stations, that means that you have to deal with each station in 1 second or less. If you collect data once per hour from each station, then that gives you 1 minute to deal with each station.

The server is not likely to be the bottle neck in the data collection. The problem will likely be how fast each PLC can turn the poll around and reply through the VPN. In considering this, you need to also account for what happens in the event of an error. You may poll a station and get no reply, which means you will have to wait for a suitable time-out before proceeding to the next station. Of course, if you are buffering data in the PLCs, you won't be losing any actual data. But again, that is more complicated.

If you need to collect data from many stations frequently, then you will likely need a program that can poll these stations in parallel rather than one at a time. That is, you would need to send out commands for all the stations without waiting for replies from each one at a time.

The PLC can probably capture things like amounts and times of peak values (e.g. maximum or minimum water levels in the past 24 hours and when they occurred) better than the server could. If the PLC captures and time stamps fast changing events, then you might be able to poll for data at a slower rate.

Another thing to consider is that since you are dealing with multiple stations, you will likely need some way of tracking and being alerted of the status of each so you know if the communications is working. People doing commercial web hosting often have their servers send them a text message to their phone or an e-mail if there is a problem they have to deal with. Since this is a normal LAMP requirement (for commercial systems at least) there is plenty of free software that integrates with LAMP to handle this.

You will probably also want a status web page for your own use that tells you the status of communications to each station. You will also want to log communications errors to a file for troubleshooting purposes.

You can get the official specs for Modbus at: http://www.modbus.org/specs.php That will give you a description of all the commands, replies, and error codes. You will need to look at the PLC manufacturer's literature to see what features they actually implemented (usually only a subset). For your application, you only need to worry about a couple of different commands.

As for programming language, given a choice between Perl and Python I would use Python. It is probably easier to learn than Perl as it doesn't have the odd syntax and numerous different ways of doing the same thing. There is a good selection of libraries available (both standard and optional) and there shouldn't be anything you need to do which you can't do in Python.
 
C

Curt Wuollet

That's pretty cool, especially if I settle on
Modicon/Telemecanique PLCs going forward. No muss, no fuss, no licensing BS, and access to your data, that's the way it should be. And I _own _it, and can add what I want. Contrast that with monopolyware from big automation. Even if you ignore the paying
through the nose part, this is more worth spending time on.

Regards

cww
 
Top