How to Quickly Make a User Interface to Control Your Arduino Program

Most Arduino programs have a few settings that you’d like to change from time to time:

  • a set-point temperature,
  • the data transmission rate, or
  • the power for a radio transmitter, for example.

MegunoLink Pro’s Interface Panel was created to modify settings and control programs using serial commands. Information entered into common controls such as buttons, check boxes and sliders can be sent through a serial channel. By sending configuration through a serial port or Ethernet connection, you don’t need to modify and upload a new program for every change. Almost any program, even Blink, could benefit from a simple user interface:

Arduino User Interface

A simple user interface created with MegunoLink Pro’s Interface Panel for a Blink program. It sends serial commands like !SetInterval 1200 to the Arduino to modify the blink interval and duration when the control values are changed.


Building the interface

To build this interface in MegunoLink Pro, create a new Interface Panel Visualizer from the Start Page, or the Visualizers popup and add labels and controls by dragging them from the toolbox. MegunoLink Pro supports many common controls including:

User interface design for Arduino

A screen shot of a partly completed control panel for the Blink 2.0 program shown in the MegunoLink Pro Interface Panel Designer. Controls are added from the toolbox (left) to the design surface (centre). Properties, such as font size, colour, alignment and control names can be changed using the Properties Panel (right).

  • Labels
  • Buttons
  • Pictures
  • Numeric up/down
  • Lists
  • Panels
  • Tabbed layout panels
  • Flow layout panels

All controls have properties. With properties you can:

  • change the foreground or background colour
  • add a background image
  • set a minimum and maximum value for numeric up/down and track-bar controls
  • anchor a control to an edge of the panel

We built a simple user interface for a program to blink the LED built-in to most Arduino boards. The interface lets you control two parameters through MegunoLink Pro: how fast the LED blinks and how long it remains on for each blink. A numeric up/down control is used for each parameter. The control named Interval sets the time between blinking; the length of the flash is set a control named Duration. Both are set in milliseconds. We also added buttons which send commands to the Arduino to print the current settings, and we use a label control for the title text.

This short video shows the interface panel being built (3 minutes):

Hook-up serial commands

Many controls can send a serial command when something happens: a button is clicked, a number is entered or a slider is moved. This serial command gets interpreted by the Arduino program to do something appropriate. For example, sending !SetInterval 2000\r to Blink 2.0 changes the interval between flashing the LED to 2 seconds. Serial commands are pretty flexible and should support any text protocol you’d like to use.

The command sent by a control is set using a property. The name of the property depends on the control and the action it is linked to, but they are all grouped under the Communications heading in the property browser and are available on the control’s smart tag.

Setting commands

The command sent when an action is performed, such as clicking a button, can be set using the properties browser (right), or a smart tag on the control. Click the small triangle in the top right corner of the control to show or hide the smart tag.

Some of the properties to send commands are:

ButtonOnClickSendThe button is clicked
Numeric up/downOnValueChangedSendArrows are used to change the value, or enter is pressed after typing a new into the box or the control loses focus
Text boxOnTextChangedSendThe text in the control is changed
Value listOnSelectionChangedSendA new item is selected from the list
Check boxOnCheckChangedSendThe box is checked or unchecked
Radio buttonOnCheckChangedSendThe radio button is checked or unchecked
Track bar with indicatorValueChangedCommandNameThe slider or numeric control value is changed
TimerOnTickSendThe selected interval has passed

Values in controls — numeric up/down, text boxes and check boxes, for example — can be sent to the Arduino as part of a serial command. The easiest way to create serial messages containing values from controls is to use the command editor. To open the command editor, click the ellipsis (…) button at the end of a command property.

Include control values in Arduino command messages

Use the command editor to include control values in command messages, or edit long commands. Special characters, such as carriage returns (\r), newlines (\n) and tabs (\t) can be added using escape codes. Click the Test button to see what will be sent when the action occurs.

A button to the right of the command text shows a menu of the available controls, and the value available from each. Making a selection from the menu inserts the appropriate text into the serial command to include the control’s value when the command is sent.

For example, the blinking interval for Blink 2.0 is set using a command like:
!SetInterval 1000\r

This would set the time between blinks to 1000 millisecond (1 second). To have MegunoLink Pro use the value from the Interval control in place of the fixed number, set the command text to:
!SetInterval [Interval.Value]\r

The text [Interval.Value] will be replaced with the value from the Interval numeric control when the command is sent. So you’ll be able to change the blink rate, simply by entering the desired interval into the control and hitting enter.

It is also possible to include simple expressions between the brackets when referring to controls. For example, if seconds were used for the value in the Interval control, instead of milliseconds, an expression could be used to convert from seconds to milliseconds when the message is sent:
!SetInterval [Interval.Value * 1000]\r

MegunoLink Pro uses the DynamicExpresso library to parse expressions. This library supports:

  • addition (+), subtraction (-)
  • multiplication (*), division (/), modulus (%)
  • conditional ({expression} ? {value if true} : {value if false})
  • less than (<=), greater than (>=), less than or equal (<=), greater than or equal (>=)

