Запись и чтение данных

Прежде чем вы начнете

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

  • Будет чтение или писать доступ к функциональному блоку к командной строке MATLAB®?

  • Данные должны быть переданы (числовой) двоичный файл или текст?

  • При каких условиях операция чтения или операция записи завершатся?

Для операций записи на эти вопросы отвечают в Записи данных. Для операций чтения на эти вопросы отвечают в Чтении Данных.

Пример - введение в запись и чтение данных

Предположим, что вы хотите возвратить идентификационную информацию для Tektronix® TDS 210 двухканальный осциллограф, соединенный с последовательным портом COM1 на платформе Windows®. Это требует записи команды *IDN? к инструменту с помощью функции fprintf, и читая назад результат той команды с помощью функции fscanf.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)

Получившаяся идентификационная информация:

out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

Закончите сеанс последовательного порта.

fclose(s)
delete(s)
clear s

Управление доступом к командной строке MATLAB

Вы управляете доступом к командной строке MATLAB путем определения, являются ли операция чтения или операция записи синхронными или асинхронными.

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

Термины, синхронные и асинхронные, часто используются, чтобы описать, как последовательный порт действует на аппаратном уровне. Стандарт RS-232 поддерживает асинхронный протокол связи. Используя этот протокол, каждое устройство использует свои собственные внутренние часы. Передача данных синхронизируется с помощью старт-бита байтов, в то время как один или несколько стоп-битов указывают на конец байта. Для получения дополнительной информации о старт-битах и стоп-битах, смотрите Формат Последовательных данных. Стандарт RS-232 также поддерживает синхронный режим, где все переданные биты синхронизируются с общим сигналом часов.

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

Примечание

Когда используется в этом руководстве, термины, синхронные и асинхронные, относятся к или операции чтения, или операции записи блокируют доступ к командной строке MATLAB. Другими словами, эти условия описывают, как программное обеспечение ведет себя, и не то, как оборудование ведет себя.

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

  • Можно дать другую команду, в то время как запись или читала, функция выполняется.

  • Можно использовать все поддерживаемые свойства коллбэка (см. События и Коллбэки).

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

Запись данных

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

Следующая таблица показывает функции, сопоставленные с записыванием данные.

Функции, связанные с Записью данных

FunctionName Описание

fprintf

Запишите текст в устройство

fwrite

Запишите двоичные данные в устройство

stopasync

Остановите асинхронные операции чтения и операции записи

Следующая таблица показывает свойства, сопоставленные с записыванием данные.

Свойства, связанные с Записью данных

PropertyName Описание

BytesToOutput

Количество байтов в настоящее время в буфере вывода

OutputBufferSize

Размер буфера вывода в байтах

Тайм-аут

Время ожидания, чтобы завершить операцию чтения или операцию записи

TransferStatus

Укажите, происходят ли асинхронная операция чтения или операция записи

ValuesSent

Общее количество значений записано в устройство

Буфер вывода и поток данных

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

  1. Данные, заданные функцией записи, отправляются в буфер вывода.

  2. Данные в буфере вывода отправляются в устройство.

Свойство OutputBufferSize задает максимальное количество байтов, которые можно сохранить в буфере вывода. Свойство BytesToOutput указывает на количество байтов в настоящее время в буфере вывода. Значения по умолчанию для этих свойств:

s = serial('COM1');
get(s,{'OutputBufferSize','BytesToOutput'})
ans = 
    [512]    [0]

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

Например, предположите, что вы пишете команде строки *IDN? в осциллограф TDS 210 с помощью функции fprintf. Как показано в следующей схеме, строка сначала записана в буфер вывода как шесть значений.

Команда *IDN? состоит из шести значений, потому что терминатор строки автоматически записан. Кроме того, формат данных по умолчанию для функции fprintf указывает, что одно значение соответствует одному байту. Для получения дополнительной информации о байтах и значениях, смотрите Байты По сравнению со Значениями. fprintf и терминатор строки обсуждены в записи текстовых Данных.

