Today is...
Monday, September 16, 2019
Welcome to Control.com, the global online
community of automation professionals.
Featured Video...
Featured Video
A demonstration of EtherCAT control of linear motors using the CTC EtherCAT master.
Our Advertisers
Help keep our servers running...
Patronize our advertisers!
Visit our Post Archive
Gui for c application
Need to move to c-programming but not sure how to make a gui

I appreciate any advice. I have been programming HMI's and PLC's for a while. I was about to switch to c-programming for portability when I started researching and have not found many gui builders. I design and program many different control systems and have done fine with plc's and hmi's for a while. My last program turned out extremely nice and I ran into a very substantial lag due to maxing out the plc (I had to mulitplex quite a few of my control functions just to fit within code size limitations). I am not trying to discuss other plc's and have fully decided to make the switch to c-programming for a few reasons that I will list in case I am incorrect in my thinking:

-portability (I would think that I can use the c-application on everything from a RTOS to windows 7 or OSX so I can write the program once and use for embedded micro-processors or a desktop on a plant floor)

-no hardware limitations (if I am using a panel pc and running an application that is taking the hardware to the limit and notice considerable lags, which happened in the above situation, I can just move to a panel pc with faster processor or more memory ect)

-If/when I decide to switch to microprocessors and develop my own boards I will know c so can use any of the standard compilers for the embedded processor manufacture of my choice

Now for the issue currently at hand. Assuming that my above thinking is correct, I want to start learning c. I catch on to languages very quickly and feel extremely confident that I can learn c quickly and start designing so systems within a few weeks (always had a strong aptitude for languages). My biggest hang-up is the gui programming. I am not interested at all in hand coding a gui and need a wysiwyg builder. What I have been looking for since their does not seem to be an all in one c gui builder out there that I can use c for everything is to create the brains of the application in c and figure out what gui builder/language I can use to connect to my main c-application. This seems to be a pretty clean scenario for me as I am used to similar architecture with the HMI and plc (HMI is the U.I. for the plc application) and would allow me to change my U.I. without changing my main application. Does anyone have any suggestions for a gui builder that I can connect with a c-application. I need something that will have examples and/or tutorials to catch on to as this is all pretty new to me. Thanks for any advice

I have a couple comments before answering your questions:

- I would suggest C++, Its not as portable as C, but pretty close. Things like pass by reference make your life easier as you will not be forgetting your "&" all the time. Also, the ability to program objects to group data and methods is very nice in writing well organized code. I don't get caught up in the "Everything must be pure OOP", but there is enough there to be very useful.

- If you notice lags in your code you might consider an RTOS. If you are using linux I hear good things about the PREEMPT_RT patches which allow nearly realtime performance, depending on your definition.

A direct answer to your question might be to use gtk+. It is natively programmed in C, but has wrappers for C++ programming that are popular. I think it is gtk-- which represents the joking naming convention of GPL projects. :o)

As far as the GUI builder, there are gui builders for gtk+, such as glade, but as I have found (and others here have mentioned) they are hardly necessary. Unless you are doing a very complicated HMI you might consider using the raw text programming instead. The reason is that GTK is very layout friendly in that you can group things by relationship and it displays them appropriately saving you time in drawing and placing all the controls.

Another option is to just use C# and windows forms programming. It is very quick to set up a simple drag and drop GUI and if this is all you need it will run on windows and linux (with mono runtime). The problem I found with this is that a HMI tends to have a lot of polled IO update displays and you end up doing a lot of programming under the hood to update the displays on the screen. This is why we ultimately developed our own simple library (see below):

I am working with the C# version of gtk, or gtk-sharp, and we have developed moderately complicated screens with very little "application specific" coding. The trick is to develop a library that you can reuse on different projects. For instance, we have a fault message area and an area for buttons and display of variables on every main screen for our machines. This is prebuilt by some library routines and then we customize it with our specific code for that machine. It works well. The reason we are using gtk# instead of gtk-- is that it is very convenient to run on our windows machines to test and then deploy it on our target linux box with the mono runtime for c# programs. It is quite well suited to this kind of work. Java is likely a candidate for this too, I just don't have experience with it.

If you are using your own software system you might consider a low priority GUI screen thread and then have higher priority "machine" threads running in the same process. Otherwise you will need some kind of IPC method to communicate between your GUI and your machine process. I've not done this, so there may be caveats, but it is a worthy goal to have everything under one process. Others may disagree, it depends on your philosophy.

You might look at M. Griffin's MBLOGIC system if you can use a web based HMI, it is flexible and open source and he is a helpful contributor to this forum.

KEJR

I appreciate the reply. It has been a while but I remember looking at MBlogic a while back and might be a viable option. I have a lot on my plate usually from hardware design to the software design including the user interface layout design ect. I really am looking for an easy transition from my dedicated softwares that I use now that limits my hardware choices to a more portable universal language like c which will open up my hardware choices to about anything I would ever need. That being said I don't want to have to (or better stated not have time for) deal with the gui any more than a drag and drop input and output to/from my c-application. So before I get neck deep in learning C I have to figure out what avenue I am going to take for my gui to make sure it will be compatible with my C-application. Really the way I would like to design these systems is with 2 different applications:

1st- the main c-application that is doing all of the logic and control
2nd- the user interface portion that just passes info back and forth to my c-application

I am used to this technique now because I currently do the same thing with 2 different components (1 processor to handle the control/logic and 2nd processor to handle the GUI). I can't seem to find where my understanding of all of this is so far off. Is it that hard when programming with an OS (I typically do not have an OS to deal with) to pass variables (inputs and outputs) from one application to another? It seems to me that the U.I. application shouldn't really matter at all and just needs to be able to access the memory area of the main c-application. I would typically have to network/communicate from one processor to another to get info back and forth but since this is all on the same processor I would think I can make my gui with Java, HTML, C++, C#, ect because it is just reading and writing data to the main c-application. All of these should be very portable and cross platform, in my mind, because linux, windows,& Mac OSX have the ability to run say a java application (if the VM is installed) and should be able to "talk" to the c-application that can also run on either of those platforms.

If my thinking is way off I would appreciate any suggestions ect
Thanks in advance

By James Ingraham on 23 February, 2011 - 2:07 am

Travis said: "I really am looking for an easy transition from my dedicated softwares that I use now that limits my hardware choices to a more portable universal language like C which will open up my hardware choices to about anything I would ever need."

Fair enough. Unquestionably, C is more commonly supported than any other language. It is also very flexible and powerful. There are downsides, however. I'm not sure that there's going to be such a thing as "an easy transition."

"That being said I don't want to have to deal with the gui any more than a drag and drop input and output to/from my C-application."

Well, here things get tricky. Because writing a single application with a GUI is one thing. Writing a GUI application that then talks to another application is something else. We'll get more into details in a bit.

"So before I get neck deep in learning C I have to figure out what avenue I am going to take for my gui to make sure it will be compatible with my C-application."

Good plan. On the one hand, like I said before, there are plenty of GUI builders that let you do everything in C. But actually talking between to programs (except for certain languages that inherently support it) is a trick.

"1st- the main c-application that is doing all of the logic and control
2nd- the user interface portion that just passes info back and forth to my C-application"

As I said, there is no standard for Inter-Process Communication in C. Shared memory is the most obvious way to do it, although the implementation of that is platform specific. And shared memory has lots of issues. I could go on about it for quite some time, but it boils down to this. Let's say you define a variable in your main application called "temperature" that is of type float. There is no way for an external program to view that variable or write data to it. Not possible. Instead, you'd create shared memory, both programs would map that memory, and then you would have to carve out a portion of that memory big enough to hold a float. Then you'd have to go to your GUI program and point to that same spot. If you mess up and call it "weight" in the GUI program, you'll never know until you start getting bizarre behavior of the system. If you later decide that there's another variable you want to share and you didn't make it part of the shared memory in advance, you will have to re-factor your main program.

