Автоматизированное рабочее место оператора радиостанции

Тип работы:
Дипломная
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к выпускной квалификационной работе на тему:

«АРМ оператора радиостанции»

Дипломник

Д.А. Шергин

студент гр. 8−78−11

Руководитель

Е.А. Коробков

Нормоконтролер

В.П. Соболева

Зав. кафедрой «Программное обеспечение»

И.О. Архипов

к.т.н., доцент

РЕФЕРАТ

Пояснительная записка к выпускной квалификационной работе бакалавра на тему «АРМ оператора радиостанции» оформлена на 61 странице, содержит 19 рисунков и 8 таблиц.

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

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

Система позволяет:

1. обеспечить настройку и запуск работы двусторонней симплексной телефонной и телеграфной связи в коротковолновом и ультра- коротковолновом диапазонах;

2. обеспечить сеансы связи для передачи произвольных файлов в пакетном режиме;

3. обеспечить защиту от несанкционированного доступа к программе;

4. при подключении к радиостанции модуля GPS/Глонасс определять координаты радиостанции в метрах или градусах.

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

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

СОДЕРЖАНИЕ

ВВЕДЕНИЕ

1. РАЗРАБОТКА АРМ ОПЕРАТОРА РАДИОСТАНЦИИ

1.1 Обоснование целесообразности разработки системы

1.1.1 Назначение объекта автоматизации

1.1.2 Обоснование цели создания системы

1.1.3 Обоснование состава автоматизируемых задач

1.2 Аналитический обзор

1.3 Основные требования к системе

1.3. Цель создания системы и критерии эффективности её функционирования

1.3.2 Функциональное назначение системы

1.3.3 Требование к функциональной структуре системы

1.3.4 Состав типовых проектных решений и пакетов прикладных программ, применяемых в системе

1.3.5 Требования к техническому обеспечению

1.3.6 Требования к информационному обеспечению

1.3.7 Требования к программному обеспечению

1.3.8 Перспективность системы, возможность ее развития

1.4 Основные технические решения проекта системы

1.4.1 Описание системы программного обеспечения

2. РАЗРАБОТКА АРМ ОПЕРАТОРА РАДИОСТАНЦИИ

2.1 Описание постановки задачи

2.1.1 Характеристика задачи

2.1.2 Входная информация

2.1.3 Выходная информация

2.2 Описание алгоритма отправки команды

2.2.1 Назначение и характеристика алгоритма

2.2.2 Используемая информация

2.2.3 Результаты решения

2.2.4 Алгоритм решения

2.3 Описание алгоритма защиты доступа к программе

2.3.1 Назначение и характеристика алгоритма

2.3.2 Используемая информация

2.3.3 Результаты решения

2.3.4 Алгоритм решения

2.4 Описание алгоритма вывода координат

2.4.1 Назначение и характеристика алгоритма

2.4.2 Используемая информация

2.4.3 Результаты решения

2.4.4 Алгоритм решения

2.5 Описание программы формирования команды

2.5.1 Функциональное назначение

2.5.2 Описание информации

2.5.3 Используемые подпрограммы

2.5.4 Описание логики

2.6 Описание контрольного примера

2.6.1 Назначение

2.6.2 Исходные данные

2.6.3 Результаты испытания программы

ЗАКЛЮЧЕНИЕ

СПИСОК ЛИТЕРАТУРЫ

ПРИЛОЖЕНИЕ 1 Тексты ОСНОВНЫХ АЛГАРИТМОВ

ПРИЛОЖЕНИЕ 2 РЕЗУЛЬТАТЫ РАБОТЫ ПРОГРАММ

ПРИЛОЖЕНИЕ 3 РУКОВОДСТВО ОПЕРАТОРА

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

ЗПЧ — заранее подготовленная частота

КВ — коротковолновый

МТГ — проводная микротелефонная гарнитура

НЧ — низкочастотный

ППРЧ — псевдослучайная перестройка рабочей частоты

ППРЧ-А — псевдослучайная перестройка рабочей частот аналоговом режиме

ППРЧ-Ц — псевдослучайная перестройка рабочей частоты в цифровом режиме

РРУ — ручная регулировка усиления

СПО — специальное программное обеспечение

ТЛФ — телефон

ТЛГ — телеграф

ТФ-А — телефон аналоговый

ТФ-Ц — телефон цифровой

УКВ — ультракоротковолновый

ЦФР — цифровая речь

ШП — шумоподавитель

A1A — телеграфия незатухающими колебаниями, код Морзе

A3A — двухполосная телеграфия, код Морзе

A3E — двухполосная телефония (радиовещание)

F3E — телефония с частотной модуляцией

J2A — однополосная телеграфия c подавлением несущей, код Морзе

ВВЕДЕНИЕ

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

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

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

1. РАЗРАБОТКА АРМ ОПЕРАТОРА РАДИОСТАНЦИИ

1.1 Обоснование целесообразности разработки системы

1.1.1 Назначение объекта автоматизации

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

1.1.2 Обоснование цели создания системы

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

Для достижения поставленной цели решаются следующие задачи задачи:

— обеспечить настройку и запуск работы двусторонней симплексной телефонной и телеграфной связи в коротковолновом и ультра- коротковолновом диапазонах;

— обеспечить сеансы связи для передачи произвольных файлов в пакетном режиме;

— реализовать протокол передачи данных между компьютером и радиостанцией;

— обеспечить защиту от несанкционированного доступа к программе;

— Обеспечить удобный пользовательский интерфейс и удобный ввод вывод пользовательских данных данных (прием передача файлов в пакетном режиме) при обмене с РС

обеспечить быстрый доступ к информации, полученной с помощью радиостанции;

— при подключении к радиостанции модуля GPS/Глонасс система должна позволять определять координаты радиостанции в метрах или градусах.

1.1.3 Обоснование состава автоматизируемых задач

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

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

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

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

1.2 Аналитический обзор

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

RS-232: Широко используемый последовательный интерфейс синхронной и асинхронной передачи данных, определяемый стандартом EIA RS-232. Изначально создавался для связи компьютера с терминалом. В настоящее время используется в самых различных применениях. Интерфейс RS-232 соединяет два устройства. Линия передачи первого устройства соединяется с линией приема второго и наоборот.