Как показано в следующей схеме, после того, как строка записана в буфер вывода, это затем записано в устройство через последовательный порт.

Запись текстовых данных

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

Например, команда Display:Contrast изменяет контрастность дисплея осциллографа.

s = serial('COM1');
fopen(s)
fprintf(s,'Display:Contrast 45')

По умолчанию fprintf записывает данные с помощью формата %s\n, потому что много устройств последовательного порта принимают только основанные на тексте команды. Однако можно задать много других форматов, как описано на страницах с описанием fprintf.

Чтобы проверить количество значений, отправленных в устройство, используйте свойство ValuesSent.

s.ValuesSent
ans =
    20

Обратите внимание на то, что значение свойства ValuesSent включает терминатор строки, потому что каждое вхождение \n в команде, отправленной в устройство, заменяется значением свойства Terminator.

s.Terminator
ans =
LF

Значение по умолчанию Terminator является символом перевода строки. Терминатор строки, требуемый вашим устройством, будет описан в его документации.

Синхронный по сравнению с асинхронными операциями записи.  По умолчанию fprintf действует синхронно и блокирует командную строку MATLAB, пока выполнение не завершается. Чтобы записать текстовые данные асинхронно в устройство, необходимо задать async как последний входной параметр к fprintf.

fprintf(s,'Display:Contrast 45','async')

Асинхронные операции не блокируют доступ к командной строке MATLAB. Кроме того, в то время как асинхронная операция записи происходит, вы можете:

  • Выполните асинхронную операцию чтения, потому что последовательные порты имеют отдельные контакты для чтения и записи

  • Используйте все поддерживаемые свойства коллбэка

Чтобы определить, какие асинхронные операции происходят, используйте свойство TransferStatus. Если никакие асинхронные операции не происходят, TransferStatus является idle.

s.TransferStatus
ans =
idle

Завершение Операции записи с fprintf.  Синхронная или асинхронная операция записи с помощью fprintf завершается когда:

  • Заданные данные записаны.

  • Прошло время, заданное как свойство Timeout.

Остановите асинхронную операцию записи с функцией stopasync.

Правила для Записи Терминатора.  Значение свойства Terminator заменяет все случаи \n в cmd. Поэтому, когда вы используете формат по умолчанию %s\n, все команды, записанные в конец устройства с этим значением свойства. Обратитесь к своей документации устройства для терминатора строки, требуемого вашим устройством.

Запись двоичных данных

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

Примечание

Некоторые устройства последовательного порта принимают только основанные на тексте команды. Эти команды могут использовать язык SCPI или некоторый другой специфичный для поставщика язык. Поэтому вы можете должны быть использовать функцию fprintf для всех операций записи.

По умолчанию fwrite переводит значения с помощью точности uchar. Однако можно задать много другой точности, как описано на страницах с описанием для этой функции.

По умолчанию fwrite действует синхронно. Чтобы записать двоичные данные асинхронно в устройство, необходимо задать async как последний входной параметр к fwrite. Для получения дополнительной информации о синхронных и асинхронных операциях записи, смотрите текстовые Данные о Записи. Для описания правил, использованных fwrite, чтобы завершить операцию записи, обратитесь к ее страницам с описанием.

Распространенные ошибки Поиска и устранения проблем

Используйте эту таблицу, чтобы идентифицировать общие ошибки fprintf.

ОшибкаПроисходит когдаПоиск и устранение проблем

??? Ошибка ==> serial.fwrite в 199 Объектах должна быть соединена с оборудованием с FOPEN.

Вы выполняете операцию записи, и объект последовательного порта не соединяется с устройством.

Используйте fopen, чтобы установить связь с устройством.

??? Ошибка ==> serial.fwrite в 199 количество записанных байтов должна быть меньше чем или равна OutputBufferSize-BytesToOutput.

Буфер вывода не может содержать все данные, которые будут записаны.

Задайте размер буфера вывода со свойством OutputBufferSize.