"Is it that hard when programming with an OS to pass variables from one application to another?"

In C, yes. Like I said, C does not define ANY way to do this. You HAVE to rely on the OS (or an abstraction of it) to get Inter-Process Communication. Depending on how complex you want to do things, IPC can be trivial to worse-than-rocket-science. That's why I mentioned known solutions to the problem, like sockets, APR's IPC primitive abstractions, and multi-client databases.

"It seems to me that the U.I. application shouldn't really matter at all and just needs to be able to access the memory area of the main C-application."

Indeed. Except that most systems go out of their way to make sure that two programs CAN'T read each others memory. And of course, on a system (like DOS, for example) that DOES allow you, you still have problems. How do I find the memory area? Will it move when I close and re-start the program? What areas do I want to allow an external program to see?

"...I would think I can make my gui with Java, HTML, C++, C#, ect because it is just reading and writing data to the main C-application."

Yes and no. (HTML can't do this at all by itself, by the way. You'd have to use CGI at the very least.) Java can talk to C... but only if you provide some kind of bridge. Typically, that means creating your IPC in C and using Java Native Interface (JNI) to call C code to do the actual communicating.

"If my thinking is way off I would appreciate any suggestions etc"

I don't know about "way off." Just "this is a deeper hole than you thought." If you're used to using a PLC and an HMI, where the HMI pulls out a specific register, you're in for a real shock when you try to pull this off in C. The closest thing would be shared memory, but while this isn't an overly complex solution it's a lot harder than just plain using C. I'd say most people don't write their applications that way. Partly because they don't need it, and partly because of the gaping hole you jump into to get it right. (An obvious one; security goes out the window. This is an issue with PLCs, of course. Hook up a serial cable and start spitting random Modbus write-register commands and the PLC will happily do whatever it's told.)

You may ask if this is the case then how the heck do databases work. Short answer; I don't know the specifics. Longer answer: Some really smart people worked on this problem for a long time. Now when you write a database you go learn how all that stuff works. But that's a lot of information if you're just trying to do some controls stuff.

Incidentally, I'd be happy to talk about this with you in more length. (MORE length? Jeez, you'd think I'd talked enough already.) Feel free to contact me at jamesi followed by @sagerobot.com You can also get the phone number for my office from our website at www.sagerobot.com

-James Ingraham
Sage Automation, Inc.

P.S. Yes, I am aware that VxWorks makes all C global variables REALLY global, so that you can in fact have a variable "temperature" in a main program that is then accessed by an HMI program using the same tag "temperature." I didn't mention this because portability was mentioned as a desire, and because I got the impression that Travis didn't want to spend thousands of dollars on development seat.

James Ingraham said:

> specific. And shared memory has lots of issues. I could go
> on about it for quite some time, but it boils down to this.
> Let's say you define a variable in your main application
> called "temperature" that is of type float. There is no way
> for an external program to view that variable or write data
> to it. Not possible. Instead, you'd create shared memory,
> both programs would map that memory, and then you would have
> to carve out a portion of that memory big enough to hold a
> float. Then you'd have to go to your GUI program and point
> to that same spot. If you mess up and call it "weight" in
> the GUI program, you'll never know until you start getting
> bizarre behavior of the system.

I've done this, and also have seen it done in commercial products. You define a header file that both the controls C file and the HMI C (or C++) file include. In this header file you define a structure that will reside in shared memory (via pointer) that includes arrays of floats, your ints, [maybe] strings, etc. You also have enumerations or #define statements that correlate to the indexes of these arrays. You could break out the "assignment" of the array indexes into a separate header file if you wish. No risk of name swapping problem that you mentioned. The reason people get into this problem on separate systems is that the projects don't always have the common include file, or what is being called the "common tag database" today.

KEJR

In reply to James Ingraham:

> As I said, there is no standard for Inter-Process Communication in C.
> Shared memory is the most obvious way to do it, although the implementation of that is platform specific.
> And shared memory has lots of issues.
> I could go on about it for quite some time, but it boils down to this.
> Let's say you define a variable in your main application called "temperature" that is of type float.
> There is no way for an external program to view that variable or write data to it.
> Not possible. Instead, you'd create shared memory, both programs would map that memory,
> and then you would have to carve out a portion of that memory big enough to hold a float.
> Then you'd have to go to your GUI program and point to that same spot.
> If you mess up and call it "weight" in the GUI program, you'll never know until you start getting bizarre behavior of the system.
> If you later decide that there's another variable you want to share and you didn't make it part of the shared memory in advance,
> you will have to re-factor your main program.

This not a problem within our project:

Here is the shared memory class (for most operating systems in use):
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlSharedMemory.html

Now define:


typedef struct
{
// todo: your data goes here
}MyData;

and use our shared memory:
MyData my_data;
<snip>
shm.write(0, &my_data, sizeof(MyData));
and in the other program
shm.read(0, &my_data, sizeof(MyData));
You may have my_input_data and my_output_data of course.
Useing shm.read()/shm.write() you automatically use a mutex. If you do not want the mutex use
MyData *my_data = (MyData *) shm.getUserAdr();


This can be easily mapped to our
pvbrowser which does the GUI.

By James Ingraham on 23 February, 2011 - 7:01 pm

Example from pvbrowser:


>Now define:
>typedef struct
>{
> // todo: your data goes here
>}MyData;
>
>and use our shared memory:
>MyData my_data;
><snip>
>shm.write(0, &my_data,
>sizeof(MyData));
>and in the other program
>shm.read(0, &my_data, sizeof(MyData));

Nifty. Several points though. First, I trust you know what you're doing, rather than this being the first time you've ever written shared memory code. Second, correct me if I'm wrong, but isn't that C++? Third, I think our points are very similar; it would be beneficial to use existing solutions rather than writing from scratch. You happen to be advocating pvbrowser as the solution, which is fine. I didn't mention it mainly because I don't know enough about it. Maybe one of these days I should correct that.

>Useing shm.read()/shm.write() you
>automatically use a mutex. If you do not
>want the mutex use
>MyData *my_data = (MyData *)
>shm.getUserAdr();

I guess the mutex is a good idea, but does that not create a chance of deadlock? What happens if a program terminates abnormally right on the memcpy line in write, thus not executing myunlock? I have to admit that I haven't looked at stuff like this in a while, so I may just be missing something. But the point remains that it takes a pretty decent programmer with some experience to understand all the nuances of this.

-James Ingraham
Sage Automation, Inc.

>Nifty. Several points though.

>correct me if I'm wrong, but isn't that C++?

Yes of course but the C++ class is just a wrapper for the C functions provided by the operating systems. You could do that in C also. The nice thing is that the class works on Unix like systems, Windows and OpenVMS.

>I guess the mutex is a good idea, but
>does that not create a chance of
>deadlock?
>What happens if a program
>terminates abnormally right on the
>memcpy line in write, thus not executing
>myunlock?

In theory yes. In practice no. If it would happen
it would happen first directly after program startup. Once the program is running i see no reason why these shared memory addresses should become invalid.

>it takes a pretty decent programmer with
>some experience to understand all the
>nuances of this.

The operating system functions that are used within the methods of rlSharedMemory are very old and hard to use. But the user does not need to care about this (He could review it for intrest)
instead he can use our simple and comfortable class.

Of course it would be nice to have a basic knowledge about parallel processes, mutex and semaphores.

I've replied to James Ingraham's comments because he has put the issues more clearly, but the answers are really directed to the problem in general.

>As I said, there is no standard for
>Inter-Process Communication in C.

Technically no, but there are a number of common methods for POSIX/unix, and C and unix are very closely tied together. Unix as we know it wouldn't work without doing lots of IPC. Many of these also work with MS Windows, because Microsoft copied quite a few unix features (you can think of MS Windows as being VMS, unix, and CP/M all tossed together in a blender and switched on "puree" for 5 minutes). Most other modern operating systems you are likely to encounter are either unix derivatives or unix clones.

The first thing that really needs to be done with this project is to put together a realistic list of target platforms and use cases. Who is going to use this, where and how are they going to use it, etc. The technical solution has to be derived from that.

>Yes and no. (HTML can't do this at all
>by itself, by the way. You'd have to
>use CGI at the very least.)

A web server is needed to serve the files, and Javascript code is required to poll the server for new data and to update the current page in the background with new data. Updating the page on the server and reloading a new page for each update isn't going to result in a very useful HMI unless your needs are extremely basic. A "web server" doesn't necessarily mean something like Apache however. It's not that difficult to make a simple web server as part of another program.

>Java can
>talk to C... but only if you provide
>some kind of bridge. Typically, that
>means creating your IPC in C and using
>Java Native Interface (JNI) to call C
>code to do the actual communicating.

For raw binary data you also have to consider word sizes, padding and alignment. You either have to really know what you're doing or make sure you use the exact same compiler (including the same version) for both programs. That includes even using C for both programs.

A better solution is to use a well defined protocol such as Modbus, or else encoding the data using JSON to create your own ad hoc HMI protocol. A lot of "simple" things are not so simple once you get into the details. HMI systems rarely need high performance just to pass data back and forth and it's generally a good idea to have an abstract representation for the data to keep the two programs as independent of each other as possible, so that minor changes in one do not propagate themselves into the other.

>this is a deeper hole than you thought.

Yes, like avoiding dead locks in message transactions.

>You may ask if this is the case then
>how the heck do databases work. Short
>answer; I don't know the specifics.

They run a server that binds to a port and listens for clients. The clients send commands in the protocol that database expects and wait for replies. Each database has its own protocol and you typically use a client library to handle the communications. Conceptually, it's no different from how Modbus/TCP works.

There are also "embedded" databases such as SQLite, but these "belong" to a single program and can't be directly accessed by multiple clients. They're called "embedded" databases because they are "embedded" into the application itself rather than running as a server.

The problem with this project seems to be that it's too open ended. It really needs to go back to the basic "who, what, when, where, and why" before figuring out what the solution should be. Let's look at the issue of portability: "(I would think that I can use the c-application on everything from a RTOS to windows 7 or OSX so I can write the program once and use for embedded micro-processors or a desktop on a plant floor)".

I'm going to guess that the control application needs to run on one computer, and the HMI needs to at least be capable of running on another (otherwise, it's not very flexible, is it?). What about viewing the HMI on your wifi connected iPad (or RIM Playbook, or Android tablet)? If you're going to write native code for each platform, you will have to write your HMI in multiple languages because the platform providers don't allow C on all of those.

