Forum: Mikrocontroller und Digitale Elektronik Schrittfrequenz für Schrittsequens?


von Huber M. (michael_h784)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte einen Schrittmotor ganz simpel ansteuern. Um mir einmal etwas 
richtig darunter vorstellen zu können. Und zwar möchte ich zu 
nachfolgenden Code anstatt des delays eine Funktion erstellen zb. 
motorspeed... Um die Geschwindigkeit zu regeln, dazu brauche ich die 
Startfrequenz und die Maximale Schrittfrequenz. Aber ich habe keine 
Ahnung wie ich dies umsetzen soll bzw. darauf komme. Denn ich kann mir 
einfach nichts daruter vorstellen.

soweit ich das verstanden habe hängt die Gechwindigkeit von der 
Geschwindigkeit der Schritt-sequence ab. Und wie ich im Forum Avr- 
tutorial hier gelesen habe ist das, mit delay zu lösen, der schlechteste 
fall. Die Frequenz soll wie zb. eine Ladekurve ansteigen?

Wie könnte jetzt für nachfolgenden Code eine Lösung aussehen.

Im Bild oben eine kleine Übersicht. Ich versorge den Motor momentan mit 
+5V

hier Datenblatt Motor.:
[[http://www.raspberrypi-spy.co.uk/wp-content/uploads/2012/07/Stepper-Motor-28BJY-48-Datasheet.pdf]]

Datenblatt Treiber.:
[[http://www.ti.com/lit/ds/symlink/uln2003a.pdf]]

Code.:
1
*SchrittFrequenz.c
2
 *
3
 * Created: 26.01.2017 09:04:19
4
 *  Author: USER
5
 */ 
6
7
#define F_CPU 1000000UL
8
#include <util/delay.h>
9
#include <avr/io.h>
10
11
// MOTORPINS HIGH
12
#define motorpin1_HIGH (PORTD |= (1<<PD0))  // ORANGE  IN1
13
#define motorpin2_HIGH (PORTD |= (1<<PD1))  // GELB    IN2
14
#define motorpin3_HIGH (PORTD |= (1<<PD2))  // VIOLETT IN3
15
#define motorpin4_HIGH (PORTD |= (1<<PD3))  // BLAU    IN4
16
17
// MOTORPINS LOW
18
#define motorpin1_LOW (PORTD &= ~(1<<PD0))  // ORANGE  IN1
19
#define motorpin2_LOW (PORTD &= ~(1<<PD1))  // GELB    IN2
20
#define motorpin3_LOW (PORTD &= ~(1<<PD2))  // VIOLETT IN3
21
#define motorpin4_LOW (PORTD &= ~(1<<PD3))  // BLAU    IN4
22
23
// SCHRITTFREQUENZ
24
#define Schrittfrequenz 100
25
26
int main(void)
27
{    // AUSGÄNGE für MOTORSTEUERUNG
28
  DDRD |= 0x0F;
29
  
30
  // Funktion Sequenz Uhrzeigersinn
31
  
32
  void Rechts (void)
33
  {
34
    //1
35
    motorpin1_HIGH;
36
    motorpin2_LOW;
37
    motorpin3_LOW;
38
    motorpin4_LOW;
39
    _delay_ms(Schrittfrequenz);
40
    //2
41
    motorpin1_HIGH;
42
    motorpin2_HIGH;
43
    motorpin3_LOW;
44
    motorpin4_LOW;
45
    _delay_ms(Schrittfrequenz);
46
    //3
47
    motorpin1_LOW;
48
    motorpin2_HIGH;
49
    motorpin3_LOW;
50
    motorpin4_LOW;
51
    _delay_ms(Schrittfrequenz);
52
    //4
53
    motorpin1_LOW;
54
    motorpin2_HIGH;
55
    motorpin3_HIGH;
56
    motorpin4_LOW;
57
    _delay_ms(Schrittfrequenz);
58
    //5
59
    motorpin1_LOW;
60
    motorpin2_LOW;
61
    motorpin3_HIGH;
62
    motorpin4_LOW;
63
    _delay_ms(Schrittfrequenz);
64
    //6
65
    motorpin1_LOW;
66
    motorpin2_LOW;
67
    motorpin3_HIGH;
68
    motorpin4_HIGH;
69
    _delay_ms(Schrittfrequenz);
70
    //7
71
    motorpin1_LOW;
72
    motorpin2_LOW;
73
    motorpin3_LOW;
74
    motorpin4_HIGH;
75
    _delay_ms(Schrittfrequenz);
76
    //8
77
    motorpin1_HIGH;
78
    motorpin2_LOW;
79
    motorpin3_LOW;
80
    motorpin4_HIGH;
81
    _delay_ms(Schrittfrequenz);
82
    
83
   }
84
   
85
   // MOTORSTOP
86
     void motorstop(void)
87
   {
88
     motorpin1_LOW;
89
     motorpin2_LOW;
90
     motorpin3_LOW;
91
     motorpin4_LOW;
92
   }
93
   
94
    while(1)
95
    {
96
        //TODO:: Please write your application code 
97
    }
98
}

Danke fürs lesen Grüsse Huber

: Verschoben durch User
von Paddy (Gast)


Lesenswert?

Verstehst du auch warum ein delay besser nicht benutzt werden kann ?
Weil man dann zwischendurch schwierig etwas anderes machen kann zb 
kommunikation oder display update.

Ich weisz nicht welchen uP du benutzt (Pi?) aber zB fuer Arduino gibt es 
die funktion millis(). Solche funktionen gibt es auch fuer Pi oder du 
kannst die selber schreiben.

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

von Huber M. (michael_h784)


Lesenswert?

Oh, da ist die Auflösung wohl zu schlecht. Der code wird mit AtmelStudio 
6.2 erstellt und auf einen Atmega88PA geschrieben:

Paddy schrieb:
> Verstehst du auch warum ein delay besser nicht benutzt werden kann ?
> Weil man dann zwischendurch schwierig etwas anderes machen kann zb
> kommunikation oder display update.

so in der art dachte ich es mir schon.

von aSma>> (Gast)


Lesenswert?

Huber M. schrieb:
> Um die Geschwindigkeit zu regeln, dazu brauche ich die
> Startfrequenz und die Maximale Schrittfrequenz. Aber ich habe keine
> Ahnung wie ich dies umsetzen soll bzw. darauf komme. Denn ich kann mir
> einfach nichts daruter vorstellen.

Das ist schon ein Komplexes Thema. Hier hast du was zum Lesen:
http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time

Mit diesen Motor und Treiber wirst du auf langer Sicht nicht glücklich. 
Die Maximale Frequenz findest du heraus druch ausprobieren. Diese wird 
nicht allzu hoch sein, da du ein Gertriebe hast. Bei höheren Drehzahlen 
hat man einfach kein Drehmoment mehr.

Schrittmotoren müssen mit einer Rampe angesteuert werden. Ist die 
Startfrequenz zu hoch, dann kommt der Motor aus dem Takt, verliert 
Schritte oder macht Geräusche und dreht sich einfach nicht.

von Huber M. (michael_h784)


Lesenswert?

aSma>> schrieb:
> Schrittmotoren müssen mit einer Rampe angesteuert werden. Ist die
> Startfrequenz zu hoch, dann kommt der Motor aus dem Takt, verliert
> Schritte oder macht Geräusche und dreht sich einfach nicht.

Da ich das ganze neben bei auch mit einem Arduino testen will. Weil ich 
mich da einfach leichter tue Sachen zu durchblicken. Jetzt dachte ich, 
ich mache mir auf dem Arduino mal etwas mit einem Timer. Jetzt komme ich 
mit dem einfachsten nicht klar, Und Zwar kann mir jemand sagen, wie ich 
""x = 1;"" richtig Eintrage, denn wenn ich das wie beim Atmelstudio 
mache, dann Kompiliert er es mir nicht.Wo liegt mein Fehler? ich glaube 
beim erneut vorwegladen??

das wäre jetzt so eingestellt das es mir alle 0,5s ein Interrupt 
aufruft. Und dann soll x = 1; sein.

hier hätte ich mal den Code..AM Arduino Board
1
 volatile int x = 0;
2
 int b = 0;
3
4
void setup()
5
{ 
6
  Serial.begin(9600);
7
8
   // Timer 1
9
  noInterrupts();           // Alle Interrupts temporär abschalten
10
  TCCR1A = 0;
11
  TCCR1B = 0;
12
13
  TCNT1 = 34286;            // Timer nach obiger Rechnung vorbelegen
14
  TCCR1B |= (1 << CS12);    // 256 als Prescale-Wert spezifizieren
15
  TIMSK1 |= (1 << TOIE1);   // Timer Overflow Interrupt aktivieren
16
  interrupts();             // alle Interrupts scharf schalten
17
}
18
// Hier kommt die selbstdefinierte Interruptbehandlungsroutine 
19
// für den Timer Overflow
20
ISR(TIMER1_OVF_vect)        
21
{
22
  TCNT1 = 34286;              
23
  x = 1;
24
}
25
26
void loop()
27
{
28
  if(x == 1)
29
  {
30
    b ++;
31
  }
32
   if( b >= 500)
33
  {
34
    b = 0;
35
  }
36
  
37
 Serial.println(b);
38
}

von posti (Gast)


Lesenswert?

Hi

Selber kein Arduino, kein C

Liest sich so, daß beim ersten Overflow vom Timer 1 der Zählerwert auf 
den berechneten Startwert gesetzt wird (damit nach der gleichen Anzahl 
an Takten der nächste Interrupt zuschlägt).
Hier würde ich den Startwert als Variabel übergeben oder in ein Register 
packen - damit kannst Du die Geschwindigkeit einstellen.

Weiter wird X auf 1 gesetzt - da verbleibt das X auch bis der Strom 
abgestellt wird.
Denke, in Deiner Abfrage if X==1 gehört noch ein X=0 zum 'Flag löschen'.

Auch sehe ich nicht, wo der Motor angesprochen wird.

Bis jetzt scheint Dein Programm bis zum ersten OVL zu warten und dann 
ratz-fatz B immer wieder bis 500 hochzuzählen.

MfG

von Huber M. (michael_h784)


Lesenswert?

posti schrieb:
> Bis jetzt scheint Dein Programm bis zum ersten OVL zu warten und dann
> ratz-fatz B immer wieder bis 500 hochzuzählen.

danke das mit dem Timer hat sich geklärt. Das hochzählen auf 500 und 
reset, war nur ein test, ob das zählen funktioniert.Mache es jetzt mit 
Atmelstudio 6.2 Und Atmega88PA

posti schrieb:
> Auch sehe ich nicht, wo der Motor angesprochen wird.

Genau das war die ursprüngliche Frage zum 1.Th wie dies aussehen könnte, 
bei obengenannten Code.

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

Hallo Huber,

> aSma>> schrieb:
>> Schrittmotoren müssen mit einer Rampe angesteuert werden. Ist die
>> Startfrequenz zu hoch, dann kommt der Motor aus dem Takt, verliert
>> Schritte oder macht Geräusche und dreht sich einfach nicht.
>
> Da ich das ganze neben bei auch mit einem Arduino testen will. Weil ich
> mich da einfach leichter tue Sachen zu durchblicken. Jetzt dachte ich,
> ich mache mir auf dem Arduino mal etwas mit einem Timer.

Für Arduino gibt es die Accelstepper.lib:
http://www.schrittmotor-blog.de/ansteuern-von-schrittmotoren-mit-arduino/
Du kannst dir die Sourcen der Lib ja ansehen, nachdem du den Motor am 
Laufen hast. Den ULN würde ich aber so bald wie möglich in die Ecke 
werfen. Da sind ja selbst schlechte Motor-Shields besser geeignet, so 
lange man sich von den angepriesenen Maximalströmen fern hält.

Mit freundlichen Grüßen
Thorsten Ostermann

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.