Dr.Godfried-Willem RAES

Kursus Experimentele Muziek: Boekdeel 2: live electronics.

Hogeschool Gent - Departement Muziek en Drama


<Naar inhoudstafel kursus>

2110:

Praktische toepassing: Kagel MM51

Een konkrete toepassing voor stappenmotoren in de kontekst van de hedendaagse muziek, vinden we in Mauricio Kagel's stuk MM51, waar een metronoom vanuit een zuiver vertikale beginstand , over een tijd van circa tien minuten geleidelijk aan schuin dient te gaan staan tot het tikken ophoudt. Dit zou theoretisch kunnen gebeuren door een gewone DC motor te gebruiken met een heel zwaar vertragende vertragingskast, maar de tijdsduur zou heel onprecies en vooral onprogrammeerbaar zijn. Omwille van de programmeringsflexibiliteit ligt het hier voor de hand een stappenmotor te gebruiken. In dit toepassingsvoorbeeld gingen we uit van een konkrete stappenmotor (Sanyo Denki) met volgende eigenschappen:

Het bitpatroon dat een dergelijke motor doet ronddraaien met de nominale 360 stappen per omwenteling ziet eruit alsvolt :

stapnr. D3 D2 D1 D0


1 1 0 1 0
2 1 0 0 1
3 0 1 0 1
4 0 1 1 0

Het is echter ook mogelijk het aantal stapjes te verdubbelen (men noemt dit 'half-step' bedrijf) door volgende patroon te gebruiken:

stapnr. D3 D2 D1 D0


1 1 0 1 0
2 1 0 0 0
3 1 0 0 1
4 0 0 0 1
5 0 1 0 1
6 0 1 0 0
7 0 1 1 0
8 0 0 1 0

Deze modus levert een soepeler draaien op, maar gaat wel gepaard met een klein verlies aan koppel.

De draairichting van de motor hangt af van de volgorde waarin we het patroon aflopen. Erg belangrijk is dat de motor geen enkel ander patroon aangeboden mag krijgen dan dat patroon dat ofwel volgt op het vorige ofwel dat eraan voorafging. Zoniet ontstaat er een 'gat' waarin de motor eventjes geen koppel kan ontwikkelingen en dus zijn belasting niet in de hand kan houden. Sommige patronen kunnen zelfs tot oververhitting en uiteindelijk vernieling van de motor leiden : zouden we bvb. het patroon 1 1 1 1 uitsturen, dan zouden de krachten van alle spoelen in de motor elkaar opheffen, waarbij de motor dus geen koppel ontwikkeld, terwijl alle fazen de maximale belastingsstroom zouden trekken. In bovenstaand voorbeeld dus 4 x 1.4 Ampere= 5.2 A. Als gevolg hiervan zal dan ook ofwel de voeding, ofwel de motor zelf, gehuld in rook, naar de eeuwige hemel der elektronische komponenten verhuizen.

Gezien de stevige stroomnood van de hier te benutten motor, lijkt het aangewezen een beroep te doen op de chip met het type L298, die immers een stroom kan leveren van 2 Ampere per motorfaze.

Deze chip biedt ons overigens ook nog de wel erg nuttige mogelijkheid om via twee bits de motorwikkelingen al of niet te bekrachtigen (de 'enable' ingangen). Hierdoor kunnen we op eenvoudige wijze via software de motor in een vrijloop toestand brengen waarin hij helemaal geen stroom opneemt.

Hoewel het mogelijk zou zijn deze chip rechtstreeks op een komputeruitgangspoort aan te sluiten, is dit hier geen goede oplossing, precies vanwege het gevaar dat de motor wel eens het gevaarlijk 1111 patroon zou kunnen krijgen , nml. bij het inschakelen, of wanneer we de motor plus interface zouden inschakelen zonder dat de komputer alles eerst naar 0 kan schakelen. Daarom voorzien we in het te realiseren praktische ontwerp voor het interface, een tussengeheugen (een zogenaamde 'Latch'), waarin het laatst ontvangen byte telkens kan worden opgeslagen en vastgehouden.

De bij een parallel-aansluiting steeds aanwezige 'strobe' lijn kan nu worden gebruikt om de inhoud van het geheugen te veranderen, en daarmee uiteraard de preciese positie van de stappenmotor.

