Forum: Mikrocontroller und Digitale Elektronik L6208 - Mikroschrittbetrieb


von Timo (Gast)



Lesenswert?

Hallo,

ich habe momentan einen mächtigen Black Out und benötige Hilfe bei der 
Realisierung des Mikroschrittbetriebs mit einem L6208.

Ich habe die Schaltung entsprechend des L6208 Datenblatts aufgebaut und 
die VRef Anschlüsse mit der PWM-Beschaltung versehen (die aus der AN 
1495 Microstepping, siehe Bild). Dann habe ich ein Programm geschrieben, 
dass ein Sinussignal ausgibt. Der Verlauf habe ich ebenfalls als Bild 
angehängt. Ein Clock-Signal (High) kommt immer dann, wenn einer der 
beiden Kurven sein Maximal oder Minimum erreicht.

Das Ergebnis ist ein ruckelnder, tanzender und pfeifender Schrittmotor 
(der ist laut DB mikroschritttauglich). Von einem schönen, leisen 
Mikroschrittbetrieb ist das ganz weit entfernt!

Zufälligerweise habe ich jetzt mal in die AN 1451 (da wird erklärt wie 
eine Schaltung für V/H-Schrittbetrieb aussieht) angeschaut. Dort wird 
auch kurz das Thema Mikroschritt angesprochen. Dort wird die gleiche 
PWM-Beschaltung, jedoch mit ganz anderen Bauteilwerten, verwendet (Siehe 
Bild 3).

Außerdem fand ich eine Formel für die Berechnung für VrefA, was wohl das 
PWM-Signal für den VrefA-Eingang sein soll. Dort steht Imax x Rsense = 
VrefA. In meinem Fall wäre dies 1A x 0,25Ohm = 0,25V.

Meine Frage ist daher, ob mein PWM Signal von bis zu 5V nicht viel zu 
hoch ist? Und welcher der beiden PWM-Beschaltung richtig ist? Oder 
benötige ich ganz andere Bauteilwerte für meine Zwecke?

Ich freue mich über jede Hilfe, da ich echt feststecke und nicht mehr 
weiter weiß.

