Skip to content

Instantly share code, notes, and snippets.

@mtfurlan
Created July 17, 2020 15:07
Show Gist options
  • Save mtfurlan/ae138eb730517ac946251124feaf9037 to your computer and use it in GitHub Desktop.
Save mtfurlan/ae138eb730517ac946251124feaf9037 to your computer and use it in GitHub Desktop.
send HPGL to plotter over GPIB
#!/usr/bin/env perl
# Send HPGL to plotter
#
# Unrelated curious marc video on pen adapter https://youtu.be/h-oj4HrTH14?t=471
use strict;
use warnings;
use LinuxGpib;
use Getopt::Std;
use File::Temp qw/ tempfile tempdir /;
use Time::HiRes qw(usleep time gettimeofday);
my $device;
my $inputFile;
#----------
# usage and option initialization
my $opt_string = 'hd:';
sub usage() {
print STDERR << "EOF";
usage: $0 -h|-d PRIMARY_ADDRESS INPUTFILE
This program sends HPGL to a plotter.
EOF
}
#----------------------
getopts( "$opt_string", \my %opt ) or usage() and exit;
my $arglen = scalar @ARGV;
if($arglen == 0 or $opt{h} or not $opt{d}) {
usage();
exit;
}
if ($opt{d}) {
$device = $opt{d};
}
$inputFile = $ARGV[0];
print "device is $device\ninputFile is $inputFile\n";
open my $inputFH, '<', $inputFile || die "cannot open input inputFile $inputFile";
my $minor = 0; # gpib driver major
my $pad = $device; # device primary bus address
my $sad = 0; # device secondary bus address
my $send_eoi = 1; # Assert eoi with last byte in ibwrt
my $eos_mode = 0; # No end of string processing
my $timeout = 17; # 1000 seconds https://linux-gpib.sourceforge.io/doc_html/reference-function-ibtmo.html
# ibsta return codes from the gpib library.
# https://linux-gpib.sourceforge.io/doc_html/reference-globals-ibsta.html
my $CMPL= 0x200;
my $END = 0x2000;
my $TIMO= 0x4000;
my $ERR = 0x8000;
printf("Attempting to open /dev/gpib%i\n"
. "pad = %d, sad = %d, timeout = %d, send_eoi = %d, eos_mode = 0x%04x\n",
$minor, $pad, $sad, $timeout, $send_eoi, $eos_mode);
# connect with 300ms timeout instead of $timeout so we can ensure IN completes in 300ms so we know we have a working device
my $dev = LinuxGpib::ibdev($minor, $pad, $sad, 10, $send_eoi, $eos_mode);
sub checkError {
my $ret = $_[0];
if($ret & $ERR) {
printf("ret err: 0x%04X\n", $ret);
printf("iberr: %02X\n", LinuxGpib::ThreadIberr());
die "dunno what to do about errors\n";
}
}
my $ret;
my $deviceData;
my $ready;
# try to initialize
$ret = LinuxGpib::ibwrt($dev, 'IN;', length('IN;'));
checkError($ret);
#if it didn't time out, we have a device so increase the timeout so commands don't get lost
$ret = LinuxGpib::ibtmo($dev, $timeout);
checkError($ret);
while (my $command = <$inputFH>) {
chomp $command;
print "$command\n";
$ret = LinuxGpib::ibwrt($dev, $command, length($command));
checkError($ret);
usleep(10000);
# the manual says that you should read the plotter's output buffer to clear
# it, but leaving this out doesn't seem to cause problems here.
#$ret = LinuxGpib::ibrd($dev, $deviceData, 2004);
#usleep(10000);
$ret = LinuxGpib::ibwrt($dev, 'OA;', length('OA;'));
checkError($ret);
usleep(10000);
$ret = LinuxGpib::ibrd($dev, $deviceData, 2004);
$deviceData =~ s/\s+//g; #remove whitespace
print "read from plotter '$deviceData'\n";
checkError($ret);
usleep(10000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment