Analogausgänge
Mit Hilfe der LIBAD4 Bibliothek ist es sehr einfach, einen Analogausgang auf eine bestimmte Spannung zu setzen. Dazu öffnet das Beispiel Messsystem (ad_open
), gibt dann die Werte an verschiedenen Ausgängen aus (ad_analog_out
) und zuletzt wird das Messsystem wieder geschlossen (ad_close
). Natürlich würde in einem realen Programm das Messsystem nur einmal am Beginn des Programms geöffent und am Ende wieder geschlossen werden.
Der Sourcecode des Beispiels befindet sich im LIBAD4 SDK im Verzeichnis examples/analog_out
(und dort jeweils in den Verzeichnissen c
, cs
und vb
für C/C++, C# und Visual Basic™ .Net). Wie alle Beispiele, verzichtet auch dieses aus Gründen der Einfachheit auf eine solide Fehlerbehandlung...
Das Beispiel verwendet die Routine write_analog_outputs()
um den Aufruf der LIBAD4 Funktionen ad_open()
, ad_analog_out()
und ad_close()
zu zeigen. An diese Routine wird der Name des Messgeräts (driver
), die Nummer des Messbereichs (range
), die Nummern der zu messenden Eingänge (chav
) und die auszugebenden Spannungswerte (voltagev
) übergeben. Die C/C++ Variante übergibt zusätzlich noch die Anzahl der Kanäle (chac
). Alle Argumente werden in main()
von der Kommandozeile gewonnen, entsprechend aufbereitet und dann an write_analog_outputs()
übergeben.
Der erste Parameter auf der Kommandozeile wird in driver
übergeben und legt das Messsystem fest. Beispielsweise öffnet "usb-ad
:@100" das USB-AD mit der Seriennumer 100. Ausführliche Hinweise zu den notwendigen Namen für die verschiedenen Messsysteme finden Sie im LIBAD4 Handbuch in Kapitel 6, Messsysteme.
Dieser Name wird von write_analog_outputs()
direkt an ad_open()
weitergegeben. Der Rückgabewert von ad_open()
ist ein Handle, der das geöffnete Messsystem repräsentiert und an alle Funktionen der LIBAD4 übergeben werden muss. Im Fehlerfall wird -1
zurückgegeben.
Der Parameter range
definiert den Messbereich und wird in main()
durch das optionale Kommandzeilenargument -r <range>
bestimmt. Per default steht dieser Wert auf 0 und wählt damit beispielsweise den +/- 5V Messbereichs eines USB-AD aus. Die einzelnen Messbereiche der verschiedenen Messsysteme sind auch in Kapitel 6 des LIBAD4 Handbuchs beschrieben.
Die restlichen Argumente auf der Kommandzeile werden von main()
in Zahlen konvertiert und in die Felder chav[]
und voltagev[]
geschrieben. In einer Schleife über alle Kanäle übergibt write_analog_outputs()
diese Werte dann an ad_analog_out()
um die Spannung am Analogausgang einzustellen. Dabei spezifiert das erste Argument (adh
) das Messsystem (wie von ad_open()
geliefert), das zweite Argument den Kanal (bestehend aus dem Kanaltyp AD_ANLOG_OUTPUT
und der Nummer des Kanals chav[i]
) und das dritte Argument den Messbereich (range
). Als letztes Argument wird voltagev[i]
übergeben, mit dem die Ausgangsspannung festgelegt wird. Die Funktion gibt im Fehlerfall einen Wert ungleich null zurück, wobei diese Fehlernummer immer einer Fehlernummer des Hostrechners entspricht (also z.B. unter Windows wird eine Fehlernummer aus <winerror.h>
zurückgegeben).
Nach dem Schleifenende wird das Messsystem mit ad_close()
wieder geschlossen.
LIBAD - Programmierschnittstelle (API)
/* Libad Analog Output Example
*
* Example showing how to set the voltage at some analog outputs
* using bmcm's LIBAD4.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "libad.h"
/* Set analog output(s).
*/
void
write_analog_outputs (const char *driver, int range, int chac, int chav[], float voltagev[])
{
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;
}
/* Set analog output to some voltage.
*/
for (i = 0; i < chac; i++)
{
int rc;
rc = ad_analog_out (adh, AD_CHA_TYPE_ANALOG_OUT | chav[i], range, voltagev[i]);
if (rc == 0)
printf ("cha %2d: %7.3f V\n", chav[i], voltagev[i]);
else
printf ("error: failed to write cha %d: err = %d\n", chav[i], rc);
}
/* Close DAQ system again.
*/
ad_close (adh);
}
/* Show usage.
*/
void
usage ()
{
printf ("usage: analog_out <driver> [ -r <range> ] [<cha1>,] <voltage1> .. [<chan>,] voltagen\n"
" <driver> string to pass to ad_open()\n"
" - will prompt for name\n"
" <range> range number of analog output\n"
" <cha1..n> number of analog output to set\n"
" <voltage1..n> output voltage\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];
float voltagev[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 channel
* numbers and voltages. Add those to the appropriate array.
*/
chac = 0;
for (i = start; i < argc; i++)
{
char *delim;
delim = strchr (argv[i], ',');
if (delim)
{
chav[chac] = atoi (argv[i]);
voltagev[chac] = (float) atof (delim+1);
}
else
{
chav[chac] = 1;
voltagev[chac] = (float) atof (argv[i]);
}
chac++;
if (chac >= 16)
break;
}
/* Set analog outputs accordingly.
*/
write_analog_outputs (name, range, chac, chav, voltagev);
if (strcmp (argv[1], "-") == 0)
{
printf ("press return to continue...\n");
fgets (tmp, sizeof(tmp), stdin);
}
return 0;
}
else
{
usage ();
return 1;
}
}
// Libad Analog Output Example
//
// Example showing how to set the voltage at some analog outputs
// using bmcm's LIBAD4.
using System;
using LIBAD4;
static class Example
{
// Set analog output(s).
static void
write_analog_outputs (string driver, int range, int[] chav, float[] voltagev)
{
// Open DAQ system.
int adh = LIBAD.ad_open (driver);
if (adh == -1)
{
Console.WriteLine ("failed to open {0}: err = {1}", driver, LIBAD.errno);
return;
}
// Set analog output to some voltage.
for (int i = 0; i < chav.Length; i++)
{
int rc;
rc = LIBAD.ad_analog_out (adh, LIBAD.AD_CHA_TYPE_ANALOG_IN | chav[i], range, voltagev[i]);
if (rc == 0)
Console.WriteLine ("cha {0,2}: {1,7:##0.000} V", chav[i], voltagev[i]);
else
Console.WriteLine ("error: failed to write cha {0}: err = {1}", chav[i], rc);
}
// Close DAQ system again.
LIBAD.ad_close (adh);
}
// Show usage.
static void
usage ()
{
Console.WriteLine ("usage: analog_out <driver> [ -r <range> ] [<cha1>,] <voltage1> .. [<chan>,] voltagen");
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..n> number of analog output to set");
Console.WriteLine (" <voltage1..n> output voltage");
}
// 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 system 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 channel
// numbers and voltages. Add those to the appropriate array.
int[] chav = new int[argv.Length - start];
float[] voltagev = new float[argv.Length - start];
for (int i = start; i < argv.Length; i++)
{
int delim = argv[i].IndexOf (',');
if (delim >= 0)
{
chav[i - start] = int.Parse (argv[i].Substring (0, delim));
voltagev[i - start] = float.Parse (argv[i].Substring (delim+1));
}
else
{
chav[i - start] = 1;
voltagev[i - start] = float.Parse (argv[i]);
}
}
// Set analog outputs accordingly.
write_analog_outputs (name, range, chav, voltagev);
if (argv[0]== "-")
{
Console.WriteLine ("press return to continue...");
Console.ReadLine ();
}
return 0;
}
else
{
usage ();
return 1;
}
}
}
' Libad Analog Output Example
'
' Example showing how to set the voltage at some analog outputs
' using bmcm's LIBAD4.
Imports System
Imports LIBAD4
Module Example
' Set analog output(s).
Sub write_analog_outputs (driver As String, range As Integer, ByVal chav As Integer(), ByVal voltagev As Single())
' 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
' Set analog output to some voltage.
For i = 0 To chav.Length-1
Dim rc As Integer
rc = LIBAD.ad_analog_out (adh, LIBAD.AD_CHA_TYPE_ANALOG_IN or chav(i), range, voltagev(i))
If rc = 0 Then
Console.WriteLine ("cha {0,2}: {1,7:##0.000} V", chav(i), voltagev(i))
Else
Console.WriteLine ("error: failed to write 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_out <driver> [ -r <range> ] [<cha1>,] <voltage1> .. [<chan>,] voltagen")
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..n> number of analog output to set")
Console.WriteLine (" <voltage1..n> output voltage")
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 channel
' numbers and voltages. Add those to the appropriate array.
Dim chav(argv.Length-1 - start) As Integer
Dim voltagev(argv.Length-1 - start) As Single
For i = start To argv.Length-1
Dim delim As Integer
delim = argv(i).IndexOf (",")
If delim >= 0 Then
chav(i - start) = Int32.Parse (argv(i).SubString (0, delim))
voltagev(i - start) = Single.Parse (argv(i).SubString (delim+1))
Else
chav(i - start) = 1
voltagev(i - start) = Single.Parse (argv(i))
End If
Next
' Set analog outputs accordingly.
write_analog_outputs (name, range, chav, voltagev)
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