Введение

В прошлом году я создал фальшивый параллельный принтер, — инструмент для перехвата вывода из порта параллельного принтера старого измерительного оборудования, чтобы данные можно было преобразовывать в скриншоты для постов и тому подобного.

Fake parallel printer photo

Это очень нишевый инструмент, но из всех разработанных мной проектов он определённо используется чаще всего.

Одна из проблем заключается в том, что для преобразования перехваченных сырых данных печати в растровое изображение требуется достаточно долгая настройка. В каком-то оборудовании применяется HP PCL, в другом — Encapsulated Postscript (EPS), а если повезёт, то вывод будет в стандартном растровом формате наподобие PCX.

В этом посте я расскажу о процедурах для создания скриншотов измерительного оборудования, которое есть лично у меня, чтобы мне не пришлось разбираться заново, когда спустя год я снова возьмусь за это оборудование.

Возможно, пост будет не очень полезен остальным людям, но, может, кому-то он пригодится при гуглении… Как всегда, я работаю с Linux, что сказывается на ПО.

Интерфейсы записи скриншотов

Вот одни из самых распространённых способов передачи скриншотов с измерительного оборудования в PC:

  • USB-флэшка

    Обычно наименее проблемный из способов, но работает только с современным оборудованием.

  • USB-кабель

    Требует некоторых усилий по настройке разрешений драйвера udev, а также скрипта, отправляющего команды для конкретного устройства. Но обычно работает хорошо.

  • Ethernet

    Тоже требует относительно современного оборудования, и часто приходится повозиться с конфигурацией.

  • Последовательный порт RS-232

    Надёжный, но часто медленный.

  • Гибкий диск

    У меня есть много оборудования с приводом гибких дисков, а также USB-привод гибких дисков для PC. Однако приводы на всём этом оборудовании поломаны, по крайней мере, они не могут корректно записывать данные на диск. Возможно, когда головка привода не используется десятками лет, происходит какое-то загрязнение.

  • GPIB

    Требует дорогостоящего интерфейсного донгла, и я так и не разобрался, как заставить его работать для всего оборудования. Например, в статье я научился работать с ним в осциллографе TDS 540, но не в осциллографе HP 54532A.

  • Порт параллельного принтера

    Доступен во многих старых железяках, но в обычном состоянии его вывод нельзя перехватывать через PC, если не использовать фальшивый параллельный принтер.

    Уже прошло больше года, и я использую его постоянно. По-моему, это самый простой для работы интерфейс из всех принтерных.

Аппаратные и программные инструменты

Донгл GPIB-USB

Если вы хотите печатать через GPIB, то вам нужен будет интерфейс с PC на GPIB. Сегодня самый дешёвый и распространённый вариант — это донглы с GPIB на USB. Я уже писал о них.

Agilent 82357B GPIB to USB dongle
Донгл Agilent 82357B GPIB-USB

Самый важный вывод: они дорогие (больше ста долларов с рук) и сложны в настройке под Linux. И, как я говорил выше, в режиме принтера он у меня работал только с некоторыми устройствами.

ImageMagick

ImageMagick — это «швейцарский нож» обработки растровых изображений. У него миллион функций, но я в основном его применял для преобразования форматов файлов и обрезки изображений.

Сомневаюсь, что существуют какие-то популярные дистрибутивы Linux, где его нет в стандартном наборе…

sudo apt install imagemagick

GhostPCL

GhostPCL используется для декодирования файлов PCL. На многих старых машинах эти файлы создаются при печати на Thinkjet, Deskjet или Laserjet.

Установка:

cd ~/tools
tar xfv ~/Downloads/ghostpdl-10.03.0.tar.gz
cd ghostpdl-10.03.0/
./configure --prefix=/opt/ghostpdl
make -j$(nproc)
export PATH="/opt/ghostpdl/bin:$PATH"
  • Установить

sudo make install

После этого в /opt/ghostpdl/bin появится куча инструментов, в том числе gs (Ghostscript) и gpcl6.

hp2xx

hp2xx преобразует файлы HPGL, изначально предназначенные для плоттера HP, в растровые изображения, EPS и так далее.

Он доступен в качестве стандартного пакета для Ubuntu:

sudo apt install hp2xx

Inkscape

Inkscape — это полнофункциональное приложение для векторного рисования, но оно также используется и как инструмент командной строки для преобразования векторного контента в растровый. Я использую его, чтобы конвертировать Encapsulated Postscript file (EPS) в растровые изображения.

Установить его в Ubuntu, как и многие популярные инструменты, очень просто:

