Since all of the interfacing software is in C/C++, I wanted to use a light weight http server framework that I could build application specific C++ code into. I did not want to use gateways or other scripts for performance reasons, not so much for this particular activity but for others which might require higher performance between the http command and the hardware. There are a couple of good packages available for these purposes. After a small amount of experimentation I decided to use libmicrohttpd. It is pretty basic and doesn’t get in your way for simple servers like this.
Once you have the hardware control software and an http server framework, the next step is to decide on the building blocks for the actual user interface itself. In support of this, there are a dizzying array of software packages including jQuery and Dojo. For this particular application I wanted to start simple and use basic html, css, and javascript.
The browser component is structured as a simple table with a CSS defined border and cell entry formats. The basic actions buttons with the numeric inputs being text box forms. An example is shown below.
Browser Control Panel for Synthesizer |
The buttons at the top allow the application software to be restarted, the BeagleBone Black to be rebooted, or the current configuration parameters to be saved persistently (and used at next power up). The shutdown button is only for testing and is not required for use. The box below that indicates if the browser is actually connected to the device, the time on the device (which should update every second if everything is working), the PLL lock status at the given frequency and the output level as currently read from the device. The next set of control buttons allows the device to run, sweep, and continuously monitor the output power level. The “run” actually will just power on or off the synthesizer boards allowing you to quiesce everything in case you are wondering where a certain signal is coming from. The level monitoring allows an output level update, constant monitoring (~100Hz) or to be completely quiet – again in case there are questions about where a certain signal is coming from. The final panel allows user inputs of various parameters and shows the currently in effect values. These allow for a single constant frequency and level setting (start parameters), or a sweep in both frequency and level (from start to stop values) along with step sizes when sweeping for both level and frequency. While sweeping the time at any given frequency and level can be configured from 0 (as fast as the device can step) to seconds using the “DwellTime” value.
This application is simple enough that it doesn’t merit a full MVC (model view controller) approach, however, a simplified variant is used – mostly to evaluate the approach. The browser client code is here while the server code is here.
The state coming back from the server is expressed as a single JSON object. This is easy to parse in javascript. To keep things responsive the state is requested from the server using http query every 100mS. The state variable contains all of the elements in the display. The JSON object is then used to update all of the DIVS in the page. This represents a single HTTP GET on the “getstate” URL and keeps the client parsing very simple along with the response construction. Each user input generates a HTTP GET on the “setstate” URL with the values being a name/value pair. Again, this keeps the HTTPD server parsing simple and allows for easy testing with human synthesizable commands. The network API is then simple enough that control can also be scripted using WGET. An external host can use bash scripts to control the device for automated test setups.
The state coming back from the server is expressed as a single JSON object. This is easy to parse in javascript. To keep things responsive the state is requested from the server using http query every 100mS. The state variable contains all of the elements in the display. The JSON object is then used to update all of the DIVS in the page. This represents a single HTTP GET on the “getstate” URL and keeps the client parsing very simple along with the response construction. Each user input generates a HTTP GET on the “setstate” URL with the values being a name/value pair. Again, this keeps the HTTPD server parsing simple and allows for easy testing with human synthesizable commands. The network API is then simple enough that control can also be scripted using WGET. An external host can use bash scripts to control the device for automated test setups.
The use of HTTP GET is not in line with network security and best practices, however, there is nothing secure about this device. It was intended for use on a dedicated and isolated network with other instruments. There is no login to prevent conflicts among users/sessions. The server will server up any file on the BBB. I am sure there are numerous other security holes within the configuration of the BBB Linux configuration as I have it setup. The whole point of this is simplicity and experimentation.
The one final interesting portion to note is the persistent configuration saving feature. Once you get things setup for a particular measurement it is exceedingly useful to be able to save it and then later just power on the device and have it start working like you wanted to without even having to attach to it with an Ethernet or browser. The BBB file system is mounted read only for robustness. The state parameters are read from a file on startup. When the server receives a save configuration command, the file system is re-mounted read/write, the configuration file with the current parameters written and then the root file system re-mounted read only. This produces a small window in time during which the device root file system may be vulnerable to interruptions. In practice, this has not proven to be a problem as the entire re-mount, write 200 bytes, re-mount operation occurs within milliseconds. If you are prepared to re-partition the eMMC on the BBB one could create a small spare partition and read/write the configuration file through a raw block device. This side steps any file system checks and integrity concerns.