Forum: Mikrocontroller und Digitale Elektronik Schrittmotor Softstart


von Thomas E. (tomedl)


Lesenswert?

Hallo!

Hat jemand eine Idee, wie ich einen Schrittmotor langsam in der Drehzahl 
hochfahren kann? Es handelt sich um einen unipolaren Motor mit 5 
Anschlüssen.

Wenn Code's dann bitte nur in BASCOM, ich versteh kein C. ;-)

Danke schon im Voraus.

Grüße
Thomas

von Teplotaxl X. (t3plot4x1)


Lesenswert?


von Fred (Gast)


Lesenswert?

In die Schleife, in der die Takte für den Motor erzeugt werden, muß
eine variable Zeitschleife rein!

also definiere zuerst 3 Konstanten

-Startfrequenz
-Arbeitsfrequenz
-Bremsfrequenz

zb wird:

beim Start wird die Zeitschleife pro Schritt immer ein wenig kürzer bis
die Arbeitsfrequenz erreicht ist.

......


Somit kanst Du eine Start.- bzw Bremsrampe erzeugen!

Gruß Fred

von Thomas E. (tomedl)


Lesenswert?

Aber wie komme ich zu einer Variablen Zeitschleife?

Bis jetzt hab ich das ganze so gemacht:
1
'Name:.............Schrittmotorsteuerung
2
'Version:..........1.0a
3
'Datum:............19.06.2008
4
'Autor:............Thomas Edlinger
5
'---------------------------------
6
'Beschreibung: Schrittmotor fährt folgende Positionen
7
'              90° nach links - warte 10s
8
'              90° nach rechts - warte 10s
9
'              180° nach links - warte 10s
10
'              180° nach rechts - warte 10s
11
12
13
14
$regfile = "m32def.dat"
15
$crystal = 1000000
16
17
'KONFIGURATION AUSGÄNGE
18
Config Portd.0 = Output
19
Config Portd.1 = Output
20
Config Portd.2 = Output
21
Config Portd.3 = Output
22
Config Portd.4 = Output
23
24
'VERGABE ALIAS-ADRESSEN
25
Led Alias Portd.0
26
S1 Alias Portd.1
27
S2 Alias Portd.2
28
S3 Alias Portd.3
29
S4 Alias Portd.4
30
31
'KONFIGURATION TIMER
32
Config Timer0 = Timer , Prescale = 256
33
On Timer0 Schrittezaehler
34
Enable Timer0
35
Start Timer0
36
Timer0 = 217
37
38
Config Timer1 = Timer , Prescale = 256
39
On Timer1 Zeitschalter
40
Enable Timer1
41
Start Timer1
42
Timer1 = 26473
43
44
'VARIABLEN
45
Dim Schritt As Byte
46
Dim Zeit As Byte
47
Dim Position As Long
48
Zeit = 1
49
50
'INTERRUPTS GLOBAL ZULASSEN
51
Enable Interrupts
52
53
54
'### HAUPTSCHLEIFE ###
55
Do
56
57
   While Zeit = 1
58
59
      If Schritt = 1 And Position < 2200 Then
60
         S1 = 1
61
         S2 = 0
62
         S3 = 0
63
         S4 = 0
64
         Incr Position
65
      End If
66
67
      If Schritt = 2 And Position < 2200 Then
68
         S1 = 0
69
         S2 = 1
70
         S3 = 0
71
         S4 = 0
72
         Incr Position
73
      End If
74
75
      If Schritt = 3 And Position < 2200 Then
76
         S1 = 0
77
         S2 = 0
78
         S3 = 1
79
         S4 = 0
80
         Incr Position
81
      End If
82
83
      If Schritt = 4 And Position < 2200 Then
84
         S1 = 0
85
         S2 = 0
86
         S3 = 0
87
         S4 = 1
88
         Incr Position
89
      End If
90
91
   Wend
92
93
   While Zeit = 2
94
95
      If Schritt = 1 And Position < 2200 Then
96
         S1 = 0
97
         S2 = 0
98
         S3 = 0
99
         S4 = 1
100
         Incr Position
101
      End If
102
103
      If Schritt = 2 And Position < 2200 Then
104
         S1 = 0
105
         S2 = 0
106
         S3 = 1
107
         S4 = 0
108
         Incr Position
109
      End If
110
111
      If Schritt = 3 And Position < 2200 Then
112
         S1 = 0
113
         S2 = 1
114
         S3 = 0
115
         S4 = 0
116
         Incr Position
117
      End If
118
119
      If Schritt = 4 And Position < 2200 Then
120
         S1 = 1
121
         S2 = 0
122
         S3 = 0
123
         S4 = 0
124
         Incr Position
125
      End If
126
127
   Wend
128
129
   While Zeit = 3
130
131
      If Schritt = 1 And Position < 4400 Then
132
         S1 = 1
133
         S2 = 0
134
         S3 = 0
135
         S4 = 0
136
         Incr Position
137
      End If
138
139
      If Schritt = 2 And Position < 4400 Then
140
         S1 = 0
141
         S2 = 1
142
         S3 = 0
143
         S4 = 0
144
         Incr Position
145
      End If
146
147
      If Schritt = 3 And Position < 4400 Then
148
         S1 = 0
149
         S2 = 0
150
         S3 = 1
151
         S4 = 0
152
         Incr Position
153
      End If
154
155
      If Schritt = 4 And Position < 4400 Then