Данный интерфейс позволяет передавать данные на расстояние до 15 метров на скорости до 115 Кбит/с.

USB: универсальная последовательная шина, предназначенная для подключения периферийных устройств. Шина USB представляет собой последовательный интерфейс передачи данных для высоко-, средне- и низкоскоростных периферийных устройств. В данное время USB интерфейс имеет более широкое распространение и позволяет передавать данные на скорости до 480 Мбит/с, но на практике эта скорость редко достигается. И дальность передачи данных не может превышать 5 метров.

Таким образом, можно сделать вывод, что мы можем использовать интерфейс RS-232, поскольку он прост в реализации, имеет удовлетворительную скорость передачи данных и имеет высокую дальность передачи данных.

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

Большое значение имеет информация, передаваемая с радиостанции, и её представление для оператора, и информация о состоянии радиостанции в данный момент.

1.3 Основные требования к системе

1.3.1 Цель создания системы и критерии эффективности её функционирования

Создание автоматизированной системы для работы оператора с радиостанцией.

Критерии эффективности функционирования:

a) Работа в различных режимах связи;

b) Смена режима работы радиостанции в короткое время;

c) Создание отчета работы при каждом запуске программы;

d) Ввод вывод информации в удобном для пользователя виде;

e) Ограничение доступа к определенным режимам связи;

f) Вход в систему по паролю;

g) Удобство использования

1.3.2 Функциональное назначение системы

Система предназначена для управления радиостанцией с помощью компьютера. Оператор должен иметь возможность с помощью компьютера управлять всеми функциями радиостанции.

При подключении радиостанции к компьютеру оператор может осуществлять двустороннюю симплексную телефонную и телеграфную радиосвязь в диапазоне коротковолновых и ультракоротковолновых частот. Передавать произвольные файлы в пакетном режиме. При подключении к радиостанции модуля GPS/Глонасс оператор может получать координаты радиостанции и высоту над уровнем моря.

1.3.3 Требование к функциональной структуре системы

Структурная схема системы представлена на рис. 1.1.

Структурная схема

рис. 1. 1

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

1.3.4 Состав типовых проектных решений и пакетов прикладных программ, применяемых в системе

В системе применяется средство для разработки приложений Microsoft Visual Studio 2008;

1.3.5 Требования к техническому обеспечению

Для работы системы необходима следующая аппаратура:

1) Изделие «Намотка — КС»

2) ПК со следующими минимальными характеристиками:

а) процессор с частотой 1 ГГц и выше;

б) объем ОЗУ 512 МБ;

в) свободное пространство на жестком диске не менее 100 МБ;

г) видеокарта обеспечивающая разрешение не хуже 800×600×16;

д) наличие последовательного порта с интерфейсом RS-232C или порта USB;

е) Монитор;

ж) клавиатура;

з) мышь.

1.3.6 Требования к информационному обеспечению

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

1) *. LOG — расширение файлов используемых для хранения информации о сеансах работы системы;

2) *. DAT — расширение файлов используемых для хранения текущих настроек системы;

3) *. SNS — расширение файлов содержащих шаблоны настроек сеансов радиосвязи.

1.3.7 Требования к программному обеспечению

На ПК должна быть установлена операционная система Windows ХР SP2 и выше и дистрибутивный пакет платформы Microsoft. NET Framework 2.0 и выше.

1.3.8 Перспективность системы, возможность ее развития

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

1.4 Основные технические решения проекта системы

1.4.1 Описание системы программного обеспечения

Для реализации и нормального функционирования проекта необходимо наличие:

1) Операционной системы Windows XP/Vista/Seven;

2) дистрибутивного пакета платформы Microsoft. NET Framework 2.0 и выше.

Для разработки системы использовалось средство разработки приложений Microsoft Visual Studio 2008 код программы написан на языке С#.

2. РАЗРАБОТКА АРМ ОПЕРАТОРА РАДИОСТАНЦИИ

2.1 Описание постановки задачи

2.1.1 Характеристика задачи

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

2.1.2 Входная информация

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

Параметры режима ТЛФ показаны в таблице 2.1.

Таблица 2. 1

Параметры режима ТЛФ

Имя параметра

Характеристики параметра (диапазон)

Тип данных

Тип режима

КВ режимы: ТФ-А, ТФ-Ц, ТФ ППРЧ-А, ТФ ППРЧ-Ц

УКВ режимы: F3A, A3E, ТФ-Ц, ТФ ППРЧ-Ц

boolean

Дополнительный параметр для ТФ-Ц

ЦФР1, ЦФР2

boolean

Частота

Для КВ: от 2000 до 29 999 КГц

Для УКВ: от 52 до 174 МГц

float

Усиление

От 0 до 99

Int

Статус кореспондента

Ведущий, ведомый

boolean

Шумоподавление

От 0 до 30

Int

Номер ППРЧ для режимов ТФ ППРЧ

От 1 до 64

Int

Параметры режимов ТЛГ и УКВ показаны в таблице 2.2.

Таблица 2. 2

Параметры режимов ТЛГ и УКВ

Имя параметра

Характеристики параметра (диапазон)

Тип данных

Класс излучения

A1A, J2A, A3A

boolean

Частота

Для КВ: от 2000 до 29 999 КГц

Для УКВ: от 52 до 174 МГц

float

Усиление

От 0 до 99

Int

Шумоподавление

От 0 до 30

Int

Параметры передачи файлов показаны в таблице 2.3.

Таблица 2. 3

Параметры передачи файлов

Имя параметра

Характеристики параметра (диапазон)

Тип данных

Статус корреспондента

Ведущий, ведомый

boolean

Частота

Для КВ: от 2000 до 29 999 КГц

float

Размер пакета

16, 32, 64, 158, 252

Int

Размер окна

От 1 до 30

Int

2.1.3 Выходная информация

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

При отсутствии подключения устройства выдается сообщение «Устройство не подключено».

Если оборудование не опознано выдается сообщение «Устройство не опознано».

Сообщения оператору об ошибках и сбоях представлены в таблице 2.4.

Таблица 2. 4

Сообщения об ошибках

Сообщения

Авария! Ошибка обмена с ПК. (формируется от ПДУ)

Авария! Ошибка хранения данных.

Внимание! Запрещенная частота.

Внимание! Нет ответа от вызываемой станции. (пока убрать)