For the control program, C sounds great, but you're going to need to set some platform targets as writing something in C doesn't suddenly make features available on platforms that don't have them.

For the HMI, there is a cross platform UI technology and it's called a web interface. Any other solution can address only a subset of those platforms. If you are happy to limit what HMI platforms can be used, then you need to make a list of what targets you need to run on.


In reply to M. Griffin:

> For raw binary data you also have to consider word sizes,
> padding and alignment. You either have to really know what
> you're doing or make sure you use the exact same compiler
> (including the same version) for both programs. That includes
> even using C for both programs.

A similar approach would be to compile a shared memory "server" driver module whereby the data structures and function calls to access those data structures are compiled at once. Then your native C library access functions are in sync with your SHM structures. It also makes it work with Java, C#, Python, etc.

By Ken Emmons Jr. on 23 February, 2011 - 9:01 am

Travis said:

> so far off. Is it that hard when programming with an OS (I
> typically do not have an OS to deal with) to pass variables
> (inputs and outputs) from one application to another? It

Its not that hard, use shared memory. I think one of the points someone else made is that to go from windows to linux to mac is tough using the same exact code with respect to networking and IPC, such as sockets, shared memory, message passing, pipes, whatever. One thing you can do is write a function called "OpenSharedMem()" or something like that and port that to different OS's.

Driver development is also an issue as someone mentioned. Ethernet has the advantage that although the calls to create a socket are somewhat different they do almost act the same under different OS's, generally speaking. Drivers for Modbus probably exist for just about anything.

KEJR

In reply to Travis:

>1st- the main c-application that is
>doing all of the logic and control
>2nd- the user interface portion that
>just passes info back and forth to my
>c-application

This is what is often done with our
http://pvbrowser.org

There is a shared memory and a mailbox you might use for communication between to processes.

Here is the class for the shared memory:
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlSharedMemory.html

Here is the class for the mailbox:
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlMailbox.html

By browsing into the source code you will see the #ifdef statements that make the library itself portable. (Linux/Unix/Windows/OS-X)

The GUI part with pvbrowser can be done very easily and comfortable.

Hi,
If you really want to know GUI programming in C. Then you have to know on how to handle mouse by C Programming first. kindly check my site
http://c-gui-thunderbolt.page.tl/Home.htm
you will have a software Thunder, which will create C GUI codes automatically based on the sketch what you draw with the tools available.

I have no knowledge in handling HMI & PLC by using C programming. If you can help me regarding the same, it will be better, i will also present a software for that too...request you to kindly ping me regarding the same.

Regards,
Carthik

By William Sturm on 22 February, 2011 - 11:54 am

I would suggest find a small portable web server library for the C portion and use a Web browser for your HMI. That way, you will be as portable as possible.GUI's tend to be not portable, as far as I am aware.

Bill Sturm

Our http://pvbrowser.org could be a solution for you.

You can easily integrate any C application into a pvserver.
As GUI designer you can use our integrated designer or Qt Designer from Nokia.
If you want to use SVG in your GUI you should use Inkscape for the design.

Since pvbrowser is a framework for HIM/SCADA you will be much quicker than if you would use GTK or Qt directly.
Also data acquisition is integrated.
As a side effect you will always get a network capable solution.

GUI builders are associated with a particular GUI toolkit. If you want a cross platform GUI, then you need a cross-platform GUI toolkit. Here's a list of some common GUI toolkits and their most common GUI builders (there are others as well).

Gtk+ = Glade
Qt = QtBuilder
wxWidgets = wxFormBuilder

Gtk+ and Qt are probably best know for being used as the basis of the Gnome and KDE desktops on Linux, BSD, and various unix flavours, but they are also used in phones and many other embedded applications. Qt is also used in quite a few MS Windows programs, as many programmers prefer using it rather than the native MS Windows GUI even if portability isn't a concern. The MS Windows and Apple OS/X GUI toolkits are part of their respective operating systems and are not cross platform so they are out of the question for your application.

Something else you might want to consider is to use Python instead of C. You will be able to write an HMI type application with much less code using Python than C. Python is much more easily made cross platform than C (you have to actually work at it to make Python platform dependent) and there are Python bindings for all of the above GUI toolkits.

If you decide to use Python you might also want to look at skipping the GUI toolkit and making direct toolkit calls as it's not actually that difficult and the nature of Python is such that GUI bindings for it don't need the masses of boilerplate that languages like C or C++ require. Some types of programs can use drag and drop GUI builders, but some applications don't have a fixed screen layout so you have to generate the UI dynamically anyway (I'm working on a program like that right now).