156
         S1 = 0
157
         S2 = 0
158
         S3 = 0
159
         S4 = 1
160
         Incr Position
161
      End If
162
163
   Wend
164
165
   While Zeit = 4
166
167
      If Schritt = 1 And Position < 4400 Then
168
         S1 = 0
169
         S2 = 0
170
         S3 = 0
171
         S4 = 1
172
         Incr Position
173
      End If
174
175
      If Schritt = 2 And Position < 4400 Then
176
         S1 = 0
177
         S2 = 0
178
         S3 = 1
179
         S4 = 0
180
         Incr Position
181
      End If
182
183
      If Schritt = 3 And Position < 4400 Then
184
         S1 = 0
185
         S2 = 1
186
         S3 = 0
187
         S4 = 0
188
         Incr Position
189
      End If
190
191
      If Schritt = 4 And Position < 4400 Then
192
         S1 = 1
193
         S2 = 0
194
         S3 = 0
195
         S4 = 0
196
         Incr Position
197
      End If
198
199
   Wend
200
201
202
203
Loop
204
205
206
'### UNTERPROGRAMME & INTERRUPTROUTINEN ###
207
Schrittezaehler:
208
209
   Timer0 = 217
210
   Schritt = Schritt + 1
211
   If Schritt = 5 Then Schritt = 1
212
213
Return
214
215
216
Zeitschalter:
217
218
   Timer1 = 26473
219
   Zeit = Zeit + 1
220
   If Zeit = 5 Then Zeit = 1
221
   Position = 0
222
223
Return
224
225
226
End

Vielleicht hilft das weiter?

Steh leider noch immer aufm Schlauch.

Grüße
Thomas

von Fred (Gast)


Lesenswert?

na gut hab mir eine Zigarette und ein Bier gehohlt und versuche
zuverstehen was du da gemacht hast.

Fred

von Thomas E. (tomedl)


Lesenswert?

Lass dir das Bier schmecken! :-)

Der Code funktioniert übrigens einwandfrei, ich möchte nur noch einen 
Sofstart haben und deshalb bin ich ja auch hier. ;-)

Grüße
Thomas

von lkmiller (Gast)


Lesenswert?

Jaja, das ist jetzt so, wie wenn einer sagt:
1
Das Haus hab ich schon, jetzt brauche ich nur noch einen Keller.


Du müsstest abhängig von der Position den
Timer0 = 217
unterschiedlich schnell laufen lassen.
Denn der schaltet deine Schritte weiter.

BTW:
Wenn ich das Listing so ansehe, dann war es doch ein weiser Entschluss,
C zu lernen.

von Fred (Gast)


Lesenswert?

Frage an Thomas E.

> unipolaren Motor mit 5 Anschlüssen

da ist doch bestimmt einer grün/gelb? -> Schutzleiter

ein unipolarer Motor hat mindestens 6 Anschlüsse! (7)
(2 Wicklungen mit je einer Mittelanzapfung + SL)

dh Du hast einen bipolaren vor Dir!

Unipolare Motoren werden mit 8 nicht 4 Zuständen
berieben. (Vollschritt) Sonst weiß der arme Kerl
ja garnicht in welcher Richtung er losdrehen soll!


zb Rechtsdrehung

Schritt  Phase1  Phase2  Feld

1          +1      0     oben
2          +1     +1     oben/rechts
3           0     +1     rechts
4          -1     +1     unten/rechts
5          -1      0     unten
6          -1     -1     unten/links
7           0     -1     links
8          +1     -1     oben/links

das - zeig einen Stomfluß umgekehrt durch die Phase an!
Dises kanst Du durch eine H-Brücke erreichen.

-> Du brauchst pro Motor (min) 4 Ausgänge (haste richtig gemacht)
   2 x für Stom an
   2 x für die Stromrichtung

lass mal am Anfang die vier verschidenen Bewegeungen weg
(90 Grad links usw)

und programmiere erstmal eine Tabelle (2) und eine Sub mit den Schritten
um nach links drehen zukönnen! Danach sollte es Dir leichtfallen
auch nach rechts drehen zu können.

Da ich aus Deiner Software sehe das du noch keine entspechende
Hardware besitzt :) und keinerlei Erfahrung mit Schritty's hast,
kannst Du das auch erstmal mit LED's an den Pin's simulieren!

zu den Rampen und der Stromharmonisierung usw werde ich Dir
dann auch weiterhelfen.


Gruß Fred

von Thomas E. (tomedl)


Lesenswert?

Fred, ich sagte doch, der Motor hat fünf Anschlüsse und der von mir oben 
gepostete Code funktioniert auch und macht was er soll. Hardware ist 
vorhanden und alles läuft soeben vor mir auf dem Tisch. Ich möchte nur 
einen Softstart haben, das ist alles.

von Fred (Gast)


Lesenswert?

edit

es ist ein schlechter Stil

die Variablen nicht nach ihre Funktion und Wertebereich zu benennen
Zeit zb für Programmphase

Dim Schritt As Byte
Dim Zeit As Byte
Dim Position As Long

besser

Dim _b_Schritt As Byte
Dim _b_Zeit As Byte
Dim _l_Position As Long

Gruß Fred

von Fred (Gast)


Lesenswert?

Mist Formatierung geht nicht so wie ich das will

besser

Dim bSchritt As Byte
Dim bZeit As Byte
Dim lPosition As Long