sudo apt install inkscape

HP 8753C Companion

Этот инструмент предназначен конкретно для векторных анализаторов цепей HP 8753. Он перехватывает плоттерные команды HPGL, извлекает данные, воссоздаёт то, что отображается на экране, и позволяет пользователю взаимодействовать с информацией.

Он доступен на GitHub.

Перехват данных GPIB в режиме Talk Only

Некоторые устройства выполняют печать в GPIB только в режиме Talk Only или их иногда проще использовать таким образом.

Когда устройство находится в режиме Talk Only, PC-контроллер GPIB становится устройством Listen Only — пассивным наблюдателем, не инициирующим команды и только получающим данные.

TDS540 in talk-only mode
TDS540 в режиме talk-only

Для записи данных печати и их сохранения в файл я написал следующий скрипт:

gpib_talk_to_file.py:

#! /usr/bin/env python3

import sys
import pyvisa

gpib_addr       = int(sys.argv[1])
output_filename = sys.argv[2]

rm = pyvisa.ResourceManager()

inst = rm.open_resource(f'GPIB::{gpib_addr}')

try:
    # Считываем данные с устройства
    data = inst.read_raw()

    with open(output_filename, 'wb') as file:
        file.write(data)

except pyvisa.VisaIOError as e:
    print(f"Error: {e}")

Pyvisa — это универсальная библиотека для общения с измерительным оборудованием. Я уже писал о ней. Когда в режиме Talk Only не поступают данные, она выполняет быстрый таймаут, но поскольку вся передача данных происходит при помощи протокола valid-ready, можно избежать проблем с таймаутами, сначала нажав на осциллографе кнопку Hardcopy или Print, и только потом запустив этот скрипт.

Это будет работать, если только печатающее устройство не замолчит в процессе печати страницы.

Осциллограф TDS 540 - вывод GPIB - PCL

TDS540 oscilloscope

У моего старого осциллографа TDS 540 нет принтерного порта, поэтому пришлось использовать GPIB. В отличие от более новых версий серии TDS, он также не умеет напрямую экспортировать растровые изображения, зато у него есть вывод:

  • Для Thinkjet, Deskjet и Laserjet в формате PCL

  • Для Epson в формате ESC/P

  • В формат Interleaf

  • В формат изображений EPS

  • В плоттерный формат HPGL

Экран TDS 540 имеет разрешение экрана 640x480. Я нашёл формат вывода Thinkjet с DPI 75x75, с которым проще всего было работать. Устройство добавляет границу в 20 пикселей слева и 47 пикселей справа, но их можно удалить при помощи ImageMagick.

GPIB имеет адрес 11, а весь процесс выглядит так:

# Перехватываем данные PCL
gpib_talk_to_file.py 11 tds540.thinkjet.pcl
# Преобразуем PCL в png 
gpcl6 -dNOPAUSE -sOutputFile=tds540.png -sDEVICE=png256 -g680x574 -r75x75 tds540.thinkjet.pcl
# Удаляем границы и обрезаем изображение под размер 640x480
convert tds540.png -crop 640x480+20+47 tds540.crop.png

Окончательный результат выглядит так:

TDS540 screenshot

HP 54542A Oscilloscope — параллельный порт — вывод PCL или HPGL

Этот осциллограф я приобрёл за смешные 20 долларов на блошином рынке электроники Кремниевой долины, и с ним мне нравится работать больше всего: пользовательский интерфейс очень плавный и интуитивно понятный. Самая большая проблема у него, как и у всех остальных старых осциллографов, заключается в том, сколько места он занимает на столе.

HP 54542A oscilloscope
Осциллограф HP 54542A

У него есть GPIB, RS-232 и параллельный порт Centronics, и все три можно использовать для печати.

Я попытался настроить печать через GPIB, но не преуспел: я смог пообщаться с устройством, отправлять команды наподобие «*IDN?» и оно отвечало без проблем, но скрипт GPIB, отлично работавший с TDS 540, всегда выполнял таймауты.

Я воспользовался своим надёжным фальшивым параллельным принтером, и он снова не подвёл. Также есть вариант использовать последовательный кабель.

Открыть меню настроек принтера можно, нажав на кнопку Utility, а затем на верхнюю программную кнопку с именем «HPIB/RS232/CENT CENTRONICS».

HP 54542A printing options
Опции печати HP 54542A

У нас есть следующие опции:

  • ThinkJet

  • DeskJet75dpi, DeskJet100dpi, DeskJet150dpi, DeskJet300dpi

  • LaserJet

  • PaintJet

  • Plotter