A very easy GUI toolkit to use is Tkinter, which comes bundled with Python. However, good documentation for it is hard to come by with the best book that I've seen being "Python and Tkinter Programming" by John E. Grayson. It's actually the best book on GUIs of *any* sort that I've seen, as the author's background is programming interfaces for equipment so the examples that he uses are a lot more meaningful than the typical business applications that most books use. On the negative side of Tkinter, you have to take a few extra steps to make Tkinter look nice as the default theme is pretty plain, and there is no GUI builder available. On the plus side, GUI programming using direct toolkit calls doesn't get any easier than this.


Another approach you might want to consider is a web based interface. I have an open source / free software (GPL) project called MBLogic that includes a web based HMI. The main MBLogic program is a complete automation platform (including soft logic), and HMIServer offers the same web based HMI in stand alone form.

Here's the project page:
http://sourceforge.net/projects/mblogic/

Here's a link to the part of the web site that discusses the HMI:
http://mblogic.sourceforge.net/mbhmi/mbhmiintro.html

I'm in the process of finishing a new program that automates most of the GUI building process (that's the program that I said requires a dynamically generated interface), so the manual process listed there for assembling web pages will very shortly become obsolete. It will be a case of drag the widgets onto the drawing, right click on each one and give it an "id" (name), open the drawing in the new program (MBLogic HMIBuilder), pick each "id" and then select your options, pick a template, click on "save", and it will automatically generate the web based HMI. I expect to have this done within a few days to a week.

MBLogic and HMIServer include communication drivers to talk to the PLC (Modbus/TCP and SBus), and they have a built-in web server to serve the HMI web pages. You run the server program on a computer (I've tested it on Linux and MS Windows), and then load the HMI web page into a web browser. The server will set up communications with the PLC, and the HMI web page will poll the server for updates. The web browser could run on the same computer as the server (e.g. on a panel PC), or it can be on another computer (or even on something like an iPad). You can have any number of clients (web browsers) connected simultaneously.

By James Ingraham on 22 February, 2011 - 1:35 pm

Wow. Just lob a grenade in here, why don't you. I'll give you my 2 cents, and then duck, since flaming arrows will doubtlessly follow.

The C language does not define a GUI, as you have already surmised. There are dozens, if not hundreds (or maybe even thousands), of solutions out there that allow you to write GUI applications in C. Off-hand, I'd say a good place to start would be GTK+. It's free, it's cross-platform, it's well-known, it's well-supported, and it has a semi-official GUI builder called Glade.

Queue ten thousand people screaming about why GTK+ is horribly inferior to < some other GUI >.

You have also apparently noticed that C does not define any mechanisms for Inter-Process Communication (IPC). This is actually the bigger problem. While again there are dozens of solutions, there's not an easy one to pick. I recommend using the Apache Portable Runtime (APR). Actually, I recommend using the APR for any and all C projects. Even so, you'll have to choose among signals, sockets, pipes, and shared memory. These are known as IPC primitives. Using IPC primitives is a good way to have race-conditions, deadlock, stale data, and other nasty scenarios. Message passing is a far better way to do it. Something like 0mq, perhaps. Or use an intermediary database, like MySQL, MonetDB, or Redis. (Queue ten thosand people screaming why those databases are all inferior to BerkleyDB or PostrgeSQL or Times Ten or ...)

What you'll notice here is that there are AWFUL lot of things to learn just to get started. The C language itself. The vagaries of the compiler & IDE you're using. The build and deployment environments (not to be confused with the actual library calls specific to various platforms.) APR, or else the specifics of the platform. The GUI API. The GUI builder. Inter-Process Communication or a database.

When my company looked at this problem, we chose to use the QNX real-time operating system. That provided the GUI API and builder, plus message passing for IPC, plus an environment we were relatively comfortable with. The downside is that our stuff is not portable to other platforms (at least not easily) and there is of course the cost of development seats and run-time licenses.

A no-cost solution could be Linux, APR, Redis, and GTK+, with Glade, gcc, and Eclipse CDT for your build environment. (Queue ten thousand people screaming that KDevelop or CodeLite is better than Eclipse CDT.)

By the way, we haven't mentioned how to talk to hardware yet. Here we open yet another can of worms. If you want blazing fast, plug-in cards on PCI / PCI Express are the way to go. Again, there's no standard C library for accessing these, so you'll have to pick a vendor for IO / DAQ cards and learn how to talk to them. If you can live with slightly less performance, you can hang everything on Ethernet (my preference.) Again, you'll have to pick a vendor and learn how their stuff talks. Here I recommend Modbus/TCP. (Remember, C does not have a standard library for TCP/IP communication. Sockets on *NIX and WinSock on Windows, or APR for cross platform.) If you want to get REALLY fancy, you can try and implement EtherCAT and (supposedly) get high performance even over Ethernet. There is an open-source implementation of the EtherCAT master library. (Modbus/TCP you can do yourself easily.)

Let's look at your original question:
"Does anyone have any suggestions for a gui builder that I can connect with a c-application."

Yes, GTK+ / Glade. But you've opened up a big ol' can of worms if you really want to do it right.

-James Ingraham
Sage Automation, Inc.

Resources:
GTK+: www.gtk.org
Glade: glade.gnome.org
Apache Portable Runtime (APR): apr.apache.org
0mq: www.zeromq.org
MySQL: www.mysql.com
MonetDB: monetdb.cwi.nl
Redis: redis.io (weird address, huh?)
gcc: gcc.gnu.org
Eclipse CDT: www.eclipse.org/cdt/
Linux: Geez, I don't even know where to start. Maybe www.ubuntu.com?
Modbus/TCP: www.modbus.org
EtherCAT: www.ethercat.org

By curt wuollet on 23 February, 2011 - 11:22 pm

I had to wait until I had time to respond a bit on this, one thing the poster did find out is that programmers tend to be somewhat opinionated:^)

It's all good advice too:^)

But overall, what I find most striking is the difference between a *NIX systems programmer's approach and modern practice for application programmers. It would be good to look at the _size_ of some of these solutions. A database, this library, that library, Java, a whole scada system, a general class messaging system? The only thing not suggested was kitchen sink 2.1:^)

Let's assume there is going to be a separation between the control part and the GUI part. Let's also assume you may want to run them on the same box or separately on Ethernet or the Internet for flexibility. That implies sockets. Let's go along with the idea that we want to program in C. Let's assume this isn't going to be a life's work. With those constraints, and the most severe constraint that it be cross platform and run on systems smaller than a Cray Supercomputer or the latest Windows requirement, whichever is smaller, my decision tree points to a tiny webserver and a lightweight browser. From my viewpoint this is a huge amount of software, but not anything like some of the suggestions. Second choice would be Glade and GTK and live with the three main platforms for presentation. Of course, I'd use NCurses and Linux on both halves and less than 10 pages of code.

Regards
cww

By James Ingraham on 24 February, 2011 - 9:38 pm

@Curt: "A database, this library, that library, Java, a whole scada system, a general class messaging system? The only thing not suggested was kitchen sink 2.1 :^)"

You know, that was sort of my point. It's easy to say "I'm gonna write a quick C program!" and then you find out that the problem requires Kitchen Sink version 4.3 (release 12). A typical palletizing application for us takes between 600-800 lines of code. But I've got 20,000 lines worth of libraries and daemons to back that up, which is already on top of a full-blown OS with a message passing framework. I'm not counting the GUI here. Granted, that 20,000 lines has a LOT of stuff that you won't need on every project. Bottom line remains; this isn't as easy at it looks.

"That implies sockets."

Here's a possibility of a naive implementation of using sockets to create a tag database. We want two applications, the control program and the GUI. So control listens, then waits for a connection from the GUI... and we're already fried, because we're WAITING. Which we don't want. So now we either have to learn about threads, or else we run a data server program. Let's say we run a data server program. The control program does a read() and gets the value of tag "x," which for argument's sake is 7. A user clicks a button on the HMI and sets x to 3. The control program adds one to "x" and writes it back. x is now 8, when it ought to be 3 (or conceivably 4). So now we have to learn about locking... and it just keeps snowballing.

