2.4.13. Взаимодействие с последовательным (RS232, RS485) портом

В системе Global выполнять чтение из последовательного (COM) порта можно используя класс TbtkScriptSerialPortObject. Получить объект связанный с последовательным портом можно через метод Application.GetSerialPort(PortName: String);

2.4.13.1. Описание классов

2.4.13.1.1. TbtkScriptSerialPortObject

2.4.13.1.1.1. Методы

  • Close - Закрытие COM порта. На закрытие выполняет освобождение занятых системных ресурсов, важно после работы с COM портом закрыть его.
  • DeregisterHandler - Дерегистрация обработчика на получение данных COM портом.
  • GetCOMMTimeouts: TbtkScriptSerialPortTimeouts - Получение параметров времение ожидания(timeout) последовательного порта. После изменения параметров, можно записать в порт используя SetCOMMTimeouts.
  • GetDCBProperties: TbtkScriptSerialPortDcbObject - Получение управляющий настроек порта в виде DCB структуры. С помощью функции можно получить текущие настройки порта, изменить нужные поля и записать в порт через SetDCBProperties.
  • Open - Открытие COM порта. После открытия порта, можно производить чтение и запись.
  • RegisterHandler(var Operation: TbtkScriptOperationObject) - Регистрация обработчика на получение данных COM портом. Зарегистрированная операция будет вызвана, когда устройство подключенное к COM порту выполнит запись в порт. Обработчик должен обладать входным параметров строковго типа. Через параметр передается имя порта из которого получены данные.
  • SetCOMMTimeouts(var TimeOuts: TbtkScriptSerialPortTimeouts ) - Запись параметровов таймаутов в порт. Параметром является структура COMMTIMEOUTS.
  • SetDCBProperties(var DCB: TbtkScriptSerialPortDcbObject) - Запись управляющей структуры DCB в порт.

2.4.13.1.1.2. Свойства

  • Data: String - данные считанные из последовательного порта, после их поступления. Поле позволяет получить данные в обработкичке на поступление данных в последовательный порт.
  • Port: String - имя последовательного порта. Свойство только для чтения
  • Opened: boolean; - возвращает состояние актиности порта. Если true - порт открыт, false - закрыт.
  • Registered: boolean; - зарегистрирован обработчик на последовательный порт или нет. True - зарегистрирован, False - не зарегистрирован.

2.4.13.1.2. TbtkScriptSerialPortDcbObject

2.4.13.1.2.1. Свойства

  • BaudRate: Integer; - Для задания значения можно использовать константы CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000;
  • ByteSize: Integer;
  • Parity: Integer; - Для задания значения можно использовать константы NOPARITY, ODDPARITY, EVENPARITY, MARKPARITY, SPACEPARITY;
  • StopBits: Integer; Константы ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS.

Описание DCB структуры в msdn

2.4.13.1.3. TbtkScriptSerialPortTimeouts

Эту структуру лучше, не использовать в режиме аснхронного чтения, когда вызывается обработчик после чтения порта. Это обусловлденно внутренними особенностями работы. Кому вдруг интерсенно, то там используется overlapped режим и Windows нам сообщается о завершение на на входе записи в ком порт сразу ‘’’блока ‘’’данных. Дальше мы получаем объем данных в COM порте и под этот объем подготавливаем буфер в который и уже записываем данные через ReadFile.  Timeouts влияет на ReadFile, но в нашем случае мы в любом случае не прочитаем больше, чем размер подготовленного буфера. Но все это относиться к асинхронному режиму, если будет реализован не асинхронный, то структура снова будет на коне.

2.4.13.1.3.1. Свойства

  • ReadIntervalTimeout: Integer
  • ReadTotalTimeoutConstant: Integer
  • ReadTotalTimeoutMultiplier: Integer
  • WriteTotalTimeoutConstant: Integer
  • WriteTotalTimeoutMultiplier: Integer

Описание Timeouts структуры в msdn

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

2.4.13.2. Пример работы

Листинг тестовой операции:

<PASCAL>
  ComPortName := GetVar('sSerialPortName');
  SerialPort := Application.GetSerialPort(ComPortName); // ComPortName = "COM3"
  SerialPort.Open;

  // Дальше идет задание настроек, но этот момент можно пропустить
  // тогда будут использованы значения по умолчанию
  // точно такие же, какие заданы в этом примере
  dcb := SerialPort.GetDCBProperties;
  dcb.BaudRate := CBR_19200;
  dcb.ByteSize := 8;
  dcb.Parity := ONESTOPBIT;
  dcb.StopBits := NOPARITY;
  SerialPort.SetDCBProperties(dcb);

  timeouts := SerialPort.GetCOMMTimeouts;
  timeouts.ReadIntervalTimeout := 50;
  timeouts.ReadTotalTimeoutConstant := 40;
  timeouts.ReadTotalTimeoutMultiplier := 40;
  timeouts.WriteTotalTimeoutConstant := 40;
  timeouts.WriteTotalTimeoutMultiplier := 40;
  SerialPort.SetCOMMTimeouts(timeouts);

  SerialPort.RegisterHandler(Selection.OperationByName('OnComPortReaded') );
</PASCAL>

Листинг операции-обработчика OnComPortReaded:

<PASCAL APortName>
  SerialPort := Application.GetSerialPort(APortName);
  ShowMessage(SerialPort.Data);
</PASCAL>

2.4.13.3. Эмулирование COM порта

Для теста можно эмулировать COM порт и записывать в него поток данных. Существуют бесплатные(условно-бесплатные) версии подобных утилит.

Проверенно работает утилита VSPE (VIRTUAL SERIAL PORTS EMULATOR) для эмуляции виртуального последовательно порта.

Для генерации трафика в цикле можно использовать утилиту AGG Com port data emulator (Freeware).