Ach ja, erschwerend kommt hinzu, dass ich kein Oszilloskop besitze. Das 
macht es nicht gerade leichter - ich weiß :(

PS: Ich hänge mal meinen bisherigen Code dran (ich hoffe, das klappt), 
das macht es vielleicht einfache mein Problem zu finden.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define F_CPU 16000000UL 
5
6
volatile uint8_t duty_cycle;
7
volatile uint8_t i;
8
const int duty[64]= {127,139,152,164,176,187,198,208,217,225,233,239,244,249,252,253,254,253,252,249,244,239,233,225,217,208,198,187,176,164,152,139,127,115,102,90,78,67,56,46,37,29,21,15,10,5,2,1,0,1,2,5,10,15,21,29,37,46,56,67,78,90,102,115};
9
const int duty2[64]={254,253,252,249,244,239,233,225,217,208,198,187,176,164,152,139,127,115,102,90,78,67,56,46,37,29,21,15,10,5,2,1,0,1,2,5,10,15,21,29,37,46,56,67,78,90,102,115,127,139,152,164,176,187,198,208,217,225,233,239,244,249,252,253};
10
11
 void timer1_init()
12
{
13
    // set up timer with prescaler = 64 and CTC mode
14
    TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);
15
 
16
    // initialize counter
17
    TCNT1 = 0;
18
 
19
    // initialize compare value
20
    OCR1A = 6249;     // 249  1ms => 1000Hz
21
            //6249 25ms =>  400Hz 
22
 
23
    // enable compare interrupt
24
    TIMSK1 |= (1 << OCIE1A);
25
 
26
    // enable global interrupts
27
    //sei();
28
}
29
30
ISR (TIMER1_COMPA_vect)
31
{
32
    // Erhöhen
33
    if (duty_cycle < 63) {
34
    duty_cycle++;
35
  }    
36
  else {
37
    duty_cycle = 0;
38
  }    
39
}
40
41
void pwm_init()                         // 8-Bit Timer
42
{
43
    // Wellenform
44
    TCCR2A |= (1<<WGM20)|(1<<WGM21);  //Phasenrichtig
45
  
46
  //OC2 Verhalten
47
  TCCR2A |= (1<<COM2A1)|(1<<COM2B1);  //Set on match, clear at top
48
  TCCR2B |= (1<<CS20);                //Vorteiler = 1
49
}
50
51
void init_IO (){
52
  DDRD |= (1 << PD0);      // PortD0 - Clock
53
  DDRD |= (1 << PD1);      // PortD1 - CW/CCW
54
  DDRD |= (1 << PD2);     // PortD2 - Enable
55
  DDRD |= (1 << PD6);     // OC2B
56
  DDRD |= (1 << PD7);     // OC2A
57
}
58
59
void main()
60
{
61
  duty_cycle = 0;       // 1. duty cycle
62
  PORTD |= (1<<PD2);      // ...aktiviere Port D2 (ENABLE)
63
  PORTD |= (1<<PD1);      // ...aktiviere Port D1 (CW)
64
  //PORTD &= ~((1<<PD1));     // ...deaktiviere Port D1 (CCW)
65
66
  // Initialisierungen  
67
  init_IO();
68
  pwm_init();
69
  timer1_init();
70
  sei();
71
   
72
    // Hauptprogramm
73
    while(1)
74
    {
75
        OCR2A = duty[duty_cycle];
76
    OCR2B = duty2[duty_cycle];
77
    
78
    // Erzeugung des Clock-Signals
79
    if (duty_cycle == 0){
80
      PORTD |= (1<<PD0);      // Clock ein
81
    }
82
    if (duty_cycle == 8){
83
      PORTD &= ~( (1<<PD0));           // Clock aus
84
    }
85
    if (duty_cycle == 16){
86
      PORTD |= (1<<PD0);      // Clock ein
87
    }
88
    if (duty_cycle == 24){
89
      PORTD &= ~( (1<<PD0));           // Clock aus
90
    }
91
    if (duty_cycle == 32){
92
      PORTD |= (1<<PD0);      // Clock ein
93
    }
94
    if (duty_cycle == 40){
95
      PORTD &= ~( (1<<PD0));           // Clock aus
96
    }
97
    if (duty_cycle == 48){
98
      PORTD |= (1<<PD0);      // Clock ein
99
    }
100
    if (duty_cycle == 56){
101
      PORTD &= ~( (1<<PD0));           // Clock aus
102
    }
103
  }    
104
}

von Timo (Gast)



Lesenswert?

Sorry, es fehlte das Bild 3

von Nope (Gast)


Lesenswert?

Hallo Timo,

hast Du Dir schonmal den Allegro A4988 angesehen? Der unterstützt out of 
the box bis zu 16-fach Mikroschritte. Müsste ich mich entscheiden, dann 
würde meine Wahl auf den Allegro fallen. Für alle die, die noch nicht 
auf SMD umgestiegen sind, gibt es den Allegro auch auf Modulen zu 
kaufen. Im Preis unterscheidet es sich kaum, denn der Preis für den 6208 
ist aus meiner Sicht an der Schmerzgrenze. Für den kleinen Aufpreis muss 
man sich nicht mehr um die Mikroschritte kümmern. Für akademische Zwecke 
ist der 6208 aber sicherlich die richtige Wahl ;-)

Gruß

von Floh (Gast)


Lesenswert?

Also mit der PWM stellst du ja den Strom ein, bei der die Endstufe 
choppt / abschaltet.
Für mein Verständnis müsstest du nur einen Sinushälfte erzeugen, die 
"negative" Hälfte wird ja durch Umpolen der Wcklung durch die interne 
Brücke erzeugt.

Zur Höhe des PWM-Signals: Du musst den Spannungsteiler dementsprechend 
anpassen, dass die maximal benötigte Vref bei 100% Duty erreicht wird. 
Bei dir also:
1A x 0,25Ohm = 0,25V Dann musst du mit dem Spannungsteiler von 5V auf 
0,25V kommen, also ein Teiler von 20 -> 19k und 1k z.B.

