The VM700T has no documented provisions for obtaining a screen image capture via the GPIB port. Some have tried various methods, with reasonable success.
The following hints are offered “as is”, but should prove useful to a skilled programmer.
GPIB, Caveats and Hints, General.
- The serial portwhich is selected for the copy port must have its flow controlset to CTS/RTS so the spooler doesn't spool the file out the serial port. If set to XON/XOFF, the file will be present for a little while and will subsequently disappear. Setting it to CTS/RTS prevents the spooler from sending the data out the port so the file stays in the spool buffer.
- It isn't necessary to specify PostScript as the file format but it provides the smallest file and thus the fastest transfer (though it is the most difficult format to translate to a bitmap).
- Using SRQ to determine when an operation has completed is not always reliable.
- No error status is sent back when an incorrect command is sent (e.g., incorrect case). Checking with evmsg? is required to determine if an operation completed without an error.
- Often, reading back the result status will hold the bus long enough that the command which was sent will have completed but this is not true for the copy command (i.e., the 0xff 0x0a is sent before the copy has completed). A fixed delay (e.g., 1 second) is required between the hardkey Copy and the next command (otherwise the frame is incomplete). Also, a fixed delay (e.g., 300 ms) is required between the "show xxx" command and actually reading the data or you will get an empty buffer (thoughyou could loop on reading it until data shows up instead of using the fixed delay).
- It is not necessary to usefilemode or to loop for the filename. Executing filesin /spooler will provide the list of files. Since the cancelcopy is sent before the hardkey Copy, only one file will be present.
- It is not necessary to use the readfile command to read the spooler data back unless the image is in a binary file format. The show command will read back the file so long as it is in ASCII format (as isa PostScript file). Attempting to send a binary file using show will result in a truncated file.
- The GPIB controller for the VM700T is slow and not ultimately robust. In some instances, sending a sequence of commands may result in the machine locking up or hanging the bus. In the case of hanging the bus, the front panel still worked but the device prevented any GPIB activity (i.e., you cannot talk to other devices on the same bus segment). In both cases, re- cycle power to get things working properly again.
- The file formats for the other printers are not clearly documented. The correct table should look like this:
Selected printer Format
------
NoneNothing
Epson LQESC/P2 (Epson escape codes /P2 version)
PostScriptPostScript level 2 compatible
ASCII PrinterASCII text only (graphics is not supported)
HP LaserJet HP PCL 4
HP DeskjetHP PCL 4
HP Thinkjet HP PCL 4
* note that all images are monochrome and are printed landscape - The resulting images are landscape and must be rotated before display. For PostScript, they also need to be translated and scaled to be a reasonable number of pixels. A utility named GhostScript has been used by some to do the conversion from PostScript to PNG (Portable Network Graphics). Rotating, translating, and scaling the image in PostScript is easy if you do it before the translation. Simply searched for the existing translate and scale commands:
535 107 translate
90 rotate 0.9 0.9 scale
and replaced them with
40 10 translate
0 rotate 0.63 0.63 scale
and then run the resulting PostScript file throughgswin32c with the following parameters:
-dSAFER -dBATCH -dNOPAUSE -Ighostscript -sDEVICE=pnggray -dTextAlphaBits=4 -r120 -g800x600 -sOutputFile=output.png input.ps
which generated an 800x600 image in PNG format with the image properly centered and sized in the portrait orientation.
------
A sample Communication Setup configuration
Communication setup
Copy
Port:SerialPort 0
Format: PostScript
Report
Port: Serial Port 0
Format: ASCII Printer
Log
Port: Serial Port 0
Format: ASCII Printer
ControlPort:SerialPort 1
Remote Control
Port: GPIB
Prompt: VM700>
Message Display: Remote
Non-SLIP Interfacing Mode: Computer
Port 0
Protocol: None
Baud Rate: 19200
Flow Control:CTS/RTS
Character Size: 8
Parity: None
Reset Character: None
Carrier Detect: disabled
Port 1
Protocol: None
Baud Rate: 9600
Flow Control:CTS/RTS
Character Size: 8
Parity: None
Reset Character: None
Carrier Detect: disabled
GPIB Device Address: 1
Code fragments, useful (and important) to experienced programmers.
//
// From the initialization in TVM700::Open
//
//
// Make sure the VM700 remote control port is set to GPIB.
//
if (get ("SPRC") != "GPIB")
throw ("The Remote Control Port must be set to GPIB and this must be done manually.");
//
// Make sure serial port 0's flow control setting is set to CTS/RTS so
// the spool file won't disappear on us.
//
if (get ("SP0F") != "CTS/RTS")
throw Exception ("The Serial Port 0 flow control setting must be set to CTS/RTS and this must be done manually.");
//
//Initialize the device to a known state where we are examining a NTSCs-video signal on ports B-C.
//Also, set the copy port to serial port 0 and set the file format to Postscript. Setting it to
//GPIB doesn't work!
//
AnsiString s;
*this < "init;"
"hardpress B;"
"hardkey C;"
"hardrelease B;"
"set VSTANTSC;"
"set VSTB NTSC;"
"set VSTC NTSC"
"set SPCP Serial Port 0;"
"set SPCF PostScript"
> s;
//
// From the actual test in TVM700::ColorBurstTest
//
*this < "execute Burst~Frequency;"
"hardkey Menu;"
"softkey Reference;"
"softkey Reference_Ch_A;"
"hardkey Average"
> s;
Sleep (1500);
*this < "hardkey Menu;"
"softkey Rescale;"
"hardkey Freeze;"
"getresults verbose"
> s;
*this < "show Burst~Frequency";
AnsiString results = get_file ();
More useful routines:
//------
void __fastcall TVM700::get_screen_capture (AnsiString filename)
{
AnsiString s;
*this < "cancelcopy" > s;
*this < "hardkey Copy"> s;
Sleep (1000); // wait for slow VM700T copy to complete
*this < "filesin /spooler";
AnsiString file = get_file ().Trim ();
if (file.IsEmpty ())
throw Exception ("Unable to read spool file for screen capture");
*this < "show /spooler/" + file;
Sleep (300); // wait for slow VM700T to start filling the buffer
s = get_file ();
if (!s.IsEmpty ())
{
//
// Rotate landscape image to portrait image and translate it and
// rescale it so the 2550x3300 image will be centered and properly
// sized in the final 620x480 image.
//
s = AnsiReplaceText (s, "535 107 translate", "40 10 translate");
s = AnsiReplaceText (s, "90 rotate 0.9 0.9 scale", "0 rotate 0.63 0.63 scale");
//
// Save the PostScript file to a temporary file.
//
ofstream out ((filename + ".ps").c_str ());
out < s;
out.close ();
}
else
throw Exception ("Error getting screen capture.");
//
// Convert PostScript file to PNG file using external ghostscript.
//
const char* GS = "ghostscript\\gswin32c -dSAFER -dBATCH -dNOPAUSE -Ighostscript -sDEVICE=pnggray -dTextAlphaBits=4 -r120 -g800x600 -sOutputFile=\"";
AnsiString command = GS + filename + ".png\" \"" + filename + ".ps\"";
if (system (command.c_str ()) == -1)
throw Exception ("Error converting PostScript file to PNG.");
DeleteFile (filename + ".ps");
}
//------
AnsiString __fastcall TVM700::get (AnsiString value)
{
AnsiString s;
*this < "get " + value;
Sleep (200); // wait for slow VM700T to get data
*this > s;
return s.Trim ();
}
Additional notes related to the previous code ideas.
The TVM700::get_file () just reads the definite length arbitrary block format file and returns it in an AnsiString. The only thing special about it is that it waits 300 ms before starting to read to give the VM700T time to start putting stuff into the buffer (since starting the read, even with a long timeout like 10 s, will not return the data but will instead timeout). All GPIB commands are sent to the VM700T using standard (C++ library) iostream inserters and reads are done using iostream extractors. The *this value isused asthe iostream handle (i.e., TVM700 has the > and < operators overloaded so they call the ibwrt and ibrd routines--an exception is generated if an error occurs).
For these examples, the programming environment used was Borland C++ Builder 6,writen in C++, and using the VCL (Visual Class Library). If you want to use M$ VCPP, you'll need to do some recoding (though the majority will port without modification). Key items like AnsiString will have to be translated to less capable classes like CString, and you'll need to find equivalent commands for things like DeleteFile, and the Exception class).