gclib 2.0.10
Galil Communications Library
All Classes Files Functions Variables Typedefs Macros Modules Pages
Examples

Controller Addresses

A core feature of gclib is the ability to connect to a controller over ethernet, serial, or PCI, using a single connection API.

  • Use GAddresses() to see the different addresses that are available.

    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      char addresses[G_SMALL_BUFFER];
      printf("%s", addresses);
      }
      #define G_SMALL_BUFFER
      Most reads from Galil are small. This value will easily hold most, e.g. TH, TZ, etc.
      Definition gclib.h:103
      GCLIB_DLL_EXPORTED GReturn GCALL GAddresses(GCStringOut addresses, GSize addresses_len)
      Uses GUtility(), G_UTIL_GCAPS_ADDRESSES or G_UTIL_ADDRESSES to provide a listing of all available con...
    • > .\addresses.exe
      192.168.0.40, DMC4040 Rev 1.3i, 192.168.0.1, Ethernet
      GALILPCI1
      COM5

    If using an ethernet controller that doesn't have an IP address yet, it will show up in GIpRequests(). Use GAssign() to give the controller an IP. If successful, the controller will begin showing up in GAddresses() under the new address.

    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      char result[G_SMALL_BUFFER];
      printf("%s\n", result);
      GAssign("192.168.0.40", "00:50:4C:20:29:69");
      }
      GCLIB_DLL_EXPORTED GReturn GCALL GIpRequests(GCStringOut requests, GSize requests_len)
      Uses GUtility(), G_UTIL_GCAPS_IPREQUEST or G_UTIL_IPREQUEST to provide a list of all Galil controller...
      GCLIB_DLL_EXPORTED GReturn GCALL GAssign(GCStringIn ip, GCStringIn mac)
      Uses GUtility(), G_UTIL_GCAPS_ASSIGN or G_UTIL_ASSIGN to assign an IP address over the Ethernet to a ...
    • > .\ip-requests.exe
      DMC4000, 10601, 00:50:4C:20:29:69, Ethernet, 192.168.0.1, 0.0.0.0
  • Use gclib.py.GAddresses() to see the different addresses that are available.

    >>> import gclib
    >>> gclib.py().GAddresses()
    {'192.168.0.40': ' DMC4040 Rev 1.3i', 'GALILPCI1': '', 'COM5': ''}

    If using an ethernet controller that doesn't have an IP address yet, it will show up in gclib.py.GIpRequests(). Use gclib.py.GAssign() to give the controller an IP. If successful, the controller will begin showing up in gclib.py.GAddresses() under the new address.

    >>> gclib.py().GIpRequests()
    {'DMC4000-10601': '00:50:4C:20:29:69'}
    >>> gclib.py().GAssign('192.168.0.40', '00:50:4C:20:29:69')
  • Use gclibjava.GclibJava.GAddresses() to see the different addresses that are available.

    • import gclibjava.*;
      public class Addresses {
      public static void main(String[] args) throws GclibJavaException {
      System.out.println(String.format(new GclibJava().GAddresses()));
      }
      }
    • > java Addresses
      192.168.0.40, DMC4040 Rev 1.3i, 192.168.0.1, Ethernet
      GALILPCI1
      COM5

    If using an ethernet controller that doesn't have an IP address yet, it will show up in gclibjava.GclibJava.GIpRequests(). Use gclibjava.GclibJava.GAssign() to give the controller an IP. If successful, the controller will begin showing up in gclibjava.GclibJava.GAddresses() under the new address.

    • import gclibjava.*;
      public class IpRequests {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava gclib = new GclibJava();
      System.out.println(gclib.GIpRequests());
      gclib.GAssign("192.168.0.40", "00:50:4C:20:29:69");
      }
      }
      Provides a class that binds to gclib's unmanaged dll.
      Definition gclib.cs:59
      string[] GIpRequests()
      Provides a list of all Galil controllers requesting IP addresses via BOOT-P or DHCP.
      Definition gclib.cs:377
      void GAssign(string ip, string mac)
      Assigns IP address over the Ethernet to a controller at a given MAC address.
      Definition gclib.cs:206
    • > java IpRequests
      DMC4000, 10601, 00:50:4C:20:29:69, Ethernet, 192.168.0.1, 0.0.0.0
  • Use gclib.GAddresses() to see the different addresses that are available.

    • string[] addresses = new gclib().GAddresses();
      System.Console.WriteLine(string.Join("\n", addresses));
      string[] GAddresses()
      Return a string array of available connection addresses.
      Definition gclib.cs:79
    • > dotnet run --project Addresses
      192.168.0.40, DMC4040 Rev 1.3i, 192.168.0.1, Ethernet
      GALILPCI1
      COM5

    If using an ethernet controller that doesn't have an IP address yet, it will show up in gclib.GIpRequests(). Use gclib.GAssign() to give the controller an IP. If successful, the controller will begin showing up in gclib.GAddresses() under the new address.

    • gclib connection = new gclib();
      string[] ipRequests = connection.GIpRequests();
      System.Console.WriteLine(string.Join("\n", ipRequests));
      connection.GAssign("192.168.0.40", "00:50:4C:20:29:69");
    • > dotnet run --project IpRequests
      DMC4000, 10601, 00:50:4C:20:29:69, Ethernet, 192.168.0.1, 0.0.0.0
  • Use Gclib.GAddresses() to see the different addresses that are available.

    • Module Program
      Sub Main(args As string())
      System.Console.WriteLine(string.Join(Environment.NewLine, new Gclib().GAddresses()))
      End Sub
      End Module
    • > dotnet run --project Addresses
      192.168.0.40, DMC4040 Rev 1.3i, 192.168.0.1, Ethernet
      GALILPCI1
      COM5

    If using an ethernet controller that doesn't have an IP address yet, it will show up in Gclib.GIpRequests(). Use Gclib.GAssign() to give the controller an IP. If successful, the controller will begin showing up in Gclib.GAddresses() under the new address.

    • Module Program
      Sub Main(args As String())
      Dim Gclib As new Gclib()
      System.Console.WriteLine(string.Join(Environment.NewLine, Gclib.GIpRequests()))
      Gclib.GAssign("192.168.0.40", "00:50:4C:20:29:69")
      End Sub
      End Module
    • > dotnet run IpRequests
      DMC4000, 10601, 00:50:4C:20:29:69, Ethernet, 192.168.0.1, 0.0.0.0
  • Use G Addresses to see the different addresses that are available.

    Addresses.vi
    •  
    •  

    If using an ethernet controller that doesn't have an IP address yet, it will show up in G Ip Requests. Use G Assign to give the controller an IP. If successful, the controller will begin showing up in G Addresses under the new address.

    IP Requests.vi
    •  
    •  