von Nope (Gast)


Lesenswert?


von Timo (Gast)


Angehängte Dateien:

Lesenswert?

@Floh: Erstmal Danke für die Informationen. Ich habe mal zwei 
Halbwellen"modelle" angehängt. Beide habe ich umgerechnet und in mein 
Programm eingefügt. Mit beiden läuft der Motor, er scheint aber 
Vollschritte zu machen. Zumindest konnte ich für eine Viertelumdrehung 
50 Schritte zählen. Der Motor macht 1,8° pro Vollschritt. Das wären 200 
pro Umdrehung und 50 für eine Viertel-Umdrehung.

Oder war das anders gemeint?

@Nope: Danke für den Hinweis, das scheint ein echt interessantes Bauteil 
zu sein. Ich habe aber extra den L6208 ausgewählt und möchte mich auch 
ganz bewusst mit dieser verdammten PWM-generierten 
Mikroschritt-Problematik auseinandersetzen. Wenn das mal laufen sollte, 
dann werde ich mich an diesen kleinen Kerl wagen. Allein die 
Grundschaltung sieht sehr simpel aus!

von Wolfgang (Gast)


Lesenswert?

Timo schrieb:
> Ein Clock-Signal (High) kommt immer dann, wenn einer der
> beiden Kurven sein Maximal oder Minimum erreicht.

Im Mikroschrittbetrieb soll jede Wicklung einen sinusförmigen Strom 
bekommen. Der L6208 sorgt nur für Stromregelung und 
Polaritätsumschaltung. Damit das kein lautes Geklapper gibt, muß die 
Polarität der jeweiligen Phase immer im Nulldurchgang umgeschaltet 
werden, d.h. der L6208 muß im Normal Drive Mode (Two Phase On) laufen 
und seinen Clock zum Umpolen immer bei Sin=0 bekommen. Aus dem 
Sinusgenerator müssen die positiven, 90° phasenverschobenen Halbwellen 
kommen, weil der Stepper-Controller nur mit pos. Referenz arbeitet und 
das Umpolen über die H-Brücke erfolgt.
s.a. 5.4 (S.8) in
http://www.deltron.ch/pdf/produkte/motoren/schrittmotor_kurz_erklaert_d.pdf

von Timo (Gast)


Angehängte Dateien:

Lesenswert?

Der L6208 läuft bereits im Normal Drive Mode, das habe ich bereits 
kontrolliert. Das mit dem Nulldurchgang habe ich falsch beschrieben und 
wohl falsch verstanden. Danke für den Hinweis! Immer wenn das Signal der 
einen Spule das Max oder Min erreicht hat, dann hat die andere Spule 
einen Nulldurchgang. Das sollte mit den Taktsignalen, weiter oben im 
Code, passen.

@Wolfgang: Schau doch mal auf das angehängte Bild. Meinst du das so mit 
dem einzuspeisenden PWM-Signal? Oder hab ich das falsch verstanden? Ich 
habe auch noch das Taktsignal hinzugefügt.

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


Lesenswert?

Hallo Timo!

Am Besten du postest mal deinen gesamten Schaltplan. Vielleicht 
funktioniert auch die Stromregelung nicht richtig.

Ohne Oszi wird eine weitere Fehlersuche allerdings schwierig. Es kann 
sein dass die 100nF deutlich zu viel sind, und du damit deinen Sinus 
versaust wenn du schneller fährst. Mit welcher Frequenz läuft denn die 
PWM, und mit welchen Taktraten versuchst du den Motor anzusteuern?

Mit freundlichen Grüßen
Thorsten Ostermann

von Timo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

den Schaltplan habe ich angehängt. Die Schaltung soll mit Jumpern 
zwischen Voll-, Halb- und Mikroschritt umschaltbar sein. Voll- und 
Halbschritt funktionieren auch super.