В отличие от ситуации с TDS 540, я не смог заставить опцию ThinkJet выполнять конвертирование во что-нибудь, но опция DeskJet75dpi нормально работала вот с этим «рецептом»:

~/projects/fake_parallel_printer/fake_printer.py -i -p /dev/ttyACM0 -f hp54542a_ -s deskjet.pcl -v
gpcl6 -dNOPAUSE -sOutputFile=hp54542a.png -sDEVICE=png256 -g680x700 -r75x75 hp54542a_0.deskjet.pcl
convert hp54542a.png -crop 640x388+19+96 hp54542a.crop.png

54542A не просто выводит содержимое экрана, но и печатает дату, а также добавляет настройки для включённых каналов, опции переключателей и так далее. Размер этих дополнительных значений зависит от количества включенных каналов и других параметров.

HP 54542A with additional info

При выборе в качестве устройства для вывода PaintJet или Plotter появляется опция выбора других цветов для обычных каналов, математических каналов, сетки, маркеров и так далее. Поэтому можно создавать красивые цветные скриншоты, хоть ЭЛТ-экран устройства и монохромный.

Я попробовал опцию PaintJet, и хотя gcpl6 смог извлечь изображение, выходные данные были гораздо хуже, чем с опцией DeskJet.

С опцией Plotter мне повезло больше. Она выводит файл в формате HPGL, который можно преобразовать в растровое изображение при помощи hp2xx. У меня сработал следующий «рецепт»:

~/projects/fake_parallel_printer/fake_printer.py -i -p /dev/ttyACM0 -f hp54542a_ -s plotter.hpgl -v
hp2xx -m png -a 1.4 --width 250 --height 250 -c 12345671 -p 11111111 hp54542a_0.plotter.hpgl

Я не в восторге от того, как это выглядит, но если вам нужны цвета, то это наилучший вариант. Опции командной строки hp2xx не интуитивны. Вероятно, картинку можно улучшить, если использовать какие-то другие опции.

HP plotter output

Осциллограф HP Inifinium 54825A — параллельный порт — Encapsulated Postscript

HP 54825A oscilloscope

Внутри этого осциллографа, который я позаимствовал у друга на неопределённый срок, есть маленький PC, работающий на старой версии Windows. Его можно подключить к Ethernet, но я никогда этого не делал: мне очень уж удобно перехватывать трафик параллельного принтера.

Я выяснил, что для этого осциллографа наилучшим вариантом для печати оказался Encapsulated Postscript. Далее я использовал Inkscape для преобразования скриншота в PNG:

./fake_printer.py --port=/dev/ttyACM0 -t 2 -v --prefix=hp_osc_ -s eps
inkscape -f ./hp_osc_0.eps -w 1580 -y=255 -e hp_osc_0.png
convert hp_osc_0.png -crop 1294x971+142+80 hp_osc_0_cropped.png

Не обращайте внимания на часть, обведённую красным, она была добавлена в пост для предыдущей статьи:

HP 54825A screenshot

TDS 684B — параллельный порт — цветной вывод PCX

Я заменил свой осциллограф TDS 540 на TDS 684B.

TDS 684B
TDS 684B

Внешне они выглядят одинаково. Кроме того, у них один и тот же базовый пользовательский интерфейс, но у 648B цветной экран, ширина спектра 1 ГГц и частота дискретизации 5 гигасэмплов в секунду.

Форматы печати

Кроме того, у 684B имеется гораздо больше вариантов вывода:

  • Вывод Thinkjet, Deskjet, DeskjetC (цветной), Laserjet в формате PCL

  • Epson в формате ESC/P

  • Термопринтер DPU

  • Монохромный и цветной PC Paintbrush в формате файлов PCX

  • Формат файлов TIFF

  • Монохромный и цветной формат BMP

  • Цветной формат RLE

  • Монохромный и цветной принтерный формат EPS

  • Монохромный и цветной плоттерный формат EPS

  • формат Interleaf .img

  • Цветной плоттерный формат HPGL

Как и у HP 54542A, у моего устройства есть GPIB, параллельный и последовательный порты. Кроме того, он может записывать файлы на дискету.

Какой же формат использовать?

Самый очевидный выбор — BMP, он нативно поддерживается всеми современными PC. Единственная проблема заключается в том, что он выводится без сжатия, поэтому при перехвате фальшивым принтером это занимает более 130 секунд. PCX — это очень старый формат растровых файлов, я пользовался им ещё в 1988 году на моём первом Intel 8088 PC, но от выполняет сжатие кодированием длин серий, что отлично подходит для скриншотов осциллографа. Печать занимает всего 22 секунды.

