Zwei Interrupts gleichzeitig Laufen

Gast #5837904
Lesenswert?

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 
:)
1
 
2

3
uint16_t Schwellwert = 65400;
4
uint16_t Schwellwert1 = 65400;
5

6
void setup() 
7
{ 
8
 noInterrupts();
9
  
10
  TCCR1A = 0;
11
  TCCR1B = 0;
12

13
  TCCR2A = 0;
14
  TCCR2B = 0;
15

16
  TCNT1 = Schwellwert;
17
  TCCR1B |= (1 << CS12);
18
  TIMSK1 |= (1 << TOIE1);
19

20
  TCNT2 = Schwellwert1;
21
  TCCR2B |= (1 << CS12);
22
  TIMSK2 |= (1 << TOIE1);
23
  
24
  interrupts();
25

26

27
}
28
void loop()
29
{
30

31
  // Motor_Rueckwaerts_Links();
32
  // Motor_Rueckwaerts_Rechts();
33

34
  // Motor_Vorwaerts_Links();
35
  // Motor_Vorwaerts_Rechts();
36

37
  // Motor_Aus();
38

39
}
40

41

42
ISR(TIMER1_OVF_vect)
43
{
44
  TCNT1 = Schwellwert;
45
  
46
  Motor_Rueckwaerts_Rechts();
47

48
}
49

50

51
ISR(TIMER2_OVF_vect)
52
{
53
  TCNT2 = Schwellwert1;
54

55
  Motor_Rueckwaerts_Links();
56
}
Gast #5838001
Lesenswert?

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.
Gast #5838117
Lesenswert?

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...
Gast #5838340
Lesenswert?

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
Gast #5838924
Lesenswert?

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
Gast #5838930
Lesenswert?

> Also der µC ist ein Atmega328P
Und dann bringt der Compiler keine Warnung bei
1
  TCNT2 = Schwellwert1;
?

> Schwellwert1 muss uint8_t heißen wobei das denke ich kein unterschied macht 
oder?
Bei
1
Schwellwert1 = 65400;
?
Gast #5838939
Lesenswert?

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.
Gast #5838979
Lesenswert?

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...
Gast #5838982
Lesenswert?

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?
Gast #5838997
Lesenswert?

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.
Gast #5839025
Lesenswert?

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
Gast #5839038
Lesenswert?

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.
#5839053
Lesenswert?

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.
#5839057
Lesenswert?

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.
Gast #5839060
Lesenswert?

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.
Gast #5839270
Lesenswert?

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.
Gast #5839448
Lesenswert?

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?
Gast #5839665
Lesenswert?

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!
#5839762
Lesenswert?

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
Gast #5839810
Lesenswert?

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
int zahl = 0;
21

22
uint16_t Schwellwert = 65200;  // Vergleichswert Für 16 Bit Register .
23

24
void setup() {
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
void loop()
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
static char Drehphase; //Static behält den Wert, auch wenn die Funktion beendet wurde -> permanent im Speicher wie globale Variable
5

6
void Motor_Vorwaerts_Links() {
7

8
  switch (Drehphase)
9
  {
10
    case 0:
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
    case 1:
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
    case 2:
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
    case 3:
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
    case 4:
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
    case 5:
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
    case 6:
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
    case 7:
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
void Motor_Vorwaerts_Rechts() {
108

109
  switch (Drehphase)
110
  {
111

112
    case 0:
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
    case 1:
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
    case 2:
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
    case 3:
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
    case 4:
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
    case 5:
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
    case 6:
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
    case 7:
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
void Motor_Rueckwaerts_Links() {
210

211
  switch (Drehphase)
212
  {
213
    case 0:
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
    case 1:
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
    case 2:
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
    case 3:
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
    case 4:
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
    case 5:
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
    case 6:
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
    case 7:
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
void Motor_Rueckwaerts_Rechts() {
306

307
  switch (Drehphase)
308
  {
309
    case 0:
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
    case 1:
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
    case 2:
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
    case 3:
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
    case 4:
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
    case 5:
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
    case 6:
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
    case 7:
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
void Motor_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
Gast #5839899
Lesenswert?

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.
Gast #5839906
Lesenswert?

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.
Gast #5839927
Lesenswert?

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.
Angehängte Dateien:
#5840103
Lesenswert?

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
static char Drehphase; //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.
Gast #5840179
Lesenswert?

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?
#5840185
Lesenswert?

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!
#5840191
Lesenswert?

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.
#5840210
Lesenswert?

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 ;-)
Beitrag #5840298 wurde von einem Moderator gelöscht.
#5840324
Lesenswert?

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.
Angehängte Dateien:
Gast #5841569
Lesenswert?

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
#5841638
Lesenswert?

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.
#5841639
Lesenswert?

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.
Gast #5842593
Lesenswert?

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
#5842621
Lesenswert?

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.
Gast #5842732
Lesenswert?

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
Gast #5842776
Lesenswert?

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.
Gast #5842797
Lesenswert?

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.
Gast #5842839
Lesenswert?

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.
Gast #5843128
Lesenswert?

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.
Gast #5843369
Lesenswert?

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;
#5843416
Lesenswert?

Gast #5843638
Lesenswert?

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
#5843686
Lesenswert?

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.
Gast #5843726
Lesenswert?

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.
#5843864
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren