diff -Naur linsmith-0.99.28/linsmith.glade linsmith-0.99.28-lg/linsmith.glade
--- linsmith-0.99.28/linsmith.glade	2012-03-16 09:47:09.000000000 -0700
+++ linsmith-0.99.28-lg/linsmith.glade	2014-11-14 11:20:53.477251688 -0800
@@ -11813,14 +11813,14 @@
 				<widget class="GtkComboBoxEntry" id="rem_serial_baud_cbox">
 				  <property name="width_request">110</property>
 				  <property name="visible">True</property>
-				  <property name="items" translatable="yes">1200
+				  <property name="items" translatable="yes">300
+1200
 2400
 4800
 9600
 19200
 38400
 57600
-76800
 115200</property>
 				  <property name="add_tearoffs">False</property>
 				  <property name="has_frame">True</property>

diff -Naur linsmith-0.99.28/src/callbacks.c linsmith-0.99.28-lg/src/callbacks.c
--- linsmith-0.99.28/src/callbacks.c	2012-03-14 15:08:01.000000000 -0700
+++ linsmith-0.99.28-lg/src/callbacks.c	2014-11-14 15:49:52.281532737 -0800
@@ -39,6 +39,9 @@
 #include "load.h"
 #include "misc.h"
 
+static gboolean abort_data_collection = FALSE;
+static gboolean data_collection_needed = FALSE;
+gboolean sched_data_collection( gpointer data );
 
 //=====================================================================
 //	Main menu
@@ -176,6 +179,10 @@
   initialize_MainWindow();
   initialize_elementtable();
   initialize_loadtable();
+
+  // add a 10ms interval check for data collection loop
+  g_timeout_add(10,sched_data_collection,NULL);  
+  
 }
 
 
@@ -609,11 +616,149 @@
   g_signal_emit_by_name(G_OBJECT(w), "clicked", NULL);
 }
 