PWM läuft mit 62,5kHz (16MHz Takt, Vorteiler 1, 8-Bit Timer) und den 
duty-Wert vom PWM ändere ich mit 40Hz. Ich sehe aber, dass das von mir 
falsch berechnet wurde. Ich wollte 400Hz haben, bin aber mit dem Komma 
verrutscht und hab anstatt 0,0025s leider mit 0,025s gerechnet. Der 
korrekte OCR1A Wert hätte 624 sein müssen.

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


Lesenswert?

Ich hab gerade mal gerechnet, dein Tiefpass am PWM-Ausgang hat eine 
Eckfrequenz von 80Hz. Das ist mindestens eine 10'er Potenz zu niedrig, 
eher zwei.

Mit freundlichen Grüßen
Thorsten Ostermann

von Timo (Gast)


Lesenswert?

Hallo Thorsten,
hast du einen Tipp, was ich am Code oder an der Schaltung verändern 
sollte, damit das PWM Signal sauber läuft.

Und wenn du noch einen Tipp hast, wo ich mich am besten zum Thema 
"Tiefpass" schlau machen kann (Buch, gute Website o.ä), wäre es auch 
super. Ich hab aufgrund deiner Antwort angefangen zu googlen, bislang 
sind das noch Böhmische Dörfer, aber das wird schon ;)

Alles Gute, Timo

von Timo (Gast)


Lesenswert?

Ah! Ich müsste einfach den Kondensator auf 10nF, bzw. 1nF reduzieren, 
richtig?

Das wäre einfach zu ändern, aber mir stellt sich eher die Frage, wieso 
ich eine Grenzfrequenz von 800Hz oder besser 8000Hz benötige.

Sorry, wenn ich mich blöd anstelle. Ich hoffe nach ein paar Schupser in 
die richtige Richtung geht mit weniger Fragen weiter! Daher vielen Dank 
für die Hilfe!!

von Timm T. (Gast)


Lesenswert?

Thorsten Ostermann schrieb:
> Ich hab gerade mal gerechnet, dein Tiefpass am PWM-Ausgang hat eine
> Eckfrequenz von 80Hz.

Daran könnte es liegen. Das erzeugt natürlich einen Phasenversatz und 
verschleift den Sinus.

Mach mal die 100n Cs oder die Rs kleiner. Oder fahr mal deutlich 
langsamer den Sinus durch.

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


Lesenswert?

Hallo Timo!

Zum Thema Filter siehe z.B.
http://www.elektronik-kompendium.de/sites/slt/0206172.htm

Die Eckfrequenz des Filters muss so tief sein, dass das Filter die PWM 
ausreichend glättet. Andererseits aber so hoch, dass die eingehenden 
Taktsignale (Mikroschritte) auch noch umgesetzt werden können. 
Üblicherweise hält man jeweils eine 10'er Potenz Abstand.

Beispiel: Max. Mikroschrittrate 20kHz (1/8-Schritt, entspricht dann 5kHz 
Halbschritt und damit 12,5U/s) -> Eckfrequenz TP-Filter 200kHz -> 
erforderliche PWM-Frequenz 2MHz.

Das war damals (anno 2000) für mich der Grund bei meiner Endstufe 
"HP-Step" (mit L6203 und L6506) einen DAC statt PWM zu verwenden:
http://www.ostermann-net.de/electronic/schritt/sm_hpstep.htm
http://www.mechapro.de/pdf/hpstep_doku_15b.pdf

Mit freundlichen Grüßen
Thorsten Ostermann

von Timo (Gast)


Lesenswert?

Den Elektronik-Kompendium-Artikel hatte ich mir auch eben durchgelesen 
;)

Ich versuche mal deinem Beispiel zu folgen und eigene Werte einzusetzen:

1/8-Schritt
2U/s  = > 3200 Takte    =>   3.200Hz
Eckfreq. Tiefpassfilter =>  32.000Hz
PWM-Frequenz            => 320.000Hz

Die PWM-Frequenz bekommt man mit einem 8-Bit Timer, Vorteiler 1 und 
Compare-Wert von 49 hin (16MHz µC-Takt).
Den Tiefpass würde ich mir R = 5k und C = 1nF auslegen.

Wäre das (für 2U/s) eine realistische Auslegung?

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


