I started using ProView. This is a process control and automation system with a FOSS license, which makes it a good approach for building some interesting projects. It is nice, you can define from single controlled nodes to complete processing stations and HMIs controlling each node. You can use simple PLC programs for the defined hardware and devices, or you can use C, C++ or Java — but Java is not so useful due to real-time application requirements — applications if the station processing and control requires more complex algorithms, which cannot be handled using PLC programs. That is the case of my current project, I am building an application that acts as PLC program which will implement some complex algorithms.
Some considerations to have in mind with that kind of control, using applications rather than PLC programs, is how you must handle the I/O and how you must handle the configured hardware and devices, even if they are configured as remote devices using RTU channels or similar communication channels, is the fact that you must use the proper flags to control the device.
sts = io_init(io_mProcess_User, app_id, &io_ctx, 0, static_cast<float>(FCM_IO_SCAN_INTERVAL)); if (EVEN(sts)) { errh_Error("ra_fcm: I/O init error: %m", sts); throw co_error(sts); }
The io_mProcess_User flag is mandatory to tell the run time environment that you will start using. So, every registered device that uses the flag 0×08, because the flag 0×04 is being used by its Profibus implementation. But that is not all, you must bind all your I/O and system wide I/O classes to be handled by the I/O Agent, so you have two main C/C++ macros to setup the binder in your application, which are called BindIoClasses and BindIoUserClasses. If you do not use the proper macro to bind your classes and the system classes that will be used, the I/O Agent will not start. For example if you want to bind a custom I/O module, you should write a code similar to this one in your C or C++ file where main() is placed.
pwr_dImport pwr_BindIoUserMethods(Camera_USB); pwr_dImport pwr_BindIoUserMethods(Camera_USBIO); pwr_BindIoUserClasses(User) = { pwr_BindIoUserClass(Camera_USB), pwr_BindIoUserClass(Camera_USBIO), pwr_NullClass };
The same should be applied to the system wide classes with the proper macro, to notify the agent that should handle the I/O devices, without taking too much care about programming, you just need to program the I/O device classes properly to be bound and registered in the run time. Also, the io_read() and io_write calls are non-blocking calls, but other calls, like QCOM related calls are blocking ones, so you need to take care on doing asynchronous or threaded calls on certain system mechanisms.
I will start writing some articles related to ProView. I hope that you will like them.