Analogeingänge
Mit Hilfe der LIBAD4 Bibliothek ist es sehr einfach, die aktuelle Spannung eines Analogeingangs zu messen. Dazu öffnet das Beispiel Messsystem (ad_open
), liest dann die Werte an verschiedenen Eingängen aus (ad_analog_in
) 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öffnet und am Ende wieder geschlossen werden.
Der Sourcecode des Beispiels befindet sich im LIBAD4 SDK im Verzeichnis examples/analog_in
(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 read_analog_inputs()
um den Aufruf der LIBAD4 Funktionen ad_open()
, ad_analog_in()
und ad_close()
zu zeigen. An diese Routine wird der Name des Messgeräts (driver
), die Nummer des Messbereichs (range
) und die Nummern der zu messenden Eingänge (chav
) ü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 read_analog_inputs()
ü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 read_analog_inputs()
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 das Feld chav[]
geschrieben. In einer Schleife über alle Kanäle übergibt read_analog_inputs()
diese Werte dann an ad_analog_in()
, mit der die Spannung eines Analogeingangs gemessen wird. Dabei spezifiert das erste Argument (adh
) das Messsystem (wie von ad_open()
geliefert), das zweite Argument den Kanal (bestehend aus dem Kanaltyp AD_ANLOG_INPUT
und der Nummer des Kanals chav[i]
) und das dritte Argument den Messbereich (range
). Als letztes Argument wird die Variable voltage
übergeben, in die ad_analog_in()
den gemessenen Spannungswert schreibt. 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 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()