Gruß Fred

von Fred (Gast)


Lesenswert?

> wenn das Funktioniert?


  While Zeit = 4

      If Schritt = 1 And Position < 4400 Then
         S1 = 0
         S2 = 0
         S3 = 0
         S4 = 1
         Incr Position
      End If

      If Schritt = 2 And Position < 4400 Then
         S1 = 0
         S2 = 0
         S3 = 1
         S4 = 0
         Incr Position
      End If

      If Schritt = 3 And Position < 4400 Then
         S1 = 0
         S2 = 1
         S3 = 0
         S4 = 0
         Incr Position
      End If

      If Schritt = 4 And Position < 4400 Then
         S1 = 1
         S2 = 0
         S3 = 0
         S4 = 0
         Incr Position
      End If

> gehört die Zeitschleife hier hin!

   Wend


Fred

von Thomas E. (tomedl)


Lesenswert?

Ja, die While-Schleife funktioniert und ich wusste vorher auch schon, 
dass dort die Zeitschleife hinkommt. Nur, wie realisiere ich die 
Zeitschleife?

von spess53 (Gast)


Lesenswert?

Hi

>ein unipolarer Motor hat mindestens 6 Anschlüsse! (7)
>(2 Wicklungen mit je einer Mittelanzapfung + SL)

Nein. Es gibt unipolare Motoren mit 5 Anschlüssen. Bei denen sind die 
Mittelanzapfungen zusammengefasst. Einen Schutzleiter habe ich bis jetzt 
bei den wenigsten Schrittmotoren gefunden.

@Thomas
Das ändert aber nichts daran, das mir die Ansteuerung sehr suspekt 
vorkommt. Normalerweise werden immer zwei Wicklungshälften bestromt. Das 
der Motor trotzdem läuft ist kein Kriterium für korrekte Ansteuerung.
Zu deinem Softstart: Wenn du 'Timer0 = 217' durch 'Timer0 = Variable' 
erstzt
und die von einem hohen Startwert bei jedem Schritt bis auf die 217 
verringert bekommst du einen Softstart.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

spess53 wrote:
> @Thomas
> Das ändert aber nichts daran, das mir die Ansteuerung sehr suspekt
> vorkommt. Normalerweise werden immer zwei Wicklungshälften bestromt. Das
> der Motor trotzdem läuft ist kein Kriterium für korrekte Ansteuerung.

Er läuft schon, nur mit vermindertem Drehmoment. Mittlerweile nehme ich 
zwei Wicklungshälften und er hat mehr Kraft.

spess53 wrote:
Wenn du 'Timer0 = 217' durch 'Timer0 = Variable'
> erstzt
> und die von einem hohen Startwert bei jedem Schritt bis auf die 217
> verringert bekommst du einen Softstart.
Das werd ich mal versuchen, danke für den Tipp.

LG
Thomas

von Fred (Gast)


Lesenswert?

@spess53

>Nein. Es gibt unipolare Motoren mit 5 Anschlüssen.

ist mir noch keiner untergekommen!

Die Mittelanzapfungen sind eigendlich IMMER getrennt, um den
Motor (unipolar) auch an bipolaren Endstufen beteiben zu können!

Aber das kann ja Thomas E. leicht ausklingeln

Gruß Fred

von spess53 (Gast)


Lesenswert?

Hi

Ein bipolarer würde mit der Ansteuerung gar nicht laufen. In meiner 
Schrittmotorsammlung habe ich jetzt ganz spontan 3 Stück gefunden. Zwei 
davon sind von EPSON.

MfG Spess

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

@Fred: Nur damit du mir auch glaubst.

MfG Spess

von Fred (Gast)


Lesenswert?

unterhalten wir uns um ausgebauten Bastelkram

oder

um Schrittmotoren mit dem was antreiben kann?
(außer leichte Druckköpfe)

bei den EPSON Motoren handelt es sich bestimmt um spez. Anfertigungen
für einen spez. Drucker. EPSON kann es sich leisten für jede Anwendung
einen spez. Motor herstellen zu lassen. (daher kein SL und zusammen
gefasste Mittelanzapfungen) Dieser Bastelkram ist aber
nach kürzester Zeit für keinen von uns mehr Verfügbar.

wenn Thomas E. wirklich was über Schritty's wissen will
sollte er sich nicht mit diesem Zeug beschäftigen!

eine gute Seite ist:

http://www.roboternetz.de/schrittmotoren.html

Gruß Fred

von Fred (Gast)


Lesenswert?

@spess53

hab ich zu spät gesehen

ich glaub Dir ja (das geht technisch), ist aber völlig
unüblich!

Gruß Fred

von spess53 (Gast)


Lesenswert?

Hi

Warum so gereizt?

MfG Spess

von Fred (Gast)


Lesenswert?

>Warum so gereizt?

Ich doch nicht. Wenn Du mich sehen könntest, würdest Du feststellen
das ich noch im Kleinsignalbereich laufe.

Aber größere Motoren werden nicht mit Spielzeugspannungen(anfangs)
bertieben! -> Schutzleiter

120V sind üblich um möglichst schnell Strom fließen zulassen.(H)

Gut mit Thomas E. lag ich wohl daneben! Wenn der Motor wirklich
ein unipolarer mit gemeinsahmer Mittelanzapfung ist!

Fred :)

von spess53 (Gast)


Lesenswert?

