Listing 1: The main program creates the window, sets up the user interface, and handles events
#include <gtk/gtk.h> #include <termios.h> #include <fcntl.h> #include "dial.h" #include "numberpad.h" int serialPort = -1; // Handle to serial port float oldValue = -1; // To avoid sending redundant commands void value_changed(GtkAdjustment* adjustment, GtkWidget* label) { unsigned char buffer[16]; int value = (int) adjustment->value; if (oldValue != value) { oldValue = value; sprintf(buffer, "%i degrees", value); gtk_label_set(GTK_LABEL(label), buffer); buffer[0] = 1; // First servo motor has ID# of 1 buffer[1] = 25 + adjustment->value; // offset 25 = 0 degrees write(serialPort, buffer, 2); } } int openSerialPort(unsigned char* portName) { int port; struct termios options; port = open("/dev/ttySA0", O_WRONLY | O_NOCTTY | O_NDELAY); if (port == -1) return -1; tcgetattr(port, &options); cfsetospeed(&options, B2400); tcsetattr(port, TCSANOW, &options); return port; } int main(int argc, char* argv[]) { GtkWidget *window; GtkWidget *label; GtkWidget *alignment; GtkWidget *vbox; GtkWidget *dial, *numberpad; GtkWidget *notebook; GtkAdjustment *adjustment; serialPort = openSerialPort("/dev/ttySA0"); if (serialPort == -1) { printf("Error: Could not open serial port\n"); return -1; // Comment this out to run the prototype on a PC } gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Servo Controller"); gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_exit), NULL); vbox = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show(vbox); adjustment = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 180, 1, 1, 0)); dial = gtk_dial_new(adjustment); numberpad = numberpad_new(adjustment); notebook = gtk_notebook_new(); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dial, gtk_label_new("Analog")); gtk_widget_show(dial); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), numberpad, gtk_label_new("Digital")); gtk_container_set_border_width(GTK_CONTAINER(numberpad), 5); gtk_widget_show(numberpad); gtk_container_add(GTK_CONTAINER(vbox), notebook); gtk_widget_show(notebook); label = gtk_label_new("0 degrees"); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5); gtk_widget_show(label); gtk_signal_connect(GTK_OBJECT(adjustment), "value_changed", GTK_SIGNAL_FUNC(value_changed), label); gtk_widget_show(window); gtk_main(); close(serialPort); return 0; }