Lesenswert?

Ja, wenn du mit den 2U/s hinkommst.

Mit freundlichen Grüßen
Thorsten Ostermann

von Timo (Gast)


Lesenswert?

Naja, 2U/s ist nicht viel, aber zum Testen reicht es erstmal aus.

Aber eine praktische Frage hab ich noch. Im ersten Posting hab ich die 
Tiefpass-Schaltung als Bild angehängt. Die Tiefpass-Schaltung vom 
Elektronik-Kompendium sieht aber den zweiten Widerstand nicht vor (der 
mit 5,1k). Wenn ich den Tiefpass mit 5k und 1nF realisieren soll, könnte 
ich den zweiten Widerstand weglassen? Wenn nicht, wie groß sollte der 
sein?

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


Lesenswert?

Der zweite Widerstand soll vermutlich den statischen Fall ohne PWM 
abfangen (z.B. wenn der Controller hängt oder programmiert wird), damit 
der Pegel am Vref Eingang des Treibers nicht zu groß wird. Der verträgt 
nämlich nicht bei allen ICs volle 5V (->Datenblatt).

Mit freundlichen Grüßen
Thorsten Ostermann

von Timo (Gast)


Lesenswert?

Vielen Dank für die Hilfe!! Ich werde das mal entsprechend testen und 
melde mich dann nochmal und berichte wie es lief.

Viele Grüsse, Timo

von Timm T. (Gast)


Lesenswert?

Thorsten Ostermann schrieb:
> Der zweite Widerstand soll vermutlich den statischen Fall ohne PWM
> abfangen

Nö, der reduziert als Spannungsteiler einfach die Ausgangsspannung des 
µC von 0..5V entsprechend 0..255 PWM-Schritten auf die Vref des 
Treibers. Im Datenblatt sollte stehen, was der Treiber für eine maximale 
Vref möchte.

Würde man das per PWM machen, könnte man von den 256 PWM-Stufen nur 1/5, 
also 50 Stufen nutzen.

Timo schrieb:
> 1/8-Schritt
> 2U/s  = > 3200 Takte    =>   3.200Hz
> Eckfreq. Tiefpassfilter =>  32.000Hz
> PWM-Frequenz            => 320.000Hz

Dabei kannst Du aber annehmen, dass Du bei höherer 
Schrittgeschwindigkeit eh keinen µStep-Betrieb mehr brauchst. Erstens 
läuft der Motor dann auch bei Viertel- oder Halbschritt rund, zweitens 
verhindert die Induktivität des Motors, dass der Windungsstrom der Vref 
folgt. Also kann man mit steigender Schrittgeschwindigkeit die Auflösung 
runternehmen, 1/64tel => 1/32tel => 1/16tel => 1/8tel => 1/4tel. Und 
dann kann man die hohen Schrittzahlen bei konstanter Vref durch den 
normalen Stepperbetrieb mit Halb- oder Viertelschritt erreichen. Damit 
sollte eine PWM-Frequenz von 24kHz (schafft der ATmega8 mit 12MHz Quarz 
bei 256er PWM) ausreichen.

von Wolfgang (Gast)


Lesenswert?

Timo schrieb:
> @Wolfgang: Schau doch mal auf das angehängte Bild. Meinst du das so mit
> dem einzuspeisenden PWM-Signal? Oder hab ich das falsch verstanden? Ich
> habe auch noch das Taktsignal hinzugefügt.

Hallo Timo,
so haut das mit den Sinuswellen noch nicht ganz hin. Es muss aussehen, 
wie hinter einem Vollwellengleichrichter, also immer der negative Teil 
(180..360° beim Sin bzw. 90..270° beim Cos) nach oben geklappt und das 
für beide Spulen. Und der Phasengenerator vom Stepper-Treiber muss 
darauf auch synchronisiert sein, damit die Zuordnung der 
Polaritätsumschaltung zu den Nulldurchgängen stimmt. Ohne 
Synchronisation kann es sonst passieren, dass der Treiber immer gerade 
auf dem Maximum die Polarität umschaltet.

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.