"Of course, I'd use NCurses and Linux on both halves and less than 10 pages of code."

I realize that you're semi-joking. I am not devoid of humor. (That was a joke.) And I bet if YOU (specifically) did it it would turn out fine. But for someone just getting their toes wet in the realm of C and Inter-Process Communication (and threading and GUIs and ...) it's not going to go well.

Finally, I have to defend myself a little from the "Cray" snap. These days I don't think Linux (with X, window manger, etc.), APR, and GTK+ are particularly resource intensive. I also mentioned Redis; the download for Redis is ~500K, doesn't require SQL, and links natively to C. My total solution would run just fine on my phone.

I've never actually written a GTK+ program or used Redis. But coming from a *NIX background, I find it impossible to write even a "Hello, world!" app on Windows. So I use APR now all the time. It handles really simple stuff like "sleep" and really complicated stuff like atomic operations. Unless I was writing something for REALLY small hardware, and thus throwing portability out the window any way, I would ALWAYS use APR. In my opinion it should be taught alongside the C Standard Library.

-James Ingraham
Sage Automation, Inc.

By curt wuollet on 25 February, 2011 - 12:54 pm

> @Curt: "A database, this library, that library, Java, a whole scada system, a general class messaging system? The only thing not suggested was kitchen sink 2.1 :^)" <

> You know, that was sort of my point. It's easy to say "I'm gonna write a quick C program!" and then you find out that the problem requires Kitchen Sink version 4.3 (release 12). A typical palletizing application for us takes between 600-800 lines of code. But I've got 20,000 lines worth of libraries and daemons to back that up, which is already on top of a full-blown OS with a message passing framework. I'm not counting the GUI here. Granted, that 20,000 lines has a LOT of stuff that you won't need on every project. Bottom line remains; this isn't as easy at it looks. <

Actually, my point from the systems programmer view was more subtle than that. Linux and *NIX in general is extremely powerful for these kinds of tasks, _iff_ you do them the #NIX way. I will use Linux as the example because it is probably the most full featured and definitely the easiest, because you have source and you can, for instance, change a driver, or use busybox, or any of the hundreds of other things tailored for this type of work. If you are a C programmer, on Linux, the world is your oyster. If you are willing to work _with_ the OS and use what's already there, you can produce something that works with a tiny fraction of the work for other OSs or the somewhat mythical "portable application". Once I have a card and a driver, a page or two of code would do the actual work of reading the card and scaling the data, etc. Another page or two with NCurses would produce a local display for verification and well... local display. A pipe to a two page Python program would give you the simple GUI the OP mentioned. A cron script could read a status register (shm) and dial the modem and send the appropriate message. VNC would give you remote access to the GUI and ssh could give you a remote terminal for the NCurses display. I haven't bought anything or added anything and I've written very little code. Finding a suitable, ready to go, small webserver from the hundreds of embedded projects wouldn't be hard either and if you don't like the shm complexity, you could centralize the data on an ordinary file in ramdisk (for speed) because "everything is a file" in Linux. And making the system two way isn't much of a stretch.

Will it win any software awards? No, but I know it will work because I have all kinds of stuff like this running. Witness my two page PLC. Is it mass marketable and will it make me a million dollars? No, but I solved _this_ problem fast and easy. What more esoteric programmers tend to forget, is that we are in the _one off problem solving_ business. You've done enough *NIX work to judge that, yes I can, very likely, do it this way and it will work, even just being a Bonehead C (tm.) programmer. People don't understand why I'm so high on Linux in automation, this is it. Small, fast, easy, extremely cost effective and robust solutions. All you have to do is be a C hacker and _use what the system offers_. Now, compare this to the other proposals and you'll see why I think they're kinda overkill:^) And the amazing part, even to me, is that it stands a very good chance of being cross platform as long as the bottom end runs on Linux. That's why I applaud the OP's decision to learn C and not get sucked into the huge bloated vortex of today's software. Hence the contrast between the systems programmer approach and the applications programmer approach. My approach is nothing special, it's just what Linux programmers do on Linux because that's what all that stuff is there for.

> "That implies sockets."

> Here's a possibility of a naive implementation of using sockets to create a tag database. We want two applications, the control program and the GUI. So control listens, then waits for a connection from the GUI... and we're already fried, because we're WAITING. Which we don't want. So now we either have to learn about threads, or else we run a data server program. Let's say we run a data server program. The control program does a read() and gets the value of tag "x," which for argument's sake is 7. A user clicks a button on the HMI and sets x to 3. The control program adds one to "x" and writes it back. x is now 8, when it ought to be 3 (or conceivably 4). So now we have to learn about locking... and it just keeps snowballing. <

> "Of course, I'd use NCurses and Linux on both halves and less than 10 pages of code." <

> I realize that you're semi-joking. I am not devoid of humor. (That was a joke.) And I bet if YOU (specifically) did it it would turn out fine. But for someone just getting their toes wet in the realm of C and Inter-Process Communication (and threading and GUIs and ...) it's not going to go well. <

But, only semi-joking:^).

> Finally, I have to defend myself a little from the "Cray" snap. These days I don't think Linux (with X, window manger, etc.), APR, and GTK+ are particularly resource intensive. I also mentioned Redis; the download for Redis is ~500K, doesn't require SQL, and links natively to C. My total solution would run just fine on my phone. <

Actually, an embedded type board would probably be an excellent way of doing this. Many have the needed analog and digital I/O on board and the drivers in the tree. But a PC would be much easier for the first pass.

> I've never actually written a GTK+ program or used Redis. But coming from a *NIX background, I find it impossible to write even a "Hello, world!" app on Windows. So I use APR now all the time. It handles really simple stuff like "sleep" and really complicated stuff like atomic operations. Unless I was writing something for REALLY small hardware, and thus throwing portability out the window any way, I would ALWAYS use APR. In my opinion it should be taught alongside the C Standard Library. <

Me neither on the GTK+ or Redis, but again, those are more at the application side.

Regards
cww

By James Ingraham on 26 February, 2011 - 5:33 pm

@Curt: "Linux and *NIX in general is extremely powerful for these kinds of tasks, _iff_ you do them the #NIX way."

No argument here.

"...you can produce something that works with a tiny fraction of the work for other OSs or the somewhat mythical "portable application"..."

Here I'll only slightly disagree. Certainly, compared to Windows or a truly portable app, writing this type of program for Linux is a lot easier. But QNX is easier still. And VxWorks has some advantages, too. You can make Linux REALLY small, but doing so takes some knowledge and work. Installing Ubuntu is trivial, but now you've got a much bigger footprint than you theoretically need.

BTW, after chastising us for throwing everything but the kitchen sink at the problem, you've added NCurses, Python, VNC, and ssh. And by implication, Python is going to require some sort of GUI. So I don't see where your solution is any smaller or less complicated than mine.

"I haven't bought anything or added anything and I've written very little code."

I also proposed a no-cost solution. And the whole reason I mentioned certain libraries was to minimize the custom code.

"What more esoteric programmers tend to forget, is that we are in the _one off problem solving_ business."

This is a very good point. I have, indeed, been focused on creating a re-usable framework for solving applications. That would necessarily make my solutions larger and more complex. If you're only going to do this once, you really could strip it down to its most basic components.

"All you have to do is be a C hacker and _use what the system offers_."

This is where I think we most diverge. IMHO, having two processes talk is a very advanced C topic. Sure, sure, sockets are trivially easy to implement. But usually those trivial implementations are either to solve trivial problems, or they're talking to something that has been designed by someone who really knows what they're doing. Race conditions, deadlock, liveness, etc. require a very deep understanding. Witness all the articles recently about how hard it is to program modern multi-core chips in a way that is actually useful.

