Home > BeagleBone > Console Based UI Development on BeagleBone

Console Based UI Development on BeagleBone

When experimenting with various devices on the BeagleBone I often get to a point with my test programs where streaming output messages (i.e. printf) to a console is no long feasible. What’s really needed at that point is a UI that displays current state information such as the value of a GPIO pin. Depending on which OS the BeagleBone is running there are a variety of graphic user interfaces (GUI) available for use. But GUI’s are never simple and with the BeagleBone you either needs to invested in a display or use X/Windows to display the GUI on another personal computer. Another alternative is to use a console based UI.

The Angstrom release of Linux that ships with the BeagleBone includes the curses and it’s newer incarnation ncurses. If you’re familiar with C programming getting a ncurses application up and running will only take a few minutes. Here is a very simple ncurses program.

poll.c

#include <ncurses.h>

void main() {
initscr();
mvprintw(5, 3, "Hello world!");
getch();
endwin();
}

Compile it with …

gcc poll.c -lncurses -o poll

Executing poll will display “Hello world!” starting at Y, X position 5, 3 on the console and then wait for a key hit before exiting.

The next step is to monitor something. The BeagleBone pulses one of its LED’s like a heart beat. poll has been adapted to monitor if the brightness value is on (255) or off (0) and count the number of times it catches it on.

poll.c

#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>

void monitor(FILE *fp) {
        int run = 1;
        int count = 0;

        nodelay(stdscr, true);
        noecho();

        mvprintw(1, 1, "brightness:");
        mvprintw(2, 1, "     count:");

        while (run) {
                char buffer[16];
                memset(buffer, 0, sizeof(buffer));

                fseek(fp, 0, 0);
                fread(buffer, sizeof(char), sizeof(buffer), fp);

                int value = atoi(buffer);
                if (value != 0) {
                        count++;
                }

                mvprintw(1, 12, "%-3s", (value != 0 ? "on" : "off"));
                mvprintw(2, 12, "%d", count);

                int c = getch();
                switch(c) {
                        case 'q':
                                run = 0;
                                break;
                }
        }
}

void main() {
        char *file = "/sys/class/leds/beaglebone::usr0/brightness";
        FILE *fp;
        if ((fp = fopen(file, "r")) == NULL) {
                fprintf(stderr, "error: cannont open %s\n", file);
        }
        else {
                initscr();
                monitor(fp);
                endwin();

                fclose(fp);
        }
}

The program opens the sys-fs file that will provide the brightness value. After initializing ncurses it goes into a loop that reads the brightness value, increments the count if the LED is on, outputs the data, and checks if the user has hit the quit (‘q’) key.

The call to nodelay() prevents getch() from blocking and noecho() configures ncurses not to echo key hits.

Running poll.

When running poll I noticed that it seems to stagger at times. The application will noticeably pause on occasion. Since the application has to share clock cycles with the other applications it only gets a slice of CPU time. The size of the slice will vary over time and depends on what other things the CPU is being asked to execute. Linux provides the nice command which specifies the application’s priority on the kernel’s run queue. Running poll with a nice of -20 (the maximum) significantly improved its responsiveness.

As a next step I’ve been exploring how to use ncurses to create an application that treats input from a device (i.e. push button) wired to a BeagleBone expansion pin as UI input. For example, pressing a push button would be like pressing a key on the keyboard. More on that in the future.

 

 

Advertisements
Categories: BeagleBone
  1. June 4, 2012 at 11:06 am

    Hi,
    Thanks for this example, it works fine on my fresh installed Ubuntu.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: