Hallo ihr lieben
Mein Schrittmotor verliert haufenweise schritte und zwar schon im µC
Programm.
Ich will einen Schrittmotor im Sinus hin und her drehen lassen.
Das ziel ist es mit zwei Schrittmotoren so eine Kreisbewegung zu
erzeugen, wobei sich dann die beiden Sinus-Bewegungen zu einem Kreis
überlagern.
aber erst mal geht es nur um die X-Achse.
Bei meinem Projekt ist es wichtig, dass die Zeit exakt eingehalten wird.
(die Frequenz des Sinus)
Deshalb kann ich nicht wie üblich die Schrittmotoren so ansteuern, dass
sie einfach ihre Steps abfahren, bis der Job erledigt ist. (das dauert
nämlich nicht immer gleich lange.
Deshalb habe ich Folgendes Programm geschrieben.
Es läuft auf einem Arduino bestückt mit einem ATMEGA 320
Was da für ein Schrittmotor Treiber dran hängt ist erst mal egal, da
meine Probleme schon im Programm liegen.
Das Programm generiert eine Sinuskurve, die die anzufahrende Position zu
einer bestimmten Zeit darstellt.
alle 0.1 Sekunden wird diese Position mit der vorherigen abgeglichen und
der Motor mit der entsprechenden Geschwindigkeit weiterbewegt, um die
nächste Position in der richtigen zeit zu erreichen.
Das ganze funktioniert auch auf den ersten Blick, aber leider gehen
viele Schritte verloren.
So ist eine exakte Ansteuerung nicht möglich.
ich gehe mal davon aus, dass das an der Programmlaufzeit liegt, die den
Motor Takt durcheinander bringt.
aber wie kann ich das besser programmieren?
ich würde mich über Hilfe sehr freuen.
das kann ja nicht so schwer sein ein Schrittmotor exakt im Sinus laufen
zu lassen.
hier der code:
1 | int stepperXPin = 13;
|
2 | int stepperXDirPin = 4;
|
3 |
|
4 |
|
5 | float i = 0.0000001;
|
6 | int amplitude = 2000;
|
7 |
|
8 | int motor_statusX = 0; // motor pin HIGH oder LOW
|
9 | float stepsX = 0; // Anzahl an Schritten die der Motor im naechsten Intervall fahren soll
|
10 | int stepCountX = 0; // Anzahl der noch zu fahrenden schritte
|
11 | float positionOldX = 0;
|
12 | float positionX = 0;
|
13 | long previousMillis = 0; // Timer fuer Interval
|
14 | long zeitaltX = 0; // Timer fuer Motor-Takt
|
15 |
|
16 |
|
17 | void setup() {
|
18 | pinMode(stepperXPin, OUTPUT);
|
19 | pinMode(stepperXDirPin, OUTPUT);
|
20 | }
|
21 |
|
22 |
|
23 | void loop()
|
24 | {
|
25 |
|
26 | //-----------------Sinus Signal Erzeugung-------------------------//
|
27 |
|
28 |
|
29 | long interval = 100000; //0.1 sekunden // Aufloesung in der die Sinuskurve in Geraden unterteilt wird.
|
30 | if (micros() - previousMillis > interval) { // takt für das ubergeben des nechsten sinus werts.
|
31 | previousMillis = micros();
|
32 |
|
33 | positionX = ((sin(i)*amplitude)); // erzeugen des sinus signals multipliziert mit der Amplitude (Anzal der Schritte)
|
34 | stepsX = positionOldX - positionX; // zu gehende schitt anzahl wird ermittet.
|
35 | stepCountX = abs(stepsX);
|
36 | positionOldX = positionX;
|
37 |
|
38 | if(stepsX < 0){ //Motor richtung wird gesetzt
|
39 | digitalWrite(stepperXDirPin, HIGH);
|
40 | }
|
41 | else {
|
42 | digitalWrite(stepperXDirPin, LOW);
|
43 | }
|
44 |
|
45 | i = i+0.1; // der zaehler für die Sinuskurve wird um 0.1 erhoeht. das ergibt bei der Sinus laenge von 2 pi eine Aufloesung von 63 pro Sinus durchlauf
|
46 | }
|
47 |
|
48 |
|
49 | //-----------------Motor Steuerung-------------------------//
|
50 |
|
51 |
|
52 | if(stepCountX > 0){ // solange es noch schritte zu gehen gibt
|
53 | if (micros() - zeitaltX >= (interval/abs(stepsX*2)) ) { // wird der motor im entsprechenden takt gepulst. (zeit geteilt durch schritte)(schitte mal zwei, da pro Schritt eimal HIGH und LOW geschaktet werden muss
|
54 |
|
55 | zeitaltX= micros();
|
56 | if (motor_statusX == 1){
|
57 | digitalWrite(stepperXPin, LOW);
|
58 | stepCountX--;
|
59 | motor_statusX = 0;
|
60 |
|
61 | }
|
62 | else
|
63 | {
|
64 | digitalWrite(stepperXPin, HIGH);
|
65 | motor_statusX = 1;
|
66 | }
|
67 | }
|
68 | }
|
69 |
|
70 | }
|