This code, when the variable Vel
is set to more than zero, starts clockwise rotation, when the variable Vel
is set to less than zero, it starts counterclockwise rotation, setting the variable Vel
to zero stops the motor.
In total, 4 stepper motors are connected to the board, which rotate at the same speed.
But here, the problem is that it may be necessary to rotate different step motors at different speeds. The Out32()
procedure outputs a whole byte (all 8 bits at the same time) to bits 2-9 of the LPT port.
Therefore, to programmatically change the rotation speed of individual SMs, it may be necessary to organize additional separate cycles in separate threads, setting different numbers of RotateStep[i]
change rates for each engine. Then the delays for each individual SD will be a multiple of the time_out
value.
Is there a procedure like Out32()
that changes only certain bits at the input of the LPT port? Then it will be possible to record the signals RotDir[i]
and RotateStep[i]
in each separate for each SD stream with its own delay time_out = K / Vel[i]
, where K
is the multiplication factor.
function Out32(PortAdr: word; Data: byte): byte; stdcall; external 'inpout32.dll';
procedure ChangeRotateSD; // Вызывается при изменении величины SetVel
var
i: Integer;
begin
i := AxisNum;
if Vel > 0 then // Направление вращения
begin
RotDir[i] := 0;
RotateStep[i] := 1
end
else if Vel < 0 then // Другое направление вращения
begin
RotDir[i] := 1;
RotateStep[i] := 1
end
else // Остановка
begin
RotDir[i] := 0;
RotateStep[i] := 0
end;
end;
function RotateThread(Parameter: pointer): Integer;
procedure Delay_mcs(time_out: double); // Задержка в микросекундах
var
iCounterPerSec: TLargeInteger;
T1, T2: TLargeInteger; // значение счётчика ДО и ПОСЛЕ операции
begin
QueryPerformanceFrequency(iCounterPerSec);
// определили частоту счётчика
QueryPerformanceCounter(T1); // засекли время начала операции
T2 := T1;
while (T2 - T1) * 1000000 / iCounterPerSec < time_out do
QueryPerformanceCounter(T2); // засекли время окончания
end;
var
PortAdr: word;
Data: byte; // То, что выдается в LPT-порт
time_out: double;
begin
PortAdr := $EEFC; // Адрес LPT-порта
time_out := 500; // Задержка в микросекундах
// Установка 0 возвращаемому значению
Result := 0;
while true do
begin
Data := RotDir[1] * 2 + RotDir[2] * 8 + RotDir[3] * 32 + RotDir[4] * 128;
Out32(PortAdr, Data);
Delay_mcs(time_out);
Data := RotateStep[1] + RotateStep[2] * 4 + RotateStep[3] * 16 +
RotateStep[4] * 64 +
RotDir[1] * 2 + RotDir[2] * 8 + RotDir[3] * 32 + RotDir[4] * 128;
Out32(PortAdr, Data);
Delay_mcs(time_out);
end;
// Конец потока
EndThread(0);
end;
procedure InitializeHardware;
var
id1: LongWord;
thread1: Integer;
msg1: TMsgRecord;
begin
IsSoftwareControlEngine := true;
RotateStep[1] := 0; // Начальная скорость вращения ШД = 0
RotateStep[2] := 0; // Начальная скорость вращения ШД = 0
RotateStep[3] := 0; // Начальная скорость вращения ШД = 0
RotateStep[4] := 0; // Начальная скорость вращения ШД = 0
RotDir[1] := 0;
RotDir[2] := 0;
RotDir[3] := 0;
RotDir[4] := 0;
thread1 := BeginThread(nil, 0, Addr(RotateThread), Addr(msg1), 0, id1);
CloseHandle(thread1);
end;