??? Ошибка ==> serial.fwrite в 192 FWRITE не может быть названа. Свойство FlowControl установлено в 'оборудование', и контакт Clear to Send (CTS) высок. Это могло указать, что последовательное устройство не может быть включено, не может быть соединено или не использует аппаратное квитирование

  • Вы устанавливаете свойство FlowControl на последовательном объекте к hardware.

  • Устройство или не соединяется или подключенное устройство, не утверждает, что это готово получить данные.

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

Чтение данных

В этом разделе описываются данные о чтении из вашего устройства последовательного порта в трех частях:

Следующая таблица показывает функции, сопоставленные с чтением данных.

Функции, связанные с чтением данных

FunctionName Описание

fgetl

Прочитайте одну строку текста от устройства и отбросьте терминатор строки

fgets

Прочитайте одну строку текста от устройства и включайте терминатор строки

fread

Считайте двоичные данные из устройства

fscanf

Считайте данные из устройства и отформатируйте как текст

readasync

Считайте данные асинхронно из устройства

stopasync

Остановите асинхронные операции чтения и операции записи

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

Свойства, связанные с чтением данных

PropertyName Описание

BytesAvailable

Количество байтов, доступных во входном буфере

InputBufferSize

Размер входного буфера в байтах

ReadAsyncMode

Задайте, является ли асинхронная операция чтения непрерывной или ручной

Тайм-аут

Время ожидания, чтобы завершить операцию чтения или операцию записи

TransferStatus

Укажите, происходят ли асинхронная операция чтения или операция записи

ValuesReceived

Общее количество значений считано из устройства

Входной буфер и поток данных

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

  1. Данные, считанные из устройства, хранятся во входном буфере.

  2. Данные во входном буфере возвращены в переменную MATLAB, заданную функцией чтения.

Свойство InputBufferSize задает максимальное количество байтов, которые можно сохранить во входном буфере. Свойство BytesAvailable указывает на количество байтов, в настоящее время доступных, чтобы быть считанным из входного буфера. Значения по умолчанию для этих свойств:

s = serial('COM1');
get(s,{'InputBufferSize','BytesAvailable'})
ans = 
    [512]    [0]

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

Например, предположите, что вы используете функцию fscanf, чтобы считать основанный на тексте ответ команды *IDN?, ранее записанной в осциллограф TDS 210. Как показано в следующей схеме, текстовые данные сначала считаны во входной буфер через последовательный порт.

Обратите внимание на то, что для данной операции чтения, вы не можете знать количество байтов, возвращенных устройством. Поэтому вы можете должны быть задать свойство InputBufferSize к достаточно большому значению прежде, чем соединить объект последовательного порта.

Как показано в следующей схеме, после того, как данные хранятся во входном буфере, это затем передается выходной переменной, заданной fscanf.

Чтение текстовых данных

Вы используете fgetl, fgets и функции fscanf, чтобы считать данные из устройства и отформатировать данные как текст.

Например, предположите, что вы хотите возвратить идентификационную информацию для осциллографа. Это требует записи команды *IDN? к инструменту, и затем чтение поддерживает результат той команды.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)
out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

По умолчанию fscanf считывает данные с помощью формата %c, потому что данные, возвращенные многими устройствами последовательного порта, являются базирующимся текстом. Однако можно задать много других форматов, как описано на страницах с описанием fscanf.

Чтобы проверить количество значений, считанных из устройства — включая терминатор строки, используйте свойство ValuesReceived.

s.ValuesReceived
ans =
    56

Синхронный По сравнению с Асинхронными Операциями чтения.  Вы задаете, являются ли операции чтения синхронными или асинхронными со свойством ReadAsyncMode. Можно сконфигурировать ReadAsyncMode к continuous или manual.

Если ReadAsyncMode является continuous (значение по умолчанию), объект последовательного порта постоянно запрашивает устройство, чтобы определить, доступны ли данные, чтобы быть считанными. Если данные доступны, они асинхронно хранятся во входном буфере. Чтобы передать данные от входного буфера до MATLAB, используйте один из синхронных (блокирование) функции чтения, такие как fgetl или fscanf. Если данные доступны во входном буфере, эти функции возвращаются быстро.

