Forum: Mikrocontroller und Digitale Elektronik Schrittmotoransteuerung mit ATmega 128


von Kay L. (king-kay)


Angehängte Dateien:

Lesenswert?

Hey,

Ich hab micht mit der ansteuerung eines Schrittmotors beschäftigt. Und 
ein ganz einfaches Programm geschrieben-- aber er dreht sich einfach 
nicht.
Könnt ihr mir bitte helfen.
Danke im Vorraus.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Kay L. schrieb:
> Hey,
>
> Ich hab micht mit der ansteuerung eines Schrittmotors beschäftigt. Und
> ein ganz einfaches Programm geschrieben-- aber er dreht sich einfach
> nicht.
> Könnt ihr mir bitte helfen.
> Danke im Vorraus.

Als Erstes solltest Du uns mitteilen, welche Leitungen Du wo 
angeschlossen hast und was für ein Schrittmotor das ist - wir haben 
keine Glaskugel :-)

Ein Fehler ist schonmal, dass Du das Datenrichtungsregister (DDRD) mit 
den Werten des Arrays beschreibst. Das sollte aber wohl eher PORTD, also 
das Ausgangsregister, sein.

Außerdem enthält Dein Array nur vier Werte, Du liest aber in jeder 
Schleife zehn Werte aus.

Und: i kann als unsigned int nie kleiner als 0 werden, die zweite 
Schleife wird also nie beendet ...

Näheres gibt es bei mehr Infos :-)

Chris D.

von Kay L. (king-kay)


Angehängte Dateien:

Lesenswert?

Hey,
Stimmt sorry, im Anhang liegen noch die Daten vom Schrittmotor vom QMOT 
Motor QSH2818

Port D 2  schwarz
Port D 3  grün
Port D 4  rot
Port D 5  blau

Wie könnt ich die denn verändern das sie beendet wird??

MFG

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Kay L. schrieb:
> Hey,
> Stimmt sorry, im Anhang liegen noch die Daten vom Schrittmotor vom QMOT
> Motor QSH2818
>
> Port D 2  schwarz
> Port D 3  grün
> Port D 4  rot
> Port D 5  blau

Ok, also gehören PD2 und PD3 und PD4 und PD5 je zu einer Spule.

Offensichtlich handelt es sich um einen bipolaren Motor. Du musst also 
die Spannungsrichtungen jeder Spule umschalten können.
Laut Datenblatt arbeitet der Motor mit max. 0,7A - Du benötigst also 
einen Treiberbaustein, da der AVR das nicht packt; beispielsweise einen 
L298, L6219 etc.

Im Vollschrittbetrieb (bei Deinem Motor also 1,8°-Schritte) werden immer 
beide Spulen bestromt und dann entsprechend nacheinander umgeschaltet:

1.Schritt: PD2=ein, PD3=aus, PD4=ein, PD5=aus
2.Schritt: PD2=aus, PD3=ein, PD4=ein, PD5=aus
3.Schritt: PD2=aus, PD3=ein, PD4=aus, PD5=ein
4.Schritt: PD2=ein, PD3=aus, PD4=aus, PD5=ein

Dual sieht das für Deinen Port D also so aus:
1.Schritt: 0b00010100 = 0x14
2.Schritt: 0b00011000 = 0x18
3.Schritt: 0b00101000 = 0x28
4.Schritt: 0b00100100 = 0x24

Ich nehme mal an, dass Du an PA0 einen Taster hängen hast, der die 
Drehrichtung ändern soll.
Im Prinzip ist es schon ok, das Array einmal von links nach rechts und 
dann von rechts nach links zu durchlaufen. Ich würde aber einfach i auf 
Unterlauf abfragen:

1
#include <avr/io.h>
2
3
void warten(void);
4
5
// char reicht - wir haben ja nur vier Werte
6
unsigned char i;
7
8
// Die Werte von oben eingesetzt
9
unsigned char tab1[] = {0x14, 0x18, 0x28, 0x24};
10
11
int main (void)
12
{
13
  DDRA = 0x00;  // IN 
14
  DDRD = 0xff;  // OUT
15
16
  while (1)
17
  {
18
    if (PINA & (1 << PA0)) 
19
    {
20
      for (i=0; i<4; i++)
21
      {
22
        PORTD = tab1 [i];
23
        warten (); 
24
      }
25
    }
26
    else
27
    {
28
      // Wenn wir bei i=0 eins abziehen, wird i=255
29
      for (i=3; i<255; i--)
30
      {  
31
        PORTD = tab1 [i];
32
        warten ();
33
      }
34
    }
35
  }
36
  return 0;
37
}
38
39
// Warteschleife
40
// (nicht schön - so etwas macht man besser mit _delay_us etc.)
41
void warten (void)
42
{
43
  unsigned long p;
44
  for (p=0; p<0x1fff; p++);
45
}


Ich hoffe, ich hab nix vergessen - ist einfach so runtergeschrieben ;-)