Completing the Interface

Hit the Apply button when the interface design is ready for testing. This updates the Interface Panel visualizer with the new design. Then, from the MegunoLink Pro visualizer, the blink rate and duration of the LEDs can be set by typing values into the controls. Pressing the buttons will display the set values in the serial monitor.

Try it Yourself

The complete source for the Blink 2.0 program, including the serial command handler and a MegunoLink Pro project with the interface panel all ready to go, is available from GitHub. This uses MegunoLink Pro’s Visual Studio Build Tool however if you want an Arduino IDE compatible version of this program click here.

Download MegunoLink Pro and test the Interface Panel with your own projects.

Please post a comment below and let us know how you get on.

Posted in Articles
12 comments on “How to Quickly Make a User Interface to Control Your Arduino Program
  1. Kaz says:

    Hi, i cant compiled the arduino ide version. im using 1.6.3.

    This what the error looks like:

    CommandParser.h:25: error: ‘prog_char’ does not name a type

    const prog_char *m_strSensor;


    sketchCommandParser.h: In member function ‘bool MLP::CommandParser::AddCommand(const __FlashStringHelper*, void (*)(MLP::CommandParameter&))’:

    CommandParser.h:61: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]

    m_Commands[m_uLastCommand].m_strSensor = (const prog_char*)pCommand;


    CommandParser.h:61: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]

    CommandParser.h:61: error: expected primary-expression before ‘const’

    m_Commands[m_uLastCommand].m_strSensor = (const prog_char*)pCommand;


    CommandParser.h:61: error: expected ‘)’ before ‘const’

    sketchCommandParser.h: In member function ‘void MLP::CommandParser::DispatchMessage()’:

    CommandParser.h:133: error: ‘prog_char’ does not name a type

    const prog_char *pchCommand = pCommand->m_strSensor;


    In file included from C:Usersmtaufiq23DesktopFGK works 2015arduino-nightlyhardwarearduinoavrcoresarduino/Arduino.h:28:0,

    from sketchBlink2.ino.cpp:1:

    CommandParser.h:139: error: ‘pchCommand’ was not declared in this scope

    chCommand = pgm_read_byte_near(pchCommand++);


    In file included from C:Usersmtaufiq23DesktopFGK works 2015C-code for FGK programFGK complete programFGK GUIBlink2Blink2.ino:2:0:

    sketchCommandParser.h: In instantiation of ‘bool MLP::CommandParser::AddCommand(const __FlashStringHelper*, void (*)(MLP::CommandParameter&)) [with int MAX_COMMANDS = 10; int CP_SERIAL_BUFFER_SIZE = 30]’:

    C:Usersmtaufiq23DesktopFGK works 2015C-code for FGK programFGK complete programFGK GUIBlink2Blink2.ino:71:52: required from here

    CommandParser.h:61: error: ‘struct MLP::CommandCallback’ has no member named ‘m_strSensor’

    m_Commands[m_uLastCommand].m_strSensor = (const prog_char*)pCommand;


    exit status 1
    ‘prog_char’ does not name a type

  2. al goddard says:

    Hello. I was wondering, is the top of the window is easily customizable? Above, you have “Interface Panel – Blinker” and “Interface Panel*”. But I’d like to know if I can have my own naming in their. If so, can you refer me instructions on how to do that? Thanks a lot.

    • Phil Rowe says:

      Hi, if you right click on the tab and select rename it will let you change the name, and show the connection and port used.


  3. Elad says:

    thanks a lot!

  4. Elad says:

    MLP realy make your life easier! thanks for that.
    Is there any way to automaticly (or not automaticly) send a time stamp (or just the hour of the day) using the MLP Control Panel?
    without Ethernet shield.

    thanks in advance.

    • Phil Rowe says:

      Hi Elad, I’m glad you have been finding MegunoLink useful. You should be able to set up a timer in the interface panel and get it to send the time every time it ticks. Use the message format [DateTime.Now.ToString(“HH mm ss – dd MM yy”)] which will send 14 08 02 – 03 05 15. You can modify it to just send the hours using “HH”.


  5. Elad says:

    what about code example for the arduino?

  6. Jim Griina says:

    The Blink program actually is a fairly good example of turning on and off a relay. If we change the program from setting blink VALUES to setting blink STATE, we get an on/off capability. Then if we expand that to multiple buttons in MLP to multiple pins on the Arduino, we have 5 buttons that can control 5 digital pins, each attached to the appropriate interface for a relay.

  7. john clark says:

    I wanted an gui because I cant write code but when I make a button it asks for code. I am trying to make a simple control panel to control 5 relays already tested and working in real time from windows desktop on an arduino mege2560 (working through firmata test) what would be really helpful is a list of possible commands to paste into the interface I think I just needed a simple one to make digital pin 4 high but these are not included or referenced so I am back to square 1 thanks

    • Phil Rowe says:

      Hi John, the problem is in the world of microcontroller you can create any kind of message so we needed MegunoLink to be flexible. What do you send using firmata to trigger one of the relays? We should be able to replicate this message whenever a button is pressed.


Leave a Reply