"Now, compare this to the other proposals and you'll see why I think they're kinda overkill"

Again, I don't see where your solution was any less "overkill" than mine. Heck, you even proposed a two-language solution!

I do think our arguments are pretty close in concept. Mainly, I'm a little more pessimistic.

-James Ingraham
Sage Automation, Inc.

By curt wuollet on 28 February, 2011 - 3:54 am

>> @Curt: "Linux and *NIX in general is extremely powerful for these kinds of tasks, _iff_ you do them the #NIX way." <<

> No argument here.

>> "...you can produce something that works with a tiny fraction of the work for other OSs or the somewhat mythical "portable application"..." <<

> Here I'll only slightly disagree. Certainly, compared to Windows or a truly portable app, writing this type of program for Linux is a lot easier. But QNX is easier still. And VxWorks has some advantages, too. You can make Linux REALLY small, but doing so takes some knowledge and work. Installing Ubuntu is trivial, but now you've got a much bigger footprint than you theoretically need. <

You don't have to know much to have a really small Linux. That's the beauty of it. The upside of having hundreds of distributions is that you can find one for nearly any purpose and embedded is where all the action is. Angstrom would be fine, but Ubuntu does fit on a BeagleBoard. I don't think you can self-host on there but I have seen it running.

> BTW, after chastising us for throwing everything but the kitchen sink at the problem, you've added NCurses, Python, VNC, and ssh. And by implication, Python is going to require some sort of GUI. So I don't see where your solution is any smaller or less complicated than mine. <

You _do_ recall that I said I'd do it with NCurses:^) That's not anything like A Java engine. Actually, I would probably do it without any display code on the bottom half. And yes, I am a little ashamed to defer to an interpreted language but overall Python might be smaller and better than some of the C solutions with all the dependencies. GUIs are simply hugely expensive, it's just a matter of degrees. Any GUI generally means a huge footprint relative to the task at hand.

>> "I haven't bought anything or added anything and I've written very little code." <<

> I also proposed a no-cost solution. And the whole reason I mentioned certain libraries was to minimize the custom code. <

>> "What more esoteric programmers tend to forget, is that we are in the _one off problem solving_ business." <<

> This is a very good point. I have, indeed, been focused on creating a re-usable framework for solving applications. That would necessarily make my solutions larger and more complex. If you're only going to do this once, you really could strip it down to its most basic components. <

That, I think, is the major difference in our viewpoints. Much of the difference relates to the difference between solving _this_ problem and a general class solution for problems like this. See below.


>> "All you have to do is be a C hacker and _use what the system offers_." <<

> This is where I think we most diverge. IMHO, having two processes talk is a very advanced C topic. Sure, sure, sockets are trivially easy to implement. But usually those trivial implementations are either to solve trivial problems, or they're talking to something that has been designed by someone who really knows what they're doing. Race conditions, deadlock, liveness, etc. require a very deep understanding. Witness all the articles recently about how hard it is to program modern multi-core chips in a way that is actually useful. <

Ah, but consider the difference between connecting two programs that you have written to communicate with each other, and the issues of serving multiple clients and the whole business of tagging your data and on and on. If you treat a socket or a pipe as a simple conduit, with the format understood, much of the oft discussed complexity falls away. It's really stylistic, using these mechanisms for what they are VS making them a generic messaging service.

>> "Now, compare this to the other proposals and you'll see why I think they're kinda overkill" <<

> Again, I don't see where your solution was any less "overkill" than mine. Heck, you even proposed a two-language solution! <

I suppose it's a matter of perspective. These are parts of nearly any Linux distribution except for Python which is on most distributions. Although, I suppose some will be omitting NCurses to discourage that nasty command line typing that seems to be the bane of GUI users.

> I do think our arguments are pretty close in concept. Mainly, I'm a little more pessimistic. <

And I fail at describing the goodness and beauty of *NIX used as intended. The appreciation is, I suppose, anachronistic in a point and click world, but the power of stringing existing things together to solve the problem at hand is well suited for the ad hoc automation world. It's a little like using a prototyping package, only once you've got something to show, you're done.

Even those who hate the whole genre would become fans if they were to learn enough to solve a few problems with it. Even many of the Linux "greatest hits" go far because they stand on the shoulders of giants and are collections of existing utilities under the facade. And grasping the ethos is the key to awesome power. Too few venture there. Even many who use Linux don't get it. They try instead to use it like Windows. A pity.

Regards
cww

Because
- sockets
- threads
- mutex
- semphore
- serial ports
- time
- shared memory
- mailbox
- PLC driver
...

are slightly different on different operating systems. i have written this library:
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classes.html

The library works on *NIX, Windows and OpenVMS

It encapsulates all these differences and makes me portable.
The GUI is also postable because of Qt.
Also databases are portable because of Qt.

As curt wuollet said:
> All you have to do is be a C hacker and _use what the system offers_
<snip>
> That's why I applaud the OP's decision to learn C and not get
> sucked into the huge bloated vortex of today's software.

You are completely right.

>I also
>mentioned Redis; the download for Redis
>is ~500K, doesn't require SQL, and links
>natively to C. My total solution would
>run just fine on my phone.

I haven't used Redis either, but I understand it to be more or less similar to Memcached but also has disk based journalled persistence. Since you wouldn't need (or want) that for this sort of application, it might be easier to just use Memcached rather than using Redis and then figuring out how to turn off the journalling. Both Redis and Memcached are in the Debian (and Ubuntu) repositories, so installation should be very simple if you're using Linux.

On another note, I'm not going to state that either this project or your (James Ingraham's) own applications are suitable applications for Python (perhaps they are, perhaps they aren't), but if you have an application that you would like to use Python for, then you should have a close look at Twisted (http://twistedmatrix.com/trac/). The initial learning curve is a bit steep, but it's an application framework that makes otherwise difficult things possible without herds of threads, processes, locks, etc. I'm using it for MBLogic and I'm doing the following with it all in one program:

1) A Modbus/TCP server.
2) Multiple (unlimited) Modbus/TCP clients.
3) A web based HMI protocol server.
4) Another HMI protocol server with read-only access.
5) An ERP protocol server.
6) A soft logic system (executes a PLC program on a regular scan).
7) A web based status and management system that lets you do live monitoring, management, configuration editing, etc.
8) A database to log alarms and events (SQLite in this case).
9) Alarm and event history query.
10) RSS feed server (for monitoring events).
11) A web server for user generated documentation.
12) Etc.

That's all in one program sharing a common data table, with no locks or threads (other than any that are buried in system libraries) or IPC to deal with. You can also use GTK+ with Twisted, but I haven't tried that. I've tested the Modbus/TCP server with 100+ incoming client connections, and the Modbus/TCP clients with 100+ outgoing connections.

Twisted has lots of other features that I haven't used yet, including protocols for:
1) SSH.
2) SMTP, IMAP, POP3 (e-mail).
3) DNS.
4) Instant messaging (AIM, Jabber, XMPP, etc.).
5) Connectors for most popular databases.
6) NNTP.
7) FTP.
8) Straight sockets (this is how I'm implementing Modbus/TCP).
9) Lots more.

By James Ingraham on 26 February, 2011 - 5:04 pm

@M Griffin "...it might be easier to just use Memcached..."

I KNEW somebody would argue about the database choice. :-) I picked Redis more or less at random out of the choices of in-memory NoSQL databases. I did actually consider Memcached, but picked Redis since Memcached is targeted at distributed systems, and I figured we were working on a smaller scale. MonetDB I mentioned as a more traditional database, but for more real-time performance than the VASTLY more common MySQL.

"...if you have an application that you would like to use Python for..."