Chris D.

von Kay L. (king-kay)


Angehängte Dateien:

Lesenswert?

Hey du,
ich hab das Programm abgeschrieben, aber es tut nicht--langsam bin ich 
am verzweifeln.

Ich hab den L298 als Treiberbaustein auf einer Externen Platine gelötet.
Anbei häng ihr dir den Schaltplan von meiner Platine. Ich habe alles 
durch gemessen Ein und Ausgänge sollten gehn.

MFG kay

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Kay L. schrieb:
> Hey du,

Redet man sich bei Euch so an?
Hier sagt man "Hallo Kay"

> ich hab das Programm abgeschrieben, aber es tut nicht--langsam bin ich
> am verzweifeln.
>
> Ich hab den L298 als Treiberbaustein auf einer Externen Platine gelötet.
> Anbei häng ihr dir den Schaltplan von meiner Platine. Ich habe alles
> durch gemessen Ein und Ausgänge sollten gehn.

Natürlich kann das so auch nicht funktionieren, weil Du nicht erwähnt 
hattest, dass PD0 und PD1 die Enable-Eingänge für den L298 sind und 
dementsprechend gesetzt (=1) sein müssen, damit der Motor überhaupt 
irgendetwas macht.
Bit 0 und Bit 1 von PORTD müssen also immer gesetzt sein, wenn der Motor 
sich bewegen soll. Die Array-Werte musst Du dementsprechend anpassen.

Chris D.

von Kay L. (king-kay)


Lesenswert?

Hallo Chris,

reicht das denn wenn ich einfach bevor ich den Motoransteuerung 
schreibe:

          PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);?

MFG Kay

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Nein, denn Du überschreibst die beiden gesetzten Bits ja durch die Bytes 
aus dem Array.
Du musst die Bits 0 und 1 doch einfach nur im Array in jedem Byte setzen 
- fertig.

Chris

von Kay L. (king-kay)


Lesenswert?

Habe ich gemacht und die Hex-zahlen umgeschrieben --aber es tut trotzdem 
nichts
Gruß Kay

von Peter (Gast)


Lesenswert?

>// Warteschleife
>// (nicht schön - so etwas macht man besser mit _delay_us etc.)
>void warten (void)
>{
>  unsigned long p;
>  for (p=0; p<0x1fff; p++);
>}

Das ist nicht nur unschön, es wird auch nicht funktionieren, der 
Optimizer schmeisst die ganze Warteschlaufe raus, weil sie aus 
Optimizersicht nichts bewirkt! Der Schrittmotor wird mit Sicherheit viel 
zu schnell getaktet und kommt gar nicht zum drehen...

Wenn es schon sein muss, das Zauberwort heisst "volatile"

void warten (void)
{
  volatile unsigned long p;
  for (p=0; p<0x1fff; p++);
}

Oder wie Du selber im Kommentar vorschlägst, verwende doch besser mal 
die _delay_us() oder _delay_ms() Funktion!

=> _delay_ms(2) // 500Hz Schrittfrequenz ist für den Anfang sicher ok

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Dann würde ich zuallererst einmal die Leitungen "durchklingeln", also 
ein kleines Programm schreiben, dass die Ausgänge PD0-PD7 setzt, z.B. so

unsigned char by;
while (1)
{
  PORTD = by;
  by++;
}

und dann mal mit dem Oszilloskop gucken, ob die entsprechenden Eingänge 
des L298 auch wirklich angesteuert werden.
Wenn kein Oszi vorhanden, dann eine Warteschleife einbauen und per 
Leuchtdiode messen.

Ansonsten sehe ich keinen Fehler.

Chris D.

@Peter: Recht haste - ich mache das immer ganz sauber über 
Timerinterrupts, dann stimmen die verzögerungen auch halbwegs :-)

von Olof G. (ole)


Lesenswert?

Moin (Das sagt man bei uns, den ganzen Tag und auch die Nacht ;) )

Also zum Thema, bei solchen Problem nehme ich immer ein paar LED´s und 
gucke mal ob überhaupt was aus dem AVR rauskommt.

Besonders gern laß ich nen Timer (wenn frei) einfach laufen und toggle 
in einer Interruptroutine einen Pin. Da kommt auch eine LED dran und 
schon weiß man, dass der µC prinzipiell läuft. Weiter ist so recht 
sicher, dass das Programm fehlerfrei auf dem AVR gelandet ist.


Evtl. ist das alles selbstverständlich, evtl aber auch nicht ;)


Vielleicht hilft es ja

Grüße aus Hamburg

von Kay L. (king-kay)


Lesenswert?

Hab das Programm geändert und eine LED angeschlossen am Ausgang passiert 
nichts, aber wenn ich direkt an das ATmeaga 128 Board klemme blinkt die 
LED.Aber auch nur am PIN 0-3. Ich denke das der Motortreiber defekt ist. 
Oder habt ihr noch ne andere Idee?

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.