-
+// get data from a remote VNA type device
+// This implementation uses the N2PK VNA as built by
+// Lawrence Glaister VE7IT  http://members.shaw.ca/swstuff/vna.html
+// the protocol is very simple. The frequency in ascii hz terminated by a return
+// is sent to the VNA, the VNA then sends back and ascii line with 3 numbers...
+// the frequency, the load resistive value and the load reactive component in ohms.
+// send: 3500000\r
+// recv: 3500000 53.25 -114.7\r
+// there are 2 uses for this automated data collection.
+// 1. continuous looping of the data collection where one may be adjusting an
+//    external circuit (like an antenna tuner) and want to see how the spread 
+//    of loads displays on the smith chart
+// 2. a one shot collection of data where one is going to use the circuits page
+//    to design a matching network for a range of frequencies. This mode is only
+//    supported by carefull timing of clicking on the cancel button.
 void
 on_load_getrem_btn_clicked             (GtkButton       *button,
                                         gpointer         user_data)
 {
+  GtkWidget *startf_widg, *endf_widg, *incrf_widg, *getrem_widg, *cancel_widg;
+//  GtkWidget *progbar_widg;
+  double start,fin,step,freq;
+  load_definition	active_load;
+  char cmd[80];
+  char resp[80];
+  int rc;
+  float r,x;
+  int hz;
+  int i;
+
+
+  fprintf(stderr,"Get remote clicked\n");
+  // start remote data collection based on user input
+  // request impedances for every freq from start to end by step
+  startf_widg = lookup_widget(MainWindow, "entry4");
+  endf_widg =   lookup_widget(MainWindow, "entry5");
+  incrf_widg =  lookup_widget(MainWindow, "entry6");
+  cancel_widg =   lookup_widget(MainWindow, "rem_cancel_btn");
+  getrem_widg =   lookup_widget(MainWindow, "load_getrem_btn");
+  
+//  progbar_widg= lookup_widget(MainWindow, "remoteprogressbar");
+  loadlist_clear();
+
+//  gtk_progress_bar_set_fraction((GtkProgressBar *)progbar_widg,0.0);
+//  gtk_progress_bar_set_text((GtkProgressBar *)progbar_widg,"");
+
+  // if serial port wont open then there is nothing to be done
+  if ( !open_serial() )
+  {
+    ok_dialog(_("Remote"), _("Opps..Unable to open serial port.\n"));
+    return; 
+  }
+
+
+  // wake up remote with a cr, discard reply
+  cmd[0] = '\r'; cmd[1] = '\0';
+  remote_send_command(cmd);
+  if (!remote_receive_reply(resp,sizeof(resp)))
+  {
+    ok_dialog(_("Remote"), _("Opps.. remote serial device did not respond.\n"
+                             "Unable to collect measurement data."));
+    close_serial();
+    return;
+  }
+
+  gtk_button_set_label((GtkButton *)getrem_widg,"Remote Active");
+  gtk_widget_set_sensitive (cancel_widg,   TRUE);       // allow cancel transfer
+  gtk_widget_set_sensitive (getrem_widg,   FALSE);
+  
+  abort_data_collection = FALSE;
+
+  start = atof(gtk_entry_get_text((GtkEntry *)startf_widg));
+  fin =   atof(gtk_entry_get_text((GtkEntry *)endf_widg)  );
+  step =  atof(gtk_entry_get_text((GtkEntry *)incrf_widg) );
+  fprintf(stderr,"scanning %f to %f by step %f\n",start,fin,step);
+  
+  if ( start > 0.0 && start <= fin && step > 0.0 )
+  {
+    // request impedance at all the freqs described by user
+    for ( freq = start; freq <= fin; freq += step )
+    {
+      if ( abort_data_collection ) break;   // covers case of a many data point collection
+      // send request
+      snprintf(cmd, sizeof(cmd),"%d\n",(int)(freq*1e6));
+      remote_send_command(cmd);
+//      if (( fin - start ) > 0.0)
+//        gtk_progress_bar_set_fraction((GtkProgressBar *)progbar_widg,(freq-start)/(fin-start));
+//      snprintf(cmd, sizeof(cmd),"%f",freq); 
+//      gtk_progress_bar_set_text((GtkProgressBar *)progbar_widg,cmd);
+
+      // to keep gui responsive, respond to other actions if there are any
+      while ( g_main_context_iteration(g_main_context_default(),FALSE) );
+
+      // post response into the load treeview (see load.c)
+      active_load.f = freq;     // default freq in mhz as per loop
+      if (remote_receive_reply(resp,sizeof(resp)))
+      {
+        rc = sscanf(resp," %d %f %f",&hz,&r,&x);
+        if ( rc == 3 )
+        {
+          active_load.f = hz / 1e6;
+          active_load.r = r;
+          active_load.x = x;
+          load_append(&active_load);
+        }
+      }
+    }
+  }
+  else
+  {
+    ok_dialog(_("Remote"), _("Opps.. Please enter reasonable data\n"
+              "for start, end and step frequencies.\n"));
+    // unclick collection mode so user can fix problem
+//    gtk_toggle_button_set_active((GtkToggleButton*)getrem_widg,FALSE);
+    gtk_button_set_label((GtkButton *)getrem_widg,"Update from remote");
+    gtk_widget_set_sensitive (cancel_widg,   FALSE);       // allow cancel transfer
+    gtk_widget_set_sensitive (getrem_widg,   TRUE);
+  }
+
+  close_serial();
+  // loop here for a fixed delay to give the user a chance to click the cancel button
+  // in case he wants a one shot data collection.
+  for ( i=0; i<75; i++ )
+  {
+    // to keep gui responsive, respond to other actions if there are any
+    while ( g_main_context_iteration(g_main_context_default(),FALSE) );  
+    usleep(10000);
+  }
+  
+//  gtk_widget_set_sensitive (getrem_widg,   TRUE);
+
+//  gtk_progress_bar_set_fraction((GtkProgressBar *)progbar_widg,0.0);
+//  gtk_progress_bar_set_text((GtkProgressBar *)progbar_widg,"");
+
+
+  // let idle process know we would like to repeat data collection
+  // posting "clicked" from here did NOT work... it appeared to
+  // recursively call us instead of posting a request for us to run again.
+  // using a toggle button or checkbox here probably makes more sense,
+  // but we can key off the label to enable repeated data collection
+  if (strcmp(gtk_button_get_label((GtkButton *)getrem_widg), "Remote Active") == 0)
+    data_collection_needed = TRUE;  
+
 }
 
 //================== Test only ===================================
@@ -643,7 +788,18 @@
 on_rem_cancel_btn_clicked              (GtkButton       *button,
                                         gpointer         user_data)
 {
-
+  // terminate remote data collection
+  GtkWidget *getrem_widg, *cancel_widg;
+  fprintf(stderr,"remote data collection cancelled\n");
+  getrem_widg   = lookup_widget(MainWindow, "load_getrem_btn");
+  cancel_widg =   lookup_widget(MainWindow, "rem_cancel_btn");
+  abort_data_collection = TRUE;
+
+  // unclick collection mode
+//  gtk_toggle_button_set_active((GtkToggleButton*)getrem_widg,FALSE);
+  gtk_button_set_label((GtkButton*)getrem_widg,"Update from remote");
+  gtk_widget_set_sensitive (getrem_widg,   TRUE);
+  gtk_widget_set_sensitive (cancel_widg,   FALSE);
 }
 
 //