Я попробовал вариант с TIFF, и с радостью увидел, что он потребовал всего 17 секунд, но вывод оказался монохромным. Поэтому для цветных растровых изображений лучше всего выбирать PCX. «Рецепт»:

~/projects/fake_parallel_printer/fake_printer.py -i -p /dev/ttyACM0 -f tds684_ -s pcx -v
convert tds684_0.pcx tds684.png
TDS 684B PCX screenshot with normal colors

На скриншоте выше показаны настройки цвета Normal. Также есть настройки Bold:

TDS 684B screenshot with bold colors

Есть и опция Hardcopy (для печати на бумаге):

TDS 684B screenshot with hardcopy colors

Это вопрос личных предпочтений. Мне больше нравится опция Normal.

Спектральный анализатор Advantest R3273 — параллельный порт — вывод PCL

Теперь перейдём к моему спектральному анализатору Advantest R3273.

R3273 spectrum analyzer

У него есть принтерный порт, отдельный параллельный порт, предназначение которого я не знаю, последовательный порт, порт GPIB и привод гибких дисков, который отказывается работать. Однако в меню я могу настроить печать только на дискеты или на параллельный порт, так что использую фальшивый параллельный принтер.

Перейти в меню конфигурации печати можно, нажав [Config] -≥ [Copy Config] -> [Printer]:

Advantest R3273 printer configuration screen
Экран конфигурации принтера Advantest R3273

R3273 поддерживает множество форматов, но добиться на нём цветного растрового изображения оказалось сложнее всего. Путём длительных проб и ошибок я пришёл к такому:

~/projects/fake_parallel_printer/fake_printer.py -i -p /dev/ttyACM0 -f r3273_ -s pcl -v
gpcl6 -dNOPAUSE -sOutputFile=r3273_tmp.png -sDEVICE=png256 -g4000x4000 -r600x600 r3273_0.pcl
convert r3273_tmp.png -filter point -resize 1000 r3273_filt.png
rm r3273_tmp.png
convert r3273_filt.png -crop 640x480+315+94 r3273.png
rm r3273_filt.png

В процессе преобразования что-то теряется. Hardcopy R3273 имитирует оттенки нажатых кнопок с паттерном дизеринга 4x4 пикселя:

R3273 dither pattern

Если использовать прямоугольный фильтр 4x4 пикселя и даунсэмплинг с коэффициентом 4, то этот паттерн дизеринга преобразуется в красивый ровный серый, но сами спектральные данные тоже отфильтровываются:

R3273 box filtered
R3273 box filtered

С показанным выше «рецептом» я использую сэмплирование из 4x4 в 1 пиксель с фазой, на которой выбираются только чёрные пиксели паттерна дизеринга. Теперь выделенные кнопки имеют сплошной чёрный цвет, а всё остальное выглядит хорошо.

Векторный анализатор цепей HP 8753C — GPIB — HP 8753 Companion

HP8753C

У моего HP 8753C есть только интерфейс GPIB, поэтому выбора особого нет.

Я использую HP 8753 Companion. С его помощью можно делать гораздо большее, а не просто скриншоты: можно сохранять замеренные данные в фильтр, загружать данные калибровочного набора и так далее. Прекрасно!

Скриншот можно рендерить так, как он выведен HP 8753C, например, так:

HP 8753C HPGL screenshot

Или можно отображать его в режиме высокого разрешения:

HP 8753C high resolution screenshot

Настройки цветов по умолчанию для HPGL неидеальны, но всё можно сконфигурировать.

Если у вас ещё нет донгла USB-GPIB, то само существование HP 8753 Companion — это хорошая причина для его приобретения.

HP 8753C high resolution Smith chart screenshot

Осциллограф Siglent SDS 2304X — USB-флэшка, Ethernet или USB

Siglent SDS2304X
Siglent SDS2304X

Siglent SDS 2304X — это мой первый осциллограф. Его спроектировали на двадцать лет позже, чем всё остальные, он имеет современный UI и такие современные интерфейсы, как USB и Ethernet. У него нет GPIB, параллельного или последовательного порта RS-232.

Мне не нравится его диапазон. UI может становиться медленным при отображении большого количества данных на экране, а выбор чего-то в меню при помощи вращающейся рукоятки без фиксации иногда очень сильно бесит. Но это мой основной рабочий инструмент, потому что он размером не с якорь: даже на моём захламлённом столе я могу без особых усилий найти для него место.