Connection Management

  • To use a controller with gclib, first pass the address to GOpen() to receive a handle to the connection. This handle will be used in future library calls such as GInfo(), which we use to display some information about the open connection. After you are done, close the connection with GClose().

    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      GCon g = 0;
      char info[G_SMALL_BUFFER];
      GOpen(argv[1], &g);
      GInfo(g, info, G_SMALL_BUFFER);
      printf("%s\n", info);
      GClose(g);
      }
      void * GCon
      Connection handle. Unique for each connection in process. Assigned a non-zero value in GOpen().
      Definition gclib.h:108
      GCLIB_DLL_EXPORTED GReturn GCALL GInfo(GCon g, GCStringOut info, GSize info_len)
      Uses GUtility() and G_UTIL_INFO to provide a useful connection string.
      GCLIB_DLL_EXPORTED GReturn GCALL GClose(GCon g)
      Closes a connection to a Galil Controller.
      GCLIB_DLL_EXPORTED GReturn GCALL GOpen(GCStringIn address, GCon *g)
      Open a connection to a Galil Controller.
    • > .\connection.exe 192.168.0.40
      192.168.0.40, DMC4040 Rev 1.3i, 10601
      
    Attention
    If the program exits before calling GClose(), the controller may be left in an inconsistent state.
  • To use a controller with gclib, first create a gclib.py() object, then pass an address to gclib.py.GOpen().
    >>> connection = gclib.py()
    >>> connection.GOpen('192.168.0.40')
    Now we can use gclib.py.GInfo() to show basic info about the open connection.
    >>> connection.GInfo()
    192.168.0.40, DMC4040 Rev 1.3i, 10601
    After you are done with the connection, close it with gclib.py.GClose().
    >>> connection.GClose()
    Attention
    If the program exits before calling gclib.py.GClose(), the controller may be left in an inconsistent state.
  • To use a controller with gclib, first create a gclibjava.GclibJava() object, then pass an address to gclibjava.GclibJava.GOpen(). After you are done, close the connection with gclibjava.GclibJava.GClose().

    • import gclibjava.*;
      public class Connection {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[1]);
      System.out.println(connection.GInfo());
      connection.GClose();
      }
      }
    • > java Connection 192.168.0.40
      192.168.0.40, DMC4040 Rev 1.3i, 10601
      
    Attention
    If the program exits before calling GClose(), the controller may be left in an inconsistent state.
  • To use a controller with gclib, first create a gclib() object, then pass an address to gclib.GOpen(). After you are done, close the connection with gclib.GClose().

    • gclib connection = new gclib();
      connection.GOpen(args[0]);
      System.Console.WriteLine(connection.GInfo());
      connection.GClose();
      string GInfo()
      Provides a useful connection string.
      Definition gclib.cs:333
      void GClose()
      Used to close a connection to Galil hardware.
      Definition gclib.cs:222
      void GOpen(string address)
      Used to open a connection to Galil hardware.
      Definition gclib.cs:439
    • > dotnet run --project Connection 192.168.0.40
      192.168.0.40, DMC4040 Rev 1.3i, 10601
    Attention
    If the program exits before calling gclib.GClose(), the controller may be left in an inconsistent state.
  • To use a controller with gclib, first create a Gclib() object, then pass an address to Gclib.GOpen(). After you are done, close the connection with Gclib.GClose().

    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      connection.GOpen(args(0))
      System.Console.WriteLine(connection.GInfo())
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Connection 192.168.0.40
      192.168.0.40, DMC4040 Rev 1.3i, 10601
    Attention
    If the program exits before calling Gclib.GClose(), the controller may be left in an inconsistent state.
  • To use a controller with gclib, first pass the address to G Open to receive a handle to the connection. This handle will be used in future library calls such as G Info, which we use to display some information about the open connection. After you are done, close the connection with G Close.

    Connection.vi


    Attention
    If the program exits before calling G Close, the controller may be left in an inconsistent state.

Commands

  • To issue commands, use GCommand() with an open connection. The following example uses GCommand() to implement a basic terminal.

    • #include <gclibo.h>
      #include <stdio.h>
      #include <string.h>
      int main(int argc, char* argv[]) {
      GCon g = NULL;
      char command[G_SMALL_BUFFER];
      char response[G_SMALL_BUFFER];
      GOpen(argv[1], &g);
      GInfo(g, response, G_SMALL_BUFFER);
      printf("Connected to %s\n", response);
      printf("Use Ctrl+C to exit.\n:");
      while (1) {
      fgets(command, sizeof(command), stdin);
      GCommand(g, command, response, G_SMALL_BUFFER, NULL);
      printf("%s", response);
      }
      GClose(g);
      }
      GCLIB_DLL_EXPORTED GReturn GCALL GCommand(GCon g, GCStringIn command, GBufOut buffer, GSize buffer_len, GSize *bytes_returned)
      Performs a command-and-response transaction on the connection.
    • > .\commands.exe 192.168.0.40
      Connected to 192.168.0.40, DMC4040 Rev 1.3i, 10601
      Use Ctrl+C to exit.
      :MG "Hello World"
      Hello World
      :^C
  • To issue commands, use GCommand() with an open connection.
    >>> connection.GOpen('192.168.0.40')
    >>> connection.GCommand('Hello World')
    'Hello World'
  • To issue commands, use gclibjava.GclibJava.GCommand() with an open connection. The following example uses gclibjava.GclibJava.GCommand() to implement a basic terminal.

    • import gclibjava.*;
      import java.util.NoSuchElementException;
      import java.util.Scanner;
      public class Commands {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[0]);
      System.out.println(connection.GInfo());
      System.out.print(":");
      Scanner scanner = new Scanner(System.in);
      try {
      while (true) {
      String result = connection.GCommand(scanner.nextLine());
      System.out.print(result.equals(":") ? result : result + "\r\n:");
      }
      } catch (NoSuchElementException e) {}
      scanner.close();
      connection.GClose();
      }
      }
    • > java Commands 192.168.0.40
      Connected to 192.168.0.40, DMC4040 Rev 1.3i, 10601
      Use Ctrl+C to exit.
      :MG "Hello World"
      Hello World
      :^C
  • To issue commands, use gclib.GCommand() with an open connection. The following example uses gclib.GCommand() to implement a basic terminal.

    • gclib connection = new gclib();
      connection.GOpen(args[0]);
      System.Console.WriteLine(connection.GInfo());
      System.Console.Write(':');
      while (true) {
      string result = connection.GCommand(System.Console.ReadLine());
      System.Console.Write(result.Length == 0 ? ":" : result + "\r\n:");
      }
      connection.GClose();
      string GCommand(string Command, bool Trim=true)
      Used for command-and-response transactions.
      Definition gclib.cs:241
    • > dotnet run --project Commands 192.168.0.40
      Connected to 192.168.0.40, DMC4040 Rev 1.3i, 10601
      Use Ctrl+C to exit.
      :MG "Hello World"
      Hello World
      :^C
  • To issue commands, use Gclib.GCommand() with an open connection. The following example uses Gclib.GCommand() to implement a basic terminal.

    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      connection.GOpen(args(0))
      System.Console.WriteLine(connection.GInfo())
      System.Console.Write(":")
      While (true)
      Dim result As String = connection.GCommand(System.Console.ReadLine())
      System.Console.Write(If(result.Length = 0, ":", result + Environment.NewLine + ":"))
      End While
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Commands 192.168.0.40
      Connected to 192.168.0.40, DMC4040 Rev 1.3i, 10601
      Use Ctrl+C to exit.
      :MG "Hello World"
      Hello World
      :^C
  • To issue commands, use G Command with an open connection.

    Commands.vi


Errors

  • All gclib functions provide a GReturn value to indicate the error, with G_NO_ERROR (0) indicating that the function was successful. Pass a GReturn value to GError() to get a string description of the error. See gclib_errors.h for a full list of error codes.
    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      GCon g = NULL;
      char buf[G_SMALL_BUFFER];
      GOpen(argv[1], &g);
      GReturn ret = GCommand(g, "invalid", NULL, 0, NULL);
      GError(ret, buf, G_SMALL_BUFFER);
      printf("Command \"invalid\" returned %i: \"%s\"\n", ret, buf);
      GClose(g);
      }
      int GReturn
      Every function returns a value of type GReturn. See gclib_errors.h for possible values.
      Definition gclib.h:107
      GCLIB_DLL_EXPORTED void GCALL GError(GReturn rc, GCStringOut error, GSize error_len)
      Provides a human-readable description string for return codes.
    • > .\errors.exe 192.168.0.40
      Command "invalid" returned -10000: "question mark returned by controller"
  • If a gclib call is unsuccessful, a gclib.GclibError will be thrown with a description of the error.
    >>> connection.GCommand('invalid')
    Traceback (most recent call last):
    ...
    gclib.GclibError: question mark returned by controller
  • If a gclib call is unsuccessful, a gclibjava.GclibJavaException() will be thrown with the error code and description.
    • import gclibjava.*;
      public class Errors {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[1]);
      try {
      connection.GCommand("invalid");
      } catch (GclibJavaException e) {
      System.out.println(String.format("Command 'invalid' returned %d: %s", e.getErrorCode(), e.getMessage()));
      }
      connection.GClose();
      }
      }
    • > java Errors 192.168.0.40
      Command "invalid" returned -10000: "question mark returned by controller"
  • If a gclib call is unsuccessful, an exception will be thrown with the error code and description.
    • gclib connection = new gclib();
      connection.GOpen(args[0]);
      try {
      System.Console.WriteLine(connection.GCommand("invalid"));
      } catch (System.Exception e) {
      System.Console.WriteLine("Command 'invalid' returned " + e.Message);
      }
      connection.GClose();
    • > dotnet run --project Errors 192.168.0.40
      Command "invalid" returned -10000: "question mark returned by controller"
  • If a gclib call is unsuccessful, an exception will be thrown with the error code and description.
    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      connection.GOpen(args(0))
      Try
      connection.GCommand("invalid")
      Catch e As System.Exception
      System.Console.WriteLine("Command 'invalid' returned " + e.Message)
      End Try
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Errors 192.168.0.40
      Command "invalid" returned -10000: "question mark returned by controller"
  • Standard error chaining is supported by gclib. See gclib_errors.h for a full list of error codes.
    Errors.vi


Program & Arrays

  • Use GProgramUpload() to get the controller's program, and use GProgramDownload() to set it. See the gclib Program Preprocessor for advanced usage.

    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      GCon g = NULL;
      char program[G_HUGE_BUFFER];
      GOpen(argv[1], &g);
      GProgramDownload(g, "MG \"Hello World\"", NULL);
      printf("%s\n", program);
      GClose(g);
      }
      #define G_HUGE_BUFFER
      Most reads from Galil hardware are small. This value will hold the largest array or program upload/do...
      Definition gclib.h:104
      GCLIB_DLL_EXPORTED GReturn GCALL GProgramUpload(GCon g, GBufOut buffer, GSize buffer_len)
      Uploads a program from the controller's program buffer.
      GCLIB_DLL_EXPORTED GReturn GCALL GProgramDownload(GCon g, GCStringIn program, GCStringIn preprocessor)
      Downloads a program to the controller's program buffer.
    • > .\program.exe 192.168.0.40
      MG "Hello World"

    Use GArrayUpload() to get an array from the controller, and use GArrayDownload() to set it.

    • Use the first and last arguments to transfer only part of the array.
    • Use G_CR or G_COMMA for carriage return or comma delimiting, respectively.
    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      GCon g = NULL;
      char array[G_HUGE_BUFFER];
      GOpen(argv[1], &g);
      GCommand(g, "DM test[5]", NULL, 0, NULL);
      GArrayDownload(g, "test", 0, 4, "1,2,3,4,5");
      GArrayUpload(g, "test", 1, 3, G_COMMA, array, G_HUGE_BUFFER);
      printf("%s\n", array);
      GCommand(g, "DA test[5]", NULL, 0, NULL);
      GClose(g);
      }
      #define G_COMMA
      For GArrayUpload(), use this value in the delim field to delimit with commas.
      Definition gclib.h:68
      GCLIB_DLL_EXPORTED GReturn GCALL GArrayDownload(GCon g, const GCStringIn array_name, GOption first, GOption last, GCStringIn buffer)
      Downloads array data to a pre-dimensioned array in the controller's array table.
      GCLIB_DLL_EXPORTED GReturn GCALL GArrayUpload(GCon g, const GCStringIn array_name, GOption first, GOption last, GOption delim, GBufOut buffer, GSize buffer_len)
      Uploads array data from the controller's array table.
    • > .\arrays.exe 192.168.0.40
      2.0000, 3.0000, 4.0000
  • Use gclib.py.GProgramUpload() to get the controller's program, and use gclib.py.GProgramDownload() to set it.

    >>> connection.GProgramDownload('MG "Hello World"')
    >>> connection.GProgramUpload()
    'MG "Hello World"'

    Use gclib.py.GArrayUpload() and gclib.py.GArrayDownload() similarly for arrays. Use the first and last arguments to transfer only part of the array.

    >>> connection.GCommand('DM test[5]')
    >>> connection.GArrayDownload('test', 0, 4, [1, 2, 3, 4, 5])
    >>> connection.GArrayUpload('test', 1, 3)
    [2.0, 3.0, 4.0]
  • Use gclibjava.GclibJava.GProgramUpload() to get the controller's program, and use gclibjava.GclibJava.GProgramDownload() to set it. See the gclib Program Preprocessor for advanced usage.

    • import gclibjava.*;
      public class Program {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[1]);
      connection.GProgramDownload("MG \"Hello World\"");
      System.out.println(connection.GProgramUpload());
      connection.GClose();
      }
      }
    • > java Program 192.168.0.40
      MG "Hello World"

    Use gclibjava.GclibJava.GArrayUpload() to get an array from the controller, and use gclibjava.GclibJava.GArrayDownload() to set it.

    • import gclibjava.*;
      public class Arrays {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[1]);
      connection.GCommand("DM test[5]");
      connection.GArrayDownload("test", java.util.Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0));
      System.out.println(connection.GArrayUpload("test"));
      connection.GClose();
      }
      }
    • > java Arrays 192.168.0.40
      2.0000, 3.0000, 4.0000
  • Use gclib.GProgramUpload() to get the controller's program, and use gclib.GProgramDownload() to set it. See the gclib Program Preprocessor for advanced usage.

    Use gclib.GArrayUpload() to get an array from the controller, and use gclib.GArrayDownload() to set it.

    • gclib connection = new gclib();
      connection.GOpen(args[0]);
      connection.GCommand("DM test[5]");
      List<double> test = new List<double>{1, 2, 3, 4, 5};
      connection.GArrayDownload("test", ref test);
      System.Console.WriteLine(string.Join(", ", connection.GArrayUpload("test")));
      connection.GClose();
      void GArrayDownload(string array_name, ref List< double > data, Int16 first=-1, Int16 last=-1)
      Downloads array data to a pre-dimensioned array in the controller's array table.
      Definition gclib.cs:104
      List< double > GArrayUpload(string array_name, Int16 first=-1, Int16 last=-1)
      Uploads array data from the controller's array table.
      Definition gclib.cs:153
    • > dotnet run --project Arrays 192.168.0.40
      2.0000, 3.0000, 4.0000
  • Use Gclib.GProgramUpload() to get the controller's program, and use Gclib.GProgramDownload() to set it. See the gclib Program Preprocessor for advanced usage.

    • Module Program
      Sub Main(args As String())
      Dim connection As Gclib = new Gclib()
      connection.GOpen(args(0))
      connection.GCommand("DM test[5]")
      connection.GProgramDownload("MG ""Hello World""")
      System.Console.WriteLine(connection.GProgramUpload())
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Program 192.168.0.40
      MG "Hello World"

    Use Gclib.GArrayUpload() to get an array from the controller, and use Gclib.GArrayDownload() to set it.

    • Module Program
      Sub Main(args As String())
      Dim connection As Gclib = new Gclib()
      connection.GOpen(args(0))
      connection.GCommand("DM test[5]")
      connection.GArrayDownload("test", new List(Of Double)({1, 2, 3, 4, 5}))
      System.Console.WriteLine(string.Join(", ", connection.GArrayUpload("test")))
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Arrays 192.168.0.40
      2.0000, 3.0000, 4.0000
  • Use G Program Upload to get the controller's program, and use G Program Download to set it. See the gclib Program Preprocessor for advanced usage.

    Program.vi


    Use G Array Upload to get an array from the controller, and use G Array Download to set it.

    • Use the first and last inputs to transfer only part of the array.
    Arrays.vi


