Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.11.2009, 19:13   #1
remz
 
Регистрация: 14.11.2009
Сообщений: 8
Вопрос Управление ШД через LPT - порт

Здравствуйте!
У меня возникла такая проблема, я написал программу, которая заставляет вращаться шаговый двигатель в оба направления, использовалась библиотека "inpout32.dll", вот исходный код процедур вращения двигателя:
1) вращение по часовой стрелке

procedure TForm1.Button3Click(Sender: TObject);
var
i,n : integer;
begin
n := StrToInt(Edit2.Text);
for i := 1 to n do
begin
Out32($378,0);
Sleep(1);
Out32($378,5);
end;
end;

2) против часовой

for i := 1 to n do
begin
Out32($378,0);
Sleep(1);
Out32($378,7);
end;

Полный оборот двигателя - это 1000 шагов, в данной программе n - количество шагов. Можно ли ускорить выполнение этих циклов?

Пробовал запустить так:

for i := 1 to n do
begin
Out32($378,0);
Out32($378,7);
end;

то блок управления, через который идут сигналы на двигатель, не успевает обработать сигналы. Подскажите, как быть?
remz вне форума Ответить с цитированием
Старый 30.11.2009, 19:20   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Так вы же задаете 1 миллисекунду (Sleep(1) всего.
У вас за сколько двигатель делает один шаг?
Явно - не за 1 миллисекунду... Гораздо дольше.
Так что вариант только один - другой, более быстроходный двигатель.
mihali4 вне форума Ответить с цитированием
Старый 30.11.2009, 19:31   #3
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
for i := 1 to n do
begin
Out32($378,0);
Out32($378,7);
end;

то блок управления, через который идут сигналы на двигатель, не успевает обработать сигналы. Подскажите, как быть?
если вы уверены что сигналы таки идут и причина именно в блоке управления:
1) какова частота импульсов поступающих в блок (осциллографом смотрели)?
2) всегда можно использовать делитель частоты
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 30.11.2009, 20:25   #4
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

К сожалению, значение оператора Sleep(1) не соответствует 1 мсек. Нижний порог оператора Sleep , как и таймера VCL( вкладка Standart) порядка 55-64 мсек (зависит от "железа").Поэтому задержку цикла Слипом здесь не желательно применять. Лучше таймер, и не обычный, а точный (была тема здесь на форуме).
http://www.programmersforum.ru/showt...E0%E9%EC%E5%F0
Второе -
Цитата:
Полный оборот двигателя - это 1000 шагов
.
Насколько я знаю, у ШД шаг поворота - 1,0 ; 1,5 ; 2,0 ; 2,5 градусов ( редко встречается 0,75).Рабочие частоты сигналов управления ШД - от 0 до 1500-2000 Гц.
Третье - попробуйте в качестве задержки вложенный цикл
Код:
for i := 1 to n do
begin
Out32($378,0);
   for j := 1 to M do  // М - подбирать для конкретного "железа"
   begin
     Inc(count);  // Оператор инкремента для заполнения цикла по J
   end;
Out32($378,7);
end;
Не очень изящный способ, но вполне работает.
Вы бы привели паспортные параметры ШД и основные требования к устройству.
И не сомневайся даже ... отдых - кайф, работа - лажа!

Последний раз редактировалось DeKot; 30.11.2009 в 20:34.
DeKot вне форума Ответить с цитированием
Старый 30.11.2009, 21:34   #5
remz
 
Регистрация: 14.11.2009
Сообщений: 8
По умолчанию