Hi

Es kommt doch wohl auf die Anwendung an. In einem Diskettenlaufwerk 
braucht man keine 120V.

MfG Spess

von Fred (Gast)


Lesenswert?

@spess53

jetzt laufen wir synchron. Aber für Thomas E. haben wir KEINE
einzige Lösung!

schwach

Gruß Fred

von spess53 (Gast)


Lesenswert?

Hi

Wieso. Meinen Vorschlag von 18:36 wollte Thomas ausprobieren. Nur bis 
jetzt keine Rückmeldung.

MfG Spess

von Falk B. (falk)


Lesenswert?

@ Thomas E. (tomedl)

Kannst du lesen? Ja? Wäre schön wenn du mal die Regeln des Forums 
beherrzigen würdest. Stehen direkt über dem Eingabefenster. Danke.

Falk

von Rahul D. (rahul)


Lesenswert?

Wieso erinnert mich das Programm so sehr an eins, das ein Mitschüler 
damals (1992; Turbo Pascal) "programmiert" hat?
Der hat eine Laufschrift programmiert, die für jeden Buchstaben ein 
eigenen Programmteil geschrieben - Felder waren ihm wohl unbekannt.

Zum Programm:

Man lässt einen Timer laufen, in dessen ISR man den Schrittmotor einen 
Schritt weiter machen lässt. (Schritt zählen, die Ausgabemaske in einem 
Feld mit 4-8  Index großen Feld speichern - dann spart man sich all die 
Abfragen).

Die ISR wird immer dann angesprungen, wenn der Timer einen bestimmten 
Vergleichswert erreicht hat (z.B. CTC-Mode).

Beim Start wird der Vergleichswert relativ hoch angesetzt, um eine 
niedrige Frequenz zu erreichen.

Eine Rampe kann man jetzt abhängig der bereits gemachten Schritte 
fahren, indem man den Vergleichswert bis zu einem bestimmten (maximale 
Schrittfrequenz) dekrementiert. "Beschleunigungsrampe"

Wenn dann eine bestimmte Schrittanzahl erreicht wurde, vergrössert man 
den Vergleichswert wieder. Dann hat man die "Bremsrampe".

Das muß man nur noch in die entsprechende Programmiersprache umsetzten. 
Welche das ist, sollte egal sein.

von Thomas E. (tomedl)


Lesenswert?

spess53 wrote:
> Wieso. Meinen Vorschlag von 18:36 wollte Thomas ausprobieren. Nur bis
> jetzt keine Rückmeldung.

So, hier nun die Rückmeldung:
Deine Idee habe ich umgesetzt und es funktioniert einwandfrei. 
Mittlerweile habe ich einen Softstart und einen Softstopp realisieren 
können.

Ihr habt mir damit sehr geholfen, auch wenn die Diskussion über die 
Anschlüsse etwas unnötig war (mein Motor hat trotzdem fünf Anschlüsse).

@Falk
Ich denke du meinst den langen Code weiter oben? Sry, der kommt das 
nächste Mal in den Anhang.

@Rahul
Ich verstehe was du meinst, allerdings weiß ich noch nicht so genau, wie 
das mit den Feldern gehen soll. Vielleicht hat jemand ein Beispiel in 
BASCOM?

Grüße
Thomas

von spess53 (Gast)


Lesenswert?

Hi

Gut zu hören.

MfG Spess

von Rahul D. (rahul)


Lesenswert?

>Vielleicht hat jemand ein Beispiel in BASCOM?

Such im Bascom-Handbuch nach "Array"!

Dein Feld müsste dann so aussehen:

Initialisierung:

DIM A(4) as byte

A(1) = 16
A(2) = 8
A(3) = 4
A(4) = 2


im Programm wird dann der Port vermutlich so gesetzt:

PortD = A(Schritt)

Dann solltest du noch eine Richtungs-Variable benutzen, und damit 
entscheiden, in welche Richtung der Motor drehen soll.
Das kann man dann dadurch realisieren, dass man den Feld-Index entweder 
hoch- oder herunterzählt.

Von Bascom habe ich sonst keine Ahnung...

von Thomas E. (tomedl)


Lesenswert?

So, nun hab ich etwas weiter gebastelt und bin iweder auf Probleme 
gestoßen.

Den Softstart habe ich so realisiert, wie von spess53 vorher oben 
beschrieben.
Dazu zähle ich den Timer-Startwert pro Timer-Überlauf um eins hoch und 
dadurch vergeht immer weniger Zeit, um den Timer zum Überlaufen zu 
bringen -> der Schrittmotor wird immer schneller.
Allerdings ist diese "Beschleunigungsrampe" nicht linear, sondern folgt 
eher mehr einer e-Funktion, da ja bei jedem Timer-Überlauf auch der 
nächste Startwert des Timers um eins erhöht wird.
In BASCOM sieht das ganze so aus:
1
ISR vom Timer0:
2
Timer0 = x
3
If x < 255 then Incr x
4
Incr y
5
If y = 5 then y=1
6
Return
x ist die Variable für den Sartwert, der Startwert selber wird mit 
Timer0 = x gesetzt. Als nächstes folgt die Bedingung für die 
Erhöhung des Startwertes:
1
Wenn x kleiner 255 dann erhöhe x um eins
Anschließend wird noch die Variable y erhöht, welche die Schrittfolge 
vorgibt. Da ich nur vier Schritte benötige, wird die Variable bei 
erreichen von dem Wert 5 auf 1 zurückgesetzt.

