Použití USB-GPIB převodníku v Linuxu
16. 3. 2010 17:37
Provozování zařízení komunikujících přes sběrnici GPIB je v Linuxu
možné a to dokonce s využitím pouze Open Source.
Pro komunikaci využívám NI GPIB-USB-HS převodník. Jeho výhoda oproti jiným převodníkům je v tom, že pro jeho rozchození není potřeba vypreparovat firmware z binárních ovladačů pro windows. Jeho VID:PID je 3923:709b.
Instalace ovladače
Pro správnou funkci je nejprve potřeba nainstalovat ovladače linux-gpib a správně ho nastavit. Instalaci provedete s použitím přiloženého ebuildu (odkaz dole) a nebo vlastní kompilací ze zdrojových kódů. Instalaci pro Debian jsem nepochopil, protože při instalaci balíku gpib-modules-source se do adresáře /usr/src nahraje archiv pouze se zdrojáky modulů. Není u nich žádný Makefile, takže je jednoduší stáhnout oficiální zdrojáky všeho a moduly zkompilovat odsud.
V souboru /etc/gpib.conf mám pro tento převodník
nastaveno
interface { minor = 0 /* board index */ board_type = "ni_usb_b" /* type of interface */ name = "violet" /* optional name*/ pad = 0 master = yes timeout = T3s set-reos = yes }
Po připojení zařízení do USB je potřeba zavolat příkaz
gpib_config --minor 0
který inicializuje převodník. Pokud chcete používat GPIB z jiného
účtu než root je dobré přidat příslušného uživatele do
skupiny gpib. Pokud vše proběhlo jak má. Měla by se vám
vytvořit zařízení /dev/gpib0 až /dev/gpib15.
Komunikace s přístrojem
Pro komunikaci s přístrojem je možné použít jednoduchou utilitku
ibtest. Pokud chcete posílat sběrnicové příkazy, použijete
volbu „b“ jako board. Jako název použijete položku „name“, kterou
jste si zvolili v konfiguraci. Pokud chcete komunikovat přímo
s přístrojem, stačí napsat „d“ jako device a následně napsat
číselně adresu tohoto přístroje.
Používám momentálně tři přístroje na této sběrnici.
- Multimetr Keithley na adrese 12
- Čítač Picotest na adrese 2
- Čítač Stanford na adrese 16
Vrátím se tedy k utilitce ibtest. Pokud tedy zvolím režim
device a následně například adresu připojeného multimetru (12), objeví se
nabídka s možností příkazů. Asi nejdůležitější příkazy jsou
v tuto chvíli příkazy „w“ a „r“.
Stisknu tedy „w“ a zadám příkaz
*IDN?
Po následném stisknutí „r“ se načte identifikace
KEITHLEY INSTRUMENTS INC.,MODEL 2700,1120230,B09 /A02
To vypadá dobře, takže zkusím načíst nějaká data. Mohu použít
například příkaz READ?, který vrátí to, co je zrovna na
displeji. Pokud jsem si tedy nastavil přístroj tak, aby měřil něco
konkrétního, pak mohu v určité periodě volat příkaz „READ?“ a tím
provádět nová měření se stejnou konfigurací. V mém případě měřím
multimetrem teplotu pomocí PT100. Ta je připojena pomocí 4 vodičů. Pro
výběr čtyřvodičového měření teploty mohu do multimetru před měření
poslat příkaz conf:fres, který přepne multimetr do přesného
měření odporu.
API pro přístup k přístroji
Pro jednoduchou komunikaci je možné použít knihovnu pro jazyk C a přímo komunikovat se zařízením.
#include <iostream> #include <gpib/ib.h> using namespace std; int main() { int dev; int board_index = 0; int pad = 12; int sad = 0; int send_eoi = 1; int eos_mode = 0; char buffer[100]; // pripojeni ke karte dev = ibdev(board_index, pad, sad, TNONE, send_eoi, eos_mode); if( dev < 0 ) { cerr << "ibdev() failed" << endl; cerr << gpib_error_string( ThreadIberr() ); return -1; } for(int i=0; i<10; i++) { // odeslani prikazu pro mereni odporu ibwrt(dev, "measure:fresistance?\n", 21); sleep(1); // nacteni dat ibrd(dev, buffer, 100); // zjistim, kolik znaku prislo a ukoncim retezec buffer[ThreadIbcnt()] = 0; cout << buffer; } // prepnu zarizeni z REMOTE do LOCAL ibloc(dev); // uzavru komunikaci se zarizenim ibonl(dev, 0); return 0; }
Při kompilaci je pak nutné přilinkovat knihovnu
libgpib.so.
Skriptování
Protože jsem si zvolil, že chci zkompilovat podporu i pro PHP. Mám teď další, trochu pohodlnější možnost komunikace s přístrojem.
#!/usr/bin/php -q <?php $pad = 12; $count = 10; function device_connect($pad) { $dev = ibdev(0, $pad, 0, T10s, 1, 0); return $dev; } function multi_prepare_fres($dev) { ibwrt($dev, "conf:fres"); } function device_disconnect($dev) { ibloc($dev); } function multi_fres($dev) { //ibwrt($dev, "meas:fres?"); ibwrt($dev, "read?"); // nactu data ibrd($dev, &$data, 1024); list($ohm4w, $secs, $rdng) = explode(",", $data); $ohm4w = $ohm4w + 0; $secs = $secs + 0; $rdng = $rdng + 0; $result = array("ohm" => $ohm4w, "time" => $secs, "rdng" => $rdng); return $result; } // prevod pro PT100 pro teploty > 100C function ohm2deg($ohm) { $a = 3.9083e-3; $b = -5.775e-7; $r = $ohm/100; return -($a - sqrt($a*$a - 4*$b + 4*$r*$b))/(2*$b); } $dev = device_connect($pad); multi_prepare_fres($dev); for($i=0; $i<$count || $count<0; $i++) { $data = multi_fres($dev); $deg = ohm2deg($data['ohm']); echo "$deg\t{$data['ohm']}\t{$data['time']}\n"; sleep(1); } device_disconnect($dev);
Program se připojí k přístroji, nastaví měření a provede deset odměrů s periodou zhruba 1s. Poté převede přístroj zpět do lokálního režimu.
Závěr
Popisovaný způsob komunikace s přístrojem funguje vcelku správně.
Není potřeba VISA knihovna, i když by to s ní bylo jednodušší. Bohužel
jsem zatím nepřišel na to, proč se dějí některé anomálie. Pokud
například násilně ukončím právě probíhající měření „CTRL-C“,
pak se celý převodník převede do nefunkčního stavu a ani po uplynutí
timeoutu se nic neděje. Nereaguje dokonce ani opětovné zavolání příkazu
gpib_config --minor 0. To také timeoutuje. Nezbývá, než celý
převodník odpojit od USB, připojit znovu a znovu spustit konfiguraci. Od
této chvíle fungují znovu všechna měření.

