====== Schrittmotor ======
Im folgenden werde ich mich bei der Beschreibung eines Schrittmotors, auf 28BYJ-48 mit dem Treiber ULN2003 beschränken.
===== erste Umdrehung =====
Ziel war es zunächst diesen Schrittmotor mit einem [[arduino|Arduino]] anzusteuern.
Dazu benötigte es zum Beipiel die Library [[http://arduino.alhin.de/download.php?id=26|AH_28BYJ48]].
#include
//Library laden
const int stepsPerRevolution = 64*64; // Anzahl Schritte pro Umdrehung * Zahnradfaktor
AH_28BYJ48 myStepper(stepsPerRevolution, 4,5,6,7);
// pin1 blau
// pin2 pink
// pin3 gelb
// pin4 orange
void setup() {
Serial.begin(9600);
}
void loop() {
myStepper.setSpeedHz(1000); //Geschwindigkeitsfrequenz setzen
myStepper.step(stepsPerRevolution); //Eine Umdrehung durchführen
delay(1000); // 1000ms warten
myStepper.setSpeedRPM(10); //Geschwindigkeit in Anzahl Umdrehungen pro Minute setzen
myStepper.step(-stepsPerRevolution); // Drehung in andere Richtung ausführen
delay(1000);
}
===== Punkte ansteuern =====
Nachdem das ansteuern eines Schrittmotors klappt, bietet es sich nun an einen zweiten mitanzusteuern, um beide Motoren ein Faden zu wickeln, das Ende beider zu verknoten um dann später Muster malen zu lassen, nachdem man an den verknoteten Punkt einen Stift befestigt hat.
Dazu ist es nötig einen Punkt abhängig von seinen Koordinaten anzusteuern. Das funktioniert vermutlich am besten über die Anzahl der Umdrehungen, die jeder Motor benötigt. Dazu wird im folgenden Programm jedoch jeder Motor am Programmstart so angenommen, als hätte er keine Umdrehungen durchgeführt, wenn er zum ersten Punkt fährt und danach erst die Fäden zusammengebunden.
#include
const int stepsPerRevolution = 64*64;
AH_28BYJ48 myStepper(stepsPerRevolution, 4,5,6,7);
// pin1 blau
// pin2 pink
// pin3 gelb
// pin4 orange
AH_28BYJ48 myStepper2(stepsPerRevolution, 8,9,10,11);
const float pi = 3.14; // Pi
const int x_max = 11; // Maxima des Feldes
const int y_max = 11;
int n_1 =0; // Auszuführende Umdrehungen zwischen letztem und neuen Punkt
int n_2 =0;
int n1_alt =0; // Umdrehungen bis zum letzten Punkt
int n2_alt = 0 ;
int n1_neu = 0; // Umdrehungen bis zum neuen Punkt
int n2_neu = 0;
int x[] = {1,2,3,4,5,6,7,8,9}; // x-Koordinaten der Punkte
int y[] = {1,2,3,4,5,6,7,8,9};
int n1_mittelpunkt = sqrt(x_max*x_max/4 + y_max*y_max /4)/ (2* pi); // Umdrehungen bis zum Mittelpunkt für den ersten Motor
int n2_mittelpunkt = sqrt(x_max*x_max/4 + y_max*y_max /4)/ (2* pi);
void setup() {
Serial.begin(9600);
}
void loop() {
n1_neu = n1_mittelpunkt; // Mittelpunkt ansteuern
n2_neu = n2_mittelpunkt;
n_1 = n1_mittelpunkt- n1_alt; // Anzahl Umdrehungen neuen Punktes minus die des alten Punktes
n_2 = n2_mittelpunkt- n2_alt;
bewegen(n_1,n_2); // Bewegung ausführen
for (int i=0; i < sizeof(x); i++){ // für alle Elemente des Punktefeldes
if (x[i] > x_max) {x[i]= x_max;} // prüfung, ob Maxima überschritten werden
if (y[i] > y_max) {y[i] = y_max;}
n1_alt= n1_neu;
n2_alt= n2_neu;
n1_neu = sqrt(y[i]*y[i]+x[i]*x[i])/ (2* pi); // Umdrehungen vom Nullpunkt berechnen
n2_neu = sqrt ( (x_max-x[i])* (x_max-x[i])+ y[i]*y[i])/ (2*pi);
n_1 = n1_neu - n1_alt; // Umdrehungen vom vorherigen Punkt berechnen
n_2 = n2_neu - n2_alt;
bewegen(n_1,n_2); // Bewegungen durchführen
}
n1_alt = n1_neu; // zurück zum Mittelpunkt
n2_alt = n2_neu;
n_1 = n1_mittelpunkt-n1_alt;
n_2 = n2_mittelpunkt-n2_alt;
bewegen(n_1,n_2);
}
void bewegen (int s1,int s2){ // Vgl Beispiel oben
if ( s1 >= s2 ){ // damit Fäden nicht außeinander reißen
for ( int i=0; i< stepsPerRevolution; i++){
myStepper.setSpeedHz(1000);
myStepper.step(s1);
myStepper2.setSpeedHz(1000);
myStepper2.step(s2);
}
delay(1000);
}
else{
for ( int i=0; i< stepsPerRevolution; i++){
myStepper2.setSpeedHz(1000);
myStepper2.step(s2);
myStepper.setSpeedHz(1000);
myStepper.step(s1);
}
delay(1000);
}
}
===== Kalibrierung =====
Wie man im Einleitungssatz des vorherigen Unterkapitels erkennt, hat der vorherige Code ein Problem. Die Motoren müssen sich am Anfang bei Null Umdrehungen befinden und man muss mitten im Programm die Fäden zusammenbinden. Tut man dies nicht, so hat man zwar ungefähr ein ähnliches Muster aber ganz woanders auf der zu projezierenden Fläche.
Daher bietet es sich an eine Kalibrierung der Motoren mittels 5 Tastern hinzuzufügen.
Das Programm startet an einem beliebigen Punkt.
Ein Taster steuert nach oben, einer nach unten, einer nach links und einer nach rechts. Der letzte Taster 'speichert' dann die Koordinaten (in Form von Umdrehungen).
#include
const int stepsPerRevolution = 64*64;
AH_28BYJ48 myStepper(stepsPerRevolution, 4,5,6,7);
// pin1 blue
// pin2 pink
// pin3 yellow
// pin4 orange
AH_28BYJ48 myStepper2(stepsPerRevolution, 8,9,10,11);
int Taster_1 = 12;
int Taster_2 = 13;
int Taster_3 = 14;
int Taster_4 = 15;
int Taster_5 = 3;
const float pi = 3.14;
int x_max = 11; // Maxima des Feldes
int y_max = 11;
int n_1 =0; // Auszuführende Umdrehungen zwischen letztem und neuen Punkt
int n_2 =0;
int n1_alt =0; // Umdrehungen bis zum letzten Punkt
int n2_alt = 0 ;
int n1_neu = 0; // Umdrehungen bis zum neuen Punkt
int n2_neu = 0;
int x[] = {1,2,3,4,5,6,7,8,9}; // x-Koordinaten der Punkte
int y[] = {1,2,3,4,5,6,7,8,9};
int n1_mittelpunkt = sqrt(x_max*x_max/4 + y_max*y_max /4)/ (2* pi);
int n2_mittelpunkt = sqrt(x_max*x_max/4 + y_max*y_max /4)/ (2* pi);
int tx_1 = 0; // Kalibrierungsmaße
int tx_2 = 0;
int ty_1 = 0;
int ty_2 = 0;
int modus = 0;
void setup() {
pinMode (12, INPUT); // Taster
pinMode (13, INPUT);
pinMode (14, INPUT);
pinMode (15, INPUT);
pinMode (3, INPUT);
Serial.begin(9600);
}
void loop() {
if (modus == 0){ // Randpunkt oben links mithilfe von Tasterbetätigung anpeilen
if (digitalRead(Taster_1)== HIGH){ // Taster 1 gedrückt --> um eine Einheit nach rechts verschieben
while(digitalRead(Taster_1)== HIGH){ }
// n1_neu = (x+1)/ (2* pi);
// n2_neu = sqrt ( (x_max-x[i]+1)* (x_max-(x[i]+1)))/ (2*pi);
// n1_alt = x / (2* pi);
// n2_alt = (x_max-x[i])/ (2*pi);
// n1 = 1/(2*pi);
// n2 = -1/(2*pi);
bewegen(1/(2*pi),-1/(2*pi));
}
if (digitalRead(Taster_2)== HIGH){ // Taster 2 gedrückt --> um eine Einheit nach links verschieben
while(digitalRead(Taster_2)== HIGH){ }
bewegen(-1/(2*pi),1/(2*pi));
}
if (digitalRead(Taster_3)== HIGH){ // Taster 3 gedrückt --> um eine Einheit nach unten verschieben
while(digitalRead(Taster_3)== HIGH){ }
bewegen(1/(2*pi),1/(2*pi));
}
if (digitalRead(Taster_4)== HIGH){ // Taster 4 gedrückt --> um eine Einheit nach oben verschieben
while(digitalRead(Taster_4)== HIGH){ }
bewegen(-1/(2*pi),-1/(2*pi));
}
if (digitalRead(Taster_5)== HIGH){ // Taster 5 --> zweiter Punkt
while(digitalRead(Taster_5)== HIGH){ }
modus = 1;
}
}
if (modus ==1){ // Anpeilen des Punktes rechts oben
if (digitalRead(Taster_1)== HIGH){ // Taster 1 gedrückt --> um eine Einheit nach rechts verschieben
while(digitalRead(Taster_1)== HIGH){ }
bewegen(1/(2*pi),-1/(2*pi));
tx_1 ++;
}
if (digitalRead(Taster_2)== HIGH){ // Taster 2 gedrückt --> um eine Einheit nach links verschieben
while(digitalRead(Taster_2)== HIGH){ }
bewegen(-1/(2*pi),1/(2*pi));
tx_1 --;
}
if (digitalRead(Taster_3)== HIGH){ // Taster 3 gedrückt --> um eine Einheit nach unten verschieben
while(digitalRead(Taster_3)== HIGH){ }
bewegen(1/(2*pi),1/(2*pi));
ty_1 ++;
}
if (digitalRead(Taster_4)== HIGH){ // Taster 4 gedrückt --> um eine Einheit nach oben verschieben
while(digitalRead(Taster_4)== HIGH){ }
bewegen(-1/(2*pi),-1/(2*pi));
ty_1 --;
}
if (digitalRead(Taster_5)== HIGH){ // Taster 5 --> letzter punkt
while(digitalRead(Taster_5)== HIGH){ }
modus = 2;
}
}
if (modus ==2){ // Anpeilen des Punktes rechts unten
if (digitalRead(Taster_1)== HIGH){ // Taster 1 gedrückt --> um eine Einheit nach rechts verschieben
while(digitalRead(Taster_1)== HIGH){ }
bewegen(1/(2*pi),-1/(2*pi));
tx_2 ++;
}
if (digitalRead(Taster_2)== HIGH){ // Taster 2 gedrückt --> um eine Einheit nach links verschieben
while(digitalRead(Taster_2)== HIGH){ }
bewegen(-1/(2*pi),1/(2*pi));
tx_2 --;
}
if (digitalRead(Taster_3)== HIGH){ // Taster 3 gedrückt --> um eine Einheit nach unten verschieben
while(digitalRead(Taster_3)== HIGH){ }
bewegen(1/(2*pi),1/(2*pi));
ty_2 ++;
}
if (digitalRead(Taster_4)== HIGH){ // Taster 4 gedrückt --> um eine Einheit nach oben verschieben
while(digitalRead(Taster_4)== HIGH){ }
bewegen(-1/(2*pi),-1/(2*pi));
ty_2 --;
}
if (digitalRead(Taster_5)== HIGH){ // Taster 5 --> start
while(digitalRead(Taster_5)== HIGH){ }
modus = 3;
}
}
if (modus ==3){ // Kalibrierungspunkte als Maxima setzen und Muster abfahren
x_max = tx_1;
y_max = ty_2;
n_1 = - sqrt(tx_1*tx_1+ty_2*ty_2)/ (2* pi); // Eckpunkt oben links ansteuern
n_2 = - (tx_1-ty_2) / (2*pi);
n1_alt = 0;
n2_alt = 0;
bewegen (n_1, n_2);
for (int i=0; i < sizeof(x); i++){
if (x[i] > x_max && modus == 3) {x[i]= x_max;} // prüfung, ob Maxima überschritten werden
if (y[i] > y_max && modus == 3) {y[i] = y_max;}
n1_alt= n1_neu;
n2_alt= n2_neu;
n1_neu = sqrt(y[i]*y[i]+x[i]*x[i])/ (2* pi); // Umdrehungen vom Nullpunkt berechnen
n2_neu = sqrt ( (x_max-x[i])* (x_max-x[i])+ y[i]*y[i])/ (2*pi);
n_1 = n1_neu - n1_alt; // Umdrehungen vom vorherigen Punkt berechnen
n_2 = n2_neu - n2_alt;
if (modus ==3 )bewegen(n_1,n_2); // Bewegungen durchführen nur wenn nicht abgebrochen wurde
if (digitalRead(Taster_5)== HIGH){ // Taster 5 gedrückt --> restart
while(digitalRead(Taster_5)== HIGH){ }
modus = 0;
}
if (modus ==3 )bewegen(n_1,n_2); // Bewegungen durchführen nur wenn nicht abgebrochen wurde
}
}
}
void bewegen (int s1,int s2){
if ( s1 >= s2 ){ // damit Fäden nicht außeinander reißen
for ( int i=0; i< stepsPerRevolution; i++){
myStepper.setSpeedHz(1000);
myStepper.step(s1);
myStepper2.setSpeedHz(1000);
myStepper2.step(s2);
}
delay(1000);
}
else{
for ( int i=0; i< stepsPerRevolution; i++){
myStepper2.setSpeedHz(1000);
myStepper2.step(s2);
myStepper.setSpeedHz(1000);
myStepper.step(s1);
}
delay(1000);
}
}
Jedoch fehlte bisher das Material zum Testen, daher besteht kein Anspruch auf Richtigkeit.