Das funktioniert auch recht gut, bis auf jene Tatsache, dass die 
"Beschleunigungsrampe" die Fomr einer e-Funktion besitzt. Warum verstehe 
ich ja, nur Abhilfe dagegen weiß ich keine. Wenn ihr mir da einen 
kleinen Tipp geben könntet, wäre ich dankbar.


Als nächstes wollte ich die von Rahul der trollige angesprochenen Felder 
angehen. Da ich leider momentan für die nächsten Stunden nicht an den 
AVR kann, aber dennoch sehr neugierig bin, frage ich einfach hier mal, 
ob das so funktionieren kann.
Ich hab mich mal im Tutorial von der Roboternetz-Seite schlau gemacht 
und habe mir dort ein wenig die Seite über Tabellen in BASCOM 
durchgelesen. Wenn ich das richtig verstanden habe, kann ich damit 
gewisse Schaltzustände der Ports einfach "abspeichern" und danach wieder 
abrufen.

Der Code für so eine Tabelle würde laut Tutorial so aussehen:
1
Schrittfolge:
2
DATA &B00000110     'Schritt1
3
DATA &B00001100     'Schritt2
4
DATA &B00011000     'Schritt3
5
DATA &B00010010     'Schritt4

Das auslesen aus der Tabelle geschieht so:
1
PORTB = LOOKUP(0 , Schrittfolge)

Mittlerweile habe ich es programmiert und es läuft, also das mit den 
Tabellen funktioniert prächtig, und ich spare einiges an Speicher.

Trotzdem belibt noch das Problem mit der Beschleunigungsrampe....

Grüße
Thomas

von spess53 (Gast)


Lesenswert?

Hi

Also mir geht es es eigentlich auch wie Rahul :Von Bascom habe ich sonst 
keine Ahnung...

Das mit der Start/ Stoprampe ließe sich evtl. auch mit einer Tabelle 
realisieren. Dort werden die Timerwerte abgelegt. Damit lässt sich jeder 
Verlauf realisieren.

>Das auslesen aus der Tabelle geschieht so:
>PORTB = LOOKUP(0 , Schrittfolge)

In deinem Programm hast du den Schrittmotor an Port D hängen, also 
sollte das auch hier so sein. Zum anderen überschreibst du mit PORTD=... 
den kompletten Port. Solange nur der Motor dranhängt gibt es keine 
Probleme. Ansonsten erst PortD (ich meine wirklich PortD und nicht PIND) 
einlesen, ein
'and &B11100001' und dann 'or' mit dem Lookupwert. Das ganze dann 
ausgeben.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

Hi!

Sry, im "echten" Programm hab ich eh PORTD stehen.

>Zum anderen überschreibst du mit PORTD=...
>den kompletten Port. Solange nur der Motor dranhängt gibt es keine
>Probleme. Ansonsten erst PortD (ich meine wirklich PortD und nicht PIND)
>einlesen, ein
>and &B11100001' und dann 'or' mit dem Lookupwert. Das ganze dann
>ausgeben.
Sry, dass verteh ich jetzt nicht.

>Das mit der Start/ Stoprampe ließe sich evtl. auch mit einer Tabelle
>realisieren. Dort werden die Timerwerte abgelegt. Damit lässt sich jeder
>Verlauf realisieren.
Werd ich mal versuchen.

von Rahul D. (rahul)


Lesenswert?

>eher mehr einer e-Funktion

Eher 1/x, da man ja die Periodendauer verkürzt...

>Tabellen in BASCOM durchgelesen.

Tabellen sind nicht das gleiche wie Felder!


Die Linearität der Frequenz kann man dadurch halbwegs erzeugen, indem 
man nicht bei jedem Durchlauf den Vergleichswert ändert, sondern in 
nicht linearen Abständen. Irgendwo hatte ich dazu noch eine Art Tabelle 
(müsste ich jetzt suchen).
Darin habe ich die Differenzfrequenz und die damit zusammenhängede 
Periodendauer zwischen zwei Schrittfrequenzen berechnen lassen 
(OpenOffice.Org Calc...).

von spess53 (Gast)


Lesenswert?

Hi

Wenn du z.B. '&B00010010' auf den Port gibst werden deine Ausgänge 7,6,5 
und 0 (die die nicht mit dem Motor verbunden sind) unweigerlich 0, egal 
was vorher dort stand. Deshalb erst Einlesen, diese Bits sichern und mit 
den zu setzenden Bits verknüpfen.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

Rahul Der trollige wrote:

> Tabellen sind nicht das gleiche wie Felder!

Und was sind dann Felder?



>Wenn du z.B. '&B00010010' auf den Port gibst werden deine Ausgänge 7,6,5
>und 0 (die die nicht mit dem Motor verbunden sind) unweigerlich 0, egal
>was vorher dort stand. Deshalb erst Einlesen, diese Bits sichern und mit
>den zu setzenden Bits verknüpfen.
Warum soll ich die Ports einlesen? Da hängt ja eh nix dran außer Motor.

von Rahul D. (rahul)


Lesenswert?

>Und was sind dann Felder?

Man kann sie auch Vektoren, Matrizen oder Array nennen.
Ich habe im anderen Post eins als Beispiel gebracht...

von spess53 (Gast)


Lesenswert?

Hi

