диплом2015. Преимущества штрихового кодирования
Скачать 0.69 Mb.
|
CApollo()CSerial()3.2 Выбор линии связи В разрабатываемой автоматизированной системе идентификации готовой продукции для передачи информации с учётной точки на персональный компьютер используется сеть Ethernet. В качестве линии связи выберем витую пару. Витая пара (Twisted pair – ТР) в настоящее время является самой распространенной средой передачи и представляет собой пару свитых проводов. Кабель, составленный из нескольких витых пар, как правило, покрыт жесткой пластиковой оболочкой, предохраняющей его от воздействия внешней среды и механических повреждений[1]. В нормальных условиях витая пара поддерживает скорость передачи данных от 10 до 100 Мбит/с. Однако ряд факторов может существенно снизить скорость передачи данных, в частности, потеря данных, перекрестное соединение и влияние электромагнитного излучения. Существует пять стандартных категорий кабеля из витых пар[1]: – кабель первой категории используется для передачи голосовых данных. С начала 80-х годов кабель CAT 1 используется в основном в качестве проводки телефонных линий. Кабель первой категории не сертифицирован для передачи данных любого типа и в большинстве случаев не рассматривается как среда для передачи цифровых данных; – кабель второй категории используется для передачи информации со скоростью не более 4 Мбит/с; – кабель третьей категории в основном используется для передачи данных со скоростью до 16 Мбит/с; – кабель четвертой категории. Кабель САТ4 сертифицирован для передачи данных со скоростью до 16 Мбит/с и состоит из четырех витых пар; – кабель пятой категории является самой распространенной средой передачи сетей Ethernet. Кабель поддерживает скорость передачи данных до 100 Мбит/с. Выберем витую пару категории САТ5 – 4-х парный кабель. Это и есть то, что обычно называют кабель «витая пара», благодаря высокой скорости передачи, до 100 Мбит/с при использовании 2-х пар и до 1000 Мбит/с, при использовании 4-х пар, является самым распространённым сетевым носителем, использующимся в компьютерных сетях до сих пор. 3.3 Обоснование выбора среды разработки и языка программирования Microsoft Visual C++ (MSVC) – интегрированная среда разработки приложений на языке C++, разработанная фирмой Microsoft и поставляемая либо как часть комплекта Microsoft Visual Studio, либо отдельно в виде функционально ограниченного комплекта Visual C++ Express Edition[6]. В студии разработчика можно строить обычные программы на C и С++, создавать статические и динамические библиотеки, создавать Windows-приложения с помощью инструмента MFC AppWizard (Application Wizard - мастер приложений) и библиотеки базовых классов MFC (Microsoft Foundation Class Library). Такие приложения называются MFC-приложениями. В состав компилятора Microsoft Developer Studio встроены средства, позволяющие программисту облегчить разработку приложений. В первую очередь к ним относятся MFC AppWisard, ClassWizard и редактор ресурсов. Благодаря MFC AppWizard среда разработчика позволяет быстро создавать шаблоны новых приложений. При этом программисту не приходится писать ни одной строчки кода. Достаточно ответить на ряд вопросов, касающихся того, какое приложение требуется создать, и исходные тексты шаблона приложения вместе с файлами ресурсов готовы. Эти тексты можно оттранслировать и получить готовый загрузочный модуль приложения. Для создания ресурсов приложения предназначен редактор ресурсов. Он позволяет быстро создавать новые меню, диалоговые панели, добавлять кнопки к панели управления toolbar и т.д. Средство ClassWizard позволяет подключить к созданным и отредактированным ресурсам управляющий ими код. Большую часть работы по описанию и определению функций, обрабатывающих сообщения от меню, органов управления диалоговых панелей и т.д., также берет на себя средство ClassWizard. MFC – это базовый набор (библиотека) классов, написанных на языке С++ и предназначенных для упрощения и ускорения процесса программирования для Windows. Библиотека содержит многоуровневую иерархию классов, насчитывающую около 200 членов. Они дают возможность создавать Windows-приложения на базе объектно-ориентированного подхода. С точки зрения программиста, MFC представляет собой каркас, на основе которого можно писать программы для Windows[6]. Библиотека MFC разрабатывалась для упрощения задач, стоящих перед программистом. Традиционный метод программирования под Windows требует написания достаточно длинных и сложных программ, имеющих ряд специфических особенностей. В частности, для создания только каркаса программы таким методом понадобится около 75 строк кода. По мере же увеличения сложности программы ее код может достигать больших размеров. Однако та же самая программа, написанная с использованием MFC, будет примерно в три раза меньше, поскольку большинство частных деталей скрыто от программиста. Одним из основных преимуществ работы с MFC является возможность многократного использования одного и того же кода. Так как библиотека содержит много элементов, общих для всех Windows-приложений, нет необходимости каждый раз писать их заново. Вместо этого их можно просто наследовать. Кроме того, интерфейс, обеспечиваемый библиотекой, практически независим от конкретных деталей, его реализующих. Поэтому программы, написанные на основе MFC, могут быть легко адаптированы к новым версиям Windows (в отличие от большинства программ, написанных обычными методами)[6]. Еще одним существенным преимуществом MFC является упрощение взаимодействия с прикладным программным интерфейсом (API) Windows. Любое приложение взаимодействует с Windows через API, который содержит несколько сот функций. Внушительный размер API затрудняет попытки понять и изучить его целиком. Зачастую даже сложно проследить, как отдельные части API связанны друг с другом. Но поскольку библиотека MFC объединяет функции API в логически организованное множество классов, интерфейсом становится значительно легче управлять[6]. В настоящий момент существует множество языков программирования, как универсальных, так и созданных для выполнения специфических задач. В данном проекте использован язык C++, который позиционируется как главный язык среды Visual Studio. Он включает систему доступа к практически любым известным и распространенным базам данных. 3.4 Выбор метода доступа к данным В данном дипломном проекте для хранения информации о штриховых кодах использовалась база данных. База данных совместно используемый набор логически связанных данных (и описание этих данных), предназначенный для удовлетворения информационных потребностей организации. Базы данных, которые состоят из двумерных таблиц, называются реляционными. Каждая таблица базы данных представляется как совокупность строк и столбцов, где строки соответствуют экземпляру объекта, конкретному событию или явлению, а столбцы – атрибутам (признакам, характеристикам, параметрам) объекта, события, явления. Для доступа к данным, хранящимся в базе данных, есть несколько способов, отличающихся друг от друга. Наиболее популярными среди универсальных механизмов доступа к данным можно назвать следующие: – Open Database Connectivity (ODBC); – OLE DB; – ActiveX Data Objects (ADO); – Borland Database Engine (BDE). ODBC (Open Database Connectivity) – широко распространенный программный интерфейс фирмы Microsoft. Для доступа к данным конкретной СУБД с помощью ODBC, кроме собственно клиентской части этой СУБД, нужен ODBC Administrator (приложение, позволяющее определить, какие источники данных доступны для данного компьютера с помощью ODBC, и описать новые источники данных), и ODBC-драйвер для доступа к этой СУБД. ODBC-драйвер представляет собой динамически загружаемую библиотеку (DLL), которую клиентское приложение может загрузить в свое адресное пространство и использовать для доступа к источнику данных. Для каждой используемой СУБД нужен собственный ODBC-драйвер, так как ODBC-драйверы используют функции клиентских API, разные для различных СУБД[7]. OLE DB и ADO – часть универсального механизма доступа к данным Microsoft (Microsoft Universal Data Access), позволяющая осуществить доступ как к реляционным, так и к нереляционным источникам данных, таким как файловая система, данные электронной почты, многомерные хранилища данных и др[7]. Для доступа к источнику данных с помощью OLE DB требуется, чтобы на компьютере, где используется клиентское приложение, был установлен OLE DB-провайдер для данной СУБД. OLE DB-провайдер представляет собой DLL, загружаемую в адресное пространство клиентского приложения и используемую для доступа к источнику данных. Для каждого типа СУБД нужен собственный OLE DB-провайдер, так как эти провайдеры базируются на функциях клиентских API, разных для различных СУБД. Процесс работы с данными можно описать в терминах взаимодействия двух объектов – Поставщика данных (Provider) и Потребителя данных (Consumer). Потребителем является приложение, запрашивающее данные и непосредственно вызывающее функции, заданные интерфейсом. Поставщик данных или Провайдер – это тот посредник, стоящий между приложением, запрашивающим данные, и источником данных[7]. Microsoft ActiveX Data Objects (ADO) – это набор библиотек, содержащих COM-объекты, реализующие прикладной программный интерфейс для доступа к таким данным и используемые в клиентских приложениях. ADO использует библиотеки OLE DB, предоставляющие низкоуровневый интерфейс для доступа к данным. OLE DB предоставляет доступ к данным с помощью COM-интерфейсов. Можно также использовать OLE DB непосредственно, минуя ADO[7]. BDE (Borland Database Engine) – универсальный механизм доступа к данным, применяемый в средствах разработки фирмы Borland (а именно – Delphi и C++Builder), а также в некоторых других продуктах. Для данного дипломного проекта выбираем метод доступа к базе данных – OLE DB. OLE DB предлагает единообразный высокопроизводительный метод доступа к данным, хранящимся в разных источниках информации, в том числе и в нереляционных БД (например, в папках систем электронной почты или простых файлах), обеспечивая при этом поддержку работы с наборами данных и иерархическими наборами записей, неподключенными постоянно к сети. 3.5 Обоснование выбора операционной системы В дипломном проекте была выбрана операционная система Windows XP. Данная операционная система является одной из самых распространенных на данный момент, она обладает так же рядом существенных преимуществ. Одним из критериев выбора Windows XP является то, что она установлена на всех персональных компьютерах ЗАО МЗХ «Атлант». Это единый (для всех программ-приложений Windows), стандартизированный и интуитивно-понятный интерфейс взаимодействия с пользователем. Т.е., даже начинающему пользователю персонального компьютера, не требуется особых усилий для освоения навыков работы с данным программным средством. Windows предлагает мощный программный интерфейс (Windows API) для разработчика программных средств – это огромный набор различных функций ядра операционной системы, предоставляемых программисту для использования в своих проектах и содержащих огромный объем кода, являющийся общим для всех программ-приложений Windows. Данная операционная система поддерживает сетевое взаимодействие удалённых компьютеров, что позволяет создавать программные приложения, работающие через сеть посредством стандартных протоколов взаимодействия. Таким образом, учитывая вышеперечисленные положительные свойства этой операционной системы, выбор данной платформы для создания программных средств, считается весьма обоснованным.
4.1 Разработка алгоритма функционирования программы Алгоритм работы программы приведен на рисунке 4.1. При запуске программы выполняется попытка открыть COM порт. Если COM порт уже занят другим приложением или возникла какая-либо ошибка, то выдаётся в отдельном окне сообщение «ошибка при открытии порта». Иначе «порт успешно открыт» и устанавливаются настройки для нормальной работы порта. Если все настройки установлены, запускаем функцию потока, в которой и будет происходить чтение данных с порта, при этом, не перегружая процессор из-за наличия бесконечного цикла. В противном случае закрываем COM порт и производим следующую попытку его открыть. В потоке запускаем функцию, которая открывает таблицу. Если таблица не была открыта данной программой, то устанавливаем счётчик попыток открыть таблицу равным пяти. Будет произведено пять попыток открыть таблицу для дальнейшей работы с ней. Выполняем проверку счётчика попыток, если он равен нулю, то заканчиваем работу с таблицей и выдаётся сообщение в отдельном окне «ошибка при открытии таблицы». Иначе пытаемся открыть таблицу и уменьшаем счётчик попыток на единицу. Если таблица была открыта каким-либо другим приложением, то также выдается сообщение «ошибка при открытии таблицы». После того, как была открыта таблица для проверки и записи данных, запускается бесконечный цикл для приёма данных в режиме реального времени. Это позволяет избежать перегрузки процессора и уменьшить ожидание ответа. Ожидаем поступление в порт данных. Если данные пришли, запускается функция чтения данных. Далее выполняется проверка записи данных в буфер. При отсутствии информации в буфере данных выполняется проверка занятости COM порта. Если проверка выполнялась успешно, ожидается считывание данных. После чего считанная информация записывается в буфер данных. Иначе ожидаем прихода новых данных. Далее считанный штрих-код в буфере данных проверяем на длину. Длинна данного кода не должна превышать 12 символов. Это объясняется выбранной в автоматизированной системе идентификации готовой продукции стандарта штрих-кода Cod39 и установленной длинной нумерации изделий на МЗХ ЗАО «Атлант». Рисунок 4.1 – Схема алгоритма работы программы Рисунок 4.1, лист 2 Если длинна штрих-кода превышает 12 символов, то последние символы отбрасываются. Последние символы – это информация, поступающая от сканера штрих-кода. Также это может быть посторонняя информация, поступающая из сети Ethernet, или накладываемые данные с прошлого раза считывания. После того, как была выполнена проверка на длину штрих-кода, выполняется запрос на совпадение данного штрих-кода со штрих-кодами, содержащимися в таблице и считанные на ранних этапах производства. Если было обнаружено совпадение, выдаётся сообщение в отдельном диалоговом окне «данный штрих код уже был считан», выполняется очистка буфера данных и рабочий переходит к считыванию следующего штрих-кода. Иначе происходит добавление данного штрих-кода из буфера данных в столбец «NAME» (этот столбец содержит штрих-коды) таблицы test.dbf. После чего добавляем текущую дату и время в буфер даты и записываем в столбец «DATE» соответствующему штрих-коду. Далее происходит запись штрих-кода в главную форму программы. По окончанию основных операций происходит очистка буфера данных, буфера COM порта и буфера даты. Это необходимо для того, чтобы данные не накладывались друг на друга, и не произошла ошибка неправильности данных на последующих считываниях штрих-кодов. При завершении работы с COM портом закрывается таблица, для дальнейшей работы с ней с помощью других приложений, останавливается поток и закрывается COM порт. 4.2 Разработка программного обеспечения Программное обеспечение разработано в среде MS Visual C++ 6.0. Для работы с базами данных использовано средство RDE Apollo OLE DB. Данная программа предназначена для автоматизированного учета шкафов и компрессоров в цехе на постах сборки и пайки посредством считывания штриховых кодов с технологических этикеток. Программа обрабатывает поступающую информацию с учетных точек, проверяет корректность принятых данных, регистрирует в базах данных, выводит результаты обработки в окно главной формы. Поступление информации происходит через COM порт, поэтому для работы необходимо его открыть. При открытии последовательного порта необходимо установить настройки порта для корректной его работы. Для открытия порта используем функцию CSerial::Open(). В этой функции устанавливаем все настройки и собственно с помощью функции CreateFile открываем последовательный порт. Для корректной работы порта используется структура DCB, которая содержит большинство настроек порта. Основными параметрами DCB структуры, которые необходимо указать, являются[5]: – DCBlength – размер самой структуры DCB. Задает длину, в байтах, структуры DCB. Используется для контроля корректности структуры при передаче ее адреса в функции настройки порта; – BaudRate – скорость передачи данных. Возможно указание любого значения, однако установленная скорость будет кратна скорости 115200. Дело в том, что в самой микросхеме порта есть два регистра, являющиеся непосредственно предделителем и делителем. Соответственно, при записи в делитель "1" – скорость будет 115200, "2" – 57600, "3" – 38400, "4" – 28800 и т.д. Устанавливаем скорость работы равной 9600. – Parity — определяет выбор схемы контроля четности. Данное поле должно содержать одно из следующих значений: а) EVENPARITY (2) дополнение до четности; б) MARKPARITY (3) бит четности всегда 1; в) NOPARITY (0) бит четности отсутствует; г) ODDPARITY (1) дополнение до нечетности; д) SPACEPARITY (4) бит четности всегда 0; В нашем случае выбираем вариант в) – бит чётности отсутствует. – StopBits – определяет количество стоповых бит. Поле может принимать следующие значения: а) ONESTOPBIT (0) один стоповый бит; б) ONE5STOPBIT (1) полтора стоповых бита; в) TWOSTOPBIT (2) два стоповых бита; В нашем случае выбираем вариант а) – один стоповый бит. – ByteSize – определяет число информационных бит в передаваемых и принимаемых байтах. Запрещенные значения: а) 5 в комбинации с StopBits=TWOSTOPBITS; б) 6,7,8 в комбинации с StopBits=ONE5STOPBITS. В нашем случае выбираем 8 информационных бит. DCB в качестве параметров имеют функции GetCommState и SetCommState. Функции необходимы для чтения/записи структуры DCB порта. Для определения таймаутов выполнения функции чтения и записи COM порта используется структура COMMTIMEOUTS. Поля структуры TCOMMTIMEOUTS имеют следующее назначение[5]: – ReadIntervalTimeout – максимальный временной промежуток (в мсек.), допустимый между двумя принимаемыми байтами. Если интервал между двумя последовательными байтами превысит заданное значение, операция чтения ReadFile завершается с возвратом всех данных из приемного буфера. Нулевое значение данного поля означает, что данный тайм-аут не используется. Комбинация: ReadIntervalTimeout := 0xFFFFFFFF; ReadTotalTimeoutMultiplier := 0; ReadTotalTimeoutConstant := 0; приводит к тому, что функция ReadFile возвращает немедленно все имеющиеся байты в приемном буфере. – ReadTotalTimeoutMultiplier – задает множитель (в мсек.), используемый для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение умножается на количество запрошенных для чтения байт; – ReadTotalTimeoutConstant – задает константу (в мсек.), используемую для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение плюсуется к результату умножения ReadTotalTimeoutMultiplier на количество запрошенных для чтения байт. Нулевое значение полей ReadTotalTimeoutMultiplier и ReadTotalTimeoutConstant означает, что общий тайм-аут для операции чтения не используется; – WriteTotalTimeoutMultiplier – задает множитель (в мсек.), используемый для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение умножается на количество записываемых байт; – WriteTotalTimeoutConstant – задает константу (в мсек.), используемую для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение прибавляется к результату умножения WriteTotalTimeoutMultiplier на количество записываемых байт. Нулевое значение полей WriteTotalTimeoutMultiplier и WriteTotalTimeoutConstant означает, что общий тайм-аут для операции записи не используется. Для чтения и записи таймаутов используются GetCommTimeouts и SetCommTimeouts соответственно. Для закрытия порта используется функция CSerial::Close(). Где с помощью CloseHandle закрывается COM порт. Для ожидания прихода байт в порт используется функция CSerial::ReadDataWaiting(). Функция CSerial::ReadData() используется для чтения данных с последовательного порта. Важным моментом в работе данной программы является проверка и запись считанного штрих-кода в таблицу. Для открытия таблицы используется функция CApollo::Open(). Для закрытия – CApollo::CloseAll(). Для запроса и записи данных используется стандартные функции средства RDE Apollo OLE DB, соответственно sx_Query и для записи - sx_Append, sx_PutString, sx_Commit. Класс Serial (Serial.h) #define FC_DTRDSR 0x01 #define FC_RTSCTS 0x02 #define FC_XONXOFF 0x04 #define ASCII_BEL 0x07 #define ASCII_BS 0x08 #define ASCII_LF 0x0A #define ASCII_CR 0x0D #define ASCII_XON 0x11 #define ASCII_XOFF 0x13 class CSerial { public: CSerial(); |
{
Close();
DeleteCriticalSection(&CriticalSection);
}
BOOL CSerial::Open(int nPort, int nBaud) ;функция, открывающая
COM порт
{
if( Opened ) return( TRUE );
char szPort[15];
DCB dcb;
wsprintf( szPort, "\\\\.\\COM%d", nPort );
Port = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if(( Port == NULL ) || ( Port == INVALID_HANDLE_VALUE )) return( FALSE );
memset( &OverlappedRead, 0, sizeof( OVERLAPPED ) );
COMMTIMEOUTS CommTimeOuts; ;определяем таймауты
выполнения функции чтения и записи
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( Port, &CommTimeOuts );
OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
dcb.DCBlength = sizeof( DCB ); ;устанавливаем
настройки последовательного порта
GetCommState( Port, &dcb );
dcb.BaudRate = nBaud;
dcb.Parity = 0;
dcb.StopBits = 0;
dcb.ByteSize = 8;
if( !SetCommState( Port, &dcb ) ||
!SetupComm( Port, 10000, 10000 ) ||
OverlappedRead.hEvent == NULL )
{
DWORD dwError = GetLastError();
if( OverlappedRead.hEvent != NULL ) CloseHandle( OverlappedRead.hEvent );
CloseHandle( Port );
return( FALSE );
}
Opened = TRUE;
return( Opened );
}
BOOL CSerial::Close() ;функция, закрывающая
COM порт
{
if( !Opened || Port == NULL ) return( TRUE );
if( OverlappedRead.hEvent != NULL ) CloseHandle( OverlappedRead.hEvent );
CloseHandle( Port );
Opened = FALSE;
Port = NULL;
return( TRUE );
}
int CSerial::GetData(void *buffer, int limit)
{
EnterCriticalSection(&CriticalSection);
DWORD dwBytesNum;
dwBytesNum = ReadData(buffer, limit);
LeaveCriticalSection(&CriticalSection);
return dwBytesNum;
}
BOOL CSerial::ClearBuffer() ;функция очистки
буфера порта
{
if( !Opened || Port == NULL ) return( FALSE );
if(!PurgeComm(Port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) return( FALSE );
return TRUE;
}
int CSerial::ReadDataWaiting() ;функция ожидания
данных
{
if( !Opened || Port == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( Port, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData(void *buffer, int limit) ;функция чтения данных
с порта
{
if( !Opened || Port == NULL ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
ClearCommError( Port, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
bReadStatus = ReadFile( Port, buffer, dwBytesRead, &dwBytesRead, &OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}
return( (int) dwBytesRead );
}
Класс Apollo (Apollo.h)
#include "sde61.h"
class CApollo
{
public:
BOOL Open(char* , char *, short);
void CloseAll();
CApollo();
virtual