Analog Inputs

It is very simple to measure the current voltage on analog inputs with the help of the LIBAD4 library. Therefore the example opens the measurement system (ad_open), then retrieves the values at the various inputs (ad_analog_in) and at last closes the measurement system again (ad_close). Evidently the measurement system would be opened just once at the start of the program and closed at the end in a real program.

You will find the source code of the example in LIBAD4 SDK in the directory examples/analog_in (and in there in the according directories c, cs and vb for C/C++, C# and Visual Basic™.Net). Like all examples, this one does away with a proper error treatment due to simplicity of handling…

The example provides the routine read_analog_inputs(), showing how to use the LIBAD4 functions ad_open(), ad_analog_in() and ad_close(). The name of the measurement device (driver), the number of the measurement range (range) and the input channels to be measured (chav) are passed on to the routine. In addition the C/C++ code passes on the number of channels (chac). All arguments are retrieved from the command line in main(), processed accordingly and passed on to read_analog_inputs().

The first parameter on the command line gets passed as driver and denotes the measurement system. The "usb-ad:@100" for example opens the USB-AD with the serial number 100. You will find detailed descriptions for the necessary names of the different measurement systems in the LIBAD4 manual in chapter 6, measurement systems.

read_analog_inputs()passes this name directly to ad_open(). The return value of ad_open() is a handle, representing the opened measurement system and has to be passed to all functions of the LIBAD4. In case of an error -1 will be returned.

The parameter range defines the measurement range and will be denoted in main() by the optional command line argument -r <range>. This value defaults to 0 and thereby selects for example the measurement range +/- 5V of an USB-AD. The individual measurement ranges of the various measurement systems are also described in chapter 6 of the LIBAD4 manual.

main() fills the array chav[] by converting the remaining arguments of the command line to numbers. The function read_analog_inputs() passes on these values in a loop over all channels to ad_analog_in(). ad_analog_in() measures the voltage of an analog input. The first argument (adh) specifies the measurement system (as returned by ad_analog_in()). The second argument specifies the channel (consisting of channel type AD_ANLOG_INPUT and the channel number chav[i]) and the third argument specifies the measurement range (range). The variable voltage is delivered as the last argument in which ad_analog_in() returns the measured voltage. On error the function returns a non-zero error code. This error code corresponds to the host computer's operating system (for example in Windows an error number is returned from <winerror.h>).

The measurement system will be closed at the end of the loop ad_close().

/* Libad Analog Input Example
 *
 * Example showing how to read the voltage at some analog inputs
 * using bmcm's LIBAD4.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "libad.h"
/* Read analog input(s).
 */
void
read_analog_inputs (const char *driver, int range, int chac, int chav[])
{
  int32_t adh;
  int i;
  /* Open DAQ system.
   */
  adh = ad_open (driver);
  if (adh == -1)
    {
      printf ("failed to open %s: err = %d\n", driver, errno);
      return;
    }
  /* Read voltage at analog inputs.
   */
  for (i = 0; i < chac; i++)
    {
      float voltage;
      int rc;
      rc = ad_analog_in (adh, AD_CHA_TYPE_ANALOG_IN | chav[i], range, &voltage);
      if (rc == 0)
        printf ("cha %2d: %7.3f V\n", chav[i], voltage);
      else
        printf ("error: failed to read cha %d: err = %d\n", chav[i], rc);
    }
  /* Close DAQ system again.
   */
  ad_close (adh);
}
/* Show usage.
 */
void
usage ()
{
  printf ("usage: analog_in <driver> [ -r <range> ] <cha1> .. <chan>\n"
          "  <driver>     string to pass to ad_open()\n"
          "               - will prompt for name\n"
          "  <range>      range number of analog input\n"
          "  <cha1>       number of first analog input to read\n"
          "  <chan>       number of last analog input to read\n");
}
/* Main entry point.
 */
int
main (int argc, char *argv[])
{
  if (argc > 1)
    {
      char *name, *p, tmp[80];
      int i, start, range, chac, chav[16];
      /* First command line argument is the DAQ's name.
       * If "-" is passed, then let's read the name from
       * the console.
       */
      name = argv[1];
      if (strcmp (argv[1], "-") == 0)
        {
          printf ("data acquisition system to open: ");
          fgets (tmp, sizeof(tmp), stdin);
          p = strchr (tmp, '\n');
          if (p)
            *p = 0;
          name = tmp;
        }
      /* Range defaults to 0 but may get overridden by
       * -r on the command line.
       */
      start = 2;
      range = 0;
      if (argc > 3)
        {
          if (strcmp (argv[start], "-r") == 0)
            {
              range = atoi (argv[start+1]);
              start += 2;
            }
        }
      /* Convert remaining command line arguments
       * into numbers and add those to the channel array.
       */
      chac = 0;
      for (i = start; i < argc; i++)
        {
          chav[chac] = atoi (argv[i]);
          chac++;
          if (chac >= 16)
            break;
        }
      /* Measure analog inputs and print results
       * to the console.
       */
      read_analog_inputs (name, range, chac, chav);
      if (strcmp (argv[1], "-") == 0)
        {
          printf ("press return to continue...\n");
          fgets (tmp, sizeof(tmp), stdin);
        }
      return 0;
    }
  else
    {
      usage ();
      return 1;
    }
}
// Libad Analog Input Example
//
// Example showing how to read the voltage at some analog inputs
// using bmcm's LIBAD4.
using System;
using LIBAD4;
static class Example
{
  // Read analog input(s).
  static void
  read_analog_inputs (string driver, int range, int[] chav)
  {
    // Open DAQ system.
    int adh = LIBAD.ad_open (driver);
    if (adh == -1)
      {
        Console.WriteLine ("failed to open {0}: err = {1}", driver, LIBAD.errno);
        return;
      }
    // Read voltage at analog inputs.
    for (int i = 0; i < chav.Length; i++)
      {
        float voltage = 0;
        int rc;
        rc = LIBAD.ad_analog_in (adh, LIBAD.AD_CHA_TYPE_ANALOG_IN | chav[i], range, ref voltage);
        if (rc == 0)
          Console.WriteLine ("cha {0,2}: {1,7:##0.000} V", chav[i], voltage);
        else
          Console.WriteLine ("error: failed to read cha {0}: err = {1}", chav[i], rc);
      }
    // Close DAQ system again.
    LIBAD.ad_close (adh);
  }
  // Show usage.
  static void
  usage ()
  {
    Console.WriteLine ("usage: analog_in <driver> [ -r <range> ] <cha1> .. <chan>");
    Console.WriteLine ("  <driver>     string to pass to ad_open()");
    Console.WriteLine ("               - will prompt for name");
    Console.WriteLine ("  <range>      range number of analog input");
    Console.WriteLine ("  <cha1>       number of first analog input to read");
    Console.WriteLine ("  <chan>       number of last analog input to read");
  }
  // Main entry point.
  static int
  Main (string[] argv)
  {
    if (argv.Length > 0)
      {
        // First command line argument is the DAQ's name.
        // If "-" is passed, then let's read the name from
        // the console.
        string name = argv[0];
        if (argv[0] == "-")
          {
            Console.Write ("data acquisition sytem to open: ");
            name = Console.ReadLine ();
          }
        // Range defaults to 0 but may get overridden by
        // -r on the command line.
        int start = 1;
        int range = 0;
        if (argv.Length > 2)
          {
            if (argv[start] == "-r")
              {
                range = int.Parse (argv[start+1]);
                start += 2;
              }
          }
        // Convert remaining command line arguments
        // into numbers and add those to the channel array.
        int[] chav = new int[argv.Length - start];
        for (int i = start; i < argv.Length; i++)
          chav[i - start] = int.Parse (argv[i]);
        // Measure analog inputs and print results
        // to the console.
        read_analog_inputs (name, range, chav);
        if (argv[0]== "-")
          {
            Console.WriteLine ("press return to continue...");
            Console.ReadLine ();
          }
        return 0;
      }
    else
      {
        usage ();
        return 1;
      }
  }
}
' Libad Analog Input Example
'
' Example showing how to read the voltage at some analog inputs
' using bmcm's LIBAD4.
Imports System
Imports LIBAD4
Module Example
  ' Read analog input(s).
  Sub read_analog_inputs (driver As String, range As Integer, ByVal chav As Integer())
    ' Open DAQ system.
    Dim adh As Integer
    adh = LIBAD.ad_open (driver)
    If adh = -1 Then
      Console.WriteLine ("failed to open {0}: err = {1}", driver, LIBAD.errno)
      Exit Sub
    End If
    ' Read voltage at analog inputs.
    For i = 0 To chav.Length-1
      Dim voltage As Single = 0.0
      Dim rc As Integer
      rc = LIBAD.ad_analog_in (adh, LIBAD.AD_CHA_TYPE_ANALOG_IN or chav(i), range, voltage)
      If rc = 0 Then
        Console.WriteLine ("cha {0,2}: {1,7:##0.000} V", chav(i), voltage)
      Else
        Console.WriteLine ("error: failed to read cha {0}: err = {1}", chav(i), rc)
      End If
    Next
    ' Close DAQ system again.
    LIBAD.ad_close (adh)
  End Sub
  ' Show usage.
  Sub Usage
    Console.WriteLine ("usage: analog_in <driver> [ -r <range> ] <cha1> .. <chan>")
    Console.WriteLine ("  <driver>     string to pass to ad_open()")
    Console.WriteLine ("               - will prompt for name")
    Console.WriteLine ("  <range>      range number of analog input")
    Console.WriteLine ("  <cha1>       number of first analog input to read")
    Console.WriteLine ("  <chan>       number of last analog input to read")
    Environment.Exit (1)
  End Sub
  ' Main entry point.
  Sub Main (ByVal argv As String())
    If argv.Length > 0 Then
      ' First command line argument is the DAQ's name.
      ' If "-" is passed, then let's read the name from
      ' the console.
      Dim name As String
      name = argv(0)
      If argv(0) = "-" Then
        Console.Write ("data acquisition sytem to open: ")
        name = Console.ReadLine ()
      End If
      ' Range defaults to 0 but may get overridden by
      ' -r on the command line.
      Dim start, range As Integer
      start = 1
      range = 0
      If argv.Length > 2 Then
        If argv(start) = "-r" Then
          range = Int32.Parse (argv(start+1))
          start = start + 2
        End If
      End If
      ' Convert remaining command line arguments
      ' into numbers and add those to the channel array.
      Dim chav(argv.Length-1 - start) As Integer
      For i = start To argv.Length-1
        chav(i - start) = Int32.Parse (argv(i))
      Next
      ' Measure analog inputs and print results
      ' to the console.
      read_analog_inputs (name, range, chav)
      If argv(0) = "-" Then
        Console.WriteLine ("press return to continue...")
        Console.ReadLine ()
      End If
      Environment.Exit (0)
    Else
      Usage
      Environment.Exit (1)
    End If
  End Sub
End Module
'''
 Libad Analog Input Example
 
 Example showing how to read the voltage at some analog inputs
 using bmcm's LIBAD4.
'''

from ctypes import *
from ctypes import GetLastError
import ctypes
from operator import le
import os.path
import sys


# Load the .dll file
my_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(my_path, "libad4.dll")

try:
    libad = CDLL(os.path.join(my_path, "libad4.dll"))
except Exception as e:
    print(e)

libad.ad_open.argtypes = [ctypes.c_char_p]
libad.ad_analog_in.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int]