Внимание! Файл существует, перезаписать?

Внимание! Файл не найден.

Внимание! Нет свободного места.

2.2 Описание алгоритма отправки команды

2.2.1 Назначение и характеристика алгоритма

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

2.2.2 Используемая информация

Используемая информация представлена в таблице 2.5.

Таблица 2. 5

Используемая информация при отправке команды

Описание информации

Тип данных

Частота приема

Float

Частота передачи

Float

Массив частот

Float[]

Найденный порт

CRS232Port

Текущее время

DateTime

Отдельный поток

BackgroundWorker

Класс, отвечающий за взаимодействие с портом

SerialPort

2.2.3 Результаты решения

При отсутствии подключения устройства выдается сообщение «Устройство не подключено».

Если оборудование не опознано выдается сообщение «Устройство не опознано».

В случае сбоя при передаче команды выдается сообщение «Ошибка: < имя команды>».

После успешного завершения отправки команды выдается сообщение «Готово: < имя команды>».

2.2.4 Алгоритм решения

Логика алгоритма представлена схематически в виде блок-схемы, представленной на рис. 2.1.

Блок-схема алгоритма отправки команды

Рис. 2. 1

2.3 Описание алгоритма защиты доступа к программе

2.3.1 Назначение и характеристика алгоритма

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

2.3.2 Используемая информация

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

2.3.3 Результаты решения

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

2.3.4 Алгоритм решения

Логика алгоритма представлена схематически в виде блок-схемы, представленной на рис. 2.2.

Блок-схема алгоритма защиты доступа

Рис. 2. 2

2.4 Описание алгоритма вывода координат

2.4.1 Назначение и характеристика алгоритма

Выводит координаты радиостанции, полученные с помощью модуля GPS/Глонасс, подключенного к радиостанции в метрах или градусах.

2.4.2 Используемая информация

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

Структура данных запроса координат представлена в таблице 2.6.

Таблица 2. 6

Структура данных запроса координат

Тип управления

Тип системы

Тип отображения

Количество байт

1

2

1

Тип управления — 0, означает запрос координат;

Тип системы:

0-ГЛОНАСС;

1-GPS;

2-ГЛОНАСС+ GPS;

3-GPS+ ГЛОНАСС.

Тип отображения:

0-градусы;

1-метры.

Структура данных приема координат представлена в таблице 2.7.

Таблица 2. 7

Структура данных приема координат

Тип управления

Координаты

Количество байт

1

50

Тип управления — 2, означает прием координат;

Координаты:

2. 41 байты координат в градусах;

42−45 Х коодината;

46 знак Х координаты;

47−50 — Y коодината;

51 знак Y координаты.

2.4.3 Результаты решения

При отсутствии подключения устройства выдается сообщение «Устройство не подключено».

Если оборудование не опознано выдается сообщение «Устройство не опознано».

В случае ошибки отправки команды выдается сообщение «Ошибка: Запрос координат».

В случае отмены отправки команды выдается сообщение «Отменено: Запрос координат».

После окончания отправки команды выдается сообщение «Готово: Запрос координат».

2.4.4 Алгоритм решения

Логика алгоритма представлена схематически в виде блок-схемы, представленной на рис. 2.3.

Блок-схема алгоритма вывода координат

Рис. 2. 3

2.5 Описание программы формирования команды

2.5.1 Функциональное назначение

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

2.5.2 Описание информации

Формат команды представлен на рисунке 2.4.

Формат команды

55h

Старт

Кому

От кого

N кадра

Длина

Информация

Контрольная сумма

Рис. 2. 4

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

55h — байт не несет информации, требуется только для перевода радиостанции в рабочий режим;

Старт — байт начала кадра (7Fh);

Кому — поле показывает, какому устройству предназначен кадр;

От кого — поле показывает, от какого устройства передается кадр;

N кадра — номер кадра в цикле обмена;

Длина — количество информационных байт;

Информация*- последовательность информационных байт;

Контрольная сумма — контрольная сумма;

*- необязательные поля.

2.5.3 Используемые подпрограммы

enumCommand — содержит список всех команд;

2.5.4 Описание логики

Логика алгоритма представлена схематически в виде блок-схемы, представленной на рис. 2.5.

Алгоритм формирования команды

Рис. 2. 5

2.6 Описание контрольного примера

2.6.1 Назначение

Данный контрольный пример служит для проверки полноты и корректности работы системы. В ходе выполнения контрольного примера должны быть просмотрены все варианты работы программы.

2.6.2 Исходные данные

Для проверки системы просматриваются все её функции и возможные ситуации.

2.6.3 Результаты испытания программы

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

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

ЗАКЛЮЧЕНИЕ

система алгоритм команда программа

В ходе выполнения выпускной квалификационной работы была разработана система автоматизации рабочего места оператора радиостанции. Система предназначена для работы с подключением радиостанции через интерфейс RS-232.

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

Разработанная система удовлетворяет всем требованиям, поставленным на стадии разработки.

СПИСОК ЛИТЕРАТУРЫ

1. Герберт Шилдт. С# Полное руководство. М.: изд-во Издательский дом «Вильямс», 2010 г. — 992с.

2. Интернет-ресурс. Последовательный интерфейс RS-232: http: //www. gaw. ru/

3. Интернет-ресурс. Работа с RS-232 портом в C#: http: //www. vr-online. ru/

4. Сенилов М. А., Архипов И. О., Соболева В. П. Методические указания по выполнению выпускной работы бакалавра. Направление 230 100. 62 «Информатика и вычислительная техника» для студентов кафедры «Программное обеспечение» — Ижевск: Издательство ИжГТУ, 2010 г. — 20с.

5. Соболева В. П. Методические указания по оформлению курсовых и дипломных работ. — Ижевск: Изд-во ИжГТУ, 2008.- 25с.

6. ГОСТ 19. 404−79 ЕСПД. Пояснительная записка. Требования к содержанию и оформлению.

7. ГОСТ 19. 505−79 ЕСПД. Руководство оператора. Требования к содержанию и оформлению.

8. ГОСТ 19. 201−78 ЕСПД. Техническое задание. Требования к содержанию и оформлению.

9. ГОСТ 19. 701−90 ЕСПД. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения.

ПРИЛОЖЕНИЕ 1