Unsolicited Data

To listen for unsolicited data, add --subscribe ALL to your connection string. See GOpen() documentation for details.

Note
Subscribing to unsolicited data does not enable interrupts or turn on data records; it only ensures that gclib will be able to receive them. See EI and DR documentation for details.
  • Use GMessage() to get unsolicited messages from the controller, GInterrupt() to get event interrupts, and GRecord() to get data records. If there is no data available, these methods will block up to five seconds before timing out.

    • #include <gclibo.h>
      #include <stdio.h>
      #include <string.h>
      int main(int argc, char* argv[]) {
      GCon g = NULL;
      char buf[G_HUGE_BUFFER];
      sprintf(buf, "%s --subscribe ALL", argv[1]);
      GOpen(buf, &g);
      GProgramDownload(g, "MG \"Hello World\"; UI0; EN", NULL);
      GCommand(g, "XQ", NULL, 0, NULL);
      printf("Got message %s", buf);
      GStatus status = 0;
      GInterrupt(g, &status);
      printf("Got interrupt %i\n", status);
      union GDataRecord record;
      GCommand(g, "DR8", NULL, 0, NULL);
      GRecord(g, &record, G_DR);
      printf("Got data record %i\n", record.dmc4000.sample_number);
      GCommand(g, "DR0", NULL, 0, NULL);
      GClose(g);
      }
      #define G_DR
      Value for GRecord() method variable for acquiring a data record via DR mode.
      Definition gclib.h:64
      unsigned char GStatus
      Interrupt status byte.
      Definition gclib.h:115
      GCLIB_DLL_EXPORTED GReturn GCALL GRecord(GCon g, union GDataRecord *record, GOption method)
      Provides a fresh copy of the controller's data record. Data is cast into a union, GDataRecord.
      GCLIB_DLL_EXPORTED GReturn GCALL GInterrupt(GCon g, GStatus *status_byte)
      Provides access to PCI and UDP interrupts from the controller.
      GCLIB_DLL_EXPORTED GReturn GCALL GMessage(GCon g, GCStringOut buffer, GSize buffer_len)
      Provides access to unsolicited messages from the controller.
      Data record union, containing all structs and a generic byte array accessor.
    • > .\unsolicited.exe 192.168.0.40
      Got message Hello World
      Got data record 39306
      Got interrupt 240
  • >>> connection.GClose()
    >>> connection.GOpen('192.168.0.40 --subscribe ALL')

    Use gclib.py.GMessage() to get unsolicited messages from the controller, and gclib.py.GInterrupt() to get event interrupts. If there is no data available, these methods will block up to five seconds before timing out.

    >>> connection.GProgramDownload('MG "Hello World"; UI0; EN')
    >>> connection.GCommand('XQ')
    ''
    >>> connection.GMessage()
    'Hello World\r\n'
    >>> connection.GInterrupt()
    240
  • Use gclibjava.GclibJava.GMessage() to get unsolicited messages from the controller, gclibjava.GclibJava.GInterrupt() to get event interrupts, and gclibjava.GclibJava.GRecord() to get data records. If there is no data available, these methods will block up to five seconds before timing out.

    • import gclibjava.*;
      public class Unsolicited {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      connection.GOpen(args[1]);
      connection.GProgramDownload("MG \"Hello World\"; UI0; EN");
      connection.GCommand("XQ");
      System.out.println("Got message " + connection.GMessage());
      System.out.println("Got interrupt " + connection.GInterrupt());
      connection.GClose();
      }
      }
    • > java Unsolicited "192.168.0.40 --subscribe ALL"
      Got message Hello World
      Got data record 39306
      Got interrupt 240
  • Use gclib.GMessage() to get unsolicited messages from the controller, gclib.GInterrupt() to get event interrupts, and gclib.GRecord() to get data records. If there is no data available, these methods will block up to five seconds before timing out.

    • using Galil;
      Gclib connection = new Gclib();
      connection.GOpen(args[0] + " --subscribe ALL");
      connection.GProgramDownload("MG \"Hello World\"; UI0; EN");
      connection.GCommand("XQ");
      System.Console.Write("Got message " + connection.GMessage());
      System.Console.WriteLine("Got interrupt " + connection.GInterrupt());
      connection.GCommand("DR8");
      System.Console.WriteLine("Got data record " + connection.GRecord<Gclib.GDataRecord4000>(true).sample_number);
      connection.GCommand("DR0");
      connection.GClose();
    • > dotnet run --project Unsolicited 192.168.0.40
      Got message Hello World
      Got data record 39306
      Got interrupt 240
  • Use Gclib.GMessage() to get unsolicited messages from the controller, Gclib.GInterrupt() to get event interrupts, and Gclib.GRecord() to get data records. If there is no data available, these methods will block up to five seconds before timing out.

    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      connection.GOpen(args(0) + " --subscribe ALL")
      connection.GProgramDownload("MG ""Hello World""; UI0; EN")
      connection.GCommand("XQ")
      System.Console.Write("Got message " + connection.GMessage())
      System.Console.WriteLine("Got interrupt {0}", connection.GInterrupt().ToString())
      connection.GCommand("DR8")
      System.Console.WriteLine("Got data record {0}", connection.GRecord(Of Gclib.GDataRecord4000)(true).sample_number)
      connection.GCommand("DR0")
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project Unsolicited 192.168.0.40
      Got message Hello World
      Got data record 39306
      Got interrupt 240
  • Use G Message to get unsolicited messages from the controller, G Interrupt to get event interrupts, and G Record to get data records. If there is no data available, these methods will block up to five seconds before timing out.

    For G Record, note that memory must be allocated using the 'Initialize Array' node to store the data record packet. This memory space is filled with the information in the data record packet and then parsed using the 'Index Array' and 'Join Numbers' nodes.

    Unsolicited.vi


Galil Connect

