Using SerialUI

Warning: deprecated API — update coming soon(ish) for version 3 API.

In the meantime, you can download it from github or the Arduino Library Manager, and check the examples, or just peek into what the drag & drop GUI builder produces.

First off, if you haven’t seen it, check out what you can do with SerialUI and then download it!

Once you have SerialUI installed (see the included INSTALL.txt file), the best thing is to look into the example  included with the code (in examples/SuperBlinker) but here we’ll go over the key points.

The following assumes your are developing for Arduino, adjust as required.

Include

The first thing you need is to include the SerialUI functionality.  Easy enough:

#include <SerialUI.h>

Strings

We are going to need some strings, to let the user know what’s going on.  To avoid taking up a ton of space in RAM, just about every SerialUI string is stored in the flash memory and used directly from there (in progmem).

There’s a little macro that makes declaring these strings easy: SUI_DeclareString(var_name, “string contents”).

Just add as many as you need for your interface.  You’ll want strings for “keys” (the menu item names) and probably for help messages, too.

Let’s say we want a simple menu like:

  • information
  • enable
    • on
    • off

Then we would have this in our code:

// the strings we'll use
SUI_DeclareString(device_greeting, 
 "+++ Welcome to the MyDevice +++\r\nEnter ? for help.");

SUI_DeclareString(top_menu_title, "MyDevice Main Menu");

SUI_DeclareString(info_key,"information");
SUI_DeclareString(info_help, 
                  "Retrieve data and current settings");

SUI_DeclareString(enable_key, "enable");
SUI_DeclareString(enable_help, "Enable/disable device");

SUI_DeclareString(enable_on_key,"on");
SUI_DeclareString(enable_off_key,"off");

Now we have some usable strings for our serial user interface.

SerialUI Instance

Next, we need an actual SerialUI object to play with.  Simply create it, passing in the greeting message as a parameter to set things up easily:

// our global-scope SerialUI object
SUI::SerialUI mySUI = SUI::SerialUI(device_greeting);

Callbacks

We want our UI to me more than pretty menus: we want it to actually do something.  For this, we’ll be associating a callback to every command.  These callbacks are just functions which return “void” and take no parameters.  What they do is up to you.

Here, we’ll have 3 commands: information and enable->on/off.  So we create 3 callbacks:

/* *********** Callbacks ************ */
void show_info()
{
   /* we will output some information.  To send 
      data to the user, always use the SerialUI 
      object (using it in exactly the same way 
      as the normal Arduino Serial):         
   */
   mySUI.print("Hello... ");
   mySUI.println("This is all my info!");
}

void turn_on()
{
   /* here we'd turn the device "on" 
      (whatever that means)
      for now, we just:
   */
   mySUI.println("ON");
}

void turn_off()
{
   // same as above, but for "off"
   mySUI.println("OFF");
}

You can do anything you like in the callbacks, including request and read user input (see showEnterDataPrompt() in the advanced usage page).

Setup

We’ve got our strings and callbacks, time to setup SerialUI and create our menu structure.  If you’re on an Arduino, the setup() function is called automatically at the start of the program.

void setup() 
{

  // Remember: SerialUI acts just like Serial,
  // so we need to
  mySUI.begin(115200); // serial line open/setup

  /* there are other settings available, for 
     input timeouts, EOL char and such--SEE the 
     example code! With the config above, set your
     Serial Monitor to 115200 baud and "Newline"
     line endings.

     Now for the menus (skipping error-checking for
     simplicity's sake, but it's all in the example)

     Get a handle to the top level menu
     Menus are returned as pointers.
  */
  SUI::Menu * mainMenu = mySUI.topLevelMenu();

  // Give the top-level menu a decent name
  mainMenu->setName(top_menu_title);

  /* we add commands using... addCommand()
     passing it the key, callback and 
     optionally help string
  */
  mainMenu->addCommand(info_key, show_info, info_help);

  /* we create sub-menus using... subMenu()
     passing the key and optionally a help string
  */
  SUI::Menu * enableMenu = 
                   mainMenu->subMenu(enable_key, 
                                        enable_help);

  /* now we have our sub-menu. Give it some
     commands, too.
  */
  enableMenu->addCommand(enable_on_key, turn_on);
  enableMenu->addCommand(enable_off_key, turn_off);

  // We are done, yay!
}

Main Loop

The final step is handling serial user requests in the main loop.  This is done by checking for the presence of a user, and calling handleRequests() until they are gone.

For Arduino, the loop function is the aptly-named loop():

void loop()
{
  /* We checkForUser() periodically, to see 
     if anyone is attempting to send us some
     data through the serial port.

     This code checks all the time, for 150 ms, 
     upon entering the loop.  In cases where you
     you would like to check only the first time
     around, use checkForUserOnce(), with a larger
     timeout, e.g.

       mySUI.checkForUserOnce(15000);

  */

  // check for a user
  if (mySUI.checkForUser(150))
  {
    // we have a user initiating contact, show the 
    // greeting message and prompt
    mySUI.enter();

    // keep handling the serial user's 
    // requests until they exit or timeout.
    while (mySUI.userPresent())
    {
      // actually respond to requests, using
      mySUI.handleRequests();
    }

  } // end if we had a user on the serial line

  // below this block, you can do whatever
  // SerialUI-unrelated stuff you need to do.  

}

And that’s it!  SerialUI will now handle connections, navigation and command calls, providing online help as requested.  Building this for the Uno, the program compiles to about 7k (a revised version that builds smaller is in the works).

If you want to avoid the cut&pasting, download this example source and go from there–but, really, you’d be better off looking into the full example (in Examples -> SerialUI -> SuperBlinker, in the Arduino IDE once the library is installed.)

For more information, about the SerialUI API and customized compilation directives, see the SerialUI Advanced Usage page.

All SerialUI pages:

SerialUI Overview
[siblings]

Leave a Reply