Цитата:
Сообщение от mihali4 Посмотреть сообщение
Так вы же задаете 1 миллисекунду (Sleep(1) всего.
У вас за сколько двигатель делает один шаг?
Явно - не за 1 миллисекунду... Гораздо дольше.
Так что вариант только один - другой, более быстроходный двигатель.
например, программа Stepmotor_LPT http://electroprivod.ru/program.htm выдает гораздо большую скорость, так что быстроходность двигателя тут не при чем.
remz вне форума Ответить с цитированием
Старый 30.11.2009, 21:41   #6
remz
 
Регистрация: 14.11.2009
Сообщений: 8
По умолчанию

Цитата:
Сообщение от DeKot Посмотреть сообщение
http://www.programmersforum.ru/showt...E0%E9%EC%E5%F0
Второе - .
Насколько я знаю, у ШД шаг поворота - 1,0 ; 1,5 ; 2,0 ; 2,5 градусов ( редко встречается 0,75).Рабочие частоты сигналов управления ШД - от 0 до 1500-2000 Гц.
Третье - попробуйте в качестве задержки вложенный цикл
Код:
for i := 1 to n do
begin
Out32($378,0);
   for j := 1 to M do  // М - подбирать для конкретного "железа"
   begin
     Inc(count);  // Оператор инкремента для заполнения цикла по J
   end;
Out32($378,7);
end;
Не очень изящный способ, но вполне работает.
Вы бы привели паспортные параметры ШД и основные требования к устройству.
Ок, спасибо, завтра стоит попробовать, используется двигатель Siemens FMStepDrive Simostep 1FL3043-0AC31-0BG0
На блоке управления выставлен 1 оборот двигателя, как 1000 шагов, я не в праве менять это значение
remz вне форума Ответить с цитированием
Старый 30.11.2009, 22:07   #7
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Если ваш блок управления (коммутатор) распределяет входные импульсы управления по четырем обмоткам, то тогда это реально - при шаге 1,5 град. 240 х 4 = 960 имп \ об.Хотя я работал с коммутаторами, преобразующими 1 управляющий импульс на входе коммутатора в 4-е импульса управления на сам двигатель.

Набросал программку управления ШД ( во вложении).
В Edit-ах устанавливаете количество шагов и частоту импульсов управления.Величину задержки в строке
Код:
_delay:= (StrToInt(Edit2.Text)) * 200; //  (200)*  - подбирать для каждого компа индивидуально
подбирать коэфициентом (200). Зависит от характеристик "железа" компа и загруженности процесами.
Поясняющая диаграмма работы :


Длительность вложенных циклов (по j) одинакова, что обеспечивает скважность управляющих импульсов = 2.
Программа работоспособна.Недостатком является то, что при выполнении цикла программа недоступна внешнему управлению.
Вложения
Тип файла: rar Упр.ШД.rar (14.4 Кб, 117 просмотров)
И не сомневайся даже ... отдых - кайф, работа - лажа!

Последний раз редактировалось mihali4; 02.12.2009 в 00:23.
DeKot вне форума Ответить с цитированием
Старый 01.12.2009, 15:35   #8
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

попробуйте еще такую конструкцию (внешнее управление доступно):
Код:
var
  tb: TTrackBar;
  on_off, FL: boolean;
  cnt: integer;
  TimerID: integer;

...
procedure TimerProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD) stdcall;
begin
 on_off:= not on_off;
 if on_off then begin
  //form1.Series1.AddY(1);
  Out32($378,5)
 end else Out32($378,0);

 timeKillEvent(TimerID); // 
  //inc(cnt); if cnt = к-во шагов then cnt:= 0 else // раскомментировать если нужно по к-ву шагов и остановить
 TimerID:= timeSetEvent(form1.tb.Position, 0, @TimerProc,0,TIME_PERIODIC) // пускаем
end;

procedure TForm1.SpeedButton5Click(Sender: TObject);
begin
 FL:= not FL; // запуск-стоп
 if fl then TimerID:= timeSetEvent(tb.Position, 0, @TimerProc,0,TIME_PERIODIC)
  else timeKillEvent(TimerID)
end;

procedure TForm1.tbChange(Sender: TObject);
begin
 caption:= format('%.f Гц', [1000 / tb.position])
end;
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 01.12.2009, 15:54   #9
remz
 
Регистрация: 14.11.2009
Сообщений: 8
По умолчанию

всем спасибо большое за советы, я уже организовал вложенный цикл, количество выполнений которого зависит от железа, у меня теперь другая проблема) я не могу остановить выполнение циклов(аварийная остановка) и не знаю как сделать секундомер, который бы засекал время выполнения
remz вне форума Ответить с цитированием
Старый 01.12.2009, 16:16   #10
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Я обращал внимание на недостаток применения циклов (при выполнении цикла программа замкнута в себе и недоступна внешним сигналам). Здесь надо применять таймер ( но не из VCL), а более точный (есть MMTimer). При работе таймера за один его такт происходит формирование управляющего импульса и остается еще время на прерывание. Т.е. внутри цикла таймера формируется импульс требуемой длительности и проверка на внешнее прерывание (аварийный останов, к примеру). Длительность такта таймера должна быть хотя бы на порядок меньше длительности импульса.
Цитата:
не знаю как сделать секундомер, который бы засекал время выполнения
Во вложении внимательно посмотрите - там реализовано измерение времени (в мсек) выполнения n-го количества "шагов" двигателя.
Код:
_time:= (_stop - _pusk);
  _frc:= round(1000 * ((StrToInt(Edit1.Text) / _time ))); // частота следования импульсов упр-я
  count:= 0;
  Form1.Label3.Caption:= 'Время выполнения  -  ' + IntToStr(_time) + '   мсек';
И не сомневайся даже ... отдых - кайф, работа - лажа!
DeKot вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LPT ПОРТ master3763 Общие вопросы C/C++ 7 11.08.2009 10:32
LPT-порт адресация #378 Dj_smart Компьютерное железо 0 08.06.2009 15:53
LPT порт. Maxs Помощь студентам 2 19.04.2009 11:47
COM порт, или LPT... _riddik Общие вопросы Delphi 1 08.06.2007 22:33