Stepper

Hallo Arduino - Fans,

ich könnte mal Eure Hilfe gebrauchen bei meinem aktuellen Arduino -Projekt.
Im Moment stehe ich auf dem Schlauch, vielleicht habt Ihr eine Idee, wie ich das realisieren kann?

Aufgabenstellung ist:

Ein Schrittmotor soll auf Tastendruck für eine bestimmte Zeit mit einer bestimmten Drehzahl laufen.
Zeit und Geschwindigkeit werden vor dem Start jeweils über Potis eingestellt und in Variablen gespeichert.
Mein Problem ist, dass die Drehzahl des Motors konstruktionsbedigt ja über das von einer Variable vorgegebene Delay geregelt wird.
Somit ist bei höherer Drehzahl die for-Schleife (für die Zeit) schneller abgearbeitet als bei geringerer Drehzahl.

Es soll aber so sein, dass der Motor für die eingestellte Zeit läuft, unabhängig von der Drehzahl.

Habt Ihr einen Lösungsvorschlag?

Vielen Dank schon mal!
Gruß Uli

Das hier ist der Code:

#include <Nextion.h>    // Funktioniert nur mit der Bibliothek " ITEAD Arduino Nextion Master"!  
int sensorPin1 = A1;    // Analog- Pin für die Laufzeit
int sensorValue1 =0;    // Variable für die Laufzeit des Motors
int sensorValue3 =0;    // Variable für die Laufzeit-Anzeige des Displays
int sensorPin2 = A0;    // Analog - PIN für die Drehzahl
int sensorValue2 =0;    // Variable für die Drehzahl des Motors
int sensorValue4 =0;    // Variable für die Drehzahl-Anzeige des Displays
int Taster1 =7;
int Led1 = 10;
int x = 0;
NexGauge xTime = NexGauge(0, 1, "xTime");     //(Seite, ID, Name)
NexGauge Speed = NexGauge(0, 2, "Speed");
NexPage page0 = NexPage(0, 0, "page0");
NexPage page1 = NexPage(1, 0, "page1");
NexPage page2 = NexPage(2, 0, "page2");
NexPage page3 = NexPage(3, 0, "page3");
NexPage page4 = NexPage(4, 0, "page4");
NexPage page5 = NexPage(5, 0, "page5");
NexTouch *nex_listen_list[] =
{
    &page0,
    &page1,
    &page2,
    &page3,
    &page4,
    &page5,
    NULL
};