s.ReadAsyncMode = 'continuous';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    56
out = fscanf(s);

Если ReadAsyncMode является manual, объект последовательного порта постоянно не запрашивает устройство, чтобы определить, доступны ли данные, чтобы быть считанными. Чтобы считать данные асинхронно, используйте функцию readasync. Затем используйте одну из синхронных функций чтения, чтобы передать данные от входного буфера до MATLAB.

s.ReadAsyncMode = 'manual';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    0
readasync(s)
s.BytesAvailable
ans =
    56
out = fscanf(s);

Асинхронные операции не блокируют доступ к командной строке MATLAB. Кроме того, в то время как асинхронная операция чтения происходит, вы можете:

  • Выполните асинхронную операцию записи, потому что последовательные порты имеют отдельные контакты для чтения и записи

  • Используйте все поддерживаемые свойства коллбэка

Чтобы определить, какие асинхронные операции происходят, используйте свойство TransferStatus. Если никакие асинхронные операции не происходят, то TransferStatus является idle.

s.TransferStatus
ans =
idle

Правила для Завершения Операции чтения с fscanf.  Операция чтения с fscanf блокирует доступ к командной строке MATLAB до:

  • Считался терминатор строки, заданный как свойство Terminator.

  • Прошло время, заданное как свойство Timeout.

  • Конкретное количество заданных значений читается.

  • Входной буфер заполнен.

Чтение двоичных данных

Вы используете функцию fread, чтобы считать двоичные данные из устройства. Чтение двоичных данных означает, что вы возвращаете численные значения к MATLAB.

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

s = serial('COM1');
fopen(s)
fprintf(s,'CURSOR?')
fprintf(s,'DISPLAY?')

Поскольку значением по умолчанию для свойства ReadAsyncMode является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от устройства. Чтобы проверить количество чтения значений, используйте свойство BytesAvailable.

s.BytesAvailable
ans =
    69

Чтобы возвратить данные в MATLAB, используйте любую из синхронных функций чтения. Однако, если вы используете fgetl, fgets или fscanf, необходимо выпустить функцию дважды, потому что существует два терминатора строки, сохраненные во входном буфере. Чтобы возвратить все данные в MATLAB в одном вызове функции, используйте fread.

out = fread(s,69);

По умолчанию fread возвращает численные значения в массивах двойной точности. Однако можно задать много другой точности, как описано на страницах с описанием fread. Чтобы преобразовать числовые данные в текст, используйте функцию char MATLAB.

val = char(out)'
val =
HBARS;CH1;SECONDS;-1.0E-3;1.0E-3;VOLTS;-6.56E-1;6.24E-1
YT;DOTS;0;45

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

Пример - пишущие и считывающие текстовые данные

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

Инструмент является Tektronix TDS 210 двухканальный осциллограф, соединенный с портом COM1. Поэтому многие следующие команды характерны для этого инструмента. Синусоида вводится в канал 2 из осциллографа, и ваше задание должно измерить напряжение от пика к пику входного сигнала.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s, сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Соединитесь с устройством — Подключение s к осциллографу. Поскольку значением по умолчанию для свойства ReadAsyncMode является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  3. Запишите и считайте данные — Запись команда *IDN? к инструменту с помощью fprintf, и затем считайте назад результат команды с помощью fscanf.

    fprintf(s,'*IDN?')
    idn = fscanf(s)
    idn =
    TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

    Необходимо определить источник измерения. Возможные источники измерения включают канал 1 и канал 2 из осциллографа.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH1

    Осциллограф сконфигурирован, чтобы возвратить измерение в канал 1. Поскольку входной сигнал соединяется с каналом 2, необходимо сконфигурировать инструмент, чтобы возвратить измерение в этот канал.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE CH2')
    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH2

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

    fprintf(s,'MEASUREMENT:MEAS1:TYPE PK2PK')
    fprintf(s,'MEASUREMENT:MEAS1:VALUE?')

    Передайте данные от входного буфера до MATLAB с помощью fscanf.

    ptop = fscanf(s,'%g')
    ptop =
    2.0199999809E0
  4. Разъединитесь и вымойтесь — Когда вам больше не нужен s, отключают его от инструмента и удаляют его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Пример - Парсинг Входных данных Используя textscan

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