@@ -747,3 +903,21 @@
 
 }
 
+
+// a function called from the main idle loop
+// used to implement the continous data collection mode
+// from the remote device.
+gboolean
+sched_data_collection( gpointer data )
+{
+  GtkWidget *load_getrem_btn_widg; 
+ 
+  if ( data_collection_needed )
+  {
+    data_collection_needed = FALSE;
+    load_getrem_btn_widg= lookup_widget(MainWindow, "load_getrem_btn");
+    g_signal_emit_by_name(G_OBJECT(load_getrem_btn_widg), "clicked", NULL);
+  }
+  return TRUE;    // make sure we get rescheduled
+}
+

diff -Naur linsmith-0.99.28/src/global.c linsmith-0.99.28-lg/src/global.c
--- linsmith-0.99.28/src/global.c	2013-01-08 20:06:48.000000000 -0800
+++ linsmith-0.99.28-lg/src/global.c	2014-11-13 17:23:06.823025620 -0800
@@ -275,6 +275,22 @@
   {CFM_W_ENTRY_INT,	"confrem_timeout_entry",	&pref.rem_timeout,	0,
    CFM_T_INT,		"remote/timeout",		0,	"2000"},
 
+   // Remote serial tab: control parameters
+  {CFM_W_ENTRY_STR,	"rem_serial_port_entry",   &pref.rem_ser_port, 0,
+   CFM_T_STR,		"remote/ser_port",	     0, "/dev/ttyS0"},
+  {CFM_W_CBOX,		"rem_serial_baud_cbox",    &pref.rem_ser_baud, 0,
+   CFM_T_INT,		"remote/ser_baud",               0, "3"},
+  {CFM_W_CBOX,		"rem_serial_stops_cbox",   &pref.rem_ser_stop, 0,
+   CFM_T_INT,		"remote/ser_stop",               0, "0"},
+  {CFM_W_CBOX,		"rem_serial_data_cbox",    &pref.rem_ser_data, 0,
+   CFM_T_INT,		"remote/ser_data",               0, "0"},
+  {CFM_W_CBOX,		"rem_serial_pority_cbox",  &pref.rem_ser_parity, 0,
+   CFM_T_INT,		"remote/ser_parity",               0, "0"},
+  {CFM_W_ENTRY_INT,	"rem_serial_timeout_entry",&pref.rem_ser_timeout, 0,
+   CFM_T_INT,		"remote/ser_timeout",	     0, "2000"},
+//  {CFM_W_ENTRY_INT,	"rem_serial_tx_timer_entry",  &pref.rem_ser_tx_timer, 0,
+//   CFM_T_INT,		"remote/ser_tx_timer",	     0, "10"},  
+
   // Noisebridge tab:
   {CFM_W_ENTRY_DOUBLE,  "conf_nb_offs_entry",           &pref.nb_offset,        2,
    CFM_T_DOUBLE,        "noisebr/offset",               0,      "110.0"},
diff -Naur linsmith-0.99.28/src/global.h linsmith-0.99.28-lg/src/global.h
--- linsmith-0.99.28/src/global.h	2012-12-02 21:08:12.000000000 -0800
+++ linsmith-0.99.28-lg/src/global.h	2014-11-13 16:59:53.703001360 -0800
@@ -115,11 +115,18 @@
          prt_g1_size;
 
   // Remote control parameters
-  char   rem_outpipe[120],
-	 rem_inpipe[120],
-  	 rem_mode;
-  int	 rem_timeout;
-
+  char  rem_outpipe[120],
+	    rem_inpipe[120],
+  	    rem_mode;
+  int	rem_timeout;
+  char  rem_ser_port[80];
+  int   rem_ser_baud,
+        rem_ser_stop,
+        rem_ser_data,
+        rem_ser_parity,
+        rem_ser_tx_timer,
+        rem_ser_timeout;
+       
   // CSV parameters
   char	 csv_sep[2];
   
diff -Naur linsmith-0.99.28/src/interface.c linsmith-0.99.28-lg/src/interface.c
--- linsmith-0.99.28/src/interface.c	2012-03-16 09:47:09.000000000 -0700
+++ linsmith-0.99.28-lg/src/interface.c	2014-11-14 11:30:13.581261442 -0800
@@ -4541,6 +4541,7 @@
                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                     (GtkAttachOptions) (GTK_FILL), 0, 0);
   gtk_widget_set_size_request (rem_serial_baud_cbox, 110, -1);
