Hallo Forum!
Bin absoluter Anfänger; Frage ist daher möglicherweise komisch.
Betreibe einen Steppermotor mit Pololu a4988. Ziel ist maximal genau eine Umdrehung pro Minute in Richtung1 in max kleinen Schritten und das über mehrere Minuten (einstellbar) und dann schnell zurück in Richtung 2.
Mit der Delay Variante und mit der Stoppuhr war das halbwegs genau. In der Folge - weil Delay ja böse - hab ich ein Programm geschrieben,
- mit dem im Vorlauf auf Delays verzichtet wird
- und bei dem eine Zeitkontrolle die einzelnen Umdrehungen und die gesamte Vorlaufzeit überwacht (Monitorausgabe).
Damit kann ich eine sehr hohe Genauigkeit - wenige Hundertstel Sekunden nach 10 Minuten - erreichen (zumindest zeigt das die Zeitkontrolle so an). Kontrolliert man den Vorlauf mit der Stoppuhr gibts Abweichungen im Sekundenbereich (2-3 Sekunden nach 10 Minuten.
Ist das normal...oder hab ich da was falsch gemacht?
Programm hier:
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Steppersteuerung --- mit Uno und Polulu Driver --- sketch_feb26g
Einzustellen: Anzahl der ganzen Umdrehungen, Steps pro Umdrehung,
Step high und Step low mit 2 Stellmöglichkeiten
Automatischer Ausgleich der Abweichung mit manuellem Programmlaufzeitausgleich
Kontrolle über Monitor, Rücklauf schnell mit Delays, W.Röder Feb2021
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
//Variable
int steps; // Schritte pro Umdrehung (3200)
int Um; // Anzahl der Umdrehungen = Minuten Laufzeit
// Zeiten
long time_0; // - Beginn Vorlauf
long time_00; // - Beginn Umdrehung
long time_a; // - Start High
long time_b; // - Start Low
long time_c; // - Ende für eine Umdrehung
long time_d; // - Ende für gesamten Vorlauf
long LZ_U; // Laufzeit ab Vorlauf
long LZ_UU; // Laufzeit Umdrehung
// Impulse
long Hi; // Impuls High
long Lo; // Impuls Low
// Auto Korrektur
long Korr0; // Auto-Korrekturen bei Low
long Korr1; // Diff pro Step als Ganzzahl teilbar durch 4
long KorrLo; // Korrigierter Low Wert
int KorrKonst; // Variable Korrektur - Ausgleich Programmablaufzeit
void setup() {
//Polulu Pins
pinMode(6, OUTPUT); // Enable
pinMode(5, OUTPUT); // Step
pinMode(4, OUTPUT); // Richtung
digitalWrite(6, LOW);
digitalWrite(5, LOW);
digitalWrite(4, HIGH);
// Schritteinstellung MS 1 - 3
pinMode(8, OUTPUT); // MS 1
pinMode(9, OUTPUT); // MS 2
pinMode(10, OUTPUT); // MS 3
digitalWrite(8, HIGH); // Schritteinstellung 1 - 3 lt. Polulu Tabell
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
/*MS1 MS2 MS3 Microstep Auflösung
L L L Full Step
H L L Half Step
L H L Quarter Step
H H L Eighth Step
H H H Sixteenth Step
*/
Serial.begin(9600);
// Variable Einstellungen
Um = 10; // Anzahl ganzer Umdrehungen
steps = 3200; // 1 U/min mit 1/8 Stepeinstellung
Hi = 9340; // Impuls High in Microsekunden ~9340
Lo = 9396; // Impuls Low in Microsekunden ~9396
KorrKonst = 56; // Variable Korrektur - Ausgleich Programmablaufzeit ~44
KorrLo = Lo; // Reset auf den Low Wert
// Ausgabe Grundeinstellungen
Serial.print("Ganze Umdrehungen ");
Serial.print(Um);
Serial.println();
Serial.print("Steps pro Umdrehung ");
Serial.print(steps);
Serial.println();
// es geht los in Richtung 1 - mit HIGH / LOW somit mit 2 Stellmöglichkeiten - Auflösung 4 micros
}
void loop() {
digitalWrite(4, LOW); // Richtung
time_0 = micros(); // Startzeit vor allen Umdrehungen
for (int u = 0; u < Um; u++) { // int u = Umdrehungszähler
Serial.println(" "); //Ausgaben am Monitor
Serial.print("Umdrehung Nr. ");
Serial.print(u+1);
Serial.println();
time_00 = micros(); // Startzeit vor einer Umdrehung
for (int s = 0; s < steps; s++) { // int s = Stepzähler
time_a = micros(); //Startzeit high
digitalWrite(5, HIGH);
while (micros() - time_a < Hi) { //Step high (~5000 oder 9340)
// do nothing
}
time_b = micros(); //Startzeit low
digitalWrite(5, LOW);
while (micros() - time_b < KorrLo) { //Step low = korregierter Low Wert
// do nothing //Gesamtlaufzeit unter 60 sec/U Wert erhöhen ...
} //über 60sec/U Wert verringern
} // ->> Ende Stepschleife
time_c = micros(); // Endzeit nach einer Umdrehung
LZ_U = (time_c - time_0); // Laufzeit ab Beginn
LZ_UU = (time_c - time_00); // Laufzeit nach aktueller Umdrehung
Korr0 = (LZ_U - (60000000 * (u + 1))) / steps; // Korrekturwert je Step
Korr1 = ((Korr0 / 4) * 4); // als Ganzzahl teilbar durch 4
KorrLo = (Lo - ((Korr0 / 4) * 4) - KorrKonst); // Korrigierter Low Wert
// Infos nach jeder Umdrehung
Serial.println();
Serial.print("Zeit in 1/1000 sec pro Umdrehung ");
Serial.print(LZ_UU / 1000);
Serial.println();
Serial.print("Soll in Sekunden ");
Serial.print(60 * (u + 1));
Serial.println();Serial.print("Gesamtlaufzeit in 1/100 sec ");
Serial.print(LZ_U / 10000);
Serial.println();
Serial.print("Korrekturbasis = Gesamtlaufzeit: ");
Serial.print(time_c);
Serial.print("-");
Serial.print(time_0);
Serial.print("=");
Serial.print(LZ_U);
Serial.println();
Serial.print("LZ Differenz zum Soll in Microsec. ");
Serial.print(LZ_U - (60000000 * (u + 1)));
Serial.println();
Serial.print("Differenz pro Step ");
Serial.print(Korr0);
Serial.print(" = gerundet auf 4 Microsec Aufloesung ");
Serial.print(Korr1);
Serial.println();
Serial.print("Low Impuls fuer naechste Umdrehung inc. KorrKonst. ");
Serial.print(KorrLo);
Serial.println();
} // ->> Ende Umdrehungsschleife
time_d = micros(); // Laufzeitkontrolle vor dem Rücklauf
Serial.println();
Serial.print("Programmlaufzeit in 1/1000 sec ");
Serial.print((time_d - time_0) / 1000);
Serial.println();
//Übergang zum Rücklauf mit delays
delay(3000);
for (int u = 0; u < Um; u++) { // int u = Umdrehungszähler
for (int s = 0; s < steps; s++)
{
digitalWrite(5, HIGH);
delayMicroseconds(1000);
digitalWrite(5, LOW);
delayMicroseconds(500);
}
}
delay(1000);
}
Danke für eure Hilfe
Werner