Seite 1 von 7
Schrittmotorsteuerung ?!
Verfasst: 21.03.2005 14:03
von Then
Hallo !
Habe mit der "INPOUT32.DLL" rumgefummelt und meine 3 Schrittmotoren auch zum Laufen bekommen, aber es ist doch noch recht langsam !
Vorallem verstehe ich folgendes nicht (Habe den Code nicht hier, aber...) :
Code: Alles auswählen
...
FOR t=1 to 100 ; 100 Schritte soll er machen
CallFunction(0,"Out32",$888,%01000000) ; X-Achse fährt einen Schritt
CallFunction(0,"Out32",$888,%00000000) ; Nullbit schicken - Keine Ahnung warum, aber ohne funzt es nicht !
Delay(1) ; Auch das kann ich nicht weglassen - summt sonst nur !
Next
...
Das ganze läuft ja, ich steuere damit eine CNC-Fräse und alle Motoren tun was sie sollen, aber im DOS gehts n Tick schneller ! Gibts da ne schnellere LIB oder so, mit der ich das auch hinkriege ??
Verfasst: 21.03.2005 14:17
von the one and only
Auf irgendner Visual Basic Seite gabs mal ein Tutorial zum ansteuern von Schrittmotoren (vb-fun.de wars glaub ich). Da wir alle wissen dass Visual Basic böse ist möchte ich meine Augen nicht verbrennen und diese Seite besuchen, aber ich denke dass es kein großes Problem sein sollte die Codebeispiele aus dem VB Tutorial auf Purebasic umzuschreiben.
Verfasst: 21.03.2005 16:36
von ORANGE
Das Problem ist das du die Schrittmotoren falsch ansteuerst. Die Teile haben eine An- und Abfallszeit. Mach einfach nen kleinen delay nach dem verschieben des Bits. Wie groß der delay sein muß hängt von der maximal Frequenz(U/min) deines Schrittmotors ab. Damit kannst du dir das Null setzen sparen. Das Null setzen darfst du nur beim anhalten nicht vergessen, sonst raucht der Motor ab.
Verfasst: 21.03.2005 16:48
von Then
Hm... verstehe nicht so ganz was Du meinst ! Kannste es mir in Code etwas verdeutlichen ?!
Verfasst: 21.03.2005 17:26
von ORANGE
Vergiss was ich sagte. Der 1ms delay ist zu groß. Bei 1ms ist f=1/0,001 gleich 1000Hz. Wenn der Motor pro Schritt 90° dreht wären das 1000/4=250U/min. Das ist wirklich etwas langsam. Also einfach selber ne Zeitschleife basteln.
Motor mit 4 Schritten pro Umdrehung und D4 - D7 als Steuerleitung:
Code: Alles auswählen
...
FOR t=1 to 100 ; 100 Umdrehungen
CallFunction(0,"Out32",$888,%10000000) ;
CallFunction(0,"Out32",$888,%00000000) ;
Gosub schleife;
CallFunction(0,"Out32",$888,%01000000) ;
CallFunction(0,"Out32",$888,%00000000) ;
Gosub schleife;
CallFunction(0,"Out32",$888,%00100000) ;
CallFunction(0,"Out32",$888,%00000000) ;
Gosub schleife;
CallFunction(0,"Out32",$888,%00010000) ;
CallFunction(0,"Out32",$888,%00000000) ;
Gosub schleife;
Next
...
schleife:
x = 0
Repeat
x = x + 1
Until x = ; ???
Return
Das Problem ist halt das die Schleife von der Cpu Geschwindigkeit abhängt. Vielleicht hat jemand ne Idee wie man nen festen Delay kleiner 1ms erzeugt.
Verfasst: 21.03.2005 17:43
von Then
Genau das ist das eigentliche Problem ! Die Steuerung für die Achsen inkl. Richtungen habe ich nun realisiert, aber es hängt in der Tat am DELAY() ! gab es da nicht mal was kleiners ?!
Verfasst: 21.03.2005 18:01
von Falko
vielleicht hilft diese Delay-schleife weiter.
Code: Alles auswählen
Procedure Delayus(t.l) ; Rechnerabhängig!
Structure DLong
lowlong.l
hilong.l
EndStructure
DLong=0
hitimefreq.DLong
QueryPerformanceFrequency_(@hitimefreq)
hitimecount1.DLong
hitimecount2.DLong
QueryPerformanceCounter_(@hitimecount1)
Repeat
QueryPerformanceCounter_(@hitimecount2)
Until Int((hitimecount2\lowlong - hitimecount1\lowlong)/(hitimefreq\lowlong/1000000.0))>=t
;Debug "time in µ: " + Str((hitimecount2\lowlong - hitimecount1\lowlong)/(hitimefreq\lowlong/1000000.0))
EndProcedure
Verfasst: 21.03.2005 18:14
von Then
@Falko : Sieht gut aus - Pause ist deutlich kleiner. Ich sollte so um die 0.3ms Pause haben. Werde ich heute Abend mal testen !!
Danke
Verfasst: 21.03.2005 18:33
von NicTheQuick
Ich habe hier auch zwei Schrittmotoren, die ich mit PureBasic ansteuere. Die haben vier Anschlüsse, wovon zwei davon jeweils negiert zu den anderen zwei sind. Da ich aber noch keine NOT-Gatter hier habe, brauche ich 4 Bits pro Motor, d.h. ich kann am LPT nur zwei Schrittmotoren ansteuern, was aber tadellos funktioniert. Die Motoren machen 100 Schritte pro Umdrehung, also 3.6° pro Schritt, was bei minimal 2 ms Umschaltzeit funktioniert. Wenn ich auf 1 ms pro Schritt gehe, fehlen einige Schritte und das ganze läuft nicht rund. Schade eigentlich.
Hier ist mein Code dafür, falls ihn jemand braucht:
Code: Alles auswählen
#InpOut_ID = 1
Global InpOut32Aktiv.l
Procedure OpenInpOut32()
Protected Result.l
Result = OpenLibrary(#InpOut_ID, "InpOut32.dll")
If Result = #False
InpOut32Aktiv = #False
MessageRequester("ERROR", "InpOut32.dll wurde nicht gefunden oder ist korrupt.", #MB_ICONERROR)
End
Else
InpOut32Aktiv = #True
EndIf
ProcedureReturn Result
EndProcedure
Procedure CloseInpOut32()
CloseLibrary(#InpOut_ID)
InpOut32Aktiv = #False
EndProcedure
Procedure SetBits(Value.l)
Protected Address.l
Address = $378
ProcedureReturn CallFunction(#InpOut_ID, "Out32", Address, Value)
EndProcedure
Procedure.l GetBits()
Protected Address.l, Value.l
Address = $379
Value = CallFunction(#InpOut_ID, "Inp32", Address)
ProcedureReturn Value
EndProcedure
Procedure.l Inp32(Address.l)
Protected Value.l
Value = CallFunction(#InpOut_ID, "Inp32", Address)
ProcedureReturn Value
EndProcedure
Procedure Out32(Address.l, Value.l)
ProcedureReturn CallFunction(#InpOut_ID, "Out32", Address, Value)
EndProcedure
Procedure CheckInpOut32Functions()
Protected FunctionName.s
If InpOut32Aktiv
Restore CheckInpOut32FunctionsData
For a.l = 1 To 2
Read FunctionName
If IsFunction(#InpOut_ID, FunctionName) = #False
MessageRequester("ERROR", "Die Funktion " + Chr(34) + FunctionName + Chr(34) +" wurde nicht gefunden", #MB_ICONERROR)
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
DataSection
CheckInpOut32FunctionsData:
Data.s "Inp32", "Out32"
EndDataSection
EndProcedure
Dim Motor.b(3)
Motor(0) = %1001
Motor(1) = %1100
Motor(2) = %0110
Motor(3) = %0011
MaxMotorSchritt.l = 4 ; Bits pro Motor
MaxPos.l = 400 ; Schritte für das Trackbargadget
Pos1.l = 0 ; Startposition von Motor 1
NewPos1.l = 0
Pos2.l = 0 ; Startposition von Motor 2
NewPos2.l = 0
t_delta.l = 2 ; Umschaltzeit pro Schritt
t_old.l = ElapsedMilliseconds()
If OpenInpOut32()
Win_Main.l = OpenWindow(#PB_Any, 0, 0, 402, 40, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Schrittmotor")
If Win_Main
If CreateGadgetList(WindowID(Win_Main))
Gad_Track1.l = TrackBarGadget(#PB_Any, 1, 1, 400, 18, 0, MaxPos)
Gad_Track2.l = TrackBarGadget(#PB_Any, 1, 21, 400, 18, 0, MaxPos)
Repeat
EventID.l = WindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Break
Case #PB_EventGadget
Select EventGadgetID()
Case Gad_Track1
NewPos1 = GetGadgetState(Gad_Track1)
Case Gad_Track2
NewPos2 = GetGadgetState(Gad_Track2)
EndSelect
Case 0
Delay(1)
EndSelect
If t_old + t_delta < ElapsedMilliseconds()
If Pos1 > NewPos1 : Pos1 - 1 : ElseIf Pos1 < NewPos1 : Pos1 + 1 : EndIf
If Pos2 > NewPos2 : Pos2 - 1 : ElseIf Pos2 < NewPos2 : Pos2 + 1 : EndIf
SetBits(Motor(Pos1 % MaxMotorSchritt) + Motor(Pos2 % MaxMotorSchritt) << MaxMotorSchritt)
t_old = ElapsedMilliseconds()
EndIf
ForEver
EndIf
CloseWindow(Win_Main)
EndIf
SetBits(0)
CloseInpOut32()
EndIf
Verfasst: 21.03.2005 18:59
von Falko
Über 2 ULN-2803-IC's kann man bei einer 4-Bit-Ansteuerung
lt. dem Buch von Burkhard Kainka u. Hans-Joachim Berndt
"PC-Schnittstellen unter Windows"
"3 Motoren" ansteuern und über Error,Select und PE 3 Endschalter abfragen.
Das Programm (Delphi) dazu habe ich auch im Buch, aber mangels der IC's noch nicht in PB probiert. Werd's aber bald machen
Die zusätzlichen 4 Leitungen, damit man den auch einen 3. Motor ansteuern
kann, sind dann nicht nur die 8 Datenleitungen für nur 2 Motoren, sondern die weiteren 4-Leitungen: Strobe, AutoFeed, Init und SLCT IN.
Kann jedem das Buch weiterempfehlen
MfG Falko