Galil Connect allows gclib to issue commands through a remote gcaps server. This makes debugging closed or distant systems much easier.

  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use GPublishServer().

    • #include <gclibo.h>
      #include <stdio.h>
      #include <stdbool.h>
      int main(int argc, char* argv[]) {
      GPublishServer(argv[1], true, true);
      printf("Published remote gcaps server \"%s\"\n", argv[1]);
      }
      GCLIB_DLL_EXPORTED GReturn GCALL GPublishServer(GCStringIn name, GOption publish, GOption save)
      Uses GUtility(), G_UTIL_GCAPS_PUBLISH_SERVER to publish local gcaps server to the local network.
    • > .\server.exe Pi
      Published gcaps server "Pi"

    On the client, use GListServers() to view all available gcaps servers. Pass a server name to GSetServer() for future gclib calls to be routed through that gcaps server. When done, pass the special string "Local" to GSetServer() to disconnect from the remote gcaps server.

    • #include <gclibo.h>
      #include <stdio.h>
      int main(int argc, char* argv[]) {
      char buf[G_SMALL_BUFFER];
      GCon g;
      printf("Available servers:\n%s\n", buf);
      GSetServer("pi");
      printf("\nAddresses reported by pi:\n%s", buf);
      GOpen("COM5", &g);
      printf("\nConnected to %s\n", buf);
      GClose(g);
      GSetServer("Local");
      }
      GCLIB_DLL_EXPORTED GReturn GCALL GListServers(GCStringOut servers, GSize servers_len)
      Uses GUtility(), G_UTIL_GCAPS_LIST_SERVERS to provide a list of all available gcaps services on the l...
      GCLIB_DLL_EXPORTED GReturn GCALL GSetServer(GCStringIn server_name)
      Uses GUtility(), G_UTIL_GCAPS_SET_SERVER to set the new active server.
    • > .\client.exe
      Available servers:
      pi
      Addresses reported by pi:
      COM5
      Connected to COM5, DMC31010 Rev 1.4f, 12345
  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use gclib.py.GPublishServer().

    >>> connection.GPublishServer('pi', True, True)

    On the client, use gclib.py.GListServers() to view all available gcaps servers. Pass a server name to gclib.py.GSetServer() for future gclib calls to be routed through that gcaps server. When done, pass the special string "Local" to gclib.py.GSetServer() to disconnect from the remote gcaps server.

    >>> connection.GListServers()
    'pi'
    >>> connection.GSetServer('pi')
    >>> connection.GAddresses(buf, G_SMALL_BUFFER)
    {'COM5': ''}
    >>> connection.GOpen("COM5")
    >>> connection.GInfo()
    'COM5, DMC31010 Rev 1.4f, 12345'
    >>> connection.GClose()
    >>> connection.GSetServer('Local')
  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use gclibjava.GclibJava.GPublishServer().

    • import gclibjava.*;
      public class Server {
      public static void main(String[] args) throws GclibJavaException {
      new GclibJava().GPublishServer(args[0], 1, 1);
      System.out.println("Published remote gcaps server " + args[0]);
      }
      }
    • > java Server Pi
      Published gcaps server "Pi"

    On the client, use gclibjava.GclibJava.GListServers() to view all available gcaps servers. Pass a server name to gclibjava.GclibJava.GSetServer() for future gclib calls to be routed through that gcaps server. When done, pass the special string "Local" to gclibjava.GclibJava.GSetServer() to disconnect from the remote gcaps server.

    • import gclibjava.*;
      public class Client {
      public static void main(String[] args) throws GclibJavaException {
      GclibJava connection = new GclibJava();
      System.out.println(connection.GListServers());
      connection.GSetServer("pi");
      System.out.println("Addresses reported by pi: " + connection.GAddresses());
      connection.GOpen("COM5");
      System.out.println(connection.GInfo());
      connection.GClose();
      connection.GSetServer("Local");
      }
      }
    • > java Client
      Available servers:
      pi
      Addresses reported by pi:
      COM5
      Connected to COM5, DMC31010 Rev 1.4f, 12345
  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use gclib.GPublishServer().

    • gclib connection = new gclib();
      connection.GPublishServer(args[0], true, true);
      System.Console.WriteLine("Published remote gcaps server " + args[0]);
      void GPublishServer(string server_name, bool publish, bool save)
      Publishes or removes local gcaps server from the network.
      Definition gclib.cs:745
    • > dotnet run --project Server
      Published gcaps server "Pi"

    On the client, use gclib.GListServers() to view all available gcaps servers. Pass a server name to gclib.GSetServer() for future gclib calls to be routed through that gcaps server.

    • gclib connection = new gclib();
      System.Console.WriteLine(connection.GListServers());
      connection.GSetServer("pi");
      System.Console.WriteLine("Addresses reported by pi: " + connection.GAddresses());
      connection.GOpen("COM5");
      connection.GSetServer("Local");
      void GSetServer(string server_name)
      Connects gclib to a new gcaps server.
      Definition gclib.cs:690
      string[] GListServers()
      Retrieves a list of gcaps servers that are advertising themselves on the local network.
      Definition gclib.cs:722
    • > dotnet run --project Client
      Available servers:
      pi
      Addresses reported by pi:
      COM5
      Connected to COM5, DMC31010 Rev 1.4f, 12345
  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use Gclib.GPublishServer().

    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      connection.GPublishServer(args(0), true, true)
      System.Console.WriteLine("Published remote gcaps server " + args(0))
      End Sub
      End Module
    • > dotnet run --project Server
      Published gcaps server "Pi"

    On the client, use Gclib.GListServers() to view all available gcaps servers. Pass a server name to Gclib.GSetServer() for future gclib calls to be routed through that gcaps server.

    • Module Program
      Sub Main(args As String())
      Dim connection As new Gclib()
      System.Console.WriteLine("Available servers: " + Environment.NewLine + String.Join(Environment.NewLine, connection.GListServers()))
      connection.GSetServer("pi")
      System.Console.WriteLine(Environment.NewLine + "Addresses reported by pi: " + Environment.NewLine + String.Join(Environment.NewLine, connection.GAddresses()))
      connection.GOpen("/dev/ttyUSB0")
      System.Console.WriteLine(Environment.NewLine + "Connected to " + connection.GInfo())
      connection.GSetServer("Local")
      End Sub
      End Module
    • > dotnet run --project Client
      Available servers:
      pi
      Addresses reported by pi:
      COM5
      Connected to COM5, DMC31010 Rev 1.4f, 12345
  • On the device hosting the remote gcaps server (in this example a Raspberry Pi), use G Publish Server.

    Server.vi


    On the client, use G List Servers to view all available gcaps servers. Pass a server name to G Set Server for future gclib calls to be routed through that gcaps server. When done, pass the special string "Local" to G Set Server to disconnect from the remote gcaps server.

    Client.vi


Example Project: Record and Replay