Ich hatte geschrieben: 'Solange nur der Motor dranhängt gibt es 
keine...'

Aber wenn noch etwas anderes dranhängt dann wird es problematisch. Auch 
bei Eingängen würde z.B. falls benutzt, der interne PullUp ausgeschaltet 
werden. Es gehört einfach zur sauberen Programmierung, das nur die Bits 
geändert werden, die geändert werden sollen. Bei so kleinen Programmen 
hast du noch den Überblick. Bei grösseren Sachen artet das sehr schnell 
in unnötigen Stress aus.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

Rahul Der trollige wrote:
>>Und was sind dann Felder?
>
> Man kann sie auch Vektoren, Matrizen oder Array nennen.
> Ich habe im anderen Post eins als Beispiel gebracht...

Habe nun versucht mich schlau zu machen, allerdings hab ich im I-net nix 
über Arrays gefunden. Kann mir jemand einen vollständigen Beispielcode 
mit einem funktionierenend Array posten?

Gru´
Thomas

von spess53 (Gast)


Lesenswert?

Hi

Wie wärs mal mit der BASCOM-Hilfe?

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

spess53 wrote:
> Hi
>
> Wie wärs mal mit der BASCOM-Hilfe?
>
> MfG Spess

Tja, entweder bin ich zu blöd, die BASCOM-Hilfe zu verstehen oder ich 
kann einfach kein Englisch. Jedenfalls check ich's net.

Gruß
Thomas

von spess53 (Gast)


Lesenswert?

Hi

BASCOM-Hilfe PDF S.233

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

Hallo!

Okay, ich habs jetzt in gefunden (genau auf Seite 233, danke Spess! ;-) 
)

Soweit ich das verstehe, ist ein Array etwas ähnliches wie eine Tabelle, 
nur mit dem Unterschied, dass mit den Daten im Array gearbeitet werden 
kann (sie können verändert werden, z.B. Wert um eins erhöhen, falls 
irgendeine Bedingung erfüllt wird).

Um ein Array zu erstellen, muss ich folgenden Code tippen:
1
Dim A(10) as Byte
2
Dim B as Byte
3
For B = 1 To 10
4
A(b) = B
Mit Dim A(10) as Byte erstelle ich das Array.
Mit DimB as Byte erstelle ich eine Variable des Typs Byte.
Mit For B = 1 To 10 definiere ich, dass die Variable B in die zehn 
Felder des Arrays gefüllt werden soll.

Und was mach ich mit A(b) = B?
Wie liest man aus dem Array aus?

Fragen über Fragen - aber ihr seht, ich bin schon ein Stückchen weiter!

;-)

lg
Thomas

von Rahul D. (rahul)


Lesenswert?

>Und was mach ich mit A(b) = B?

Damit weist man den aktuellen Wert von B dem Array A an der Stelle B zu.
Zuweisen und Auslesen geht genauso wie mit "normalen" Variablen.

von Thomas E. (tomedl)


Lesenswert?

Rahul Der trollige wrote:
>>Und was mach ich mit A(b) = B?
>
> Damit weist man den aktuellen Wert von B dem Array A an der Stelle B zu.
> Zuweisen und Auslesen geht genauso wie mit "normalen" Variablen.

Aha, also wird das Array nicht mit Zahlen von 1 bis 10 bezeichnet, 
sondern mit Buchstaben? Da könnte man dann ja nur 26 Felder haben? Mir 
kommt vor, da verstehe ich was nicht richtig.

Also gut, nochmal von vorne:
1
Dim A(10) as Byte   'Array mit 10 Feldern erstellen
2
Dim B as Byte       'Variable B als Byte definieren
3
For B = 1 To 10     'Variable B in die 10 Felder füllen
4
A(b) = B            'dem Feld b vom Array A den Wert von B zuweisen

Auslesen würde dann so funktionieren:
1
If A(b) = 8 then Led=1 else Led=0    'nur ein Beispiel

Gruß
Thomas

von spess53 (Gast)


Lesenswert?

Hi

>Aha, also wird das Array nicht mit Zahlen von 1 bis 10 bezeichnet,
>sondern mit Buchstaben?

B ist eine Variable und kann deshalb so gross werden, wie der 
Variablentyp, den du mit DIM vereinbart hast.

Nimm mir es bitte nicht übel, aber du hast noch einige Defizite. 
Versuche doch mal in einer Bibliothek ein Buch über BASIC zu bekommen. 
Da kannst du dich mal über grundlegende Funktionen, Datentypen und 
Programmiertechniken informieren. Das Internet ist auch nicht das Non 
plus Ultra.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

spess53 wrote:

> Nimm mir es bitte nicht übel, aber du hast noch einige Defizite.
> Versuche doch mal in einer Bibliothek ein Buch über BASIC zu bekommen.
> Da kannst du dich mal über grundlegende Funktionen, Datentypen und
> Programmiertechniken informieren. Das Internet ist auch nicht das Non
> plus Ultra.

Wieso sollte ich es dir übel nehmen? Ich habe erst vor zwei Monaten mit 
der µC-Spielerei begonnen und bin mir daher im Klaren, dass ich noch 
lange nicht der perfekte Programmierer bin. Aber aus diesem Grund frag 
ich hier ja nach, um meine Projekte zu verwirklichen. Ich werde mich mal 
nach einem guten Buch umsehen, danke für den Tipp.

Grüße
Thomas