Het volledige hardware schema ziet er dan uit als volgt:

 

Eens deze klus geklaard, moeten we natuurlijk nog een stukje software schrijven om de motor op de gewenste manier te doen draaien.

Daartoe bepalen we eerst welke elementen van de beweging we variabel willen hebben :

Ook dienen we te weten wat het adres is van de komputeruitgangspoorten die we willen gebruiken voor onze sturing:

Wanneer we een IBM-achtige PC gebruiken , en daarvan de printerpoort als datapoort willen inzetten dan zijn deze adressen afhankelijk van de konfiguratie een van volgende drie mogelijkheden:

Datapoortadres Strobe poort Bitpositie

De respektievelijke bits vinden we terug op de DB25 printerkonnector op de komputer : pin 1 is het strobe bit , pinnen 2 tot en met 9 zijn de databits. Hiervan zullen we de bits D0-D3 (pinnen 2, 3, 4, 5) gebruiken voor het bitpatroon dat de motor doet bewegen , en de bits D4 en D5 als 'enable' signalen. De bits D6 en D7 blijven ongebruikt.

Nu zijn er hierbij twee verschillende mogelijkheden om zo'n programma op te zetten:

We hebben beide mogelijkheden, ter illustratie, iets verder uitgewerkt:

Kode voorbeeld voor Microsoft Basic:

CLS
DEFINT A,Z
DIM S(10)
S(0) = 5 : S(1) = 1: S(2) = 9: S(3) = 8
' bitpatroon in decimaal
S(4) = 10: S(5) = 2: S(6) = 6: S(7) = 4
'set enable bits 1
FOR I = 0 TO 7: S(I) = S(I) + 16: NEXT I
FOR I = 0 TO 7: S(I) = S(I) + 32: NEXT I
SH = INP(&H37A) ' strobe high uitgangspositie
 
LOOKUP:
T = 10 ' default staptijdwaarde
I = -1 'beginstand stappenteller
LOCATE 10, 10
PRINT " + = sneller - = trager * = HOLD 0 = los Q=QUIT"
DO
I = I + 1
I = I MOD 8
IF K$ = "+" THEN T = T - 1
IF K$ = "-" THEN T = T + 1
T = ABS(INT((T)))
IF K$ = "0" THEN
WHILE INKEY$ <> "": WEND: 'empty keyboard buffer
S(I) = S(I) - 48
' alles los koppel=0 - disable motor
LOS = I
GOSUB DRAAI
WHILE INKEY$ = "": WEND
S(I) = S(I) + 48
END IF
IF INKEY$ = "*" THEN
WHILE INKEY$ = "": WEND
END IF
GOSUB DRAAI
LOOP UNTIL K$ = "Q" OR K$ = "q"
'schakel motor uit
OUT &H378, 0: OUT &H37A, SH - 1: OUT &H37A, SH
END
 
DRAAI:
OUT &H378, S(I): OUT &H37A, SH - 1: OUT &H37A, SH
LOCATE 14, 10: PRINT "Step nr.:"; I; " Byte="; S(I)
SOUND 20000, T
K$ = INKEY$
RETURN

De algoritmische versie (eveneens voor Microsoft Basic) ziet eruit alsvolgt :

CLS
SH = INP(&H37A)
INIT:
INPUT " Draairichting ? ( R of L ) ",D$
INPUT " Staptijd ? ( in 0.05s)",T
INPUT " Aantal stappen? ",STP
R=0 : L=0
IF D$="R" THEN R=-1 : L=1
IF D$="L" THEN R=1 : L=-1
IF R=0 OR L=0 THEN GOTO INIT
T=ABS(T)
STP=ABS(STP)
GOSUB ALGOSTEP
GOTO INIT
 