I have no problem with Python. However, I don't KNOW Python, so for me that's a barrier. We could debate the merits of various languages endlessly. (Actually, I'd enjoy that.) But the original question was about C, and I feel I can speak to that with some experience. So I'm glad you're here to bring up the Python points.

"...have a close look at Twisted (http://twistedmatrix.com/trac/)..."

I may do that one of these days. I'd also like to take a closer look at MBLogic. There's only so many hours in the day, though.

-James Ingraham
Sage Automation, Inc.

In reply to James Ingraham: I just installed and tested a quick benchmark with both Redis and Memcached. In each case I wrote a short Python program and then created 1000 key-value pairs in the database, and then timed how long it would take to read them back 100 times (in other words, read 100,000 key-value pairs one at a time).

The times were quite close, with Memcached being marginally faster, but when looking at "top", it was obvious that the Memcached server was taking a smaller proportion of the CPU time than Redis was. In both cases however, it was my client which was taking the majority of the CPU time (this was tested on a single core computer). I would say that overall, Memcached was faster than Redis (in this particular case), but not by a large margin.

Both databases have very similar interfaces. I was able to modify the Redis benchmark program to use Memcached by just changing the module import statement and the object initialisation statement.

On a fairly slow PC, I was reading approximately 10,000 key-value pairs per second. That's actually pretty good performance, considering that it's doing this one element at a time. A more efficient client could improve on that, but let's work with the 10,000 updates per second number. That's an average of 100 microseconds per transaction when running over localhost. That's when doing one key-value pair at a time.

Redis also has commands for reading and writing multiple key-value pairs at a time, so it may have an advantage over Memcached in some cases as I would expect that a transaction involving multiple key-value pairs would be much faster than doing an update using multiple single updates. I ran a slightly different test to check this by setting 2000 key-value pairs and then reading them back 2000 values at a time. In this case the performance was 25,000 key-value pairs per second, and the bottleneck here was clearly the (very simple) client, so the actual database is capable of going much faster than this (I used 2000 key-value pairs, as that happens to also be the maximum number of coils you can read with one command using Modbus).

At this point you're asking yourself why I'm going on about this. The discussion of Redis and Memcached set off a rather interesting train of thought for me which I will explain here. Let's call database 'keys' 'tags' and then consider the following:

1) We have an in-memory key-value (tag-value) database.

2) We can connect to it with large numbers of clients.

3) These clients can communicate with the database using the tag (key) names.

4) Each client can be a simple program running in it's own process.

5) A client can be anything that wants to read or write a 'tag'.

This sounds an awful lot like the core of a tag based soft logic or SCADA system. Let's imagine we have the following:

1) The Redis database could be initialised with a set of tag names.

2) A system management server would be started up.

3) The system management server would read in a set of configuration
files.

4) Based on the configuration, it would fork off a series of child processes.

5) Each child process would be passed it's configuration as part of its parameters.

6) Each child process would connect to the Redis server.

7) The child processes could be anything - a communications (e.g. Modbus/TCP) server, clients (e.g. Modbus/TCP), HMI server, soft logic execution servers, etc.

8) The child processes could be controlled from the management server via a separate command channel (possibly DBus) and made to stop, restart, report on progress etc.

9) Child processes could be written in virtually any language (the Redis web site lists client bindings for 22 different languages).

10) Each child could run on its own time schedule, possibly even taking advantage of real-time schedulers.

11) The system would be very, very, scalable, and able to take advantage of all the hardware you could throw at it. A four socket motherboard with quad core CPUs? If you need that, the system should be able to make use of it if you can split up the tasks. You could even distribute the processing over multiple computers.

12) The Redis memory persistence features database could be used to store tag values to disk so you can recover the program state after a restart.

13) Redis will do master-slave replication, so you can set it up for redundancy or distributed operation.

14) It's very expandable, in that you can add more child processes to support additional protocols or features.

15) The tags (keys) would be the native system tag names which each child would use, so there's no need to come up with a physical address to tag name mapping system. Each child would handle that as would be appropriate.

16) The values can be anything, so again, you're not restricted by data type (although the child processes would need to know how to handle them).

17) Each child process can be stopped and restarted independently, so as long as you are keeping the important parts of the state in the database, you can change, reconfigure, and upgrade the child processes while the system is running.

This is a very interesting idea. The key points would be:

a) The key-value store in-memory database as the centre of the system as a tag-based data store.

b) Small, simple, independent clients, with each one doing a single task.

c) Use a separate command channel (possibly DBus) to monitor and control the clients.

d) A system management server to start up and control the clients. This would use a web based control interface for user interaction.

I don't have time to pursue this at the moment, but it's a very interesting idea.

It should just be noted that the database approach for shared memory or "tags" is not portable to realtime systems unless you can live with your variable access at a lower priority than your machine control threads. (Unless said database was RTOS compatible....)

KEJR

By James Ingraham on 28 February, 2011 - 5:56 pm

@M Griffin: I had a very similar thought process, although not quite as well-thought out as yours. Thanks for the hard numbers; they're quite interesting.

@KEJR: Well, like we've said before, there's real-time and then there's "real-time." An in-memory database designed for high-throughput will probably be pretty good in most cases. M Griffin is guessing 100us look-ups. Not bad. There are some apps that can't handle that, or can't handle whatever jitter might be in there, but it would be perfectly sufficient for a wide range of applications.

-James Ingraham
Sage Automation, Inc.

By curt wuollet on 22 February, 2011 - 5:20 pm

The problem is that while C is portable, GUIs tend to be very platform specific. For cross platform GUIs the trend is towards Java and to some extent, Python. One work around is to use a browser interface, but that would be a bit much on an embedded platform. There are cross platform GUI packages that have a C interface and that may be what you are looking for. They, for the most part are proprietary and somewhat expensive. I don't do much with GUIs but there are folks here that do that can perhaps advise you. Bear in mind that the GUI typically involves vastly more code than a typical control app. I do applaud your decision not to simply do the Windows thing. There are plenty of those folks already. In the post PC era, they will be fighting over scraps and legacy. And you will be well positioned.

Regards
cww

One comment I would make about using any open source package is to read the license agreement carefully. Most indicate if you are writing the application using open source your derivative work also becomes open source and you must provide the source to your customers. This is fine for internal use but may not be palatable for consultants, integrators, etc. Just don't get caught like LinkSys using open source then not wanting to provide the source code later on. You will lose the lawsuit in the courts or in the court of public opinion.

On the topic of writing display vs code it seems strange that people have been working with these two mediums for over 20 years and we still don't have an good, integrated, simple , cross-platform, solution yet. The closest I have seen is LabView in which you have a display window and code window. It is slightly cross platform but kind of expensive.

Just my 2

>One comment I would make about using
>any open source package is to read the
>license agreement carefully. Most
>indicate if you are writing the
>application using open source your

This is a common misconception. Most licenses state that any modifications to the library itself must be made open source, while if you use an open source library you do not need to make your entire project open source. As you state, read the license. Many new libraries are released under very liberal licenses like the MIT license so that there is no discussion whether this is an issue. But for most cases, this is a non-issue

Thanks to all that have written in this post!!! I am really glad there are so many people that have such strong opinions in one direction or another that are willing to share so that I can research each. I have been looking at all of the responses while learning about the different technologies mentioned in each response which is why my response has been slow (still not complete but wanted to respond and thank before to much time passed).