Инструмент является Tektronix TDS 210 двухканальный осциллограф, соединенный с последовательным портом COM1.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s, сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Соединитесь с устройством — Подключение s к осциллографу. Поскольку значением по умолчанию для свойства ReadAsyncMode является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  3. Запишите и считайте данные — Запись команда RS232? к инструменту с помощью fprintf, и затем считайте назад результат команды с помощью fscanf. RS232? запрашивает настройки RS-232 и возвращает скорость в бодах, установку программного управления потоком, установку аппаратного управления потоками, тип контроля четности и терминатор строки.

    fprintf(s,'RS232?')
    data = fscanf(s)
    data =
    9600;0;0;NONE;LF

    Используйте функцию textscan, чтобы проанализировать и отформатировать переменную data в пять новых переменных.

    C = textscan(a, '%d%d%d%s%s','delimiter',';'); 
    
    [br, sfc, hfc, par, tm] = deal(C{:});
    
    br =
            9600
    sfc =
         0
    hfc =
         0
    par = 
        'NONE'
    tm = 
        'LF'
  4. Разъединитесь и вымойтесь — Когда вам больше не нужен s, необходимо отключить его от инструмента и удалить его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Пример - считывающий двоичные данные

Этот пример показывает как вы, чтобы загрузить отображение на экране осциллографа TDS 210 на MATLAB. Данные об отображении на экране передаются и сохранили использование на диск растрового формата Windows. Эти данные обеспечивают постоянную запись вашей работы и являются простым способом зарегистрировать важный сигнал и параметры осциллографа.

Поскольку переданный объем данных, как ожидают, будет довольно большим, он асинхронно возвращен во входной буфер, как только это доступно от инструмента. Это позволяет вам выполнять другие задачи, в то время как передача прогрессирует. Кроме того, осциллограф сконфигурирован к его самой высокой скорости в бодах 19 200.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s, сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Сконфигурируйте значения свойств — Конфигурируют входной буфер, чтобы принять довольно большое количество байтов и сконфигурировать скорость в бодах к самому высокому значению, поддержанному осциллографом.

    s.InputBufferSize = 50000;
    s.BaudRate = 19200;
  3. Соединитесь с устройством — Подключение s к осциллографу. Поскольку значением по умолчанию для свойства ReadAsyncMode является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  4. Запишите и считайте данные — Конфигурируют осциллограф, чтобы передать отображение на экране как битовый массив.

    fprintf(s,'HARDCOPY:PORT RS232')
    fprintf(s,'HARDCOPY:FORMAT BMP')
    fprintf(s,'HARDCOPY START')

    Ожидайте, пока все данные не отправляются во входной буфер, и затем передайте данные рабочему пространству MATLAB как 8-битные целые числа без знака.

    out = fread(s,s.BytesAvailable,'uint8');
  5. Разъединитесь и вымойтесь — Когда вы больше не будете нуждаться в s, будете отключать его от инструмента и удалять его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Просмотр растровых данных

Чтобы просмотреть растровые данные, выполните эти шаги:

  1. Откройте дисковый файл.

  2. Запишите данные в дисковый файл.

  3. Закройте дисковый файл.

  4. Считайте данные в MATLAB с помощью функции imread.

  5. Масштабируйте и отобразите данные с помощью функции imagesc.

Обратите внимание на то, что версии файлового ввода-вывода fopen, fwrite и функций fclose используются.

fid = fopen('test1.bmp','w');
fwrite(fid,out,'uint8');
fclose(fid)
a = imread('test1.bmp','bmp');
imagesc(a)

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

mymap = [0 0 0; 1 1 1];
colormap(mymap)

Следующая схема показывает изображение полученного растрового изображения.