Федеральное агентство по образованию
ДАЛЬНЕВОСТОЧНЫЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНСТИТУТ ФИЗИКИ И ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ
Кафедра физики атомов и молекул
ПРИМЕНЕНИЕ АВТОМАТИЗИРОВАННОГО АДАПТИВННОГО ИНТЕРФЕРОМЕТРА ДЛЯ ИССЛЕДОВАНИЯ НАНОСМЕЩЕНИЙ МИКРООБЪЕКТОВ
Исполнитель
Студент группы 141б Ефимов Т.А.
Руководитель Ромашко Р.В.
Владивосток 2010г.
Содержание
Введение. 3
1. Теоретические основы.. 5
1.1 Принцип действия адаптивного интерферометра. 5
1.2 Фоторефрактивный эффект. 6
1.3 Ортогональная геометрия взаимодействия световых волн в фоторефрактивном кристалле. 9
2. Экспериментальная часть. 11
2.1 Экспериментальная установка. 11
2.2. Исследуемые объекты.. 12
2.3 Методика эксперимента. 13
2.4 Экспериментальные результаты.. 15
Заключение. 17
Список литературы.. 18
Приложение. 20
Программа «motor control for 8DCMC1. 20
Введение
Регистрация колебаний и смещений микрообъектов является важнейшей задачей при разработке, создании и применении различных осцилляторов, резонаторов, микро- и нано- электромеханических систем. Такие системы применяются в химии и биологии, служат датчиками физических величин, например, для измерения малых и сверхмалых масс [1-3].
Особенностью исследования микрообъектов, микромеханических систем является то, что амплитуда собственных колебаний не превышает десятков нанометров, при этом сами объекты и измерительная система в целом подвергаются неконтролируемым шумовым воздействиям внешней среды.
Интерферометрические измерительные системы являются наиболее чувствительными инструментами для исследования широкого класса физических величин, в том числе параметров механических колебаний объектов. Вместе с тем высокая чувствительность любого интерферометра делает его в значительной степени подверженным влиянию внешних факторов (изменению температуры, давления, неконтролируемых деформаций, микросейсмических вибраций и пр.)
Для исследования механических параметров микрообъектов в настоящей работе был применен адаптивный интерферометр, основанный на использовании двухволнового взаимодействия в фоторефрактивных кристаллах [4]. Адаптивные интерферометры являются высокоэффективными системами измерения малых фазовых изменений в условиях неконтролируемых воздействий окружающей среды. Под высокой эффективностью адаптивного интерферометра понимается высокая чувствительность и высокая помехозащищенность, обеспечиваемые интерферометрическим принципом измерения, голографическим принципом восстановления фронта световой волны (включая, сколь угодно сложные, например, спекловые) и адаптивными свойствами динамической голограммы, используемой для объединения световых пучков [5].
Таким образом, применение адаптивного интерферометра позволяет обеспечить стабильность параметров измерительной системы, а так же, благодаря постоянной перезаписи динамической голограммы в фоторефрактивном кристалле, осуществить фильтрацию низкочастотных шумов.
Целью данной работы является разработка, практическая реализация и исследование системы регистрации малых колебаний микрообъектов на основе адаптивного интерферометра.
1. Теоретические основы
1.1 Принцип действия адаптивного интерферометра
Отличие адаптивного интерферометра от классического заключается в том, что в первом вместо обычного светоделительного элемента (куба или зеркала) используется среда, в которой постоянно записывается динамическая голограмма [5].
Формирование голограммы происходит в фоторефрактивном кристалле непосредственно при попадании на него оптического излучения. Дополнительная обработка (проявление, фиксация и т.п.) не требуется. Таким же образом, при помощи света голограмма может быть стерта. Свет вызывает внутри кристалла перераспределение зарядов, и в течение характерного времени (времени записи) устанавливается динамическое равновесие между распределениями интенсивности записывающего света и электрического заряда. Если параметры световых волн, формирующих голограмму, изменяются быстро, за время меньше времени записи, то голограмма не успевает следовать за ними. К «быстрым» здесь следует отнести изменения, вызванные воздействием исследуемого объекта (или физической величины). Для таких изменений голограмма будет «заморожена» (аналог статической голограммы), что обеспечит преобразование на ней световых волн и получение информации об объекте.
В противном случае, если параметры световых волн меняются медленно (за время, превышающее характерное время записи), что, как правило, характерно для большинства температурных влияний или, например, медленного накопления механических напряжений в исследуемом объекте, то в кристалле запишется новая голограмма, заменив старую. Как следствие, изменения параметров световых волн, а, следовательно, и отрицательное влияние внешних факторов на измерительную систему будут компенсированы изменениями, произошедшими в голограмме. В этом заключается общий принцип адаптивности измерительной системы на основе применения динамических голограмм. Таким образом, динамическая голограмма является своего рода фильтром низких частот, что позволяет компенсировать влияние на интерферометр любых медленно изменяющихся внешних воздействий.
адаптивный интерферометр световая волна
Запись голограммы происходит в фоторефрактивном кристалле. В основе процесса записи голограммы лежит фоторефрактивный эффект (ФРЭ), заключающийся в изменении коэффициента преломления среды под действием света. ФРЭ впервые был обнаружен в Лаборатории Бэлл в 1966 г. как нежелательное искажение оптического луча при прохождении через нелинейные электрооптические кристаллы LiNbO3
и LiTaO3
[6]. Было установлено, что вызванные светом изменения показателя преломления кристалла приводят к искажению фронта распространяющейся в нем световой волны и, как следствие, ограничение использования этих материалов в системах генерации второй гармоники или высокоскоростных модуляторах. Вскоре после открытия фоторефрактивного эффекта было обнаружено, что фоторефрактивный кристалл может быть возвращен в исходное состояние нагревом или равномерной засветкой. Таким образом, фоторефрактивный кристалл может быть использован для записи и стирания в реальном времени голограмм, которые теперь могут стать динамическими. К настоящему времени фоторефрактивный эффект обнаружен в большом количестве материалов: диэлектриках, полупроводниках, жидких кристаллах, органических полимерах [7-10].
Для возникновения фоторефрактивного эффекта в некотором материале последний должен обладать фотопроводящими свойствами и быть электрооптическим. В простейшей модели фоторефрактивного эффекта предполагается, что кристалл имеет носители заряда одного типа – электроны – и примеси двух типов – доноры и акцепторы, энергетические уровни которых располагаются в запрещенной зоне, как показано на рисунке 1. Предполагается, что некоторые доноры и все акцепторы ионизированы. В отсутствии светового излучения основным механизмом, пополняющим зону проводимости электронами, является тепловое возбуждение. Динамическое равновесие между теплогенерацией электронов и их обратной рекомбинацией определяет концентрацию свободных электронов ne
, которая в большинстве случаев является однородной по объему кристалла величиной или ее флуктуациями можно пренебречь.
Рис 1. Модель фоторефрактивного эффекта. Электроны возбуждаются светом с донорных уровней (
D
) в зону проводимости, где они диффундируют и дрейфуют в электрическом поле до тех пор, пока не будут захвачены акцепторами (А) или ионизированными донорами
Попадание светового излучения в фотопроводящий кристалл приводит к возникновению в нем дополнительных (фотоиндуцированных) пар электронов и ионизированных доноров. Фотоиндуцированные электроны, диффундировавшие в слабоосвещенные области, захватываются там акцепторами. В то же время, ионизированные доноры не могут двигаться, являясь частью кристаллической решетки, что ведет к локальным нарушениям электронейтральности. Возникает так называемый пространственный заряд, плотность распределения которого неоднородна и повторяет интерференционное распределение интенсивности света. Нескомпенсированный заряд приводит к появлению электрического поля , называемого полем пространственного заряда. Под действием этого поля все свободные электроны (как индуцированные светом, так и термически) начинают дрейфовать, формируя электрический ток.
В свою очередь, электрическое поле , возникшее внутри фоторефрактивного кристалла, приводит к изменению его показателя преломления в силу наличия у него электрооптических свойств.
Объектный и опорный световые пучки, интерференция которых создает голограмму, одновременно дифрагируют на ней так, что дифрагировавшая часть объектного пучка распространяется в направлении опорного пучка и наоборот. Благодаря основному принципу голографии волновой фронт дифрагировавшей части опорного пучка представляет точную копию недифрагировавшей части объектного пучка. То же остается справедливым для другой пары пучков в кристалле. В результате после кристалла в направлении каждого пучка мы имеем когерентное сложение двух интерферирующих световых пучков с абсолютно одинаковыми волновыми фронтами. Таким образом, проблема сопряжения волновых фронтов в интерферометре на основе голограммы (в том числе динамической) решается автоматически. Это позволяет в частности использовать волны со сколь угодно сложным волновым фронтом как в одном, так и в обоих плечах адаптивного интерферометра без снижения эффективности его работы.
1.3 Ортогональная геометрия взаимодействия световых волн в фоторефрактивном кристалле
Существует несколько схем записи голограмм в фоторефрактивном кресталле: пропускающая, отражательная и ортогональная [11]. Как было показано [12] в широком круге задач наиболее перспективной является ортогональная геометрия.
Схема ортогонального взаимодействия световых пучков в фоторефрактивном кристалле представлена на рис. 2.
Рис. 2 Схема ортогонального взаимодействия световых пучков в фоторефрактивном кристалле
S – объектная волна, R – опорная. Световые лучи приходят в фоторефрактивный кристалл под прямым углом, где формируют голографическую решетку, которая направлена к ним под углом 45º. Характер взаимодействия световых пучков определяет их взаимная ориентация по отношению к кристаллографическим осям. Эффективность взаимодействия волн в электрооптическом кристалле существенно зависит от ориентации электрического поля в кристалле, среза кристалла и ориентации голографической решетки относительно кристаллографических осей [12].
Рис. 3 Ортогональная схема записи голограммы в фоторефрактивном кристалле
При ориентации кристалла, как показано на рис. 3 взаимодействуют S-компоненты объектной и опорной волны, P-компоненты ортогональны и не взаимодействуют. Что делает измерительную систему поляризационно независимой. Благодаря этому в качестве объектной волны может использоваться излучение от диффузно-рассевающих объектов или излучение вышедшей из многомодового волоконного световода.
2. Экспериментальная часть
2.1 Экспериментальная установка
Для исследования колебаний микрообъектов была собранна экспериментальная установка на основе голографического принципа объединения волн, изображенная на рис. 4.
Рис.4 Схема экспериментальной установки.
m
1,
m
3,
m
4 – зеркала;
m
2 – светоделитель;
L
1,
L
2,
L
3 – собирающие линзы; λ/4 – четвертьволновая пластинка; ФРК – фоторефрактивный кристалл;
D
– электродинамический преобразователь; ФП – фотоприемник;
MT
–моторезированный двух-координатный транслятор
В качестве источника излучения использовался Nd:YAG-лазер с длиной волны 1064 нм. Лазерный пучок делился на объектный и опорный. Объектный пучок фокусировался и направлялся на исследуемый объект, закрепленный на калиброванный электродинамический преобразователь, с помощью которого осуществлялось передача колебаний исследуемому объекту. Вследствие колебаний образца, отраженное от него излучение было модулировано по фазе, которое затем собиралось линзой и направлялось в фоторефрактивный кристалл. Демодуляция фазы отраженной волны осуществлялась за ее взаимодействия с опорной волной на динамической голограмме формеруемой в кристалле CdTe. Интенсивность объектного пучка регистриловаллось с помощью фотоприемника. Сигнал которого через АЦП поступал в компьютер.
2.2 Исследуемые объекты
В качестве исследуемых объектов были выбраны вытянутые кварцевые световоды диаметром 15 мкм
и 2 мкм
без дополнительных отражающих покрытий. Отношение мощности отраженного от объекта излучения и излучения направляемого на объект не превышало 5%. Тем самым моделировалось исследование слабоотражающих и полупрозрачных объектов.
Рис. 5 Снимок исследуемого образца с диаметром 15 мкм
Рис. 6 Снимок исследуемого объекта с диаметром 2 мкм
Рис. 7 Снимок лазерного пучка отраженного от исследуемого объекта
Несмотря на сложную структуру отраженного от объекта пучка (рис. 8) , благодаря голографическому принципу объединения волн в кристалле, в данном интерферометре может быть выполнена его фазовая демодуляция.
2.3 Методика эксперимента
Объектный пучок фокусировался короткофокусной линзой L
1
(рис. 4) на исследуемый объект (рис. 4). Поперечный диаметр объектного пучка в месте максимальной фокусировке составлял 50 мкм
.
Исследуемый объект располагался рядом с реперным кварцевым волокном с диаметром 130 мкм
на рамке, жестко связанной с электродинамическим преобразователем (рис. 8). В силу того что объекты имели малый размер для поиска и исследования образца использовалась двухкоординатная система линейного моторизированного перемещения Standa8DCMC1.
Данная система позволила перемещать образец относительно объектного пучка с точностью до 14 нм
.
Рис. 8 Взаимное расположение образца с диаметром 15 мкм и реперного кварцевого волокна
Управление отдельными нано-трансляторами системы моторизированного перемещения осуществлялось с помощью команд подаваемых с компьютера на контроллер. Для подачи команд и автоматизации управления было разработано и реализованно специализированное программное обеспечение «motor control for 8DCMC1», главное диалоговое окно которого представлено на рис. 8. (листинг файлов программы приведен в приложении)
Рис. 9 Главное диалоговое окно программы «motor control for 8DCMC1»
С помощью данной программы была осуществлена регистрация и синхронизация сигнала, подаваемого на АЦП, с передвижением нано-транслятора, что позволило правильно интерпретировать полученные результаты.
Перемещение образцов относительно объектного пучка осуществлялась от реперного кварцевого волокна к исследуемому образцу по направлению Х, как показано на рис. 8.
Экспериментально полученная зависимость амплитуды демодулированного сигнала от положения сканирующего пучка для двух образцов с диаметром 15 мкм
и 2 мкм
приведена на рис. 10. При этом амплитуда колебаний образца составляла 20 нм
.
Рис. 10 Зависимости амплитуды сигнала от положения сканирующего пучка для образцов с диаметром 15 мкм и 2 мкм
Как видно из рис. 10 характер изменения сигнала демодуляции с расстоянием от реперного оптического волокна соответствует прямому оптическому измерению с помощью микроскопа (рис. 7), что подтверждает полученные результаты.
Заключение
Таким образом, в настоящей работе разработана и практически реализована система регистрации малых колебаний микрообъектов с помощью адаптивного интерферометра на основе динамических ортогональных голограмм, формируемых в фоторефрактивном кристалле. Показано что такая система позволяет регистрировать колебания объектов размерами 2 мкм. Создано программное обеспечение для управления нано-позиционерами.
С учетом того, что ортогональная геометрия формирования динамической голограммы в ФРК позволяет создавать поляризационно-независимые схемы адаптивных интерферометров, разработанная измерительная система может быть использована в том числе и для исследования сложных микро- и нано- объектов, взаимодействие излучения с которыми может приводить к полной его деполяризации.
Список литературы
1. B. Ilic, H. G. Craighead, S. Krylov, W. Senaratne, C. Ober, and P. Neuzil. Attogram detection using nanoelectromechanical oscillators // J. Appl. Phys. - 2004–Vol.95.
2. M. Sato, B. E. Hubbard, L. Q. English, and A. J. Sievers, B. Ilic, D. A. Czaplewski and H. G. Craighead. Study of intrinsic localized vibrational modes in micromechanical oscillator arrays // CHAOS - 2003. –Vol. 13, No.2 – P.702-715.
3. L. Sekaric,a) M. Zalalutdinov, S. W. Turner, A. T. Zehnder, J. M. Parpia, and H. G. Craighead Nanomechanical resonant structures as tunable passive modulators of light // J. Appl. Phys. - 2002 –Vol.80.
4. S. Di Girolamo, A.A.Kamshilin, R.V.Romashko, Yu.N.Kulchin, J.-C.Launay. Fast adaptive interferometer on dynamic reflection hologram in CdTe:V // Optics Express. – 2007. – Vol.15. – No.2. – P.545-555.
5. М. П. Петров, С. И. Степанов, А. В. Хоменко. Фоточувствительные электрооптические среды в голографии и оптической обработке информации. – Л.: Наука Ленингр. отд.-ние. – 1983. – 269 с.
6. A. Ashkin, G. D. Boyd, J. M. Dziedzic, R. G. Smith, A. A. Ballman, J. J. Levinstein, K. Nassau. Optically-induced refractive index inhomogeneities in LiNbO3
and LiTaO3
// Appl. Phys. Lett. – 1966. – V.9. – P.72.
7. P. Gunter, J.-P. Huignard, eds. Photorefractive materials and their applications 2: Materials. – Springer Series in Optical Sciences. – 2007. – V.114. – 646 p.
8. G. Zhang, D. Kip, D. D. Nolte, J. Xu, eds. OSA Trends in Optics and Photonics: Photorefractive Effects, Materials, and Devices. – 2005. – V.99.
9. P. Delaye, C. Denz, L. Mager, G. Montemezzani, eds. OSA Trends in Optics and Photonics: Photorefractive Effects, Materials, and Devices. – 2003. – V.87.
10. В. Л. Винецкий, Н. В. Кухтарев. Динамическая голография. – Киев: Наукова думка. – 1983. – 125 с.
11. Di Girolamo S., Romashko R.V., Kulchin Y.N., Kamshilin A.A. Orthogonal geometry of wave interaction in a photorefractive crystal for linear phase demodulation // Opt. Commun. – 2010. - V.283. - P.128-131.
12. R. V. Romashko, S. Di Girolamo, Y. N. Kulchin, and A. A. Kamshilin. Photorefractive vectorial wave mixingin different geometries// J. Opt. Soc. Am. -2010. -Vol. 27. No. 2. –P. 311-317.
Программа «motor control for 8DCMC1»
Данная программа создана в среде MSVisualC++ 6.0 на базе класса MFC.Состоит из двух диалоговых окон: SERIALGATETEST_DIALOG и ABOUTBOX. Реализованы следующие функции:
1. Взаимодействие с COM – портом компьютера. Чтение и запись информации в памяти контроллера 8DCMC1 по средствам интерфейса RS232. Эта функция реализована в виде отдельной библиотеки – SerialGate.dll.
2. Аналог командной строки для управления шаговыми двигателями, содержащий поле ввода и поле вывода.
3. Задание параметров работы шаговых двигателей (скорость, ускорение).
4. 2D-cканированиевыбранного участка.
5. Опрос АЦП, запись полученных данных в файл.
Листинг
SerialGateTest.cpp:
#include "stdafx.h"
#include "SerialGateTest.h"
#include "SerialGateTestDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CSerialGateTestApp, CWinApp)
//{{AFX_MSG_MAP(CSerialGateTestApp)
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CSerialGateTestApp construction
CSerialGateTestApp::CSerialGateTestApp()
{
}
CSerialGateTestApp theApp;
// CSerialGateTestApp initialization
BOOL CSerialGateTestApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();// Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic();// Call this when linking to MFC statically
#endif
CSerialGateTestDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
return FALSE;
}
Листинг
SerialGateTestDlg.cpp:
#include <stdio.h>
#include <string.h>
#include <string>
#include "stdafx.h"
#include "SerialGateTest.h"
#include "SerialGateTestDlg.h"
#include <windows.h>
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//using System;
int key=0;
//#include "thread.h"
//#include System::Threading;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialGateTestDlg dialog
CSerialGateTestDlg::CSerialGateTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSerialGateTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSerialGateTestDlg)
m_port = 5;
m_rate = 9600;
m_recieve = _T("");
m_send = _T("");
m_axsis = _T("");
m_vel = _T("");
m_asel = _T("");
m_gomr = _T("");
m_mraxsis0 = _T("");
m_mraxsis1 = _T("");
m_tapeaxsis0 = _T("");
m_tapeaxsis1 = _T("");
m_dataininput = _T("");
m_dataoutput = _T("");
m_past = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSerialGateTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSerialGateTestDlg)
DDX_Control(pDX, IDC_RECIEVE, m_recievecontr);
DDX_Text(pDX, IDC_PORT, m_port);
DDX_Text(pDX, IDC_RATE, m_rate);
DDX_Text(pDX, IDC_RECIEVE, m_recieve);
DDX_Text(pDX, IDC_SEND, m_send);
DDX_Text(pDX, IDC_SETAXSCIS, m_axsis);
DDX_Text(pDX, IDC_SETVEL, m_vel);
DDX_Text(pDX, IDC_SETASEL, m_asel);
DDX_Text(pDX, IDC_MR, m_gomr);
DDX_Text(pDX, IDC_MRAXSIS0, m_mraxsis0);
DDX_Text(pDX, IDC_MRAXSIS1, m_mraxsis1);
DDX_Text(pDX, IDC_TAPEAXSIS1, m_tapeaxsis1);
DDX_Text(pDX, IDC_DATAEXCHANGE, m_dataininput);
DDX_Text(pDX, IDC_DATAEXCHANGE2, m_dataoutput);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSerialGateTestDlg, CDialog)
//{{AFX_MSG_MAP(CSerialGateTestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON2, OnOpen)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON1, OnSend)
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_ON_SETAXSIS, OnOnSetaxsis)
ON_BN_CLICKED(IDC_ON_SETACSEL, OnOnSetacsel)
ON_BN_CLICKED(IDC_ON_SETVELOS, OnOnSetvelos)
ON_BN_CLICKED(IDC_ON_MOTROON, OnOnMotroon)
ON_BN_CLICKED(IDC_ON_MOTOROFF, OnOnMotoroff)
ON_BN_CLICKED(IDC_ON_MR, OnOnMr)
ON_BN_CLICKED(IDC_ON_GO, OnOnGo)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialGateTestDlg message handlers
BOOL CSerialGateTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
SetIcon(m_hIcon, FALSE);// Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CSerialGateTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSerialGateTestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CSerialGateTestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSerialGateTestDlg::OnOpen()
{
// TODO: Add your control notification handler code here
UpdateData(true);
if(m_port == 0 || m_rate == 0)
{
MessageBox("Not correct data","Error", MB_ICONERROR);
return;;
}
bool b = sg.Open(m_port, m_rate);
if(b == false)
{
MessageBox("Can`t open Port","Error", MB_ICONERROR);
return;;
}
else
{
MessageBox("Port open OK","Info", MB_ICONINFORMATION);
}
SetTimer(1, 1000, NULL);
}
void CSerialGateTestDlg::OnTimer(UINT nIDEvent)
{
if (key==0)
{// TODO: Add your message handler code here and/or call default
char buff[128];
int rcv = sg.Recv(buff, sizeof(buff));
this->m_recievecontr.SetWindowText("");
if(rcv > 0)
{
for(int i = 0; i< rcv; i++)
this->m_recieve += buff[i];
UpdateData(false);
}
}
CDialog::OnTimer(nIDEvent);
}
void CSerialGateTestDlg::OnSend()
{
// TODO: Add your control notification handler code here
UpdateData(true);
int len = this->m_send.GetLength();
if(len > 0)
{
char* LocBuf = m_send.GetBuffer(128);
sg.Send(LocBuf, len);
m_send.ReleaseBuffer();
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
}
}
void CSerialGateTestDlg::OnButton3()
{
UpdateData(true);
int len = this->m_send.GetLength();
if(len > 0)
{
char ent=0x01;
char* ent2 = &ent;
sg.Send(ent2, 1);
char* LocBuf = m_send.GetBuffer(128);
sg.Send(LocBuf, len);
m_send.ReleaseBuffer();
}
}
void CSerialGateTestDlg::OnOnSetaxsis() //выбор оси
{
UpdateData(true);
intpopytka=0;
//изменение активного мотора
char ctrlkey=0x01;
char* ctrlkey2 = &ctrlkey;
sg.Send(ctrlkey2, 1);
int len=1;
char* LocBuf = m_axsis.GetBuffer(128);
sg.Send(LocBuf, len);
m_send.ReleaseBuffer();
CString tp="tp";
char* LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
}
void CSerialGateTestDlg::OnOnSetacsel() //установить ускорение
{
UpdateData(true);
CString sa="sa";
char* LocBuf2 = sa.GetBuffer(128);
sg.Send(LocBuf2, 2);
sa.ReleaseBuffer();
int len = this->m_asel.GetLength();
if(len > 0)
{
char* LocBuf = m_asel.GetBuffer(128);
sg.Send(LocBuf, len);
m_asel.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
//проверкаtl
CString tl="tl";
char* LocBuf3 = tl.GetBuffer(128);
sg.Send(LocBuf3, 2);
tl.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
//m_recievecontr.SetWindowText("0");
//CEdit::Clear;
//UpdateData(false);
}
}
void CSerialGateTestDlg::OnOnSetvelos()
{
UpdateData(true);
CString sv="sv";
char* LocBuf2 = sv.GetBuffer(128);
sg.Send(LocBuf2, 2);
sv.ReleaseBuffer();
int len = this->m_vel.GetLength();
if(len > 0)
{
char* LocBuf = m_vel.GetBuffer(128);
sg.Send(LocBuf, len);
m_vel.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
//проверкаty
CString ty="ty";
char* LocBuf3 = ty.GetBuffer(128);
sg.Send(LocBuf3, 2);
ty.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
}
}
void CSerialGateTestDlg::OnOnMotroon()
{
UpdateData(true); //включить мотор
CString mn="mn";
char* LocBuf2 = mn.GetBuffer(128);
sg.Send(LocBuf2, 2);
mn.ReleaseBuffer();// TODO: Add your control notification handler code here
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
}
void CSerialGateTestDlg::OnOnMotoroff() //выключить мотор
{
CString mf="mf";
char* LocBuf2 = mf.GetBuffer(128);
sg.Send(LocBuf2, 2);
mf.ReleaseBuffer();// TODO: Add your control notification handler code here
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
}
void CSerialGateTestDlg::OnOnMr() //перемещение
{
UpdateData(true);
CString mr="mr";
char* LocBuf2 = mr.GetBuffer(128);
sg.Send(LocBuf2, 2);
mr.ReleaseBuffer();
int len = this->m_gomr.GetLength();
if(len > 0)
{
char* LocBuf = m_gomr.GetBuffer(128);
sg.Send(LocBuf, len);
m_gomr.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
//проверкаty
CString tp="tp";
char* LocBuf3 = tp.GetBuffer(128);
sg.Send(LocBuf3, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
//m_recieve.Clear();
}
}
void CSerialGateTestDlg::OnOnGo() //////////////////кнопка GO//////////////////////
{
UpdateData(true);
key=1;
int axis=0;
intres;
TP0:
//изменение активного мотора
char ctrlkey=0x01;
char* ctrlkey2 = &ctrlkey;
sg.Send(ctrlkey2, 1);
int len=1;
char axsis0='0';
char* axsis0_2 = &axsis0;
sg.Send(axsis0_2, 1);
CString tp="tp";
char* LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
Sleep(700); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff[128];
int rcv = sg.Recv(buff, sizeof(buff));
int elmbuff=rcv-1;
buff[rcv]=0;
CString str;
for(int i = 0; i< rcv; i++)
str += buff[i];
char* j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
CStringmraxsis0_2; //сюда записывается занчение е окошка editaxsis0
GetDlgItemText(IDC_MRAXSIS0,mraxsis0_2);
int posnum0=atoi(mraxsis0_2);
int posnum0_mr=res-posnum0/2;
CString mraxsis0_mr;
mraxsis0_mr =itoa(posnum0_mr,mraxsis0_mr.GetBuffer(10),10);
//выполним перемещение на нулевую позицию//
CString mr="MA";
char* LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis0_mr.GetLength();
char* LocBuf9 = mraxsis0_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis0_mr.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
int gto0=posnum0_mr;
int posicino00=res;
Sleep(400);
TP1:
//изменение активного мотора
sg.Send(ctrlkey2, 1);
len=1;
char axsis1='1';
char* axsis1_2 = &axsis1;
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(700);
//организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff2[128];
rcv = sg.Recv(buff2, sizeof(buff2));
elmbuff=rcv-1;
buff2[rcv]=0;
CString str2;
for(i = 0; i< rcv; i++)
str2 += buff2[i];
j = strchr(buff2, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff2, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
CStringmraxsis1_2; //сюда записывается занчение е окошка editaxsis0
GetDlgItemText(IDC_MRAXSIS1,mraxsis1_2);
int posnum1=atoi(mraxsis1_2);
int posnum1_mr=res-posnum1/2;
CString mraxsis1_mr;
mraxsis1_mr =itoa(posnum1_mr,mraxsis1_mr.GetBuffer(10),10);
//выполним перемещение на нулевую позицию//
mr="MA";
LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis1_mr.GetLength();
LocBuf9 = mraxsis1_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis1_mr.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
int gto1=posnum1_mr;
int posicino01=res;
Sleep(130);
int pos01=gto1;
int pos00=gto0;
int modul;
do
{
Sleep(400);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(800); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
CStringstr;
char buff[128];
rcv = sg.Recv(buff, sizeof(buff));
if(rcv > 0)
elmbuff=rcv-1;
buff[rcv]=0;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
}//ожидание прихода подвижки в заданное место
modul=res-gto0;
if (modul<0) modul=-modul;
} while (modul>20);
do
{
Sleep(800);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(400); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff[128];
rcv = sg.Recv(buff, sizeof(buff));
elmbuff=rcv-1;
buff[rcv]=0;
CString str;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}//ожидание прихода подвижки в заданное место
modul=res-gto1;
if (modul<0) modul=-modul;
}while (modul>20);
MessageBox("peremecheno","ok", MB_ICONINFORMATION);
//UpdateData(false);
//////////////организуем сканирование////////////////
int tape0=0;
int tape1=0;
int tape0t=0; //текущий проход
int tape1t=0;
//CString tapeaxsis0_1;
//GetDlgItemText(IDC_TAPEAXSIS0,tapeaxsis0_1);
//tape0=atoi(tapeaxsis0_1);
CString tapeaxsis1_1;
GetDlgItemText(IDC_TAPEAXSIS1,tapeaxsis1_1);
tape1=atoi(tapeaxsis1_1);
//перемещение по оси 1//
while (tape1t<tape1)
{
//премещение по оси 0//
//UpdateData(false);
//CString mraxsis0_mr;
//mraxsis0_mr =itoa(posnum0_mr,mraxsis0_mr.GetBuffer(10),10);
//this->m_pastcontrol.SetWindowText("");
//CString tape1tstr;
//tape1tstr =itoa(tape1t,tape1tstr.GetBuffer(10),10);
//this->m_past=tape1tstr;
tape1t++;
//изменение активного мотора
charctrlkey=0x01;
char* ctrlkey2 = &ctrlkey;
sg.Send(ctrlkey2, 1);
int len=1;
char axsis0='0';
char* axsis0_2 = &axsis0;
sg.Send(axsis0_2, 1);
CString tp="tp";
char* LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
char ent=0x0D;
char* ent2 = &ent;
sg.Send(ent2, 1);
Sleep(600); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff1[128];
int rcv = sg.Recv(buff1, sizeof(buff1));
buff1[rcv]=0;
char* j = strchr(buff1, '+');
int res = atoi(j);
if (j==0)
{
j = strchr(buff1, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
CStringmraxsis0_2; //сюда записывается занчение е окошка editaxsis0
GetDlgItemText(IDC_MRAXSIS0,mraxsis0_2);
posnum0=atoi(mraxsis0_2);
posnum0_mr=posicino00+posnum0/2; //перемещаемся вперед
CString mraxsis0_mr;
mraxsis0_mr =itoa(posnum0_mr,mraxsis0_mr.GetBuffer(10),10);
//выполним перемещение//
CStringmr="MA";
char* LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis0_mr.GetLength();
char* LocBuf9 = mraxsis0_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis0_mr.ReleaseBuffer();//enter
sg.Send(ent2, 1);
gto0=posnum0_mr;
//считывание данных из файла//
CStringinputfile;
GetDlgItemText(IDC_DATAEXCHANGE, inputfile);
CString outputfile;
GetDlgItemText(IDC_DATAEXCHANGE2, outputfile);
CString strinput;
CString stroutput;
CStdioFile FileInPut(inputfile, CFile::shareDenyNone);
CStdioFile FileOutPut(outputfile, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::shareDenyNone);
FileInPut.SeekToEnd();
int positionFileInPut1=FileInPut.GetPosition();
//считывание данных из файла//
Sleep(300);
do
{
Sleep(400);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(800); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
CStringstr;
char buff[128];
rcv = sg.Recv(buff, sizeof(buff));
if(rcv > 0)
{
elmbuff=rcv-1;
buff[rcv]=0;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
}//ожидание прихода подвижки в заданное место
modul=res-gto0;
if (modul<0) modul=-modul;
} while (modul>20);
//дождемся пока подвижка примет первоночальное положение//
//считывание данных из файла//
FileInPut.SeekToEnd();
FileOutPut.SeekToEnd();
int positionFileInPut2=FileInPut.GetPosition();
FileInPut.Seek(positionFileInPut1, CFile::begin);
CString space=" ";
//char buffstr[128];
for (int positionFileInPutCurrent=FileInPut.GetPosition(); positionFileInPutCurrent<positionFileInPut2; positionFileInPutCurrent=FileInPut.GetPosition())
{
//FileOutPut.ReadString(stroutput);
FileInPut.ReadString(strinput);
char* buffstr = strinput.GetBuffer(128);
int lenstr=strinput.GetLength();
buffstr[lenstr]=0;
char* j = strchr(buffstr, ',');
stroutput=j+1;
FileOutPut.WriteString(stroutput);
FileOutPut.WriteString(space);
}
//перемещение по оси 1//
FileOutPut.WriteString("\r\n");
//изменение активного мотора//
sg.Send(ctrlkey2, 1);
len=1;
char axsis1='1';
char* axsis1_2 = &axsis1;
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff4[128];
rcv = sg.Recv(buff4, sizeof(buff4));
buff4[rcv]=0;
j = strchr(buff4, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff4, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
CStringmraxsis1_2; //сюда записывается занчение е окошка editaxsis0
GetDlgItemText(IDC_MRAXSIS1,mraxsis1_2);
int posnum1=atoi(mraxsis1_2);
int posnum1_mr=pos01+tape1t*posnum1/tape1;
CString mraxsis1_mr;
mraxsis1_mr =itoa(posnum1_mr,mraxsis1_mr.GetBuffer(10),10);
gto1=posnum1_mr;
//выполним перемещение//
mr="MA";
LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis1_mr.GetLength();
LocBuf9 = mraxsis1_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis1_mr.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300);
do
{
Sleep(400);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
len=1;
char axsis1='1';
char* axsis1_2 = &axsis1;
sg.Send(axsis1_2, 1);
sg.Send(ctrlkey2, 1);
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(800); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
CStringstr;
char buff[128];
rcv = sg.Recv(buff, sizeof(buff));
if(rcv > 0)
{
elmbuff=rcv-1;
buff[rcv]=0;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
}//ожидание прихода подвижки в заданное место
modul=res-gto1;
if (modul<0) modul=-modul;
} while (modul>20);
//переведем подвижку в первоначальное положение//
//изменение активного мотора//
Sleep(300);
ctrlkey=0x01;
ctrlkey2 = &ctrlkey;
sg.Send(ctrlkey2, 1);
len=1;
axsis0='0';
axsis0_2 = &axsis0;
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
ent=0x0D;
ent2 = &ent;
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff7[128];
rcv = sg.Recv(buff7, sizeof(buff7));
elmbuff=rcv-1;
buff7[rcv]=0;
CStringstr7;
for(i = 0; i< rcv; i++)
str7 += buff7[i];
j = strchr(buff7, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff7, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
//сюда записывается занчение е окошка editaxsis0
GetDlgItemText(IDC_MRAXSIS0,mraxsis0_2);
posnum0=atoi(mraxsis0_2);
posnum0_mr=pos00; //перемещаемся назад
mraxsis0_mr =itoa(posnum0_mr,mraxsis0_mr.GetBuffer(10),10);
//выполним перемещение на нулевую позицию//
mr="MA";
LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis0_mr.GetLength();
LocBuf9 = mraxsis0_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis0_mr.ReleaseBuffer();//enter
sg.Send(ent2, 1);
gto0=pos00;
Sleep(300);
do
{
Sleep(300);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
CStringstr8;
char buff8[128];
rcv = sg.Recv(buff8, sizeof(buff8));
if(rcv > 0)
{
elmbuff=rcv-1;
buff8[rcv]=0;
for(int i = 0; i< rcv; i++)
str8 += buff8[i];
j = strchr(buff8, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff8, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
}//ожидание прихода подвижки в заданное место
modul=res-gto0;
if (modul<0) modul=-modul;
} while (modul>20);//дождемся пока подвижка примет первоночальное положение//
UpdateData(true);
//перемещение по оси 1//
}
/////////////////////////////////////////////
//вернем систему в первоночальное положение//
/////////////////////////////////////////////
Tp0:
//изменение активного мотора
sg.Send(ctrlkey2, 1);
len=1;
axsis0='0';
axsis0_2 = &axsis0;
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
posnum0_mr=posicino00;
mraxsis0_mr =itoa(posnum0_mr,mraxsis0_mr.GetBuffer(10),10);
//выполним перемещение на нулевую позицию//
mr="MA";
char* LocBuf11 = mr.GetBuffer(128);
sg.Send(LocBuf11, 2);
mr.ReleaseBuffer();
len=mraxsis0_mr.GetLength();
char* LocBuf14 = mraxsis0_mr.GetBuffer(128);
sg.Send(LocBuf14, len);
mraxsis0_mr.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(200);
UpdateData(true);
gto0=posicino00;
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
Sleep(300);
char buff10[128];
rcv = sg.Recv(buff10, sizeof(buff10));
Tp1:
//изменение активного мотора
sg.Send(ctrlkey2, 1);
len=1;
axsis1='1';
axsis1_2 = &axsis1;
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300);
//организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
rcv = sg.Recv(buff10, sizeof(buff10));
posnum1_mr=posicino01;
mraxsis1_mr =itoa(posnum1_mr,mraxsis1_mr.GetBuffer(10),10);
gto1=posicino01;
//выполним перемещение на нулевую позицию//
mr="MA";
LocBuf8 = mr.GetBuffer(128);
sg.Send(LocBuf8, 2);
mr.ReleaseBuffer();
len=mraxsis1_mr.GetLength();
LocBuf9 = mraxsis1_mr.GetBuffer(128);
sg.Send(LocBuf9, len);
mraxsis1_mr.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
UpdateData(true);
Sleep(130);
do
{
Sleep(300);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis0_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
CStringstr;
char buff[128];
rcv = sg.Recv(buff, sizeof(buff));
if(rcv > 0)
{
elmbuff=rcv-1;
buff[rcv]=0;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}
}//ожидание прихода подвижки в заданное место
modul=res-gto0;
if (modul<0) modul=-modul;
} while (modul>40);
do
{
Sleep(400);
//изменение активного мотора
sg.Send(ctrlkey2, 1);
sg.Send(axsis1_2, 1);
tp="tp";
LocBuf2 = tp.GetBuffer(128);
sg.Send(LocBuf2, 2);
tp.ReleaseBuffer();
//enter
sg.Send(ent2, 1);
Sleep(300); //организуем паузу чтобы контроллер успел ответить
//считаем текущую позицию//
charbuff[128];
rcv = sg.Recv(buff, sizeof(buff));
elmbuff=rcv-1;
buff[rcv]=0;
CString str;
for(int i = 0; i< rcv; i++)
str += buff[i];
j = strchr(buff, '+');
res = atoi(j);
if (j==0)
{
j = strchr(buff, '-');
res = atoi(j); //в res здесь храниться текущие положение
}//ожидание прихода подвижки в заданное место
modul=res-gto1;
if (modul<0) modul=-modul;
}while (modul>20);
key=0;
////////////////////////////////////////////
}
Листинг
SerialGate.dll
SerialGate.cpp:
#include "stdafx.h"
#include "SerialGate.h"
#include <iostream>
#include <Winspool.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec (dllexport) bool SerialGate::Open(int port, int baud)
{
char COM_string[20];
sprintf(COM_string,"\\\\.\\COM%d", port);
m_hFile = CreateFile(COM_string, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
{
return false;
}
DCB dcb;
GetCommState(m_hFile, &dcb);
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
SetCommTimeouts(m_hFile, &CommTimeOuts);
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.BaudRate = baud;
SetCommState(m_hFile, &dcb);
this->state = true;
return true;
}
extern "C" __declspec (dllexport) SerialGate::SerialGate()
{
this->state = false;
}
extern "C" __declspec (dllexport) SerialGate::~SerialGate()
{
this->Close();
}
extern "C" __declspec (dllexport) void SerialGate::Close()
{
this->state = false;
CloseHandle(m_hFile);
}
extern "C" __declspec (dllexport) void SerialGate::Clean()
{
if(!state)
return;
PurgeComm(m_hFile, PURGE_TXCLEAR|PURGE_RXCLEAR);
}
extern "C" __declspec (dllexport) int SerialGate::Send(char* buff, int szBuff)
{
if(!state)
return 0;
if(buff == NULL || szBuff <= 0)
{
return 0;
}
DWORD lpdwBytesWrittens = 0;
WriteFile(m_hFile, buff, szBuff, &lpdwBytesWrittens, NULL);
return lpdwBytesWrittens;
}
extern "C" __declspec (dllexport) int SerialGate::Recv(char* buff, int szBuff)
{
if(!state)
return 0;
if(buff == NULL || szBuff <= 0)
{
return 0;
}
DWORD dwBytesRead = 0;
ReadFile(m_hFile, buff, szBuff, &dwBytesRead, NULL);
return dwBytesRead;
}
extern "C" __declspec (dllexport) void SerialGate::SetLine(OUT_LINES_NAME ln, bool state)
{
if(!state)
return ;
unsigned char value;
if(ln == DTR)
{
if(state)
value = 6;
else
value = 5;
}
if(ln == RTS)
{
if(state)
value = 4;
else
value = 3;
}
EscapeCommFunction(m_hFile, value);
}
extern "C" __declspec (dllexport) bool SerialGate::GetLine(IN_LINES_NAME ln)
{
if(!state)
return 0;
unsigned long ul = 0;
GetCommModemStatus(m_hFile, &ul);
if(ul == 0x10 && ln == CTS)
{
return true;
}
if(ul == 0x20 && ln == DSR)
{
return true;
}
if(ul == 0x40 && ln == RING)
{
return true;
}
if(ul == 0x80 && ln == RLSD)
{
return true;
}
return false;
}
extern "C" __declspec (dllexport) void SerialGate::GetPortsInfo(PortInfo* pi)
{
DWORD Ports_MemSize = 0;
DWORD Ports_Count = 0;
BYTE* lpPorts = NULL;
//Getting Ports_MemSize value...
EnumPorts(NULL,
1,
lpPorts,
0,
&Ports_MemSize,
&Ports_Count);
//Getting lpPorts...
lpPorts = new BYTE[Ports_MemSize];
EnumPorts(NULL,
1,
lpPorts,
Ports_MemSize,
&Ports_MemSize,
&Ports_Count);
//Forming List Of Ports...
DWORD dw;
TCHAR str[8];
char temp[4];
int port = -1;
PORT_INFO_1 *pPortInfo;
pPortInfo = (PORT_INFO_1 *)lpPorts;
int counter = 0;
bool av = false;
for (dw = 0; dw < Ports_Count; dw++)
{
lstrcpyn(str, pPortInfo->pName, 4);
str[4] = 0;
if (lstrcmpi(str, "com") == 0)
{
//printf("%s\n", pPortInfo->pName);
memset(temp, '\0', sizeof(temp));
temp[0] = pPortInfo->pName[3];
if(pPortInfo->pName[4]!=':' && pPortInfo->pName[4]!='\0')
temp[1] = pPortInfo->pName[4];
if(pPortInfo->pName[5]!=':' && pPortInfo->pName[5]!='\0')
temp[2] = pPortInfo->pName[5];
port = atoi(temp);
//printf("%d\n", port);
char COM_string[20];
sprintf(COM_string,"\\\\.\\COM%d", port);
HANDLE h = CreateFile(COM_string, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
if(h == INVALID_HANDLE_VALUE)
{
//return false;
av = false;
}
else
{
av = true;
CloseHandle(h);
}
pi->p[counter].Id = port;
pi->p[counter].Availbl = av;
counter++;
}
pPortInfo++;
}
pi->koll = counter;
delete [] lpPorts;
}
Листинг
SerialGate.dll
SerialGate.h:
#include <windows.h>
#define MAX_WIN_PORT 255
struct Port
{
unsigned char Id;
bool Availbl;
};
struct PortInfo
{
Port p[MAX_WIN_PORT];
unsigned char koll;
};
extern "C" class __declspec (dllexport) SerialGate
{
public:
enum IN_LINES_NAME {CTS, DSR, RING, RLSD};
enum OUT_LINES_NAME {DTR, RTS};
SerialGate();
~SerialGate();
bool Open(int port, int baud);
int Send(char* buff, int szBuff);
int Recv(char* buff, int szBuff);
void SetLine(OUT_LINES_NAME ln, bool state);
bool GetLine(IN_LINES_NAME ln);
void GetPortsInfo(PortInfo* pi);
void Close();
void Clean();
private:
HANDLE m_hFile;
bool state;
};
|