ALGOSTEP:
IF L=1 THEN I=STP ELSE I=-1
'steppingmotor algoritme
DO
I = I - R ' wanneer R negatief is draait de motor omgekeerd
J = J + 1
S = 48
' enable bits D4 en D5 ( = 32+16)
IF I MOD 8 < 3 THEN S = S OR 1 IF (I + 4) MOD 8 < 3 THEN S = S OR 2
IF (I + 6) MOD 8 < 3 THEN S = S OR 4
IF (I + 2) MOD 8 < 3 THEN S = S OR 8
'dummy ter controle:
LOCATE 15, 10: PRINT "Step nr.:"; I MOD 8; " Byte="; S;
'uitsturing naar motor
OUT &H378,S : OUT &H378,SH-1 : OUT &H378,SH
SOUND 20000, T
LOOP UNTIL J=STP OR INKEY$ <> ""
RETURN

Een kode voorrbeeld voor aansturing van deze stappenmotor binnen de programmeeromgeving geboden door <GMT> onder Windows 98, NT of Windows 2000, waarbij de aansturing van de motor als taak binnen de multitasker wordt gedefinieerd ziet eruit alsvolgt:

SUB StepMot ()
' demo code for controlling a stepping motor.
' fields in the task structure will be used as follows:
' freq = stepping frequency
' pan = direction 0= turn left, 127= turn right, 64 = turn loose
' tempo = number of steps to perform.

STATIC lastbyte AS BYTE
' hold the last byte sent to the stepper.
STATIC lastIdx AS BYTE
' holds the last index to the pattern array data
STATIC init AS BYTE
STATIC pat() AS BYTE
STATIC strobebyte AS BYTE

IF ISFALSE init THEN
DIM pat(0 TO 7) AS STATIC BYTE
pat(0) = 10
pat(1) = 8
pat(2) = 9
pat(3) = 1
pat(4) = 5
pat(5) = 4
pat(6) = 6
pat(7) = 2
BIT SET lastbyte,4
BIT SET lastbyte,5
IF ISTRUE App.Padr THEN
Strobebyte = PortIn(App.Padr + 2)
init = %True
ELSE
init = %False
StopTask %Stepper
EXIT SUB
END IF
END IF

IF ISFALSE Task(%Stepper).tempo THEN
Stoptask %Stepper
ELSE
DECR Task(%Stepper).tempo
END IF

SELECT CASE Task(%Stepper).pan
CASE < 64

' turn left
IF lastIdx > 0 THEN DECR lastIdx ELSE lastIdx = 7
lastbyte = pat(lastIdx)
BIT SET lastbyte,4
BIT SET lastbyte,5


CASE 64


' disable current through windings:
lastbyte = lastbyte AND &HF0


CASE > 64


INCR lastIdx
IF lastIdx > 7 THEN lastIdx = %False
lastbyte = pat(lastIdx)
BIT SET lastbyte,4
BIT SET lastbyte,5

END SELECT

PortOut App.Padr, lastbyte
' send the bit pattern to the selected I/O port
Strobe App.Padr + 2, 11, 0, 1000

END SUB

Om deze taak nu ook van instrukties te voorzien, kunnen we bvb. een nieuwe taak opzetten als:

SUB StepperBallet ()

' this task sends command to the stepping motor
IF ISFALSE Task(%Stepper).switch THEN
' set new parameters for the stepper:
Task(%Stepper).freq = 1 + (200 * RND(1))
Task(%Stepper).pan = RND(1) * 127
' random direction
Task(%Stepper).tempo = 5 + (RND(1)* 355)
' number of steps to perform
StartTask %Stepper
' start the stepper motor controll task
ELSE
Task(%StepBal).freq = 10
EXIT SUB
END IF

END SUB

Een heel wat meer geavanceerde toepassing van stappenmotoren vinden we in mijn muziekautomaten behorende tot het grote <Slag-Werk> projekt, <Rotomoton>, waar vijf stappenmotoren de toonhoogte van de rototoms bepalen. Details van dit ontwerp zijn de vinden op de logos website. Ook in de robot <Flex> spelen grote stappenmotoren een belangrijke rol. In onze cornet spelende robot <Korn> gebruikten we stappenmotoren voor de beweging van de cornet in twee assen. Low-level stappenmotoren besturingskode maakt deel uit van de GMT- software bibliotheek en ook voor Basic Stamps (PIC controllers) is source kode op onze site weer te vinden.


Terug naar de inhoudstafel: Index Kursus

Naar homepage dr.Godfried-Willem RAES