moinsen Community,
Ich habe Folgendes Problem:
ich habe zwei Schrittmotoren die ziemlich empfindlich auf delays
Reagieren ( wenigen µs)
so da ich die nicht einfach im main() laufen lassen kann da alles andere
dort drin auch einen delay haben. Also hab ich die in einen Interrupt
reingesteckt. So ein Motor läuft auch Top, den main() kann ich auch
nebenbei benutzen. so lange rede kurzer Sinn: ich habe zwei
Schrittmotoren die exakt (oder wie es möglich ist) gleichzeitig laufen.
Meine Überlegung war, einen zweiten Interrupt laufen zu lassen. Aber es
läuft immer nur ein Motor von den zweien. Kann das überhaupt
funktionieren ? wenn ja wo ist der Fehler an meinem Code? Danke schonmal
:)
Zwei Interrupts genau gleichzeitig laufen lassen kann zu interessanten
Effekten führen. Versuch mal, den Lauf der Motoren in einem Interrupt
zusammenzufassen oder einen der Schwellwerte leicht verändert zu
initialisieren und später mit dem richtigen Wert zu beschreiben
Je nach Controller solltest Du im Datenblatt auch Interrupt-Prioritäten
finden.
Wenn's knapp wird, sollte man beim Betreten einer ISR lieber die
Interrupts als erstes deaktivieren und sie vorm verlassen wieder
aktivieren.
Viktor B. schrieb:> Versuch mal
wenn der code con Motor...() in der loop() zu lang war, warum sollte es
dann in der isr besser sein? die interrupts laufen ueber, das ist es.
:->>>
Deine Schrittmotoren reagieren empfindlich auf Delay.
Und schon mal klar: im µs-Bereich.
Solche Probleme gibt es eher selten bei Schrittmotoren, aber
umso häufiger bei schlecht durchdachten Konzepten. Bevor du dir
das nicht selbst klargemacht hast, wirst du auch mit GHz-µCs
nix zum Laufen bekommen.
Isso...
Horst schrieb:> Je nach Controller solltest Du im Datenblatt auch Interrupt-Prioritäten> finden.AVR kennt keine Interrupt Prioritäten, da geht nur einer.
Auf die Gefahr hin, daß es für Dich einen 'Kulturschock' darstellt, zwei
Beispiele wie man mit einem Arduino Uno zwei Schrittmotore unabhängig
voneinander ansteuern kann:
http://mino-elektronik.de/Generator/takte_impulse.htm#bsp3a
Man kann es ggf. auch schlichter anstellen, stößt dann vermutlich bald
wieder auf Probleme.
Damit ein Computer zwei Funktionen (Interrupt-Routinen) gleichzeitig
ausführen kann, braucht er zwei CPU Kerne. Ich nehme mal an, dass deine
Hardware das nicht bietet.
Vermutlich liegt dein eigentliches Problem darin, dass deine
Motor-Funktionen blockierende Warteschleifen enthalten und somit
Multitasking verhindern.
Für kleine Single-Core Prozessoren sind Zustandsautomaten eine gute
Methode, blockierende Warteschleifen zu umgehen und dadurch Multitasking
in der Hauptschleife zu ermöglichen.
Ich empfehle dazu http://stefanfrings.de/multitasking_arduino/index.html
S. Landolt schrieb:> Es sieht irgendwie nach AVR8 aus, aber welcher Typ in dieser Reihe hat> einen 16-bit-Timer2?
Nur sehr wenige Tinys. Konkret fallen mir im Moment nur 441/841 ein.
Bei den Megas ist Timer2 immer nur 8 Bit und die meisten Tinys haben
überhaupt keinen Timer2.
> Konkret fallen mir im Moment nur 441/841 ein.
Danke für die Auskunft.
Es wäre schon sinnvoll gewesen, sicajo hätte gleich geschrieben, dass
er einen solchen hat.
Danke erstmal für die vielen Antworten
Also der µC ist ein Atmega328P der besitzt 3 Timer.
0 und 2 sind 8Bit und 1 ist ein 16Bit. Schon mal ein Fehler im Code
entdeckt Schwellwert1 muss uint8_t heißen wobei das denke ich kein
unterschied macht oder?
wenn die Schrittmotor Routinen in einen Code mache ist der eine
geringfügig langsamer und mir ist keine Methode eingefallen die troztdem
gleichzeitig laufen zu lassen.
Ich weiß gar nicht ob der Schrittmotor oder Der Treiber so empfindlich
ist.
Meinen kompletten Code kann ich gerne Posten wenn ich zu Hause bin dann
schau ich mir auch mal den Link von m.n. an
also kann ich hieraus erstmal mitnehmen das ich keine zwei Interrupts
gleichzeitig laufen lassen kann ?
So hoffe hab niemanden übersehen
Mfg
sicajo schrieb:> kann ich hieraus erstmal mitnehmen das ich keine zwei Interrupts> gleichzeitig laufen lassen kann ?
Du kannst überhaupt nicht zwei Sachen gleichzeitig laufen lassen. Der
Mikrocontroller hat nämlich nur eine CPU. Ich dachte, ich hätte mich da
klar ausgedrückt.
S. Landolt schrieb:> Es wäre schon sinnvoll gewesen, sicajo hätte gleich geschrieben, dass> er einen solchen hat.
Nunja, inzwischen wissen wir ja: hat er nicht.
Und damit hat er dann auch gleich unmißverständlich klargestellt: er hat
auch sonst keinerlei Ahnung. Ein typischer C&P-"Programmierer" halt...
klar 8 Bit sind ja nur 256. Ja gut blöd hab nichts gesagt. warum hat er
denn bitte nicht gemeckert ?
ja ich kann natürlich nicht etwas gleichzeitig laufen lassen. Das ist
alles nacheinander.
Und ne solange es nicht Sekunden unterschied ist können die ruhig
versetzt laufen Hauptsache Syncron. Hast du eine Idee S.Landold?
sicajo schrieb:> warum hat er denn bitte nicht gemeckert ?
Wer ist er? Und warum sollte er meckern?
> ja ich kann natürlich nicht etwas gleichzeitig laufen lassen. Das ist> alles nacheinander.> Und ne solange es nicht Sekunden unterschied ist können die ruhig> versetzt laufen Hauptsache Syncron.
Synchron ist aber das Gegenteil von Versetzt. Erst wenn die Aufgabe klar
ist, kann man ein Lösungskonzept erstellen.
sorry blöd formuliert. Vielleicht braucht ihr auch ein paar mehr Infos.
also die Schrittmotoren sind zwei Räder ( Roboter ). Also es wäre gut
wenn Die, so weit es möglich ist, beiden Synchron laufen. Wenn Motor 2
10ms (oder was auch immer ) später startet ist das absolut kein Problem.
Sollte halt nur nicht zu viel Verzögerung sein möchte ja nicht, dass der
Roboter nach Rechts oder Links Zieht.
naja Er sollte doch meckern wenn ich bei einem 8 Bit Register eine Zahl
von 65000 angebe.
Mfg
sicajo schrieb:> Er sollte doch meckern wenn ich bei einem 8 Bit Register eine Zahl> von 65000 angebe.
Wer ist "er"? Du meinst vielleicht den Compiler. Der meckert
tatsächlich, es sei denn, man unterdrückt alle Warnungen, wie es die
Arduino IDE standardmäßig tut. Kann man aber einstellen.
Um zwei Motoren synchron anzusteuern, braucht man in der Regel gar keine
Interrupts. Höchstens vielleicht einen Systemtimer
(Millisekunden-Counter). Wir wissen nicht, was deine Interrupthandler
machen und warum du überhaupt Interrupts verwendet hast. Sogar dein
Quelltext ist geheim, ebenso der Schaltplan und die Aufgabenstellung.
Also können wir Dir auch nicht helfen, außer die Info, dass dein Ansatz
mit sehr hoher Wahrscheinlichkeit ungeeignet ist und dass du dich mit
Zustandsautomaten beschäftigen sollst.
sicajo schrieb:> wenn die Schrittmotor Routinen in einen Code mache ist der eine> geringfügig langsamer und mir ist keine Methode eingefallen die troztdem> gleichzeitig laufen zu lassen.
Das Zauberwort lautet Multitasking und ist gar nicht so schwer, wenn
man das Konzept erst einmal verstanden hat. Dann reicht ein Timer und
das Ergebnis ist trotzdem deutlich besser ;-)
> also kann ich hieraus erstmal mitnehmen das ich keine zwei Interrupts> gleichzeitig laufen lassen kann ?
Falsch. Man kann schon, aber daraus wird noch lange kein gescheites
Konzept. Vor allem dann, wenn deine Funktionen
Motor_Rueckwaerts_Rechts();
Motor_Rueckwaerts_Links();
blockierend bzw. mit eher langen Delays arbeiten.
Stefanus F. schrieb:> Synchron ist aber das Gegenteil von Versetzt.
SCHWACHSINN! Auch versetzt laufende Abläufe bzw. hier Timer sind
synchron! Ebenso Vielfache von Takten etc., wie die PLLs und ähnliche
Schaltungen erzeugen.
Synchron heißt NICHT gleichzeitig oder mit Phasenlage 0°!!!
https://de.wikipedia.org/wiki/Synchronit%C3%A4t
Es heißt vielmehr "zeitlich genau definiert". Dazu gehören auch
phasenverschobene Signale mit gleicher Frequenz.
> Erst wenn die Aufgabe klar> ist, kann man ein Lösungskonzept erstellen.
Die IST klar! Der OP will 2 Schrittmotoren unabhängig voneinander in der
Geschwindigkeit steuern.
sicajo schrieb:> naja Er sollte doch meckern wenn ich bei einem 8 Bit Register eine Zahl> von 65000 angebe.
Das würde "Er" auch tun, wenn nicht irgendwelche Wichser beschlossen
hätten, dass man zarte User standardmäßig nicht mit "unnötigen"
Fehlermeldungen oder Warnungen gängeln sollte...
Die sollen doch softwaremäßig nur Wichsvorlagen zusammenkopieren und vor
allem die völlig überteuerte Systemhardware kaufen.
Darin besteht im Kern das Arduino-Konzept.
sicajo schrieb:> Oje ich wollte kein Streit auslösen...
Keine Bange. Der c-hater kann nicht anders. Der ist im Tiefflug durch
die Kinderstube geflogen und seine Mutter hat bei seiner Erziehung auf
ganzer Linie versagt.
Nicht deine Schuld...
Falk B. schrieb:> Die IST klar! Der OP will 2 Schrittmotoren unabhängig voneinander in der> Geschwindigkeit steuern.
Na, dann wirst du ihm sicher gerne eine passende Lösung präsentieren,
die uns alle in deinen Schatten stellt.
Stefanus F. schrieb:> Falk B. schrieb:>> Die IST klar! Der OP will 2 Schrittmotoren unabhängig voneinander in der>> Geschwindigkeit steuern.>> Na, dann wirst du ihm sicher gerne eine passende Lösung präsentieren,> die uns alle in deinen Schatten stellt.
Hast du Komplexe? Oder einen kleinen . . . . Schatten? ;-)
Stefanus F. schrieb:> Erst wenn die Aufgabe klar> ist, kann man ein Lösungskonzept erstellen.Falk B. schrieb:> Die IST klar! Der OP will 2 Schrittmotoren unabhängig voneinander in der> Geschwindigkeit steuern.Stefanus F. schrieb:> Na, dann wirst du ihm sicher gerne eine passende Lösung präsentieren,> die uns alle in deinen Schatten stellt.Falk B. schrieb:> Hast du Komplexe? Oder einen kleinen . . . . Schatten?
Ich habe tatsächlich einen Vogel, nicht mehr alle Tassen im Schrank und
manchmal einen neben mir her laufen. Aber sonst ist alles Ok.
Zurück zum Thema: War das nun so falsch von mir, weitere Infos zur
Aufgabe anzufordern? Anscheinend bist auch du doch nicht in der Lage,
eine Lösung anzubieten.
Stefanus F. schrieb:> Zurück zum Thema: War das nun so falsch von mir, weitere Infos zur> Aufgabe anzufordern? Anscheinend bist auch du doch nicht in der Lage,> eine Lösung anzubieten.
Du hast schon wieder einen akuten Anfall von Helfersyndrom. Und einem
Minderwertigkeitskomplex.
Falk B. schrieb:> Du hast schon wieder einen akuten Anfall von Helfersyndrom.
Falk, das musst du mir nicht immer wieder vorwerfen, denn jedes mal
offenbarst du damit, was für eine Sorte Mensch du bist. Auf jeden Fall
nicht die Sorte von Mensch, mit der ich zu tun haben möchte. In sofern
darfst du mich gerne mal am ...
Wenn ich helfen möchte, dann lass mich das tun. Sag Du mir nicht, was
ich zu tun habe. Wenn hier mehr geholfen wird, als Dir zusagt, dann
halte dich bitte einfach raus!
Deine Nummer von vor kurzem habe ich nicht vergessen. Da hast du mich
und andere aufgefordert, das Helfen sein zu lassen. Als der Fragende
dann ganz kurz davor war, mir einen Entwicklungsauftrag zu erteilen,
hast du ihn mir weg geschnappt und das fertige Programm präsentiert. So
viel dazu, du hast selber auch ein Helfersyndrom, aber du willst ganz
alleine der Held sein, der hier hilft. Merkst du eigentlich nicht, wie
rücksichtslos dieses Verhalten ist?
Stefanus F. schrieb im Beitrag #5839
> Als der Fragende> dann ganz kurz davor war, mir einen Entwicklungsauftrag zu erteilen,> hast du ihn mir weg geschnappt
Tja, falscher Stolz und Eitelkeit sind deine Attribute, Stefan. Jetzt
ist es endlich raus!
Moin,
Vielleicht mal zum Verständtnis für sicajo, wie Interupts funktionieren,
denn ich denke da fehlt noch der Durchblick:
Der Controller macht immer eins nach dem anderen. Gleichzeitig geht da
gar nichts. (Abgesehen von Hardware, es klappert ein Byte auf Uart, SPI,
I2C rein/raus o.ä.)
Wenn ein Int zuschlägt, wird die Main unterbrochen und sofort die ISR
ausgeführt. Alle anderen Ints sind dann erstmal gesperrt. Es wird das
abgearbeitet was in der ISR steht. Kommt in der Zeit ein anderer Int,
bleibt das Flag stehen und der wird dann abgearbeitet, wenn die erste
ISR fertig ist.
Kommt ein anderer Int zweimal, geht der zweite verloren. Das Flag kann
nur einmal gesetzt werden. Kommt der gleiche Int nochmal, während seine
ISR abgearbeitet wird, wird der danach gleich nochmal ausgeführt.
Es gibt da eine Reihenfolge der Ints (wenn also wähend einer ISR zwei
Int zuschlagen, welche wird dann zuerst ausgeführt) aber wenn das eine
Rolle spielt, sollte man das Konzept überdenken oder man weiß ganz genau
was man tut.
man kann auch Ints zulassen in einer ISR. Wer sowas tut und auch
beherrscht, fragt aber nicht hier im Forum.
Zuerst hast Du was von µs geschrieben. Du hast garantiert keine
Schrittmotoren, bei denen das relevant ist.
Bei zwei Schrittmotoren kann man kaum so mies programmieren, daß diese
nicht quasi synchron laufen. Da spielen selbst ein paar ms sicher keine
Rolle. Zumindest nicht im Bastelbereich.
Gruß,
Norbert
Norbert S. schrieb:> Zuerst hast Du was von µs geschrieben. Du hast garantiert keine> Schrittmotoren, bei denen das relevant ist.
Stimmt, aber . . .
> Bei zwei Schrittmotoren kann man kaum so mies programmieren, daß diese> nicht quasi synchron laufen.
Wenn das mal kein Irrtum ist ;-)
piep piep piep wir haben uns alle lieb.
Sorry etwas verspätet aber die der komplette Code :
1
2
/* Schrittmotor Variablen deklaration */
3
4
#define Rad_Links_I01 2
5
#define Rad_Links_I11 3
6
#define Rad_Links_PHASE1 4
7
#define Rad_Links_I02 7
8
#define Rad_Links_I12 6
9
#define Rad_Links_PHASE2 5
10
11
#define Rad_Rechts_I01 8
12
#define Rad_Rechts_I11 9
13
#define Rad_Rechts_PHASE1 10
14
#define Rad_Rechts_I02 13
15
#define Rad_Rechts_I12 12
16
#define Rad_Rechts_PHASE2 11
17
18
/* Schrittmotor Variablen deklaration Ende */
19
20
intzahl=0;
21
22
uint16_tSchwellwert=65200;// Vergleichswert Für 16 Bit Register .
23
24
voidsetup(){
25
26
Serial.begin(9600);// Serielle Verbingung Starten
27
28
/* Schrittmotor Pin konfiguration */
29
30
pinMode(Rad_Links_I01,OUTPUT);
31
pinMode(Rad_Links_I11,OUTPUT);
32
pinMode(Rad_Links_PHASE1,OUTPUT);
33
pinMode(Rad_Links_I02,OUTPUT);
34
pinMode(Rad_Links_I12,OUTPUT);
35
pinMode(Rad_Links_PHASE2,OUTPUT);
36
37
pinMode(Rad_Rechts_I01,OUTPUT);
38
pinMode(Rad_Rechts_I11,OUTPUT);
39
pinMode(Rad_Rechts_PHASE1,OUTPUT);
40
pinMode(Rad_Rechts_I02,OUTPUT);
41
pinMode(Rad_Rechts_I12,OUTPUT);
42
pinMode(Rad_Rechts_PHASE2,OUTPUT);
43
44
/* Schrittmotor Pin konfiguration Ende */
45
46
noInterrupts();// alle Interrupts löschen
47
48
TCCR1A=0;// TCCR1A Register auf null setzen
49
TCCR1B=0;// TCCR1B Register auf null setzen
50
51
TCNT1=Schwellwert;
52
TCCR1B|=(1<<CS12);
53
TIMSK1|=(1<<TOIE1);
54
55
interrupts();// Interrupts Starten
56
57
}
58
voidloop()
59
{
60
61
if(zahl<20)
62
{
63
zahl++;
64
delay(500);
65
}
66
else
67
{
68
69
zahl=0;
70
71
}
72
73
Serial.println(zahl);
74
75
76
/* Motor Ansteuerung zufuß */
77
78
// Motor_Rueckwaerts_Links();
79
// Motor_Rueckwaerts_Rechts();
80
81
// Motor_Vorwaerts_Links();
82
// Motor_Vorwaerts_Rechts();
83
84
// Motor_Aus();
85
86
87
88
89
}
90
91
/* Interrupt Routine Rad Rechts */
92
93
ISR(TIMER1_OVF_vect)
94
{
95
TCNT1=Schwellwert;
96
97
if(zahl>=10)
98
{
99
100
Motor_Vorwaerts_Rechts();
101
102
}else
103
{
104
105
Motor_Rueckwaerts_Rechts();
106
107
}
108
}
109
110
/* Interrupt Routine Ende */
und hier die Funktionen
1
2
3
4
staticcharDrehphase;//Static behält den Wert, auch wenn die Funktion beendet wurde -> permanent im Speicher wie globale Variable
5
6
voidMotor_Vorwaerts_Links(){
7
8
switch(Drehphase)
9
{
10
case0:
11
//Phase 1
12
digitalWrite(Rad_Links_I01,HIGH);
13
digitalWrite(Rad_Links_I11,LOW);
14
digitalWrite(Rad_Links_PHASE1,HIGH);
15
digitalWrite(Rad_Links_I02,HIGH);
16
digitalWrite(Rad_Links_I12,LOW);
17
digitalWrite(Rad_Links_PHASE2,LOW);
18
break;
19
20
case1:
21
//Phase 2
22
digitalWrite(Rad_Links_I01,HIGH);
23
digitalWrite(Rad_Links_I11,HIGH);
24
digitalWrite(Rad_Links_PHASE1,HIGH);
25
digitalWrite(Rad_Links_I02,LOW);
26
digitalWrite(Rad_Links_I12,LOW);
27
digitalWrite(Rad_Links_PHASE2,LOW);
28
break;
29
30
case2:
31
//Phase 3
32
digitalWrite(Rad_Links_I01,HIGH);
33
digitalWrite(Rad_Links_I11,LOW);
34
digitalWrite(Rad_Links_PHASE1,LOW);
35
digitalWrite(Rad_Links_I02,HIGH);
36
digitalWrite(Rad_Links_I12,LOW);
37
digitalWrite(Rad_Links_PHASE2,LOW);
38
break;
39
40
case3:
41
//Phase 4
42
digitalWrite(Rad_Links_I01,LOW);
43
digitalWrite(Rad_Links_I11,LOW);
44
digitalWrite(Rad_Links_PHASE1,LOW);
45
digitalWrite(Rad_Links_I02,HIGH);
46
digitalWrite(Rad_Links_I12,HIGH);
47
digitalWrite(Rad_Links_PHASE2,LOW);
48
break;
49
50
case4:
51
//Phase 5
52
digitalWrite(Rad_Links_I01,HIGH);
53
digitalWrite(Rad_Links_I11,LOW);
54
digitalWrite(Rad_Links_PHASE1,LOW);
55
digitalWrite(Rad_Links_I02,HIGH);
56
digitalWrite(Rad_Links_I12,LOW);
57
digitalWrite(Rad_Links_PHASE2,HIGH);
58
break;
59
60
case5:
61
//Phase 6
62
digitalWrite(Rad_Links_I01,HIGH);
63
digitalWrite(Rad_Links_I11,HIGH);
64
digitalWrite(Rad_Links_PHASE1,LOW);
65
digitalWrite(Rad_Links_I02,LOW);
66
digitalWrite(Rad_Links_I12,LOW);
67
digitalWrite(Rad_Links_PHASE2,HIGH);
68
break;
69
70
case6:
71
//Phase 7
72
digitalWrite(Rad_Links_I01,HIGH);
73
digitalWrite(Rad_Links_I11,LOW);
74
digitalWrite(Rad_Links_PHASE1,HIGH);
75
digitalWrite(Rad_Links_I02,HIGH);
76
digitalWrite(Rad_Links_I12,LOW);
77
digitalWrite(Rad_Links_PHASE2,HIGH);
78
break;
79
80
case7:
81
//Phase 8
82
digitalWrite(Rad_Links_I01,LOW);
83
digitalWrite(Rad_Links_I11,LOW);
84
digitalWrite(Rad_Links_PHASE1,HIGH);
85
digitalWrite(Rad_Links_I02,HIGH);
86
digitalWrite(Rad_Links_I12,HIGH);
87
digitalWrite(Rad_Links_PHASE2,HIGH);
88
break;
89
90
91
}
92
if(Drehphase<7)//Position im Zeitverlaufdiagramm mit Halbschrittbetrieb
93
{
94
Drehphase++;
95
96
97
}
98
else
99
{
100
Drehphase=0;
101
}
102
103
104
}
105
106
107
voidMotor_Vorwaerts_Rechts(){
108
109
switch(Drehphase)
110
{
111
112
case0:
113
//Phase 9
114
digitalWrite(Rad_Rechts_I01,LOW);
115
digitalWrite(Rad_Rechts_I11,LOW);
116
digitalWrite(Rad_Rechts_PHASE1,HIGH);
117
digitalWrite(Rad_Rechts_I02,HIGH);
118
digitalWrite(Rad_Rechts_I12,HIGH);
119
digitalWrite(Rad_Rechts_PHASE2,HIGH);
120
break;
121
122
case1:
123
//Phase 10
124
digitalWrite(Rad_Rechts_I01,HIGH);
125
digitalWrite(Rad_Rechts_I11,LOW);
126
digitalWrite(Rad_Rechts_PHASE1,HIGH);
127
digitalWrite(Rad_Rechts_I02,HIGH);
128
digitalWrite(Rad_Rechts_I12,LOW);
129
digitalWrite(Rad_Rechts_PHASE2,HIGH);
130
break;
131
132
case2:
133
//Phase 12
134
digitalWrite(Rad_Rechts_I01,HIGH);
135
digitalWrite(Rad_Rechts_I11,HIGH);
136
digitalWrite(Rad_Rechts_PHASE1,LOW);
137
digitalWrite(Rad_Rechts_I02,LOW);
138
digitalWrite(Rad_Rechts_I12,LOW);
139
digitalWrite(Rad_Rechts_PHASE2,HIGH);
140
break;
141
142
case3:
143
//Phase 13
144
digitalWrite(Rad_Rechts_I01,HIGH);
145
digitalWrite(Rad_Rechts_I11,LOW);
146
digitalWrite(Rad_Rechts_PHASE1,LOW);
147
digitalWrite(Rad_Rechts_I02,HIGH);
148
digitalWrite(Rad_Rechts_I12,LOW);
149
digitalWrite(Rad_Rechts_PHASE2,HIGH);
150
break;
151
152
case4:
153
//Phase 14
154
digitalWrite(Rad_Rechts_I01,LOW);
155
digitalWrite(Rad_Rechts_I11,LOW);
156
digitalWrite(Rad_Rechts_PHASE1,LOW);
157
digitalWrite(Rad_Rechts_I02,HIGH);
158
digitalWrite(Rad_Rechts_I12,HIGH);
159
digitalWrite(Rad_Rechts_PHASE2,LOW);
160
break;
161
162
case5:
163
//Phase 15
164
digitalWrite(Rad_Rechts_I01,HIGH);
165
digitalWrite(Rad_Rechts_I11,LOW);
166
digitalWrite(Rad_Rechts_PHASE1,LOW);
167
digitalWrite(Rad_Rechts_I02,HIGH);
168
digitalWrite(Rad_Rechts_I12,LOW);
169
digitalWrite(Rad_Rechts_PHASE2,LOW);
170
break;
171
172
case6:
173
//Phase 16
174
digitalWrite(Rad_Rechts_I01,HIGH);
175
digitalWrite(Rad_Rechts_I11,HIGH);
176
digitalWrite(Rad_Rechts_PHASE1,HIGH);
177
digitalWrite(Rad_Rechts_I02,LOW);
178
digitalWrite(Rad_Rechts_I12,LOW);
179
digitalWrite(Rad_Rechts_PHASE2,LOW);
180
break;
181
182
case7:
183
//Phase 17
184
digitalWrite(Rad_Rechts_I01,HIGH);
185
digitalWrite(Rad_Rechts_I11,LOW);
186
digitalWrite(Rad_Rechts_PHASE1,HIGH);
187
digitalWrite(Rad_Rechts_I02,HIGH);
188
digitalWrite(Rad_Rechts_I12,LOW);
189
digitalWrite(Rad_Rechts_PHASE2,LOW);
190
break;
191
192
193
194
}
195
if(Drehphase<7)//Position im Zeitverlaufdiagramm mit Halbschrittbetrieb
196
{
197
Drehphase++;
198
199
200
}
201
else
202
{
203
Drehphase=0;
204
}
205
206
207
}
208
209
voidMotor_Rueckwaerts_Links(){
210
211
switch(Drehphase)
212
{
213
case0:
214
//Phase 1
215
digitalWrite(Rad_Links_I01,LOW);
216
digitalWrite(Rad_Links_I11,LOW);
217
digitalWrite(Rad_Links_PHASE1,HIGH);
218
digitalWrite(Rad_Links_I02,HIGH);
219
digitalWrite(Rad_Links_I12,HIGH);
220
digitalWrite(Rad_Links_PHASE2,HIGH);
221
break;
222
223
case1:
224
//Phase 2
225
digitalWrite(Rad_Links_I01,HIGH);
226
digitalWrite(Rad_Links_I11,LOW);
227
digitalWrite(Rad_Links_PHASE1,HIGH);
228
digitalWrite(Rad_Links_I02,HIGH);
229
digitalWrite(Rad_Links_I12,LOW);
230
digitalWrite(Rad_Links_PHASE2,HIGH);
231
break;
232
233
case2:
234
//Phase 3
235
digitalWrite(Rad_Links_I01,HIGH);
236
digitalWrite(Rad_Links_I11,HIGH);
237
digitalWrite(Rad_Links_PHASE1,LOW);
238
digitalWrite(Rad_Links_I02,LOW);
239
digitalWrite(Rad_Links_I12,LOW);
240
digitalWrite(Rad_Links_PHASE2,HIGH);
241
break;
242
243
case3:
244
//Phase 4
245
digitalWrite(Rad_Links_I01,HIGH);
246
digitalWrite(Rad_Links_I11,LOW);
247
digitalWrite(Rad_Links_PHASE1,LOW);
248
digitalWrite(Rad_Links_I02,HIGH);
249
digitalWrite(Rad_Links_I12,LOW);
250
digitalWrite(Rad_Links_PHASE2,HIGH);
251
break;
252
253
case4:
254
//Phase 5
255
digitalWrite(Rad_Links_I01,LOW);
256
digitalWrite(Rad_Links_I11,LOW);
257
digitalWrite(Rad_Links_PHASE1,LOW);
258
digitalWrite(Rad_Links_I02,HIGH);
259
digitalWrite(Rad_Links_I12,HIGH);
260
digitalWrite(Rad_Links_PHASE2,LOW);
261
break;
262
263
case5:
264
//Phase 6
265
digitalWrite(Rad_Links_I01,HIGH);
266
digitalWrite(Rad_Links_I11,LOW);
267
digitalWrite(Rad_Links_PHASE1,LOW);
268
digitalWrite(Rad_Links_I02,HIGH);
269
digitalWrite(Rad_Links_I12,LOW);
270
digitalWrite(Rad_Links_PHASE2,LOW);
271
break;
272
273
case6:
274
//Phase 7
275
digitalWrite(Rad_Links_I01,HIGH);
276
digitalWrite(Rad_Links_I11,HIGH);
277
digitalWrite(Rad_Links_PHASE1,HIGH);
278
digitalWrite(Rad_Links_I02,LOW);
279
digitalWrite(Rad_Links_I12,LOW);
280
digitalWrite(Rad_Links_PHASE2,LOW);
281
break;
282
283
case7:
284
//Phase 8
285
digitalWrite(Rad_Links_I01,HIGH);
286
digitalWrite(Rad_Links_I11,LOW);
287
digitalWrite(Rad_Links_PHASE1,HIGH);
288
digitalWrite(Rad_Links_I02,HIGH);
289
digitalWrite(Rad_Links_I12,LOW);
290
digitalWrite(Rad_Links_PHASE2,LOW);
291
break;
292
293
}
294
if(Drehphase<7)//Position im Zeitverlaufdiagramm mit Halbschrittbetrieb
295
{
296
Drehphase++;
297
}
298
else
299
{
300
Drehphase=0;
301
}
302
303
}
304
305
voidMotor_Rueckwaerts_Rechts(){
306
307
switch(Drehphase)
308
{
309
case0:
310
//Phase 9
311
digitalWrite(Rad_Rechts_I01,HIGH);
312
digitalWrite(Rad_Rechts_I11,LOW);
313
digitalWrite(Rad_Rechts_PHASE1,HIGH);
314
digitalWrite(Rad_Rechts_I02,HIGH);
315
digitalWrite(Rad_Rechts_I12,LOW);
316
digitalWrite(Rad_Rechts_PHASE2,LOW);
317
break;
318
319
case1:
320
//Phase 10
321
digitalWrite(Rad_Rechts_I01,HIGH);
322
digitalWrite(Rad_Rechts_I11,HIGH);
323
digitalWrite(Rad_Rechts_PHASE1,HIGH);
324
digitalWrite(Rad_Rechts_I02,LOW);
325
digitalWrite(Rad_Rechts_I12,LOW);
326
digitalWrite(Rad_Rechts_PHASE2,LOW);
327
break;
328
329
case2:
330
//Phase 11
331
digitalWrite(Rad_Rechts_I01,HIGH);
332
digitalWrite(Rad_Rechts_I11,LOW);
333
digitalWrite(Rad_Rechts_PHASE1,LOW);
334
digitalWrite(Rad_Rechts_I02,HIGH);
335
digitalWrite(Rad_Rechts_I12,LOW);
336
digitalWrite(Rad_Rechts_PHASE2,LOW);
337
break;
338
339
case3:
340
//Phase 12
341
digitalWrite(Rad_Rechts_I01,LOW);
342
digitalWrite(Rad_Rechts_I11,LOW);
343
digitalWrite(Rad_Rechts_PHASE1,LOW);
344
digitalWrite(Rad_Rechts_I02,HIGH);
345
digitalWrite(Rad_Rechts_I12,HIGH);
346
digitalWrite(Rad_Rechts_PHASE2,LOW);
347
break;
348
349
case4:
350
//Phase 13
351
digitalWrite(Rad_Rechts_I01,HIGH);
352
digitalWrite(Rad_Rechts_I11,LOW);
353
digitalWrite(Rad_Rechts_PHASE1,LOW);
354
digitalWrite(Rad_Rechts_I02,HIGH);
355
digitalWrite(Rad_Rechts_I12,LOW);
356
digitalWrite(Rad_Rechts_PHASE2,HIGH);
357
break;
358
359
case5:
360
//Phase 14
361
digitalWrite(Rad_Rechts_I01,HIGH);
362
digitalWrite(Rad_Rechts_I11,HIGH);
363
digitalWrite(Rad_Rechts_PHASE1,LOW);
364
digitalWrite(Rad_Rechts_I02,LOW);
365
digitalWrite(Rad_Rechts_I12,LOW);
366
digitalWrite(Rad_Rechts_PHASE2,HIGH);
367
break;
368
369
case6:
370
//Phase 15
371
digitalWrite(Rad_Rechts_I01,HIGH);
372
digitalWrite(Rad_Rechts_I11,LOW);
373
digitalWrite(Rad_Rechts_PHASE1,HIGH);
374
digitalWrite(Rad_Rechts_I02,HIGH);
375
digitalWrite(Rad_Rechts_I12,LOW);
376
digitalWrite(Rad_Rechts_PHASE2,HIGH);
377
break;
378
379
case7:
380
//Phase 16
381
digitalWrite(Rad_Rechts_I01,LOW);
382
digitalWrite(Rad_Rechts_I11,LOW);
383
digitalWrite(Rad_Rechts_PHASE1,HIGH);
384
digitalWrite(Rad_Rechts_I02,HIGH);
385
digitalWrite(Rad_Rechts_I12,HIGH);
386
digitalWrite(Rad_Rechts_PHASE2,HIGH);
387
break;
388
389
390
391
}
392
if(Drehphase<7)//Position im Zeitverlaufdiagramm mit Halbschrittbetrieb
393
{
394
Drehphase++;
395
}
396
else
397
{
398
Drehphase=0;
399
}
400
401
}
402
403
404
voidMotor_Aus(){
405
406
digitalWrite(Rad_Links_I01,HIGH);
407
digitalWrite(Rad_Links_I11,HIGH);
408
digitalWrite(Rad_Links_I02,HIGH);
409
digitalWrite(Rad_Links_I12,HIGH);
410
digitalWrite(Rad_Links_PHASE1,HIGH);
411
digitalWrite(Rad_Links_PHASE2,HIGH);
412
413
digitalWrite(Rad_Rechts_I01,HIGH);
414
digitalWrite(Rad_Rechts_I11,HIGH);
415
digitalWrite(Rad_Rechts_I02,HIGH);
416
digitalWrite(Rad_Rechts_I12,HIGH);
417
digitalWrite(Rad_Rechts_PHASE1,HIGH);
418
digitalWrite(Rad_Rechts_PHASE2,HIGH);
419
420
}
So nicht wundern ich habe den zweiten Timer erstmal Rausgenommen und im
Main einen Zähler eingefügt und zu schauen wie dich der Interrupt
verhält wenn er einfach so Veränderd wird.
Also wie gesagt die Hauptsache ist die Laufen synchron, da habe ich mich
villeicht etwas Falsch ausgedrückt. Die idee mit dem Motor versetzt
Laufen lassen hatte ich auch schon wusste nur nicht wie
Mfg
der Motor hat keine beschreibung drauf ist aber ein ganz normaler mit
zwei spulen und 4 eingänge also hab an dem gleichen Treiber ein paar
andere angeschlossen. treiber ist ein MTS2916a
Datenblatt :
http://ww1.microchip.com/downloads/en/devicedoc/22259c.pdf
Die Arduino-PinOut-Funktion auf der einen Seite und der direkte Zugriff
auf die Timer-Register widerspricht sich etwas.
Für die GPIO-Ausgabe solltest du auch direkt mit den Registern "reden",
und dabei das ganze "Schaltwort" (das, was du auf drei DigitalWrites
verteilst) in einem Rutsch übertragen. Das würde die Sache schon mal
beschleunigen.
Das ganze Gehampel mit den Switch-Case-Abfragen könnte man auch mit
Arrays verringern. Hat aber nichts mit dem eigentlichen Problem zu tun,
würde es aber erleichtern, und das Programm übersichtler machen.
Du brauchst eigentlich nur einen Timer mit dessen ISR.
In der ISR werden beide Motoren getaktet. Dann sind sie schon mal
synchron.
Da du aber auch Kurven fahren willst, brauchst du für jeden Motor eine
eigene Drehphasen-Variable (sofern ich deinen Programmkot richtig
interpretiert habe).
Du müüstest also einfach die Drehphasen-Variablen je nach Richtung in
der ISR hoch oder runterzählen (jetzt zählst du ja nur hoch...) und dann
die Ausgänge setzen.
Du hast einfach einen Fehler bei der Modularisierung gemacht.
Was hälst Du eigentlich davon, erstmal in die Grundlagen einzusteigen?
https://www.mikrocontroller.net/articles/Schrittmotoren
Du wirst Dich, wenn Du Positionen einigermaßen flott "anfahren" willst
sowieso mit Rampen etc. beschäftigen müssen.
Lass erstmal einen Schrittmotor nach Deinen Wünschen laufen, dann
beziehe einen 2. ein. Ich sehe auch keinen Grund, die nicht parallel für
eine Achse (mit gleichen Impulsen) anzusteuern, wenn Du immer wieder
"Referenzfahrten" zur Synchronisierung (mit Endschaltern) durchführst.
sicajo schrieb:> treiber ist ein MTS2916a
Der ist funktionskompatibel zum L6219 von STM. Dazu läßt sich vielleicht
Arduino-Code im Netz finden.
Selber habe ich auch Routinen, aber damit kommst Du womöglich nicht
klar, da Deine Programmiererfahrungen noch sehr klein sind.
Wenn Du irgendeinmal Land sehen willst, vergiss diese "digital_write()"
Aufrufe und lege alle Pins eines Motors auf einen gemeinsamen Port. Das
Ausgabemuster wird dann aus einer Tabelle entnommen.
Ich hänge trotzdem ein Beipiel für einen ATmega8 mit einem Motor an
PortB an, nur damit Du siehst, wie es gemacht werden könnte. Mit dabei
ist nach eine Rampe und Stromabsenkung für den Stillstand.
Deutlich einfacher dürfte es für Dich sein, spezielle Controller für
jeden Motor zu nehmen, die nur mit Richtung und Takt angesteuert werden
müssen. Damit geht auch eine exakte Gleichzeitigkeit der Schritte, da
die Hardware der Timer für die Taktausgabe zuständig ist. Beispiele:
A4982, A4988 oder was es sonst noch als "Ramsch-Ware" mit ungenügender
Kühlung gibt.
sicajo schrieb:> piep piep piep wir haben uns alle lieb.>> Sorry etwas verspätet aber die der komplette Code :
Schon mal gelesen, was di in dem Fenster steht?
"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"
Dein Code ist der übliche Arduino-Overkill, naja. Aber prinzipiell gibt
es da erstmal kein Problem mit Delays etc. D.h. auch mit 2 Timern sollte
das laufen, auch wenn man nur einen braucht.
Deine Timerinitialisierung stimmt nicht. Der Timer läuft normal im Mode
0 mit normalem Overflow bei 0xFFFF. Das manuelle Nachladen in der ISR
macht man beim AVR meistens nicht, schon gar nicht beim Vorteiler 1.
Dafür gibt es den CTC-Modus, der kann das automatisch.
1
staticcharDrehphase;//Static behält den Wert, auch wenn die Funktion beendet wurde -> permanent im Speicher wie globale Variable
Der Kommentar ist richtig, die Lage der Variablen aber nicht ;-)
Denn nur wenn sie innerhalb einer Funktion deklariert wird, ist es auch
eine lokale, statische Variable. Du hast sie aber außerhalb einer
Funktion geschrieben, damit ist sie eine globale Variable, welche nur
innerhalb der Datei sichtbar ist. Das ist was anderes.
digitalWrite() ist eine recht komplexe Unterfunktion, d.h. mit sehr
langer Laufzeit. Und dann noch 6 Aufrufe, da kann dem AVR leicht die
Puste ausgehen.
Besser ist es, die beiden Motoren auf jeweils 2 Ports zu legen und diese
dann mit einem direkten Zugriff zu laden.
Falk B. schrieb:> D.h. auch mit 2 Timern sollte> das laufen, auch wenn man nur einen braucht.
Du hast schon bemerkt, dass ein 500 ms Delay eingebaut ist? (Milli nicht
Mikro).
O.K., zu Test-Zwecken - aber was soll das. Dann versuche ich aber nicht
die Schritt-Motore per bit-banging mit CPU-Takt zu bewegen - oder habe
ich da etwas übersehen?
Peter D. schrieb:> digitalWrite() ist eine recht komplexe Unterfunktion, d.h. mit sehr> langer Laufzeit.
Jaja, es leben die Legenden! Wahrscheinlich mehrere Millisekunden, was?
Beitrag "Re: Suche jemanden mit Oszilloskop zum Optimieren von Signalleitungen"
7us sind nicht das Ende der AVR-Welt!
> Und dann noch 6 Aufrufe, da kann dem AVR leicht die> Puste ausgehen.
Käse^3!
Ich zitier mal den Herrn Nuhr "Wenn man keine Ahnung hat, . . ."
> Besser ist es, die beiden Motoren auf jeweils 2 Ports zu legen und diese> dann mit einem direkten Zugriff zu laden.
WOW! Da bist du ja schon der 2. oder 3. mit dem Expertentipp!
Rohrzange schrieb:> Falk B. schrieb:>> D.h. auch mit 2 Timern sollte>> das laufen, auch wenn man nur einen braucht.>> Du hast schon bemerkt, dass ein 500 ms Delay eingebaut ist? (Milli nicht> Mikro).
Das ist an der Stelle vollkommen unkritisch.
Allerdings ist der nichtatomare Zugriff auf die nicht volatile Variable
zahl viel kritischer 8-0
> O.K., zu Test-Zwecken - aber was soll das. Dann versuche ich aber nicht> die Schritt-Motore per bit-banging mit CPU-Takt zu bewegen
Tut er nicht.
>- oder habe> ich da etwas übersehen?
Ja. Timer 1 läuft mit Prescaler 256 und zählt von 65200 bis 65535, macht
85760 CPU-Takte bzw. eine Periodendauer von 5,3ms. Geht so, ist aber
schon recht flott.
Falk B. schrieb:> Tut er nicht.
Was denn?
Falk B. schrieb:> Ja. Timer 1 läuft mit Prescaler 256 und zählt von 65200 bis 65535, macht> 85760 CPU-Takte bzw. eine Periodendauer von 5,3ms. Geht so, ist aber> schon recht flott.
Sicher?
sicajo schrieb:> TCNT1 = Schwellwert;
O.K. Du bist der Experte.
Rohrzange schrieb:> Falk B. schrieb:>> Tut er nicht.>> Was denn?
Er taktet den Schrittmotor nicht mit Dutzenden kHz oder gar MHz, wie
dein Satz vermutete.
> Falk B. schrieb:>> Ja. Timer 1 läuft mit Prescaler 256 und zählt von 65200 bis 65535, macht>> 85760 CPU-Takte bzw. eine Periodendauer von 5,3ms. Geht so, ist aber>> schon recht flott.>> Sicher?
Ja, wenn der gezeigte Code auf dem Controller läuft.
> sicajo schrieb:>> TCNT1 = Schwellwert;>> O.K. Du bist der Experte.
Sieht so aus ;-)
Soo, ich hab das Konstrukt mal aufgeräumt.
1.) Variablen zur Kommunikation zwischen Hauptprogramm (loop()) und ISR
müssen volatile und atomar zugreifbar sein, siehe Interrupt.
2.) Timer 1 im CTC Mode ist bequemer und einfacher nutzbar.
3.) Lokale Variablen müssen lokal definiert werden!
4.) Zur Ansteuerung der Motoren nimmt man je nur eine Funktion und
übergibt die Richtung mit einem Parameter. Das spart Tipparbeit,
Quelltext (Übersicht) und vermeidet Fehler in doppelten Funktionen.
5.) Das Hauptprogramm übergibt an die ISR einen Schrittbefehl über die
Variablen schrittM1 und SchrittM2. Dann muss es entweder ausreichend
warten oder prüfen, ob die Variablen schon wieder 0 sind. Dann sind die
Schritte ausgeführt.
Hi,
ich weiß nicht ob ihr gegen mich oder euch gegenseitig schießt.
Falk B. schrieb:> Soo, ich hab das Konstrukt mal aufgeräumt.
Der Code ist super vielen dank dafür.
hab mich da mal Reingefuchst, habe aber noch ein paar fragen:
- wozu wurden die Funktionen vor dem Setup noch mal deklariert?
- in den Funktionen den schritt mit dem Phase + Step habe ich nicht ganz
verstanden
- wozu genau ist die variable flag_timer ?
Mfg
sicajo schrieb:> - wozu wurden die Funktionen vor dem Setup noch mal deklariert?
Genau darum. Weil eine Funktion entweder vor der ersten Verwendung
definiert sein muss (Die echte Funktion mit Inhalt) oder wenigstens
deklariert werden muss (Nur der Funktionskopf mit Parametern).
> - in den Funktionen den schritt mit dem Phase + Step habe ich nicht ganz> verstanden
Steht das nicht im Kommentar?
1
phase=(phase+step)&7;// Schritte addieren und Modulo 8 bilden
Man addiert den step und berechnet dann den Modulo Wert. D.h. wenn phase
+ step >7 oder <0 werden, gibt es einen Über/Unterlauf auf 0 oder 7.
Damit ist phase immer im Bereich 0-7. Die bitweise UND-Verknüpfung (&)
ist deutlich einfacher und schneller als eine echte Modulo Operation
(%), funktioniert aber nur bei 2er Potenzen. Man könnte es auch mit If
machen, das ist aber mehr Schreibarbeit.
1
phase=phase+step;
2
if(phase>7)phase-=7;
3
if(phase<0)phase+=7;
Hier müßte man phase dann aber als vorzeichenbehaftete Variable
definieren.
> - wozu genau ist die variable flag_timer ?
Für später ;-) Ich wollte da was anderes machen, hab mich dann aber
dagegen entschieden.
sicajo schrieb:> achso das habe ich auch nicht ganz verstanden>> if ( schrittM2 ) {
wenn man eine Variable "einfach so" hinschreibt, ist das die Kurzform in
C für
schrittM2 != 0
Siehe ein C-Buch deiner Wahl, Auswertung logischer Ausdrücke.
> Motor2(schrittM2);> schrittM2 = 0;> }
Also nur wenn schrittM2 != 0 ist, wird die Motorfunktion aufgerufen und
anschließend die Variable gelöscht.
Ah okay. Ich merk schon ich muss noch einiges lernen.
zwei fragen hätte ich zum Schluss noch
1. In den Funktionen ist die Variable "Step" was tut die und warum wird
sie zur Phase addiert ?
2. Warum laufen die Beiden Motoren jetzt synchron ? Ist das speziell
dein Code oder hatte ich das nicht richtig verstanden mit dem
gleichzeitig laufen lassen ?
Danke :)
Mfg
sicajo schrieb:> Ah okay. Ich merk schon ich muss noch einiges lernen.
In der Tat.
> 1. In den Funktionen ist die Variable "Step"
Das ist ein Funktionsparameter, deswegen steht die ja auch im
Funktionskopf!
> was tut die
Ja was wohl? Sie sagt der Funktion, ob der Motor einen Schritt vor oder
zurück laufen soll.
>und warum wird> sie zur Phase addiert ?
Weil das der aktuelle Stand des Motors ist?
> 2. Warum laufen die Beiden Motoren jetzt synchron ?
War das nicht das Ziel?
> Ist das speziell> dein Code
Sieht so aus.
> oder hatte ich das nicht richtig verstanden mit dem> gleichzeitig laufen lassen ?
Keine Ahnung.
Hi,
ich meinte weil die Variable Im Kopf der Funktion deklariert und dannach
direkt addiert wurde ohne einen wert. Das verwirrt mich etwas. Aber da
Sie ja auch farblich hinterlegt ist muss sie ja auch schon von selber
eine Funktion haben oder ?
Mfg
Wenn die Funktion mit step=+1 aufgerufen wird, erhöht sie die Phase bei
jedem Aufruf. Wobei der Modulus bewirkt, das nach 7 wieder die 0 kommt
(wie bei ein Zählwerk, dass überläuft).
Wenn sie mit step=-1 aufgerufen wird, verringert sich die Phase bei
jedem Aufruf. Wobei der Modulus bewirkt, das nach 0 wieder die 7 kommt
(wie bei ein Zählwerk, dass rückwärts überläuft).
Step bestimmt also, ob der Motor einen Schritt vorwärts oder Rückwärts
machen soll.
Holger schrieb:> Stefanus F. schrieb:>> step=+1>> step += 1>> bzw. weiter unten>> step -= 1>> :-)
Nein Holger, das habe ich schon ganz genau so gemeint, wie ich es
hingeschrieben habe. Ich denke nicht, dass die Motor-Funktionen von Falk
für andere Schrittweiten als +1 und -1 vorgesehen sind.
ich steh grad bissel auf dem schlauch. Verstehe ich das richtig dass,
phase + step immer der case ist in dem das Programm sich gerade
befindet. Wenn ja wozu brauche ich dann step
sicajo schrieb:> ich steh grad bissel auf dem schlauch. Verstehe ich das richtig> dass,> phase + step immer der case ist in dem das Programm sich gerade> befindet. Wenn ja wozu brauche ich dann step
Es gibt acht Phasen, mit denen der Motor angesteuert wird, also ach
unterschiedliche Kombinationen von Signalen. Diese müssen der Reihe nach
vorwärts oder Rückwärts durchlaufen werden, damit sich der Motor dreht.
Der step Parameter bestimmt, ob der nächste Schritt diese Phasen
vorwärts oder rückwärts durchläuft.
In Falks Code ist sehr deutlich zu sehen, dass die Phase in der
switch-case Anweisung ausgewertet wird und dass es acht Phasen gibt.
Step wird zur Phase addiert. Da Step nur die Werte 1 oder -1 haben darf,
wird beim nächsten Schritt die Phase um eins erhöht oder verringert.
Step bestimmt also die Laufrichtung des Motors.
sicajo schrieb:> Hi,>> ich meinte weil die Variable Im Kopf der Funktion deklariert und dannach> direkt addiert wurde ohne einen wert. Das verwirrt mich etwas.
Ja, weil du nicht mal eine hauchdünne Ahnung von C hast. Das kann man
aber durch lesen und verstehen eines C-Buches ändern.
sicajo schrieb:> ich steh grad bissel auf dem schlauch. Verstehe ich das richtig dass,> phase + step immer der case ist in dem das Programm sich gerade> befindet. Wenn ja wozu brauche ich dann step
Bist du so merkbefreit oder ein Troll?
Wieso bist du denn jetzt so gemein?
Bist du mit Profi Programmierkenntnissen geboren ? Wage ich stark zu
bezweifeln. Nichts desto trotz danke für die Hilfe.
Sicajo schrieb:> Wieso bist du denn jetzt so gemein?
Ich glaube, er hat das nicht böse gemeint. Aber es dich damit wach
rütteln und dir klar machen, dass du dich mit diesem Projekt übernommen
hast. In Zeiten, wo alle im Internet immer "so einfach geht das"
präsentieren, ist das leider ein zunehmendes Problem.
Mir war es zuerst bei Koch-Rezepten im TV aufgefallen. O-Ton "Ich habe
da mal etwas vorbereitet". Danach griff es auf die Bücher über und jetzt
eben auch aufs Internet. Alle wollen nur noch behaupten "schau mal, ich
bin ein Superheld, ich kann das ganz schnell und für mich ist das ganz
einfach". Die Leute lügen, was das Zeug hält. Sie wollen damit nur
Klicks sammeln bzw. ihre Bücher verkaufen.
(Falls du ein ehrliches Kochbuch suchst: Das Dr. Ötker Schulkochbuch)
Fang klein an und arbeite ein Grundlagenbuch für C durch.
Wenn du 3 LED's unabhängig voneinander in unterschiedlichen Rythmen
blinken lassen kannst (ohne Quellcode zu kopieren) bist du schon einen
großen Schritt weiter. Danach fragst du zuerst einzelne Tasten (später
eine Tastenmatrix) ab, die das Blinkmuster umschaltet.
Aber bilde Dir nicht ein, dass du das mit 2-3 Programmen an drei
Wochenenden hinbekommen wirst. Da tastet man sich schrittweise heran.
Wenn du dafür letztendlich 50 Programme schreibst, ist das durchaus
normal.
sicajo schrieb:> kennst du denn ein gutes C Buch?
Leider nein. Das Buch das ich lange empfohlen hatte bekommt man nicht
einmal mehr im Antiquariat. Was da aktuell gut ist, weiß ich nicht.
sicajo schrieb:> ich meinte weil die Variable Im Kopf der Funktion deklariert und dannach> direkt addiert wurde ohne einen wert. Das verwirrt mich etwas. Aber da> Sie ja auch farblich hinterlegt ist muss sie ja auch schon von selber> eine Funktion haben oder ?
Falls Du damit die Variable 'phase' in den Funktionen Motor1()/Motor2()
meinst: die wird sehr wohl initialisiert - und zwar automatisch mit dem
Wert 0 (wegen der 'storage class' 'static')
static uint8_t phase;
ist also dasselbe wie
static uint8_t phase = 0;
Hi
Werde ich mal Rum stöbern, ob ich ein passables finde. Ich würde zwar
nicht behaupten ich bin Anfänger, habe mich aber jedoch nie wirklich
richtig damit befasst, sondern nur das was ich gerade gebraucht habe.
Denke das ist das Problem und wird mal Zeit. Mal was anderes. Trau mich
gar nicht zu fragen aber der OCR Wert "Timer_period" liegt bei 20000. Im
Datenblatt Das Register hat 16Bit sprich 65536. Wie verhält sich der
Wert zum Motor ? Da ich merke dass bei weitem nicht die ganze Kraft vom
Motor benutzt wird. Sobald ich an diesem wert drehe passiert nicht
wirklich was bis auf das der Motor Wackelt und Vibriert
Mfg
sicajo schrieb:> Hi> Werde ich mal Rum stöbern, ob ich ein passables finde. Ich würde zwar> nicht behaupten ich bin Anfänger,
Wer nicht mal die Grundzüge von Funktionen und deren Parametern
verstanden hat, IST totaler Anfänger!
> habe mich aber jedoch nie wirklich> richtig damit befasst, sondern nur das was ich gerade gebraucht habe.
So sieht's aus. Nie auch nur ansatzweise ein paar elementare Grundlagen
verstanden und mit mehr Glück als Verstand irgendwie irgendwas zustande
bekommen. Vor allem mit Copy & Paste.
> Denke das ist das Problem und wird mal Zeit.
Genau.
> Mal was anderes. Trau mich> gar nicht zu fragen aber der OCR Wert "Timer_period" liegt bei 20000. Im> Datenblatt Das Register hat 16Bit sprich 65536.
Das ist der mögliche Maximalwert! Man darf da auch kleinere Zahlen
reinschreiben!
> Wie verhält sich der> Wert zum Motor ?
Er bestimmt die Frequenz der Timer-ISR. Der Timer zählt diese Anzahl von
Takten und löst dann einen Interrupt aus. Kleinerer Wert, kleinere
Periodendauer, größere Frequenz. Pro Interrupt macht der Motor maximal
einen Schritt, so ist es im Moment programmiert.
> Da ich merke dass bei weitem nicht die ganze Kraft vom> Motor benutzt wird.
Wieso? Wie stellst du das fest?
> Sobald ich an diesem wert drehe passiert nicht
Was drehst du denn da? Auf welchen Wert verstellst du das? Wenn der Wert
und damit die Periodendauer zu klein wird, verschluckt der Motor
Schritte und wird schwächer.
Falk B. schrieb:> Das ist der mögliche Maximalwert! Man darf da auch kleinere Zahlen> reinschreiben!
wäre der Maximalwert bei einem 16Bit Register nicht 65000?
> Wieso? Wie stellst du das fest?
der Code den ich vorher hatte, hat mehr Kraft am Motor bewirkt und war
auch schneller
> Was drehst du denn da? Auf welchen Wert verstellst du das? Wenn der Wert> und damit die Periodendauer zu klein wird, verschluckt der Motor> Schritte und wird schwächer.
hab den wert erhöht.Wird wohl der Fehler sein wie du gesagt hast, wenn
20000 der Maximalwert ist.
sicajo schrieb:> Falk B. schrieb:>>> Das ist der mögliche Maximalwert! Man darf da auch kleinere Zahlen>> reinschreiben!>> wäre der Maximalwert bei einem 16Bit Register nicht 65000?
Das Troll-O-Meter schläglt schon wieder mächtig aus!
>> Wieso? Wie stellst du das fest?>> der Code den ich vorher hatte, hat mehr Kraft am Motor bewirkt und war> auch schneller
Glaub ich eher nicht.
> hab den wert erhöht.Wird wohl der Fehler sein wie du gesagt hast, wenn> 20000 der Maximalwert ist.
OK, jetzt bist du endgültig bei 100% Trollfaktor angekommen.
Glückwunsch! Und noch viel Spaß dabei.