von spess53 (Gast)


Lesenswert?

Hi

Sieh mal hier im Forum unter Buchtipps nach. Das Buch von Kühnel könnte 
etwas für dich sein.

MfG Spess

von Thomas E. (tomedl)


Lesenswert?

spess53 wrote:
> Hi
>
> Sieh mal hier im Forum unter Buchtipps nach. Das Buch von Kühnel könnte
> etwas für dich sein.
>
> MfG Spess
Ich werde die Bücher von Dr. Claus Kühnel und Ronald Walter bestellen.

Grüße
Thomas

von eProfi (Gast)


Lesenswert?

Um eine konstante Beschleunigung zu erhalten, musst Du die Frequenz 
linear mit der Zeit erhöhen, nicht linear mit der Schrittzahl.
Und die vergangene Zeit kannst Du errechnen, indem Du alle bisherigen 
Timerwerte zusammenaddierst.

Oder Du machst es so:

Frequenz = Startfrequenz;
Beschleunigung = Startbeschleunigung; //z.B. +1
Wartezeit = 0;

loop:
Frequenz += Beschleunigung * Wartezeit;

if(Frequenz == Zielfrequenz){Beschleunigung = 0;}
//oder if(Schrittzahl == BeschlEnde){Beschleunigung = 0;}

else if(Schrittzahl == BremsBeginn){Beschleunigung = -1;}
else if(Schrittzahl == BremsEnde){MotorStop;}
Wartezeit = Taktfrequenz / Frequenz;


Es ist angebracht, die Frequenz nicht in Hertz, sondern in z.B. 
Achtelhertz zu berechnen (Fixed-Point-Arithmetik).

Statt der Division   Wartezeit = Taktfrequenz / Frequenz;
kannst Du auch eine Tabelle verwenden.


Um welche Frequenzen geht es denn hier?

von Thomas E. (tomedl)


Lesenswert?

Hallo!

Danke für die Antwort, eProfi, aber ich habe das Problem bereits gelöst. 
Es läuft parallel zum Haupttimer ein zweiter Timer mit, der beim 
Überlauf den Startwert des Haupttimers um eins erhöht. Damit bekomme ich 
eine lineare Beschleunigungsrampe.

Das einzige, was mir jetzt noch zu schaffen macht, ist das von spess53 
angesprochene Problem mit dem überschreiben des gesamten PortD.

Ich kann die LED, die an PortD.0 hängt nicht mehr benutzen, da ich bei 
jedem Schritt den gesamten PortD neu überschreibe. Die Tabelle dazu:
1
   Data &B00000110
2
   Data &B00001100
3
   Data &B00011000
4
   Data &B00010010
Jetzt müsste ich irgendwie den PortD.0 dazu kriegen, nicht von dieser 
Tabelle erfasst zu werden und damit jederzeit und unabhängig zu ändern 
ist.

Grüße
Thomas

von Thomas E. (tomedl)


Lesenswert?

Hallo!

Ich habe das Problem jetzt folgendermaßen gelöst:
1
If X = 1 Then A = Lookup(0 , Schritte)
2
   If X = 2 Then A = Lookup(1 , Schritte)
3
   If X = 3 Then A = Lookup(2 , Schritte)
4
   If X = 4 Then A = Lookup(3 , Schritte)
5
6
   A = A Or B
7
8
   Portd = A
9
10
   If Y < 50 Then B = 1 Else B = 0
In die Variable A wird der Wert aus der Tabelle geschrieben (z.B. 
&B00000110) und mit PortD = A ausgegeben. Die Variable B kann die Werte 
0 oder 1 annehmen. Ganz unten prüfe ich dann noch den Wert von Y, falls 
dieser 50 überschreitet wird der Wert von B geändert.

Das Ganze funktioniert auch einwandfrei, aber eine Frage hab ich noch. 
Was wird mit A = A Or B gemacht? Für mich wäre das ein Widerspruch, da 
ich einfach sage: A istgleich A oder B. Damit wäre ja A eigentlich 
unbestimmt oder?

Vielleicht weiß ja jemand die Antwort auf meine Frage.

LG
Thomas

von Rahul D. (rahul)


Lesenswert?

>A istgleich A oder B. Damit wäre ja A eigentlich unbestimmt oder?

Das ist kein Vergleich, sondern eine Zuweisung.

Man könnte es auch so schreiben:

X = A Or B

A = X

Am Ende steht in A das gleiche wie bei A = A or B

von eProfi (Gast)


Lesenswert?

Aber auch dann hast Du keine lineare Beschleunigung, da die 
SchrittFrequenz ja TimerFrequenz / Teilerwert ist und Du den Teilerwert 
linear änderst, dann hast Du ja eine 1/x Funktion.

Naja, ist aber trotzdem schon mal besser als das Incrementen mit der 
Schrittfrequenz, da die Funktion bei Deinen Werten vermutlich doch 
ziemlich linear verläuft (deshalb habe ich nach Deinen Frequenzen 
gefragt).

Nochwas: Es ist oft viel einfacher, beim Zählen nicht bei 1, sondern bei 
0 zu beginnen.
Außerdem kannst Du den Schrittzähler und den "StepState" in ein- und der 
selben Variablen speichern.

Ich würde folgendes vorschlagen:

Portd = Lookup(0,StepCnt AND 3) OR Ledzustand