Тексты ОСНОВНЫХ АЛГАРИТМОВ

П1.1. Текст программы CRS232Port. cs:

using System;

using System. Collections. Generic;

using System. IO. Ports;

using System. Threading;

using NamotkaLibrary. Protocol;

using NamotkaLibrary. Protocol. Commands;

namespace NamotkaLibrary. Classes

{

public class CRS232Port: SerialPort

{

#region Delegates

public delegate void OnRecievedEventHandler (CCommand _command);

public delegate void GetFrameEventHandler (byte[] frame, bool isFrame, bool isCommand);

#endregion

private List< byte> _cacheBuffer = new List< byte>();

private enumDevices _iam;

private List< enumDevices> _iamAccept;

private bool _killFrameToSend = false;

/// < summary>

/// Очередь на прием кадров

/// < /summary>

//private List< CFrame> _ReadFrameQueue = new List< CFrame>();

/// < summary>

/// Очредь на посылку кадров

/// < /summary>

private List< CFrame> _WriteFrameQueue = new List< CFrame>();

private Thread _ThreadToSend;

private Thread _ThreadToRead;

private Thread _ThreadToCommand;

private byte _IndexFrame;

public bool isWaitForSend;

/// < summary>

/// Класс конструктор для инициализации порта

/// < /summary>

/// < param name="portName"> Название порта, например COM1< /param>

/// < param name="iam"> Устройство, которому изначально отправляем кадры

/// < param name="iamAccept"> Список устройств, которыми мы можем выступать, и на эти запросы должны откликаться

/// < param name="baundRate"> Битрейт, например 9600< /param>

/// < param name="parity"> Бит четности< /param>

/// < param name="dataBits"> Бит данных< /param>

/// < param name="stopBits"> Стоповый бит< /param>

public CRS232Port (string portName, enumDevices iam, List< enumDevices> iamAccept, int baundRate, Parity parity,

int dataBits, StopBits stopBits)

: base (portName, baundRate, parity, dataBits, stopBits)

{

_iam = iam;

_iamAccept = iamAccept;

CLog. Info (string. Format («{0}: Инициализируем», portName));

ReceivedBytesThreshold = 1;

double _timeout = 2 560 000 / baundRate; //примерно 23 мсек на посылку 256 байт при скорости в 115 200 бит

ReadTimeout = (int) Math. Floor (_timeout);

WriteTimeout = (int) Math. Floor (_timeout);

//DataReceived += portDataReceived;

ErrorReceived += portErrorReceived;

PinChanged += portPinChanged;

CLog. Info (string. Format («{0}: Открываем», portName));

CLog. Info (ReadBufferSize. ToString ());

CLog. Info (WriteBufferSize. ToString ());

// DtrEnable = true;

DtrEnable = false;

RtsEnable = false;

///Инициализируем потоки на примем и итправку кадров

Open ();

//Сделано для того, чтобы поток на прием успел подгрузиться раньше отправки. (Для слабых машин).

System. Threading. Thread. Sleep (300);

_ThreadToSend = new Thread (ThreadToSend);

_ThreadToSend. Name = «Send «+ _ThreadToSend. ManagedThreadId;

_ThreadToSend. Start ();

_ThreadToRead = new Thread (ThreadToRead);

_ThreadToRead. Name = «Read «+ _ThreadToSend. ManagedThreadId;

_ThreadToRead. Start ();

}

public enumDevices Iam

{

get { return _iam; }

}

public List< enumDevices> IamAccept

{

get { return _iamAccept; }

}

public byte IndexFrame

{

get { return _IndexFrame; }

}

public event GetFrameEventHandler onGetFrame;

public event OnRecievedEventHandler onRecieved;

protected virtual void OnReceived (CCommand _command)

{

if (onRecieved ≠ null)

onRecieved (_command);

}

public void UpdateIndex ()

{

if (_IndexFrame == 255)

_IndexFrame = 0;

else

_IndexFrame += 1;

}

/// < summary>

/// Возвращает значение, жив ли поток на отправку.

/// < /summary>

/// < returns></returns>

public bool ThreadToSend_isAlive ()

{

if (_ThreadToSend. IsAlive)

return true;

else

return false;

}

public void SetIndex (byte _z)

{

_IndexFrame = _z;

}

/////Временный метод

//public void AddPacket (byte[] buffer)

//{

// var _Frame = new CFrame (buffer);

// _ReadFrameQueue. Add (_Frame);

//}

/// < summary>

/// Включает DTR на время time

/// < /summary>

/// < param name="time"> время в мс< /param>

public void DTREnable (int time)

{

DtrEnable = true;

Thread. Sleep (time);

DtrEnable = false;

}

public void DTRDisable (int time)

{

DtrEnable = false;

Thread. Sleep (time);

DtrEnable = true;

}

/// < summary>

/// Закрываем порт

/// < /summary>

public void MyClose ()

{

if (IsOpen)

{

base. Close ();

}

}

/// < summary>

/// Посылаем фрейм

/// < /summary>

/// < param name="_Packet"> </param>

public void Send (CFrame _Packet)

{

lock (_WriteFrameQueue)

{

if (_ThreadToSend. IsAlive)

{

_WriteFrameQueue. Add (_Packet);

}

else

{

_Packet. State = enumState. Error;

}

}

}

/// < summary>

/// Метод, удаляющий указанный кадр из очереди на отправку

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

public void RemoveTargetFrameToSend (int _PacketNumber)

{

try

{

if (_WriteFrameQueue. Count ≠ 0)

{

if (_PacketNumber < _WriteFrameQueue. Count)

{

CLog. Info (string. Format (PortName + «: Удаляем пакет {1}, его номер в очереди: {0}», _PacketNumber. ToString (),_WriteFrameQueue[_PacketNumber]. ToString ()));

_WriteFrameQueue. RemoveAt (_PacketNumber);

}

else

{

throw new Exception (string. Format («Пакета с выбранным номером {0} не существует в очереди. «, _PacketNumber. ToString ()));

}

}

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

/// < summary>

/// Метод, удаляющий все кадры из очереди на отправку

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

public void ClearWriteFrameQueue ()

{

try

{

if (_WriteFrameQueue. Count ≠ 0)

{

_WriteFrameQueue. Clear ();

CLog. Info (PortName + «: Очистили очередь на отправку 1»);

}

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

/// < summary>

/// Метод, прерывающий процесс отправки текущего кадра (Выставляет флаг, который делает пакет, крутящийся в цикле, мертвым)

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

public void KillFrameToSend ()

{

try

{

_killFrameToSend = true;

CLog. Info (PortName + «: Убили текущий пакет на отправку»);

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

/// < summary>

/// Метод, удаляющий всю информацию из буффера приема

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

public void ClearReadFrameQueue ()

{

try

{

if (_cacheBuffer. Count ≠ 0)

{

_cacheBuffer. Clear ();

CLog. Info (PortName + «: Очистили буффер приема 2»);

}

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

/// < summary>

/// Метод, удаляющий все кадры из очереди на отправку и всю информацию из буффера приема

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

public void ClearAllFrameQueues ()

{

try

{

if (_WriteFrameQueue. Count ≠ 0)

{

_WriteFrameQueue. Clear ();

CLog. Info (PortName + «: Очистили очередь на отправку 3»);

}

if (_cacheBuffer. Count ≠ 0)

{

_cacheBuffer. Clear ();

CLog. Info (PortName + «: Очистили буффер приема 3»);

}

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

/// < summary>

/// Метод, удаляющий указанный кадр из очереди принятых кадров

/// < /summary>

/// < param name="_PacketNumber"> Номер пакета из списка, который нужно удалить< /param>

//public void RemoveTargetReceivedFrame (int _PacketNumber)

//{

// if (_ReadFrameQueue. Count ≠ 0)

// {

// _ReadFrameQueue. RemoveAt (_PacketNumber);

// }

//}

/// < summary>

/// Возвращает CFrame стоящий на посылке.

/// < /summary>

/// < returns></returns>

public CFrame GetCurrentFrameToSend ()

{

if (_WriteFrameQueue. Count == 0)

return null;

return _WriteFrameQueue[0];

}

/// < summary>

/// Удаляет CFrame стоящий на посылке.

/// < /summary>

/// < returns></returns>

public void RemoveCurrentFrameToSend ()

{

if (_WriteFrameQueue. Count ≠ 0)

{

_WriteFrameQueue. RemoveAt (0);

}

}

/// < summary>

/// Метод вызыватся, если порт не удалось настроить…

/// Признак того, что надо менять параметры работы порта

/// < /summary>

/// < param name="sender"> </param>

/// < param name="e"> </param>

private void portPinChanged (object sender, SerialPinChangedEventArgs e)

{

CLog. Info (PortName + «: portPinChanged:» + e);

}

/// < summary>

/// Метод который вызывается когда произошла ошибка при получении данных

/// < /summary>

/// < param name="sender"> </param>

/// < param name="e"> </param>

private void portErrorReceived (object sender, SerialErrorReceivedEventArgs e)

{

//Выходим если порт в состоянии закрытия.

CLog. Info (e. ToString ());

}

/// < summary>

/// Метод для чтения данных с порта

/// < /summary>

public void ThreadToCommand (object command)

{

CCommand _command = (CCommand)command;

try

{

_command. onCommandReceived ();

lock (Global_locks. waitcomplete)

{

if (_command. Prepare ())

{

CLog. Info (string. Format («{0}: {1} Попали в execute пришедшей команды», PortName, _command. Name));

_command. Execute ();

}

}

if ((_command. Name ≠ «ПРМ») & & (_command. Name ≠ «ПРД») & & (_command. Name ≠ «Запрос телеметрии»)) _command. onCommandCompleted ();

CLog. Info (string. Format («{0}: Завершение минипотока обработки команды {1}», PortName, _command. Name));

}

catch (Exception _ex)

{

_command. onError ();

CLog. Error (_ex);

}

}

/// < summary>

/// Метод для чтения данных с порта

/// < /summary>

public void ThreadToRead ()

{

//Выходим если порт в состоянии закрытия.

if (!IsOpen) return;

CLog. Info (PortName + «: Поток отвечающий за прием — запущен. «);

while (IsOpen)

{

try

{

int bytes = BytesToRead;

var buffer = new byte[bytes];

Read (buffer, 0, bytes);

_cacheBuffer. AddRange (buffer);

if (_cacheBuffer. Count > 0)

{

if (_cacheBuffer. IndexOf (CFrame. VersionFrame) ≠ 1)

{

Utils. WriteBytesToLog (PortName + «Ошибка в буфере», _cacheBuffer. ToArray ());

if (_cacheBuffer. IndexOf (CFrame. VersionFrame) < 0)

{

//В буфере по любому должен оставаться идентификатор пакета

//если его нет — то буфер 100% с ошибкой

CLog. Info (PortName + «: Очистили буффер приема 4»);

_cacheBuffer. Clear ();

}

else

{

_cacheBuffer. RemoveRange (0, _cacheBuffer. IndexOf (CFrame. BeginFrame));

}

Utils. WriteBytesToLog (PortName + «Исправленный буфер», _cacheBuffer. ToArray ());

}

while (CFrame. isFrame (_cacheBuffer. ToArray ()) & & IsOpen)

{

byte[] _frame = CFrame. GetFrame (_cacheBuffer. ToArray ());

_cacheBuffer. RemoveRange (0, _frame. Length);

Utils. WriteBytesToLog (PortName + «: Выделеный фрейм из буфера: «, _frame);

bool isFrame = false;

bool isCommand = false;

CFrame _Frame = null;

CCommand _command = null;

try

{

_Frame = new CFrame (_frame);

isFrame = true;

if (_iamAccept. Contains (_Frame. ToDevice))

{

_command = _Frame. Parse ();

_command. m_Port = this;

_command. Action = enumAction. Receive;

_command. State = enumState. Receive;

_ThreadToCommand = new Thread (ThreadToCommand);

_ThreadToCommand. Name = «Command «+ _ThreadToCommand. ManagedThreadId;

_ThreadToCommand. Start ((_command));

CLog. Info (string. Format («{0}: Запущен минипоток обработки команды {1}», PortName, _command. Name));

isCommand = true;

OnReceived (_command);

}

else

{

CLog. Info (PortName + «Пришедший кадр не для меня!»);

}

}

catch (Exception innerException)

{

CLog. Error (PortName + «Ошибка формирования кадра», innerException);

}

if (isFrame & & !isCommand)

{

if (_iamAccept. Contains (_Frame. ToDevice))

{

//Отправляем квитанцию только если пришедший кадр для меня

CCommand ticket = CCommand. GetCommand (enumCommand. Ticket);

ticket. TimeOutToSend = 0; //не ждать ответа вообще.

ticket. Action = enumAction. Send;

CProtocol. Send (this, _Frame. FromDevice, _Frame. ToDevice, _Frame. Index, ticket);

}

}

if (onGetFrame ≠ null)

{

onGetFrame (_frame, isFrame, isCommand);

}

Thread. Sleep (1);

CLog. Info (string. Format («{0}: Поток обработки команды {1} завершен», PortName, _command. Name));

}

}

}

catch (TimeoutException)

{

CLog. Warning (PortName + «: Время ожидания истекло!»);

}

catch

{

CLog. Warning (PortName + «: Ошибка!»);

}

Thread. Sleep (ReadTimeout);

}

CLog. Info (string. Format («{0}: Поток, отвечающий за прием кадров, завершен! n», PortName));

}

/// < summary>

/// Метод, работающий в потоке и отсылающий пакетв по очереди

/// < /summary>

public void ThreadToSend ()

{

//Выходим если порт в состоянии закрытия.

if (!IsOpen) return;

CLog. Info (PortName + «: Поток отвечающий за отправку — запущен. «);

while (IsOpen)

{

_killFrameToSend = false;

while (_WriteFrameQueue. Count > 0 & & IsOpen)

{

_killFrameToSend = false;

CFrame _packet = _WriteFrameQueue[0];

try

{

int _timeout = 0;

while (

!_packet. isDead

& & _packet. State ≠ enumState. Error

& & (int)_packet. TimeOutStep >= _timeout

& & IsOpen)

{

switch (_packet. State)

{

case enumState. Busy:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

CLog. Warning (

string. Format («{1}: Кадр {0}: Устройство занято обработкой данных. Ждем цикл. «, _packet. Index, PortName));

CLog. Info (

string. Format («{2}: Кадр {0}: Ожидания подтверждения {1} msec. «, _packet. Index, (int)_packet. TimeOutStep,

PortName));

_timeout = 0;

break;

case enumState. TicketReceived:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

CLog. Info (string. Format («{2}: Кадр {0}: Попали в статус TicketReceived. {1} msec. «, _packet. Index, (int)_packet. TimeOutStep, PortName));

if (_packet. State ≠ enumState. DoneReceived)

_packet. onTicketReceived ();

_timeout = (int)_packet. TimeOutStep + 10;

if (_packet. State ≠ enumState. DoneReceived)

_packet. State = enumState. DoneWaiting;

break;

case enumState. DoneWaiting:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

CLog. Info (string. Format («{2}: Кадр {0}: Попали в статус DoneWaiting. {1} msec. «, _packet. Index, (int)_packet. TimeOutStep, PortName));

//TODO: Разкомментарить, когда найду баг, почему не проставляется статус DoneRecieved иногда при приходе «Готово».

/*if ((int)_packet. TimeOutStep == _timeout)

{

_packet. CountTryToSend += 1;

if (!_packet. isDead & & this. IsOpen)

{

Write (_packet. Packet, 0, _packet. Packet. Length);

Utils. WriteBytesToLog (PortName + «: Послан фрейм (retry): «, _packet. Packet);

CLog. Info (string. Format («{2}: Кадр {0}: Послан ожидаем ответ от устройства. (Попытка {1})», _packet. Index,

_packet. CountTryToSend, PortName));

_timeout = 0;

_packet. onDoneWaiting ();

}

}*/

break;

case enumState. DoneReceived:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

CLog. Info (string. Format («Кадр {0}: Попали в статус DoneReceived. «, _packet. Index));

_packet. onCompleteReceived ();

_timeout = (int)_packet. TimeOutStep + 10;

break;

case enumState. Error:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

_packet. onError ();

_timeout = (int)_packet. TimeOutStep + 10;

break;

case enumState. Sended:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

if ((int)_packet. TimeOutStep == _timeout)

{

_packet. CountTryToSend += 1;

if (!_packet. isDead & & this. IsOpen)

{

Write (_packet. Packet, 0, _packet. Packet. Length);

Utils. WriteBytesToLog (PortName + «: Послан фрейм (retry): «, _packet. Packet);

CLog. Info (string. Format («{2}: Кадр {0}: Послан ожидаем ответ от устройства. (Попытка {1})», _packet. Index,

_packet. CountTryToSend, PortName));

_timeout = 0;

_packet. onSended ();

}

}

break;

case enumState. Send:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

///-------------

if (!CFrame. isFrame (_cacheBuffer. ToArray ()))

{

_packet. CountTryToSend += 1;

if (!_packet. isDead & & this. IsOpen)

{

_packet. onSend ();

Write (_packet. Packet, 0, _packet. Packet. Length);

_packet. State = enumState. Sended;

Utils. WriteBytesToLog (PortName + «: Послан фрейм (1): «, _packet. Packet);

CLog. Info (string. Format («{2}: Кадр {0}: Послан ожидаем ответ от устройства. (Попытка {1})», _packet. Index,

_packet. CountTryToSend, PortName));

_timeout = 0;

if ((int)_packet. TimeOutStep == 0)

{

//Говорит о том, что надо выйти из цикла

_timeout = (int)_packet. TimeOutStep + 10;

}

//_packet. onSend ();

//_packet. State = enumState. Sended;

}

}

else

{

CLog. Info (string. Format («{1}: Кадр {0}: не послан так как буфер приема не обработан. «, _packet. Index, PortName));

}

///--------------

break;

default:

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

break;

}

_timeout += 10;

CLog. Info (string. Format («{1}: Ожидаем {0}, {2}», _timeout, PortName, _packet. Command. Name));

//Проверяем, следует ли прервать отправку.

if (_killFrameToSend == true)

{

_killFrameToSend = false;

_packet. isDead = true;

}

Thread. Sleep (10);

}

}

catch (TimeoutException e)

{

CLog. Error (

string. Format («{1}: Кадр {0}: Время ожидания на посылку кадра истекло. «, _packet. Index, PortName), e);

_packet. State = enumState. Error;

_packet. onError ();

}

catch (Exception _ex)

{

//TODO: 1+1ин раз при онлайн смене устройств обмена, сюда пришло packet = null. Проверить, отдебажить.

CLog. Error (

string. Format («{1}: Кадр {0}: Возникла неизвестная ошибка при посылке кадра. «, _packet. Index, PortName),

_ex);

_packet. State = enumState. Error;

_packet. onError ();

}

/*finally

{

lock (_WriteFrameQueue)

{

if (_WriteFrameQueue. Count > 0)

{

CLog. Info (string. Format («{1}: Кадр {0}: Удаляем кадр из очереди», _packet. Index, PortName));

//Гарантирует что удаляется именно тот пакет, который обрабатывали

_WriteFrameQueue. Remove (_packet);

}

}

}*/

}

//Усыпляем поток — состояние ожидания

Thread. Sleep (10);

}

CLog. Info (string. Format («{0}: Поток, отвечающий за отправку кадров, завершен! n», PortName));

}

}

}

П1.2. Текст программы CComand. cs

using System;

using System. Collections. Generic;

using System. Text;

using System. Threading;

using NamotkaLibrary. Classes;

using NamotkaLibrary. Protocol. Commands;

namespace NamotkaLibrary. Protocol

{

public delegate void CCommandErrorEventHandler (Object sender, string error);

public delegate void DoneAndOutEventHandler (Object sender, EventArgs e);

public class CCommand: ICommand

{

public static event CCommandErrorEventHandler onErrorReceived;

public virtual string Name

{

get

{

return «Нет имени»;

}

}

protected virtual void OnErrorReceivedCCommand (string error)

{

if (onErrorReceived ≠ null)

onErrorReceived (this, error);

}

//Вычтвыляется если необходимо подтверждение команды

public bool CompleteRequired { get; set; }

//Время ожидания подтверждения команды

public uint CompleteRequiredTime { get; set; }

object _lockFrame = new object ();

#region onTicketReceived () Реакция на пришежший тикет для фрейма команды

public virtual void onTicketReceived ()

{

lock (Global_locks. waitcomplete)

{

//TODO: Именно тут перебивался когда-то статус DoneReceived на TicketReceived

CLog. Info (string. Format (m_Port. PortName + «: {0} 4 Выставляем статус TicketReceived», this. Name));

if (State ≠ enumState. DoneReceived)

State = enumState. TicketReceived;

try

{

CLog. Info (string. Format (

«{1}: {2}: Кадр {0}: Подтвержден квитанцией»,

_Frames[0]. Index, m_Port. PortName, _Frames[0]. Command. Name));

if (CompleteRequired)

{

_Frames[0]. TimeOutStep = CompleteRequiredTime;

}

else

{

CLog. Info (string. Format («{1}: {2}: Кадр {0}: Удаляем из очереди»,_Frames[0]. Index, m_Port. PortName, _Frames[0]. Command. Name));

lock (_lockFrame)

{

_Frames. RemoveAt (0);

m_Port. RemoveTargetFrameToSend (0);

}

if (_Frames. Count > 0)

{

Send (m_Port);

}

}

return;

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

}

#endregion

#region onCompleteReceived ()Реакция на пришедший «Готово» для фрейма команды

public virtual void onCompleteReceived ()

{

lock (Global_locks. waitcomplete)

{

CLog. Info (string. Format (m_Port. PortName + «: {0} 3 Выставляем статус DoneReceived», this. Name));

State = enumState. DoneReceived;

try

{

if (_Frames. Count > 0)

{

CLog. Info (string. Format («{1}: {2}: Кадр {0}: Подтвержден командой готово»,

_Frames[0]. Index, m_Port. PortName, _Frames[0]. Command. Name));

lock (_lockFrame)

{

CLog. Info (string. Format (m_Port. PortName + «: {0} 4 Выставляем статус DoneReceived», this. Name));

_Frames[0]. State = enumState. DoneReceived;

CLog. Info (string. Format (m_Port. PortName + «: Удаляем пакет {0}», _Frames[0]. ToString ()));

_Frames. RemoveAt (0);

m_Port. RemoveTargetFrameToSend (0);

}

if (_Frames. Count > 0)

{

Send (m_Port);

}

}

return;

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

}

#endregion Реакция на пришедший «Готово» для фрейма команды

#region onError ()Реакиця на ошибку внутри фрейма команды

public virtual void onError ()

{

CLog. Info (string. Format («{0}: Ошибка — команда не выполнена. «, m_Port. PortName));

enumState LastState = State;

State = enumState. Error;

try

{

lock (_lockFrame)

{

CLog. Info (m_Port. PortName + «: Реакиця на ошибку внутри фрейма команды. Очистили лист CFrame 1»);

_Frames. Clear ();

}

if (_Frames. Count > 0)

{

OnErrorReceivedCCommand (string. Format («{0}: Ошибка команды: '{1}', статус: {2}», m_Port. PortName, _Frames[0]. Command. Name, LastState. ToString (), Code[0]. ToString ()));

throw new Exception (string. Format («{0}: Ошибка команды: '{1}', статус: {2}», m_Port. PortName, _Frames[0]. Command. Name, LastState. ToString (), Code[0]. ToString ()));

}

else

{

OnErrorReceivedCCommand (string. Format («{0}: Ошибка команды: '{1}', статус: {2}», m_Port. PortName, Name, LastState. ToString (), Code[0]. ToString ()));

throw new Exception (string. Format («{0}: Ошибка команды: '{1}', статус: {2}», m_Port. PortName, Name, LastState. ToString (), Code[0]. ToString ()));

}

}

catch (Exception _ex)

{

CLog. Error (_ex);

}

}

#endregion

#region onSended ()Реакция после отправки

public virtual void onSended ()

{

if (_Frames. Count > 0)

CLog. Info (

string. Format («{1}: Кадр {0}: Кадр отправлен. «,

_Frames[0]. Index, m_Port. PortName));

}

#endregion

#region onDoneWaiting ()

public virtual void onDoneWaiting ()

{

if (_Frames. Count > 0)

CLog. Info (

string. Format («{1}: Кадр {0}: Кадр ожидает команду готово. «,

_Frames[0]. Index, m_Port. PortName));

}

#endregion

#region onSend ()Реакция до отправки

public virtual void onSend ()

{

if (_Frames. Count > 0)

CLog. Info (

string. Format («{1}: Кадр {0}: Кадр готов к отправке. «,

_Frames[0]. Index, m_Port. PortName));

}

#endregion

//Посылка тикета в ответ на принятую команду.

public virtual void onCommandReceived ()

{

sendTicket (this);

CLog. Info (string. Format («Отправили квитанцию на команду: {0}», this. Name));

}

//Посылка готово в ответ на обработанную команду.

public virtual void onCommandCompleted ()

{

//lock (_lockFrame)

//{

// m_Port. RemoveTargetReceivedFrame (0);

//}

sendComplete (this);

CLog. Info (string. Format («Отправлена 'Готово' на команду: {0}», this. Name));

}

/// < summary>

/// Статический список команд и их обработчиков

/// < /summary>

private static readonly Dictionary< enumCommand, Type> _CommandList

= new Dictionary< enumCommand, Type> ();

/// < summary>

/// Действие, которое выполняет комманда

/// < /summary>

private enumAction _Action = enumAction. Unknown;

/// < summary>

/// Представление тела коммадны

/// < /summary>

private byte[] _Body;

/// < summary>

/// Код команды (смотри документацию)

/// < /summary>

private byte[] _Code;

/// < summary>

/// Блок данных команды

/// < /summary>

private byte[] _Data;

internal List< CFrame> _Frames;

internal enumDevices _fromDevice;

internal byte _MaxTryToSend;

/// < summary>

/// Состояние команды в текущйи момент

/// < /summary>

private enumState _State = enumState. Initialize;

internal UInt32 _TimeOutToSend;

internal enumDevices _toDevice;

public CCommand ()

{

CompleteRequired = false;

CompleteRequiredTime = 0;

}

/// < summary>

/// Конструктор для экземпляра команды

/// < /summary>

/// < param name="indexCommand"> </param>

public CCommand (enumCommand indexCommand)

{

CompleteRequired = false;

CompleteRequiredTime = 0;

if (indexCommand ≠ enumCommand. Ticket)

{

_Code = new byte[1];

Code[0] = (byte) indexCommand;

Data = null;

}

}

public bool AnyTargetDevice { get; set; }

public UInt32 TimeOutToSend

{

set { _TimeOutToSend = value; }

get { return _TimeOutToSend; }

}

public byte MaxTryToSend

{

get { return _MaxTryToSend; }

set { _MaxTryToSend = value; }

}

public enumDevices toDevice

{

get { return _toDevice; }

set { _toDevice = value; }

}

public enumDevices fromDevice

{

get { return _fromDevice; }

set { _fromDevice = value; }

}

public byte[] Data

{

get { return _Data; }

set

{

_Data = value;

_Body = null;

}

}

public byte[] Body

{

get

{

if (_Body == null)

{

int _length = (_Code ≠ null? _Code. Length: 0) + (_Data ≠ null? _Data. Length: 0);

if (_length > 0)

{

_Body = new byte[_length];

_Body[0] = _Code[0];

if (_Data ≠ null)

for (byte i = 0; i < (byte) _Data. Length; i++)

_Body[i + 1] = _Data[i];

}

}

return _Body;

}

}

public object[] Params { get; set; }

#region ICommand Members

public CFrame Ticket { get; set; }

public List< CFrame> Frames

{

get { return _Frames; }

set { _Frames = value; }

}

public CRS232Port m_Port { get; set; }

public enumState State

{

get { return _State; }

set { _State = value; }

}

public enumAction Action

{

get { return _Action; }

set { _Action = value; }

}

public byte[] Code

{

get { return _Code; }

set

{

if (_Code == null)

_Code = new byte[1];

_Code = value;

}

}

/// < summary>

/// Подготовка команды на осное полученого фрейма

/// < /summary>

/// < param name="_Frame"> </param>

/// < param name="_Command"> </param>

public virtual bool Prepare (CFrame _Frame, byte[] _Command)

{

return true;

}

/// < summary>

/// Подготовка команды

/// < /summary>

/// < param name="toDevice">к какому устройству< /param>

/// < param name="fromDevice"> от какого устройства< /param>

/// < returns></returns>

public virtual bool Prepare (enumDevices toDevice, enumDevices fromDevice)

{

_toDevice = toDevice;

_fromDevice = fromDevice;

return Prepare ();

}

/// < summary>

/// Запуск комманды на выполнение

/// < /summary>

public virtual bool Execute ()

{

CLog. Info (string. Format («{0}: {1}: Base Execute. «, this. m_Port. PortName, this. Name));

return true;

}

/// < summary>

/// Подготовка команды

/// в зависемости от вбранного действия и состояния

/// Подготовка собирает команду и разбивает ее на фреймы.

/// < /summary>

public virtual bool Prepare ()

{

return true;

}

/// < summary>

/// Посылка подготовленой команды

/// Посылка может осуществляться несколькими фреймами

/// < /summary>

/// < returns></returns>

public virtual bool Send (CRS232Port _Port)

{

if (_Frames. Count > 0 & & _Port. IsOpen)

{

_Frames[0]. Index = _Port. IndexFrame;

_Port. UpdateIndex ();

_Frames[0]. State = enumState. Send;

m_Port = _Port;

m_Port. Send (_Frames[0]);

return true;

}

return false;

}

#endregion

public static void initialize ()

{

_CommandList. Add (enumCommand. Empty, typeof (cmdEmpty));

_CommandList. Add (enumCommand. WriteROM, typeof (cmdWriteROM));

_CommandList. Add (enumCommand. ProgramMode, typeof (cmdProgramMode));

_CommandList. Add (enumCommand. EndCycle, typeof (cmdTicket));

_CommandList. Add (enumCommand. ClearROM, typeof (cmdClearROM));

_CommandList. Add (enumCommand. CheckROM, typeof (cmdCheckROM));

_CommandList. Add (enumCommand. Complete, typeof (cmdComplete));

_CommandList. Add (enumCommand. Ticket, typeof (cmdTicket));

_CommandList. Add (enumCommand. Data, typeof (cmdData));

_CommandList. Add (enumCommand. DataEnd, typeof (cmdDataEnd));

_CommandList. Add (enumCommand. Message, typeof (cmdMessage));

ПоказатьСвернуть
Заполнить форму текущей работой