# Read analog inputs.
def read_analog_input(driver, rng, cha):

    # Open DAQ System.
    adh = libad.ad_open(driver.encode('utf-8'))

    if adh == -1:
        print("failed to open %s: err = %r\n" % (driver, ctypes.GetLastError()))
        return

    # Read voltage at analog inputs.
    for i in range(len(cha)):
        voltage = c_float()

        rc = libad.ad_analog_in(adh, int(cha[i]), int(rng), byref(voltage))

        if rc == 0:
            print("cha %2d: %7.3f V" % (int(cha[i]), voltage.value))
        else:
            print("error: failed to read cha %d: err = %d\n" % (int(cha[i]), rc))

    #Close DAQ System again.
    libad.ad_close(adh)

def usage():
    print("usage: <driver> [ -r <range> ] <cha1> .. <chan>\n"
          "  <driver>     string to pass to ad_open()\n"
          "               - will prompt for name\n"
          "  <range>      range number of analog input\n"
          "  <cha1>       number of first analog input to read\n"
          "  <chan>       number of last analog input to read\n")

def main():
    argv = sys.argv

    if len(argv) > 1:

        # First command line argument is the DAQ's name.
        name = argv[1]

        # Range defaults to 0 but may get overridden by
        # -r on the command line.        
        start = 2
        rng = 0

        if len(argv) > 3:
            if '-r' in argv:
                rng = argv[argv.index('-r')+1]
                start += 2

        # Convert remaining command line arguments
        # into numbers and add those to the channel array.
        cha = [argv[i] for i in range(start, len(argv))]

        read_analog_input(name, rng, cha)
    else:
        usage()
        return 1


if __name__ =='__main__':
    main()