Oder numeriert BASCOM ein Array ab 1?  Das wäre ein Grund, den Compiler 
sofort beiseite zu legen.

Aber ich sehe schon, Du kannst auf dem Gebiet der Binärzahlen und der 
Boolschen Algebra noch viel lernen. Mit der Zeit bekommt man ein Gefühl 
dafür.
Viel Spass dabei!

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe das Problem jetzt folgendermaßen gelöst:

>   If X = 1 Then A = Lookup(0 , Schritte)
>   If X = 2 Then A = Lookup(1 , Schritte)
>   If X = 3 Then A = Lookup(2 , Schritte)
>   If X = 4 Then A = Lookup(3 , Schritte)

Für so etwas gibt es 'Switch case'

MfG Spess

von Carsten (Gast)


Lesenswert?

>Für so etwas gibt es 'Switch case'

case seleckt
...
...

.
.
.

um einen auf Geschwindigkeit zu machen, nicht auf Code-Größe

von lkmiller (Gast)


Lesenswert?

>   If X = 1 Then A = Lookup(0 , Schritte)
>   If X = 2 Then A = Lookup(1 , Schritte)
>   If X = 3 Then A = Lookup(2 , Schritte)
>   If X = 4 Then A = Lookup(3 , Schritte)

Nicht, dass ich eine Ahnung von Basic hätte,
aber in C könnte ich die 4 Zeilen oben so schreiben:

A = Lookup(X-1 , Schritte)

????

von Carsten (Gast)


Lesenswert?

> A = Lookup(X-1 , Schritte)

das wird Dein Comp. ähnlich übersetzen!

von spess53 (Gast)


Lesenswert?

Hi

Sollte natürlich 'select case' heissen. Mein einziger Kontakt zu BASCOM 
war bisher, daß ich mal vor einigen Jahren mal die Codebegrenzung der 
Demoversion gehackt habe. Um weiteren Diskussionen vorzubeugen: Ich habe 
das nie genutzt und auch nicht weitergegeben.

MfG Spess

von STK500-Besitzer (Gast)


Lesenswert?

>> A = Lookup(X-1 , Schritte)

>das wird Dein Comp. ähnlich übersetzen!

Wie was?
Der Bascom-Compiler übersetzt
>   If X = 1 Then A = Lookup(0 , Schritte)
>   If X = 2 Then A = Lookup(1 , Schritte)
>   If X = 3 Then A = Lookup(2 , Schritte)
>   If X = 4 Then A = Lookup(3 , Schritte)

in

> A = Lookup(X-1 , Schritte)

Dann wäre er wirklich gut.

>Portd = Lookup(0,StepCnt AND 3) OR Ledzustand

Das würde voraussetzen, dass man immer mit Schritt "0" anfängt.
Wenn man eine bestimmte Strecke fährt (z.B. 30 Schritte) und dann eine 
weitere (z.B. 45 Schritte), dann setzt man den Schrittzähler i.d.R. 
wieder auf 0 zurück. da sich weder 30 noch 45 durch 4 teilen lassen, 
hätte man einen selbstgemachten Schrittfehler.
Für diese Anwendung mag
>Portd = Lookup(0,StepCnt AND 3) OR Ledzustand
funktionieren - bei Erweiterungen gäbe es Probleme.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Mir ist gerade Appnote vom Atmel in die Hände gefallen. Der zugehörige 
Code ist zwar in C. Aber vielleicht hilft es dir trotzdem weiter.

MfG Spess

von Simon K. (simon) Benutzerseite


Lesenswert?

Carsten wrote:
>> A = Lookup(X-1 , Schritte)
>
> das wird Dein Comp. ähnlich übersetzen!

Das wird mein C (?) Compiler garantiert NICHT in ein switch/case oder if 
Konstrukt übersetzen.

von Rahul D. (rahul)


Lesenswert?

>Das wird mein C (?) Compiler garantiert NICHT in ein switch/case oder if
>Konstrukt übersetzen.

Kann dein C-Compiler auch Bascom nebenbei? ;)

von eProfi (Gast)


Lesenswert?

STK500-Besitzer:
"Das würde voraussetzen, dass man immer mit Schritt "0" anfängt."

Nein, der StepCnt ist ein globaler Zähler, der alle Steps (increment für 
vorwärts  und  decrement für rückwärts) mitzählt und gleichzeitig die 
untersten Bits als Pointer in die Tabelle zeigen.

Zähler ist dafür vielleicht ein suboptimaler Name, StepState ginge auch.

Nochmal, diese Variable ist.


Schade, dass fast keine Schrittmotoren 256 Schritte pro Umdrehung haben.

Beispiel:
Wenn Du bei Schritt 123 stehst und 30 Schritte nach rechts machst, steht 
er danach auf Schritt 153. Danach 45 Schritte nach links --> Schritt 108

30 Schritte nach rechts:
Schritt Pointer Bitmuster
123     3       1000
124     0       0001
125     1       0010
...
152     0       0001
153     1       0010
jetzt Drehrichtung umkehren (45 Schritte nach links):
152     0       0001
151     3       1000
...
109     1       0010
108     0       0001

Man bracht keine Fallunterscheidung o.ä. für die Richtung. Man 
subtrahiert einfach 1 und fertig.

Das geht übrigens auch über eine Umdrehung hinaus.



Zum Setzen der Bits:

PortD = PortD  AND  $1e   OR  stepTable[StepCnt AND 3]

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.