+  gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("300"));  
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("1200"));
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("2400"));
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("4800"));
@@ -4548,7 +4549,6 @@
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("19200"));
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("38400"));
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("57600"));
-  gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("76800"));
   gtk_combo_box_append_text (GTK_COMBO_BOX (rem_serial_baud_cbox), _("115200"));
 
   label494 = gtk_label_new (_("Data bits:"));

diff -Naur linsmith-0.99.28/src/remote.c linsmith-0.99.28-lg/src/remote.c
--- linsmith-0.99.28/src/remote.c	2007-11-11 19:09:03.000000000 -0800
+++ linsmith-0.99.28-lg/src/remote.c	2014-11-14 15:03:52.961484685 -0800
@@ -1,12 +1,19 @@
+/* this file updated Nov 13 2014 by L. Glaister to support remote serial ops */
+
 #include <gtk/gtk.h>
 #include <fcntl.h>
-
+#include <termios.h>
+#include <unistd.h>		// for isatty()
 #include "support.h"
 #include "main.h"
 #include "global.h"
 #include "misc.h"
 #include "remote.h"
 
+
+static int fd;      // local file descripter for serial port
+
+
 int
 fifos_created(void)
 {
@@ -65,20 +72,64 @@
   return;
 }
 
-
 void
 remote_send_command(char *cmd)
 {
-}
+  int rc;
+  
+  if ( fd == 0 )
+    return;
 
+//  fprintf(stderr,"remote_send_command(%s), %d chars \n",cmd, strlen(cmd));
+  while (*cmd)
+  {
+    rc = write( fd, cmd++, 1);
+    // pace writes to serial port for slow external controllers
+    usleep(5000);      // 5ms -- this could be programmable
+  }
+}
 
+// get a measurement string from the remote device
+// return TRUE if a measurement was received, FALSE is comms
+// timed out
 int
-remote_receive_reply(char *reply)
+remote_receive_reply(char *reply, int maxsize)
 {
-  return FALSE;
+  int count = 0;
+  int result;
+  char c;
+  
+  if( maxsize < 2)
+  {
+    // bad call, need at least 2 bytes for null terminated return string
+    fprintf(stderr,"remote_receive_reply(): invalid string size passed in\n");
+      return FALSE;
+  }
+  
+  reply[0] = '\0';
+  while( count < (maxsize-1) )
+  {
+	result = read( fd, &c, 1);
+	if ( result == 0 )
+    {
+      // serial port timed out
+      fprintf(stderr,"serial port time out after %d bytes\n",count);
+      return FALSE;
+    }
+    // skip leading non numerics
+    if ( count == 0 && (c < '0' || c > '9') ) continue;
+
+    // expect cr lf as terminator on serial port data
+    if ( c == '\r' ) continue;
+    if ( c == '\n' ) break;
+    reply[count++] = c;
+    reply[count] = '\0';
+  }
+  return TRUE;
 }
 
 
+
 void
 set_remote_enabled(GtkWidget *ref, int state)
 {
@@ -90,3 +141,130 @@
 //  gtk_widget_set_sensitive(w, state);
   g_object_set(G_OBJECT(w), "visible", state, NULL);
 }
+
+// open the serial port to communicate with the remote VNA
+// return TRUE if all ok and FALSE if there is a problem
+int
+open_serial( void )
+{
+  struct termios oldtio,newtio;
+//  data in pref.xxx relating to serial port setup
+//  char rem_ser_port[80];
+//  int  rem_ser_baud,  rem_serial_baud_cbox [300 1200 2400 4800 9600 19200 38400 57600 115200]
+//       rem_ser_stop,  rem_serial_stops_cbox [1 2]
+//       rem_ser_data,  rem_serial_data_cbox [8,7]
+//       rem_ser_parity, rem_serial_parity_cbox [None Even Odd]
+//       rem_ser_timeout;  rem_serial_timeout_entry (ms)
+//       rem_ser_tx_timer  rem_serial_tx_timer_entry (ms)
+  fprintf(stderr,"attempting to open %s serial port for remote control...\n",pref.rem_ser_port);
+  
+  if ( (fd = open(pref.rem_ser_port, O_RDWR|O_NOCTTY)) < 0 )
+  {
+    perror("open serial");
+    return FALSE;
+    // if you get a permission error, you probably need to add yourself to
+    // the dialout group then log out and in again. see menu/Administration/users and groups.
+    // /dev/ttyS0 is probably owned by root:dialout
+  }
+//  fprintf(stderr,"serial port opened...OK\n");
+
+  // device is not a terminal;
+  if( !isatty(fd) )
+  {
+    fprintf(stderr,"port specified is not a terminal\n");
+    close(fd);
+    return( FALSE );
+  }
+  
+//  fprintf(stderr,"serial port is a terminal...OK\n");
+    
+  tcgetattr(fd,&oldtio);          /* save current serial port settings */
+  bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
+
+  // WARNING.... these indexes must match up with the indexes for the values
+  // programmed in glade. I dont believe there is an easy way to convert
+  // from the pref.xxx index to what the bits are we need.
+  // BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
+//  fprintf(stderr,"setting baud index=%d ...OK\n",pref.rem_ser_baud);
+  switch ( pref.rem_ser_baud )
+  {
+  case 0: newtio.c_cflag |= B300;
+    break;  
+  case 1: newtio.c_cflag |= B1200;
+    break;
+  case 2: newtio.c_cflag |= B2400; 
+    break;
+  case 3: newtio.c_cflag |= B4800;
+    break;
+  case 4: newtio.c_cflag |= B9600;
+    break;
+  case 5: newtio.c_cflag |= B19200;
+    break;
+  case 6: newtio.c_cflag |= B38400;
+    break;
+  case 7: newtio.c_cflag |= B57600;
+    break;
+  case 8: newtio.c_cflag |= B115200;
+    break;
+
+  default: newtio.c_cflag |= B9600;
+    fprintf(stderr,"Opps... baud rate index out of range.. defaulting to 9600baud\n");
+  }
+
+  // set the number of data bits
+  switch ( pref.rem_ser_data )
+  {
+  case 0: newtio.c_cflag |= CS8;
+    break;
+  case 1: newtio.c_cflag |= CS7; 
+    break;
+  default: newtio.c_cflag |= CS8;
+    fprintf(stderr,"Opps... data bit index out of range.. defaulting to 8 bits\n");
+  }
+
+  // set number of stop bits, normally 1 (index 0)
+  if ( pref.rem_ser_stop == 1 ) newtio.c_cflag |= CSTOPB;
+
+  // set preference for parity.. if odd or even, then turn on parity bit
+  if ( pref.rem_ser_parity == 1 || pref.rem_ser_parity == 2)
+  {
+    newtio.c_cflag |= PARENB;
+    if (pref.rem_ser_parity == 2) newtio.c_cflag |= PARODD;
+  }
+  // add a couple more config bits to make port work
+  // CLOCAL  : local connection, no modem control
+  // CREAD   : enable receiving characters
+  newtio.c_cflag |= (CLOCAL | CREAD);
+
+  // IGNPAR  : ignore bytes with parity errors
+  // ICRNL   : map CR to NL (otherwise a CR input on the other computer
+  //           will not terminate input)
+  //          otherwise make device raw (no other input processing)
+  newtio.c_iflag = IGNPAR;
+
+  // Raw output.
+  newtio.c_oflag = 0;
+
+  // ICANON  : to enable canonical input
+  // disable all echo functionality, and don't send signals to calling program
+  newtio.c_lflag = 0;
+  newtio.c_cc[VTIME]    = pref.rem_ser_timeout/100;  /* inter-character timer  sec = time *0.1 sec */
+  newtio.c_cc[VMIN]     = 0;     /* blocking read until 1 character arrives */	
+
+  // now clean the modem line and activate the settings for the port
+  tcflush(fd, TCIFLUSH);
+  tcsetattr(fd,TCSANOW,&newtio);
+
+  // use code below if they need to be restored (old port settings)
+  // tcsetattr(fd,TCSANOW,&oldtio);
+  fprintf(stderr,"serial port configured...OK\n");
+  return TRUE;
+}
+
+// close the serial port and release resources
+void 
+close_serial( void )
+{
+  close(fd);
+}
+
diff -Naur linsmith-0.99.28/src/remote.h linsmith-0.99.28-lg/src/remote.h
--- linsmith-0.99.28/src/remote.h	2006-04-10 22:51:41.000000000 -0700
+++ linsmith-0.99.28-lg/src/remote.h	2014-11-13 16:46:32.890987414 -0800
@@ -2,5 +2,5 @@
 
 void	remote_create_fifos(void);
 void	remote_send_command(char *cmd);
-int	remote_receive_reply(char *reply);
+int	    remote_receive_reply(char *reply, int maxsize);
 void	set_remote_enabled(GtkWidget *ref, int state);