void setup() {
Serial.begin(9600);
nexInit();
delay(2000);          // eingefügt, um das lästige Ruckeln beim Einschalten zu vermeiden, bis der Treiber bereit ist.                    
pinMode(8, OUTPUT);   // direction PIN
pinMode(9, OUTPUT);   // step Pin
pinMode(Led1, OUTPUT);
pinMode(Taster1,INPUT_PULLUP);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
page0.show();
delay(1500);
page1.show();
delay(1500);
page2.show();
delay(1500);
page3.show();
delay(1500);
page4.show();
delay(1500);
page5.show();
delay(1500);
}
void loop() {
// Variable für die Laufzeit des Motors
sensorValue1 = analogRead(sensorPin1);
sensorValue1 = map(sensorValue1, 1023,0,0,3600); //1023,0, 0, 255); // war 0, 1023, 3600, 1 ;  ((1600))
// Hier wird die Laufzeit-Anzeige für das Display eingestellt
sensorValue3 = analogRead(sensorPin1);
sensorValue3 = map(sensorValue3, 1023, 0, 0, 255); // war 0, 1023, 3600, 1 ;
xTime.setValue(int(sensorValue3));
// Variable für die Drehzahl des Motors
sensorValue2 = analogRead(sensorPin2);
sensorValue2 = map(sensorValue2, 1023,0, 1600, 1); // war 0, 1023, 3600, 1 ;  ((1600))
// Hier wird die Geschwindigkeits-Anzeige für das Display eingestellt
sensorValue4 = analogRead(sensorPin2);
sensorValue4 = map(sensorValue4, 1023, 0, 0, 255); // war 0, 1023, 3600, 1 ;
Speed.setValue(int(sensorValue4));


//Serial.println(sensorValue1);  //wurde eingefügt, um die Sensorwerte auszulesen, bevor der Taster gedrückt wurde.
//Serial.println(sensorValue2);  //wurde eingefügt, um die Sensorwerte auszulesen, bevor der Taster gedrückt wurde.
// Hier wird der Taster abgefragt
if(!digitalRead(Taster1))
  {
  for(x=0;x<sensorValue1;x++)
 //for(x=0;x<10000;x++)
 {
digitalWrite(9, HIGH);
digitalWrite(Led1, HIGH);
//delay(300);
delayMicroseconds(sensorValue2);
//delayMicroseconds(100);             // eingefügt 7.4.19, so läuft er sofort los
digitalWrite(9, LOW);
digitalWrite(Led1, LOW);
delayMicroseconds(sensorValue2);
//delayMicroseconds(100);             // eingefügt 7.4.19, so läuft er sofort los
//delay(300);
 
 }
 
 
 }
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

// SensorValue1 is 0..3600 seconds? milliseconds? hours?
// you will have to convert it to milliseconds
unsigned long interval = SensorValue1 * 1000; // msec
unsigned long startTime = millis();
//for (x = 0; x < sensorValue1; x ++)
while( millis() - startTime <= interval )
{
  digitalWrite (9, HIGH);
  digitalWrite (Led1, HIGH);
  delayMicroseconds (sensorValue2);
  digitalWrite (9, LOW);
  digitalWrite (Led1, LOW);
  delayMicroseconds (sensorValue2);
}

Hallo Eltrom,

es gibt einige Dinge die es den anderen Forummitgliedern ganz wesentlich erleichtern dir zu helfen.

Poste den Programmocde als code-section. Das macht man indem man den "insert-code" button benutzt.
Sieht so aus <|> Dieser Button befindet sich ganz links oben oberhalb des Texteingabefeldes.

der code wird dann so dargestellt

int sensorPin1 = A1;    // Analog- Pin für die Laufzeit
int sensorValue1 =0;    // Variable für die Laufzeit des Motors
int sensorValue3 =0;    // Variable für die Laufzeit-Anzeige des Displays
int sensorPin2 = A0;    // Analog - PIN für die Drehzahl
int sensorValue2 =0;    // Variable für die Drehzahl des Motors
int sensorValue4 =0;    // Variable für die Drehzahl-Anzeige des Displays

Ich glaube nicht das die Kommentare präzise beschreiben was der Code macht.

Es gibt eine Variable für die Drehzahl des Schrittmotors und auf dem Display kann man eine andere Drehzahl einstellen?

Also Poti das an A0 angeschlossen ist steht meinetwegen auf "10"
und dann drehe ich am Poti das an A1 angeschlossen ist und dann zeigt mir das Display je nach Poti-stellung mal "20" mal "40" mal 200" als "Display-Drehzahl" an obwohl die Drehzahl am Schrittmotor immer auf "10" steht???
Das ergibt keinen Sinn.

Verwende konsequent selbsterklärende Namen
statt:

int sensorPin1 = A1;
const int PotiLaufzeitPin  = A1;

statt

int sensorValue1 =0;
int MotorLaufzeit = 0;

An der Stelle wird klar "MotorLaufZeit" ist ein Name der den Nagel noch nicht auf den Kopf trifft.
Um die Laufzeit konstant zu machen musst du die GesamtzahlSchritte berechnen

GesamtzahlSchritte = AnzahlSchritteProUmdrehung * UmdrehungenProSekunde * LaufZeitSekunden

Und die For-schleife läuft dann von 1 bis GesamtzahlSchritte
Das erfordert jetzt erst einmal einiges an rechnerischer Analyse was da alles für Berechnungen angestellt werden müssen.
tja gut programmieren hat auch was mit Mathematik zu tun.

pinMode(8, OUTPUT);   // direction PIN
pinMode(9, OUTPUT);   // step Pin
const int DirPin = 8;
const int StepPin = 9;

pinMode(DirPin, OUTPUT);   
pinMode(StepPin , OUTPUT);

und weiter unten

digitalWrite(StepPin, HIGH);

Dadurch das man Variablen anstatt von hardcodierten Zahlen verwendet wird der Code leichter lesbar
und wenn du je mal denIO-Pin wechselst dann musst du nur an einer einzigen Stelle etwas ändern und die Änderung wird überall wirksam. Mit hardcodierten Zahlen musst du jede Stelle an der die Zahl steht ändern.

Da zeigt sich dann "das besonders schnelle Programmieren (Am Anfang) macht das Fertigstellen des Projekts besonders langsam weil man später mehr Mühe hat.

Darüber hinaus: Wie wäre es mit der Verwendung einer library die ganz viele Schrittmotorfunktionen hat?

viele Grüße Stefan

Hi

Da Dir ja schon aufgefallen ist, daß ein schneller drehender Motor eine feste Anzahl an Schritte schneller abgearbeitet hat - warum nimmst Du nicht die Zeit als Kriterium, ob die LaufZEIT bereits vergangen ist?
Zumindest wäre Das mein Ansatz - es mag durchaus noch kompliziertere Herangehensweisen geben, als zuvor die Schritte zu berechnen, Die bei der höheren Geschwindigkeit in 'der und der Zeit' geschafft werden - aber wofür?
In beiden Fällen wird Dir die 'Uhrzeit' am Ende der Laufzeit eindeutig sagen, daß jetzt wohl Schluss ist.

Wie gesagt: nur mein Weg, erscheint mir aber wesentlich logischer, als die Berechnung, in Der noch die Mondphase einbezogen werden kann ...

MfG

Du könntest die MobaTools verwenden und dann die Laufzeit rein von der Zeit abhängig machen. Du könntest sogar bei deinen 'geliebten' delay() bleiben ;). Ein kleines Beispiel - mit konstanten Werten, die Du aber natürlich leicht variabel machen kannst:

#include <MobaTools.h>

const byte stepPin = 6;
const byte dirPin  = 5;

const byte tasterPin = A0;

const int umdrMin = 600;   // 60 Umdrehungen / Minute
const long laufZeit = 2000; // Laufzeit 2 Sekunden

MoToStepper myStepper ( 200, A4988 );   // 200 Steps/ Umdrehung ( gegebenenfalls anpassen )

void setup() {
    // put your setup code here, to run once:
    myStepper.attach( stepPin, dirPin );
    myStepper.setRampLen( 10 );

    pinMode( tasterPin, INPUT_PULLUP );

}

void loop() {
    // put your main code here, to run repeatedly:
    if ( digitalRead( tasterPin ) == LOW ) {
        myStepper.setSpeed( umdrMin ); //Geschwindigkeit einstellen
        myStepper.rotate( 1 );  // Vorwarts drehen
        delay ( laufZeit );
        myStepper.rotate( 0 ); //  wieder anhalten
    }

}

Wenn Du die delay loswerden willst, kannst Du den MoTo Timer einsetzen:

#include <MobaTools.h>

const byte stepPin = 6;
const byte dirPin  = 5;

const byte tasterPin = A0;

const int umdrMin = 600;   // 60 Umdrehungen / Minute
const long laufZeit = 2000; // Laufzeit 2 Sekunden

MoToStepper myStepper ( 200, A4988 );
MoToTimer   stopUhr;

void setup() {
    // put your setup code here, to run once:
    myStepper.attach( stepPin, dirPin );
    myStepper.setRampLen( 10 );

    pinMode( tasterPin, INPUT_PULLUP );

}

void loop() {
    // put your main code here, to run repeatedly:
    if ( digitalRead( tasterPin ) == LOW && !stopUhr.running() ) {
        myStepper.setSpeed( umdrMin );  // Umdrehungszahl einsteeln ( in Umd/Min*10 )
        myStepper.rotate( 1 );          // Vorwarts drehen
        stopUhr.setTime( laufZeit );    // Zeit aufziehen
    }

    if ( stopUhr.expired() ) {
        // Zeit ist abgelaufen
        myStepper.rotate( 0 ); //  wieder anhalten
    }
}

Das in deinen Code einzubauen überlass ich jetzt mal dir 8)