I mentioned previously that I wanted the 2-Step approach of a gui app and separate main/control app. This approach I figured would be a little more difficult and definitely not as clean as a single app but I figured I would be asking way to much to get the gui drag and drop ide that would also let me hand code the integrated main/control app and then compile everything down to c. Most of my gui's are pretty simple and I use a CAD software to create indicator lights, toggle switches, and appropriate animated gifs where needed. My customers tend to respond to the pretty wow effect of animations and typically base my entire control program on how pretty my screen shots are instead of intuitiveness of the gui layout or efficiency of the control algorithms. Usually takes me longer to layout the gui than write my control code but a necessary evil these days!!! Anyway the 2-application approach I figured would allow me to focus on the control code which is what I really care about when designing and would be very portable (at least I thought it would be with c and now that I look a little deeper into it I may have to really consider platform(s) as I am writing the code even if in c. Still no big deal I think. I have looked into the higher level languages like python that was mentioned but I have liking for low level embedded processor boards which if I learned and programmed in c I have the ability to go down to very low level programming as well. This may be something I need to let go of for now if I am taking to much of an unorthodox approach by not making my gui and main app all 1 app. Smarter people than me have decided common ways to do things in programming (although I am not scared to venture outside the box) and would like opinions on just how far I am going outside the box with the 2app approach. In reality my target will be (most of the time) either a desktop computer for SCADA type apps and panel pc's running typically an embedded Linux or windows for the turnkey products we sell that include controls on board. I will interface most of the time with modbus remote I/O for any I/O needs.

Another advantage I was seeing from the 2-step approach was that I don't have to consider my gui when debugging. Personally, I am fine with 1's and 0's but my control algorithms most of the time seem to be graded on how pretty my indicator light renderings are (not really a graphics guy myself but have learned to be because of this). This way the gui can be debugged separately from the main app. I have been thinking and even downloaded (but not played with yet) M. Griffin's software because as for my gui needs I thought the web was a great out of the box thinking (or at least my box). Most OS's have a web client capability which would give me cross platform for the gui and then connect to my c-app (still undetermined method and am looking at all of your suggestions). Thank you M.Griffin for the suggestion and would be interested in what others would have to say about this method. My only concern for this may be speed. Do any of you think I may have problems with this method when I am in speed critical applications? The more layers (i.e. virtual machines) I would think could affect speed and motion control applications but maybe ok for portability and non-speed critical applications.

Again thanks to all who have contributed as you have saved me many nights sitting up to study and understand the best routes to go!!!!!!!!!!!!!!!!!!!!!!!!

Separate control and HMI applications is a very conventional approach. This is how most HMI systems work. The only question people here are debating is the best way to implement it.

As for the speed of a web interface, the HMI is separate from your control application so the speed of the HMI is not directly related to the speed of your control code.

If you are concerned about the speed of the graphics update, that will depend on how graphics intensive your HMI screens are. The standard demo HMI that I include with MBLogic takes about 3 percent CPU. The server load is approximately 0.5 percent for HMIServer (when handling just the HMI load). If you want to run continuous smooth graphical animations (as opposed to just changing when the data has changed), then the load will depend on whether you have hardware graphics acceleration. If that's a concern, then avoid the smooth animations (the only thing that uses smooth animations in the demo is the flashing light where the dot "grows" from the centre to fill the lens).

There are several points to keep in mind here. The first is that I'm not talking about simple static pages like you see on Control.com (or 99% of other web sites for that matter). That sort of web page creates the page on the server, and your browser just downloads and displays it until you load a new page.

The sort of web interface that I'm talking about runs a program which reads data from the control applications and uses the results to update the screen. It's the same principles as you would use for an HMI that was written in C, except you are writing it in Javascript and using HTML, CSS, and SVG for the screen design. The web page gets loaded *once*, and after that a Javascript library polls the server for data (not new web pages) and uses that data to update the display.

The second point is that if you happen to like the Javascript libraries, SVG widgets, web page templates, etc. that I wrote, but you don't want to use the MBLogic or HMIServer server programs, you can substitute your own server. The protocol that I used is fairly simple and fully documented. The HMI web pages won't care if you substitute your own server. You can build your own HMI server into your control program, or alternatively run a separate server as another process (with your control program as a client to that server). I don't know much about your application or the market you are addressing, so I can't say what the best approach is here.

The third point is that as well as an application specific HMI, you are going to want some sort of control and management interface that tells you if the system is up and running, what it's status is, whether you have any communication errors, etc. You will also want to be able to send commands to the control application to shut down, reload the configuration, etc. A web interface is very handy for this as well.

The fourth and final point is that this is not necessarily an either/or situation. You can use interface and control protocols that will work with either a web application or a conventional C client. As long as either type can use the same protocol, the control program itself won't care (or know) what is at the other end. You could start with an HMI written in C, and then add a web based client later. Your C HMI could open a plain socket with the control program server and just send JSON based messages back and forth. If you want to add a web interface later, you can use another socket to serve HTTP messages (these would have the same JSON payload, but would add the HTTP headers in front). Since the basic message format would be the same for each method, the change would have less impact on your control program.

I will re-iterate a point though. I don't know your application. I can't say for sure what the best method is. I can give you some pros and cons, but I'm not standing in your shoes so I can't say for sure what the best method is. However, you emphasized having the maximum flexibility and portability, and for an HMI application the best solution for that is a web interface. You're going to have to learn something about web pages and Javascript to really take advantage of that, but they're not that difficult.

I have a program in c language, may I know the easier way to create GUI in quick? Thanks a lot ya..
I just a beginner in C language and have no knowledge on GUI.=(

By James Ingraham on 9 February, 2012 - 10:26 am

(a) This probably isn't the best place to ask this question. There are more appropriate forums with people who are more directly involved in such things.

(b) You haven't given us a lot of information, like what kind of operating system or hardware you're using.

(c) Having said all that, the obvious choice is GTK+, although it's a little tricky on Windows. You could also look at IUP, though I don't know much about it. There's even wxC, although that doesn't look like an easy option. For straight C, GTK+ is one of the only well-known, well-supported, well-documented, robust, multi-platform GUI libraries out there.

(d) http://en.wikipedia.org/wiki/List_of_widget_toolkits

Good luck.

-James Ingraham
Sage Automation, Inc.

By Ken Emmons Jr. on 9 February, 2012 - 1:08 pm

These aren't all pure C, but the following recommendations are either C++ or C#.

GTK# using monodevelop is a good choice for cross compatibility apps. It's a little confusing because it wraps the GTK+ C libraries into .NET, but most of the time the problems are missing documentation. I've had good luck with this library on linux/windows cross compatibility projects. If you need high performance (i.e. not JIT compiled .NET apps) and cross compatibility I'd look at QT. I've not used QT but it seems to be a powerful well defined system.

If you just want to write some basic GUI and run on windows, I'd recommend windows forms with C#. It'll leverage some of your C experience.

I guess of all the above recommendations the QT approach is the purest to C. I didn't mention GTK+ for C because James Ingraham already did.

KEJR

By Curt Wuollet on 9 February, 2012 - 5:49 pm

I write GTK+ stuff for living these days and it works well, especially with Glade which is the screen builder. Check out the screen builders because they save an enormous amount of time. Most of the code is just callbacks and treeview manipulation. It mixes well with straight C code so if you are adding a GUI to an existing C application I think GTK+ is one of the easier ways, Of course, I've never worried about whether it will run on Windows, That might add complexity to the job, But if you use something like Eclipse that handles the build, it should be much the same.

Regards
cww

By Vladimir E. Zyubin on 9 February, 2012 - 5:52 pm

have a look at http://en.wikipedia.org/wiki/Processing_(programming_language)

if your application deals with automation -- have a look at LabVIEW. Integration with your code can be done via dll, or just rewrite the code.

Hello,

a good library to study graphic interfaces is the library SDL
(http://www.libsdl.org)

Best Regards
Armin Steinhoff

Hi.

You can test Proview here: http://www.proview.se/v2/
which is an open source free HMI and soft PLC under linux providing GUI support and Modules that where you can write C or C++

regards

/Bruno