Можно было бы подумать, что для сохранения скриншотов я пользуюсь USB или Ethernet, но чаще всего я просто перекидываю данные между устройством и PC на USB-флэшке, потому что настраивать подключение всегда немного утомительно. Однако если настаиваете, я могу сделать всё и так:

Ethernet

Для настройки Ethernet нужно зайти в [Utility] -> [Next Page] -> [I/O] -> [LAN].

В отличие от моего логического анализатора HP 1670G, Siglent поддерживает DHCP, но при написании этого поста устройство отказывалось брать IP-адрес в моей сети. Никакие перезагрузки, отключение и включение DHCP не помогли.

В прошлом мне удавалось заставить его работать, но сегодня не повезло. Вероятно, вы уже понимаете, почему не требующая никакой настройки USB-флэшка стала привлекательной альтернативой.

USB

Для работы с USB вам понадобится древний реликт — кабель USB-B. После его подключения он отображается так:

sudo dmesg -w
[314170.674538] usb 1-7.1: new full-speed USB device number 11 using xhci_hcd
[314170.856450] usb 1-7.1: not running at top speed; connect to a high speed hub
[314170.892455] usb 1-7.1: New USB device found, idVendor=f4ec, idProduct=ee3a, bcdDevice= 2.00
[314170.892464] usb 1-7.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[314170.892469] usb 1-7.1: Product: SDS2304X
[314170.892473] usb 1-7.1: Manufacturer: Siglent Technologies Co,. Ltd.
[314170.892476] usb 1-7.1: SerialNumber: SDS2XJBD1R2754

Три важных параметра:

  • USB vendor ID: f4ec

  • USB product ID: ee3a

  • Product serial number: SDS2XJBD1R2754

Нужно настроить правила udev, так чтобы можно было получать доступ к этому USB-устройству без полномочий root, создав файл /etc/udev/rules.d/99-usbtmc.rules и добавив в него следующую строку:

SUBSYSTEM=="usb", ATTR{idVendor}=="f4ec", ATTR{idProduct}=="ee3a", MODE="0666"

Очевидно, что vendor ID и product ID нужно заменить на ваши.

Сделаем новые правила udev активными:

sudo udevadm control --reload-rules
sudo udevadm trigger

Теперь можно скачивать скриншоты при помощи такого скрипта:

siglent_screenshot_usb.py:

#!/usr/bin/env python3

import argparse
import io
import pyvisa
from pyvisa.constants import StatusCode

from PIL import Image

def screendump(filename):
    rm = pyvisa.ResourceManager('')

    # Siglent SDS2304X
    scope = rm.open_resource('USB0::0xF4EC::0xEE3A::SDS2XJBD1R2754::INSTR')
    scope.read_termination = None

    scope.write('SCDP')
    data = scope.read_raw(2000000)
    image = Image.open(io.BytesIO(data))
    image.save(filename)
    scope.close()
    rm.close()

if __name__ == '__main__':

    parser = argparse.ArgumentParser(
        description='Grab a screenshot from a Siglent DSO.')
    parser.add_argument('--output', '-o', dest='filename', required=True,
        help='the output filename')
    
    args = parser.parse_args()
    screendump(args.filename)

Снова обратите внимание на эту строку

    scope = rm.open_resource('USB0::0xF4EC::0xEE3A::SDS2XJBD1R2754::INSTR')

и не забудьте заменить 0xF4EC0xEE3A и SDS2XJBD1R2754 правильными product ID, vendor ID и serial number USB-устройства.

Скрипт вызывается так:

./siglent_screenshot_usb.py -o siglent_screenshot.png

Если всё будет хорошо, то вы получите что-то подобное:

Siglent SDS2304X screenshot

Комментарии (2)


  1. Serge78rus
    03.12.2024 12:58

    Сейчас, прежде чем планировать покупку измерительного оборудования, имеет смысл заглянуть на страницу https://sigrok.org/wiki/Supported_hardware на предмет поддержки конкретного типа прибора. Даже если сам sigrok и окажется не нужным, в его исходниках можно подсмотреть как общаться с конкретным типом оборудования. А вообще автор затронул крайне актуальную и болезненную тему.


  1. Gapon65
    03.12.2024 12:58

    А почему отсутствие поддержки DHCP столь большая проблема? Если речь идет о домашнем роутере то все позволяют сконфигурировать статический IP адрес для данного MAC (Ethernet) адреса устройства. С моим SDS1102X этот подход работает хорошо.

    rm = pyvisa.ResourceManager()
    inst = rm.open_resource('TCPIP0::192.168.0.21')