This project contains two example programs.

  • The 'Record' example uses RA in continuous mode along with GArrayUpload() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of all axes.

    • #include <gclibo.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <time.h>
      char buf[G_HUGE_BUFFER];
      void check(GReturn ret, GCon g) {
      if (ret == G_NO_ERROR)
      return;
      GCommand(g, "TC1", buf, G_HUGE_BUFFER, NULL);
      printf("%s\n", buf);
      }
      GError(ret, buf, G_HUGE_BUFFER);
      fprintf(stderr, "Error %i: %s\n", ret, buf);
      GClose(g);
      exit(ret);
      }
      int main(int argc, char* argv[]) {
      if (argc != 3) {
      fprintf(stderr, "Usage: replay.exe ADDRESS SECONDS\n");
      return 0;
      }
      GCon g = NULL;
      union GDataRecord record;
      GSize bytesReturned;
      check(GOpen(argv[1], &g), g);
      check(GCommand(g, "MG_BV", buf, G_HUGE_BUFFER, &bytesReturned), g);
      size_t axes = atoi(buf);
      char axisLabels[8] = {'A', 'B', 'C', 'D', 'E', 'F', 'H'};
      char arrayNames[8][5];
      for (int i = 0; i < axes; i++)
      sprintf(arrayNames[i], "pos%c", axisLabels[i]);
      check(GCmd(g, "MO"), g);
      strcpy(buf, "DM");
      for (int i = 0; i < axes; i++)
      sprintf(buf, strcat(buf, "%s pos%c[1000]"), i > 0 ? "," : "", axisLabels[i]);
      check(GCmd(g, buf), g);
      strcpy(buf, "RA");
      for (int i = 0; i < axes; i++)
      sprintf(buf, strcat(buf, "%s pos%c[]"), i > 0 ? "," : "", axisLabels[i]);
      check(GCmd(g, buf), g);
      strcpy(buf, "RD");
      for (int i = 0; i < axes; i++)
      sprintf(buf, strcat(buf, "%s _TP%c"), i > 0 ? "," : "", axisLabels[i]);
      check(GCmd(g, buf), g);
      check(GCmd(g, "RC 1,-1000"), g);
      size_t start = 0, end;
      char positions[8][G_HUGE_BUFFER];
      char* tokens[8];
      int count;
      time_t startTime = time(NULL);
      FILE* file = fopen("positions.txt", "w");
      while (difftime(time(NULL), startTime) < atof(argv[2])) {
      GSleep(500);
      check(GCommand(g, "MG_RD", buf, G_HUGE_BUFFER, NULL), g);
      end = atoi(buf);
      for (int i = 0; i < axes; i++) {
      check(GArrayUpload(g, arrayNames[i], start, end < start ? -1 : end, G_COMMA, positions[i], G_HUGE_BUFFER), g);
      if (end < start) {
      check(GArrayUpload(g, arrayNames[i], 0, end, G_COMMA, buf, G_HUGE_BUFFER), g);
      strcat(positions[i], ", ");
      strcat(positions[i], buf);
      }
      }
      count = end - start;
      if (end < start)
      count += 1000;
      for (int i = 0; i < count; i++) {
      for (int j = 0; j < axes; j++) {
      tokens[j] = strtok( i == 0 ? positions[j] : NULL, " ,");
      if (tokens[j] == NULL)
      break;
      fprintf(file, "%s%s", j == 0 ? "" : ",", tokens[j]);
      }
      fputc('\n', file);
      }
      start = end;
      }
      fclose(file);
      check(GCmd(g, "RC 0"), g);
      GClose(g);
      }
      unsigned int GSize
      Size of buffers, etc.
      Definition gclib.h:109
      #define G_BAD_RESPONSE_QUESTION_MARK
      Operation received a ?, indicating controller has a TC error.
      #define G_NO_ERROR
      Return value if function succeeded.
      Definition gclib_errors.h:9
      GCLIB_DLL_EXPORTED void GCALL GSleep(unsigned int timeout_ms)
      Uses GUtility() and G_UTIL_SLEEP to provide a blocking sleep call which can be useful for timing-base...
      GCLIB_DLL_EXPORTED GReturn GCALL GCmd(GCon g, GCStringIn command)
      Wrapper around GCommand for use when the return value is not desired.
    • > .\record.exe 192.168.0.40 5

    The 'Replay' example uses the file produced by 'Record' along with CM to accurately reproduce the recorded movement.

    • #include <gclibo.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <time.h>
      char buf[G_HUGE_BUFFER];
      void check(GReturn ret, GCon g) {
      if (ret == G_NO_ERROR)
      return;
      GCommand(g, "TC1", buf, G_HUGE_BUFFER, NULL);
      printf("%s\n", buf);
      }
      GError(ret, buf, G_HUGE_BUFFER);
      fprintf(stderr, "Error %i: %s\n", ret, buf);
      GClose(g);
      exit(ret);
      }
      int main(int argc, char* argv[]) {
      if (argc != 2) {
      fprintf(stderr, "Usage: replay.exe ADDRESS\n");
      return 0;
      }
      GCon g = NULL;
      check(GOpen(argv[1], &g), g);
      check(GCommand(g, "MG_BV", buf, G_HUGE_BUFFER, NULL), g);
      size_t axes = atof(buf);
      char axisMask[] = "ABCDEFGH";
      axisMask[axes] = '\0';
      GCommand(g, "MG_CM", buf, G_HUGE_BUFFER, NULL);
      int contourSpace = atof(buf);
      check(GCmd(g, "MO"), g);
      sprintf(buf, "SH %s", axisMask);
      check(GCmd(g, buf), g);
      sprintf(buf, "CM %s", axisMask);
      check(GCmd(g, buf), g);
      check(GCmd(g, "DT -1"), g);
      int lastPositions[8];
      int positions[8];
      FILE* f = fopen("positions.txt", "r");
      fgets(buf, G_HUGE_BUFFER, f);
      char* tok = strtok(buf, ", ");
      for (int i = 0; i < axes; i++)
      lastPositions[i] = atof(tok);
      while (fgets(buf, G_HUGE_BUFFER, f)) {
      char* tok = strtok(buf, ", ");
      for (int i = 0; i < axes; i++) {
      positions[i] = atof(tok);
      tok = strtok(NULL, ", ");
      }
      strcpy(buf, "CD");
      for (int i = 0; i < axes; i++) {
      sprintf(&buf[strlen(buf)], "%i", positions[i] - lastPositions[i]);
      lastPositions[i] = positions[i];
      if (i != axes - 1)
      strcat(buf, ",");
      }
      GReturn ret = GCmd(g, buf);
      GCmdT(g, "TC1", buf, G_HUGE_BUFFER, NULL);
      if (strcmp(buf, "32 Segment buffer full") == 0) {
      GCommand(g, "MG_DT", buf, G_HUGE_BUFFER, NULL);
      if ((int)atof(buf) == -1)
      GCmd(g, "DT 1");
      GSleep(100);
      }
      }
      }
      do {
      GCommand(g, "MG_CM", buf, G_HUGE_BUFFER, NULL);
      } while ((int)atof(buf) < contourSpace);
      fclose(f);
      strcpy(buf, "CD ");
      for (int i = 0; i < axes; i++)
      strcat(buf, i == 0 ? "0" : ",0");
      strcat(buf, "=0");
      check(GCmd(g, "RC 0"), g);
      check(GCmd(g, "MO"), g);
      GClose(g);
      }
      GCLIB_DLL_EXPORTED GReturn GCALL GCmdT(GCon g, GCStringIn command, GCStringOut trimmed_response, GSize response_len, GCStringOut *front)
      Wrapper around GCommand that trims the response.
    • > .\replay.exe 192.168.0.40
  • The 'Record' example uses RA in continuous mode along with gclib.py.GProgramUpload() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of all axes.

    • import gclib
      import sys
      import time
      def main():
      if (len(sys.argv) != 2):
      print(f"Usage: record.py ADDRESS SECONDS", file=sys.stderr)
      return
      connection = gclib.py()
      try:
      connection.GOpen(sys.argv[1])
      axes = int(float(connection.GCommand("MG_BV")))
      axisLabels = [chr(i) for i in range(ord('A'), ord('A') + axes)]
      connection.GCommand('MO')
      connection.GCommand('DM' + ','.join([f"pos{x}[1000]" for x in axisLabels]))
      connection.GCommand('RA' + ','.join([f"pos{x}[]" for x in axisLabels]))
      connection.GCommand('RD' + ','.join([f"_TP{x}" for x in axisLabels]))
      connection.GCommand('RC 1,-1000') # Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      start = 0
      end = -1
      positions = [None] * axes
      startTime = time.time()
      f = open("positions.txt", "w")
      while (time.time() - startTime < float(sys.argv[2])):
      time.sleep(0.5); # Assumes TM1000
      end = int(float(connection.GCommand("MG_RD")))
      for (i, label) in enumerate(axisLabels):
      positions[i] = connection.GArrayUpload(f'pos{label}', start, -1 if end < start else end)
      if end < start:
      positions[i] += connection.GArrayUpload(f'pos{label}', 0, end)
      for i in range(end - start if end > start else 1000 - start + end):
      f.write(','.join([str(pos[i]) for pos in positions]) + '\n')
      start = end
      f.close()
      connection.GCommand("RC 0")
      except gclib.GclibError as e:
      print(e)
      connection.GClose()
      if __name__ == '__main__':
      main()
      Error class for non-zero gclib return codes.
      Definition gclib.py:146
      Represents a single Python connection to a Galil Controller or PLC.
      Definition gclib.py:152
    • > python record.py 192.168.0.40 5

    The 'Replay' example uses the file produced by 'Record' along with CM to accurately reproduce the recorded movement.

    • import gclib
      import sys
      import time
      def main():
      if len(sys.argv) != 1:
      print(f'Usage: replay.py ADDRESS', file=sys.stderr)
      return
      connection = gclib.py()
      try:
      connection.GOpen(sys.argv[1])
      axes = int(float(connection.GCommand("MG_BV")))
      axisMask = ''.join([chr(i) for i in range(ord('A'), ord('A') + axes)])
      connection.GCommand(f'SH {axisMask}')
      connection.GCommand(f'CM {axisMask}')
      connection.GCommand('DT -1')
      contourSpace = int(float(connection.GCommand('MG_CM')))
      f = open("positions.txt", "r")
      lastPositions = None
      for line in f.read().splitlines()
      positions = line.split(',')
      if lastPositions:
      movement = [int(float(pos)) - int(float(lastPos)) for pos, lastPos in zip(positions, lastPositions)]
      try:
      connection.GCommand(f'CD {','.join([str(x) for x in movement])}')
      if (connection.GCommand('TC1') != '32 Segment buffer full'):
      raise
      if (int(float(connection.GCommand('MG_DT'))) == -1):
      connection.GCommand('DT 1')
      time.sleep(0.1)
      lastPositions = positions
      f.close()
      while int(float(connection.GCommand('MG_CM'))) < contourSpace:
      time.sleep(0.5)
      connection.GCommand(f'CD {','.join(['0'] * len(axisMask))}=0')
      connection.GCommand('RC 0')
      connection.GCommand('MO')
      except gclib.GclibError as e:
      print(e)
      connection.GClose()
      if __name__ == '__main__':
      main()
    • > python replay.py 192.168.0.40
  • The 'Record' example uses RA in continuous mode along with gclibjava.GclibJava.GProgramUpload() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of all axes.

    • import gclibjava.*;
      import java.util.NoSuchElementException;
      import java.util.Scanner;
      import java.util.List;
      import java.util.ArrayList;
      import java.util.Collections;
      import java.io.FileWriter;
      import java.io.IOException;
      public class Record {
      public static void main(String[] args) throws GclibJavaException, IOException, InterruptedException {
      if (args.length != 2) {
      System.out.println("Usage: Record ADDRESS SECONDS");
      return;
      }
      GclibJava connection = new GclibJava();
      connection.GOpen(args[0]);
      int axes = (int)Float.parseFloat(connection.GCommand("MG_BV"));
      String axisLabels = "ABCDEFGH".substring(0, axes);
      connection.GCommand("MO");
      List<String> list = new ArrayList<String>(axes);
      for (int i = 0; i < axes; i++) list.add(String.format("pos%c[1000]", axisLabels.charAt(i)));
      connection.GCommand("DM" + String.join(",", list));
      for (int i = 0; i < axes; i++) list.set(i, String.format("pos%c[]", axisLabels.charAt(i)));
      connection.GCommand("RA" + String.join(",", list));
      for (int i = 0; i < axes; i++) list.set(i, String.format("_TP%c", axisLabels.charAt(i)));
      connection.GCommand("RD" + String.join(",", list));
      connection.GCommand("RC 1,-1000"); // Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      List<List<Double>> positions = new ArrayList<List<Double>>(Collections.nCopies(axes, new ArrayList<Double>()));
      List<String> axisPositions = new ArrayList<String>(Collections.nCopies(axes, ""));
      long startTime = System.currentTimeMillis();
      short start = 0, end;
      try(FileWriter fw = new FileWriter("positions.txt")) {
      while (System.currentTimeMillis() - startTime < Float.parseFloat(args[1]) * 1000) {
      Thread.sleep(500);
      end = (short)Float.parseFloat(connection.GCommand("MG_RD"));
      for (int i = 0; i < axes; i++) {
      positions.set(i, connection.GArrayUpload(String.format("pos%c", axisLabels.charAt(i)), start, end < start ? (short)-1 : end));
      if (end < start)
      positions.get(i).addAll(connection.GArrayUpload(String.format("pos%c", axisLabels.charAt(i)), 0, end));
      }
      for (int i = 0; i < (end > start ? end - start : 1000 - start + end); i++) {
      for (int axis = 0; axis < axes; axis++)
      axisPositions.set(axis, positions.get(axis).get(i).toString());
      fw.write(String.join(",", axisPositions) + System.lineSeparator());
      }
      start = end;
      }
      }
      connection.GCommand("RC 0");
      connection.GClose();
      }
      }
    • > java record 192.168.0.40 5

    The 'Replay' example uses the file produced by 'Record' along with CM to accurately reproduce the recorded movement.

    • import gclibjava.*;
      import java.util.NoSuchElementException;
      import java.util.Scanner;
      import java.util.List;
      import java.util.ArrayList;
      import java.util.Collections;
      import java.io.FileReader;
      import java.io.BufferedReader;
      import java.io.IOException;
      public class Replay {
      public static void main(String[] args) throws GclibJavaException, IOException, InterruptedException {
      if (args.length != 1) {
      System.out.println("Usage: Replay ADDRESS");
      return;
      }
      GclibJava connection = new GclibJava();
      connection.GOpen(args[0]);
      int axes = (int)Float.parseFloat(connection.GCommand("MG_BV"));
      String axisLabels = "ABCDEFGH".substring(0, axes);
      connection.GCommand("SH" + axisLabels);
      connection.GCommand("CM" + axisLabels);
      connection.GCommand("DT -1");
      int contourSpace = (int)Float.parseFloat(connection.GCommand("MG_CM"));
      long startTime = System.currentTimeMillis();
      try(BufferedReader br = new BufferedReader(new FileReader("positions.txt"))) {
      String line = br.readLine();
      String[] positions;
      String[] lastPositions = null;
      String[] movement = new String[axes];
      while (line != null) {
      positions = line.split(",");
      if (lastPositions == null) {
      lastPositions = positions;
      continue;
      }
      for (int i = 0; i < axes; i++) {
      movement[i] = String.valueOf((int)(Float.parseFloat(positions[i]) - Float.parseFloat(lastPositions[i])));
      }
      try {
      connection.GCommand("CD " + String.join(",", movement));
      } catch (GclibJavaException e) {
      if (!(e.getErrorCode() == -10000 && connection.GCommand("TC1").startsWith("32")))
      throw e;
      if ((int)Float.parseFloat(connection.GCommand("MG_DT")) == -1)
      connection.GCommand("DT 1");
      Thread.sleep(500);
      }
      lastPositions = positions;
      line = br.readLine();
      }
      }
      while ((int)Float.parseFloat(connection.GCommand("MG_CM")) < contourSpace)
      Thread.sleep(500);
      connection.GCommand(String.format("CD %s=0", String.join(",", Collections.nCopies(axes, "0"))));
      connection.GCommand("RC 0");
      connection.GCommand("MO");
      connection.GClose();
      }
      }
    • > java replay 192.168.0.40
  • The 'Record' example uses RA in continuous mode along with Gclib.GProgramUpload() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of all axes.

    • if (args.Length != 2) {
      System.Console.WriteLine("Usage: record.exe ADDRESS SECONDS");
      return;
      }
      gclib connection = new gclib();
      try {
      connection.GOpen(args[0]);
      int axes = (int)float.Parse(connection.GCommand("MG_BV"));
      string axisLabels = "ABCDEFGH".Substring(0, axes);
      connection.GCommand("MO");
      connection.GCommand("DM" + string.Join(',', from x in axisLabels select $"pos{x}[1000]"));
      connection.GCommand("RA" + string.Join(',', from x in axisLabels select $"pos{x}[]"));
      connection.GCommand("RD" + string.Join(',', from x in axisLabels select $"_TP{x}"));
      connection.GCommand("RC 1,-1000"); // Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      List<double>[] positions = new List<double>[axes];
      int startTime = DateTime.Now.Second;
      short start = 0, end;
      using (StreamWriter file = new StreamWriter("positions.txt")) {
      while (DateTime.Now.Second - startTime < float.Parse(args[1])) {
      System.Threading.Thread.Sleep(500);
      end = (short)float.Parse(connection.GCommand("MG_RD"));
      for (int i = 0; i < axes; i++) {
      positions[i] = connection.GArrayUpload($"pos{axisLabels[i]}", start, end < start ? (short)-1 : end);
      if (end < start)
      positions[i].AddRange(connection.GArrayUpload($"pos{axisLabels[i]}", 0, end));
      }
      for (int i = 0; i < (end > start ? end - start : 1000 - start + end); i++)
      file.WriteLine(string.Join(',', from x in positions select x[i].ToString()));
      start = end;
      }
      }
      } catch (System.Exception e) {
      if (e.Message.StartsWith("-10000"))
      System.Console.WriteLine(connection.GCommand("TC1"));
      else
      System.Console.WriteLine(e.Message);
      }
      connection.GCommand("RC 0");
      connection.GClose();
    • > dotnet run --project Record 192.168.0.40 5

    The 'Replay' example uses the file produced by 'Record' along with CM to accurately reproduce the recorded movement.

    • if (args.Length != 1) {
      System.Console.WriteLine("Usage: record.exe ADDRESS");
      return;
      }
      gclib connection = new gclib();
      try {
      connection.GOpen(args[0]);
      int axes = (int)float.Parse(connection.GCommand("MG_BV"));
      string axisLabels = "ABCDEFGH".Substring(0, axes);
      connection.GCommand($"SH {axisLabels}");
      connection.GCommand($"CM {axisLabels}");
      connection.GCommand("DT -1"); // Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      int contourSpace = (int)float.Parse(connection.GCommand("MG_CM"));
      int startTime = DateTime.Now.Second;
      using (StreamReader sr = new StreamReader("positions.txt")) {
      string? line = sr.ReadLine();
      List<int> positions;
      List<int>? lastPositions = null;
      while (line != null) {
      positions = line.Split(',').Select(x => int.Parse(x)).ToList();
      if (lastPositions == null) {
      lastPositions = positions;
      continue;
      }
      try {
      connection.GCommand($"CD {string.Join(',', from i in Enumerable.Range(0, axes) select positions[i] - lastPositions[i])}");
      } catch (System.Exception e) {
      if (!(e.Message.StartsWith("-10000") && connection.GCommand("TC1").StartsWith("32")))
      throw;
      if ((int)float.Parse(connection.GCommand("MG_DT")) == -1)
      connection.GCommand("DT 1");
      System.Threading.Thread.Sleep(500);
      }
      lastPositions = positions;
      line = sr.ReadLine();
      }
      }
      while ((int)float.Parse(connection.GCommand("MG_CM")) < contourSpace)
      System.Threading.Thread.Sleep(500);
      connection.GCommand($"CD {string.Join(',', Enumerable.Repeat("0", axes).ToArray())}=0");
      connection.GCommand("RC 0");
      connection.GCommand("MO");
      } catch (System.Exception e) {
      if (e.Message.StartsWith("-10000"))
      System.Console.WriteLine(connection.GCommand("TC1"));
      else
      System.Console.WriteLine(e.Message);
      }
      connection.GCommand("RC 0");
      connection.GClose();
    • > dotnet run --project Replay 192.168.0.40
  • The 'Record' example uses RA in continuous mode along with Gclib.GProgramUpload() to allow recording movement for an arbitrary amount of time. It produces a file with the recorded positions of all axes.

    • Imports System.IO
      Module Program
      Sub Main(args As String())
      If args.Length <> 2
      System.Console.WriteLine("Usage: record.exe ADDRESS SECONDS")
      return
      End If
      Dim connection As new gclib()
      Try
      connection.GOpen(args(0))
      Dim axes As Integer = CType(Single.Parse(connection.GCommand("MG_BV")), Integer)
      Dim axisLabels As String = "ABCDEFGH".Substring(0, axes)
      connection.GCommand("MO")
      connection.GCommand("DM" + String.Join(",", from x in axisLabels select $"pos{x}[1000]"))
      connection.GCommand("RA" + String.Join(",", from x in axisLabels select $"pos{x}[]"))
      connection.GCommand("RD" + String.Join(",", from x in axisLabels select $"_TP{x}"))
      connection.GCommand("RC 1,-1000") ' Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      Dim positions(axes - 1) As List(Of Double)
      Dim axisPositions(axes - 1) As String
      Dim startTime As Date = Now
      Dim endTime As Date = DateAdd("s", Single.Parse(args(1)), startTime)
      Dim first As Short = 0
      Dim last As Short
      first = 0
      Using writer As System.IO.StreamWriter = New System.IO.StreamWriter("positions.txt")
      While Now < endTime
      System.Threading.Thread.Sleep(500)
      last = Single.Parse(connection.GCommand("MG_RD"))
      For i = 0 To axes - 1
      positions(i) = connection.GArrayUpload(String.Format("pos{0}", axisLabels(i)), first, If(last < first, -1, last))
      If (last < first)
      positions(i).AddRange(connection.GArrayUpload(String.Format("pos{0}", axisLabels(i)), 0, last))
      End If
      Next
      For i = 0 To If(last > first, last - first, 1000 - first + last)
      For x = 0 To axes - 1
      axisPositions(x) = positions(x)(i).ToString()
      Next
      writer.WriteLine(String.Join(",", axisPositions))
      Next
      first = last
      End While
      End Using
      Catch e as System.Exception
      If e.Message.StartsWith("-10000")
      System.Console.WriteLine(connection.GCommand("TC1"))
      Else
      System.Console.WriteLine(e.Message)
      End If
      End Try
      connection.GCommand("RC 0")
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project record 192.168.0.40 5

    The 'Replay' example uses the file produced by 'Record' along with CM to accurately reproduce the recorded movement.

    • Module Program
      Sub Main(args As String())
      If args.Length <> 1
      System.Console.WriteLine("Usage: record.exe ADDRESS")
      return
      End If
      Dim connection As new gclib()
      Try
      connection.GOpen(args(0))
      Dim axes As Integer = CType(Single.Parse(connection.GCommand("MG_BV")), Integer)
      Dim axisLabels As String = "ABCDEFGH".Substring(0, axes)
      connection.GCommand(String.Format("SH {0}", axisLabels))
      connection.GCommand(String.Format("CM {0}", axisLabels))
      connection.GCommand("DT -1") ' Assuming TM1000, record at 2ms intervals (1ms on DMC30010 / EDD37010 / RIO47000)
      Dim contourSpace As Integer = Single.Parse(connection.GCommand("MG_CM"))
      Dim startTime As Integer = DateTime.Now.Second
      Using sr As System.IO.StreamReader = new System.IO.StreamReader("positions.txt")
      Dim line As String = sr.ReadLine()
      Dim positions As List(Of Integer)
      Dim lastPositions As List(Of Integer) = Nothing
      While line <> Nothing
      positions = line.Split(",").Select(Function(x) Integer.Parse(x)).ToList()
      If lastPositions Is Nothing
      lastPositions = positions
      Continue While
      End If
      Try
      connection.GCommand(String.Format("CD {0}", String.Join(",", From i in Enumerable.Range(0, axes) Select positions(i) - lastPositions(i))))
      Catch e As System.Exception
      If Not(e.Message.StartsWith("-10000") And connection.GCommand("TC1").StartsWith("32"))
      Throw
      End If
      If CType(Single.Parse(connection.GCommand("MG_DT")), Integer) = -1
      connection.GCommand("DT 1")
      End If
      System.Threading.Thread.Sleep(500)
      End Try
      lastPositions = positions
      line = sr.ReadLine()
      End While
      End Using
      While CType(Single.Parse(connection.GCommand("MG_CM")), Integer) < contourSpace
      System.Threading.Thread.Sleep(500)
      End While
      connection.GCommand(String.Format("CD {0}=0", string.Join(",", Enumerable.Repeat("0", axes).ToArray())))
      connection.GCommand("RC 0")
      connection.GCommand("MO")
      Catch e As System.Exception
      If (e.Message.StartsWith("-10000"))
      System.Console.WriteLine(connection.GCommand("TC1"))
      Else
      System.Console.WriteLine(e.Message)
      End If
      End Try
      connection.GCommand("RC 0")
      connection.GClose()
      End Sub
      End Module
    • > dotnet run --project replay 192.168.0.40