@StefanL38: Jetzt bin ich wieder in der schon an anderer Stelle beschriebenen Zwickmühle, denn ich habe zur Ordnung meiner Gedanken ein Programm geschrieben, um mich in die Problematik einzudenken. Andere würden Grafiken malen oder Ablaufdiagramme schreiben.
Soll ich dieses Programm geheim halten?
Meine Entscheidung, ich zeige das Programm und überlasse es dem TO, etwas davon zu nehmen oder auch nicht.
Als Fan der MobaTools nutze ich diese und eine Schrittkette (= finite state machine; = endlicher Automat) mit switch/case realisiert. Da kann ich einfacher denken ![]()
Getestet mit UNO, DRV8825 und einem Schrittmotor:
//#define DEBUGGING // Einkommentieren für die Serielle Ausgabe
#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.print(__VA_ARGS__)
#define DEBUG_L(...) Serial.println(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_L(...)
#endif
#include <MobaTools.h>
MoToStepper Step(200, STEPDIR); // Schritte pro Umdrehung
const byte stepPin = 2; // X.STEP
const byte dirPin = 5; // X.DIR
const byte sensorPin = 9;
const uint32_t mindestZeit = 2000;
uint32_t detectTime;
uint32_t jetzt;
void setup() {
DEBUG_B(115200);
DEBUG_L(F("Start ..."));
pinMode(sensorPin, INPUT_PULLUP); //Sensor eingang
Step.attach( stepPin, dirPin ); // stepPin, dirPin
Step.setSpeed( 3000 ); // = 300 U/Min
Step.setRampLen( 50 ); // Beschleunigung
Step.setZero(); // Referenzpunkt setzen
Step.rotate( 1 ); // Richtung ist immer vorwärts
}
void loop()
{
jetzt = millis();
static byte schritt = 0;
switch ( schritt )
{
case 0:
if (digitalRead(sensorPin) == LOW) // Sensor detektiert etwas
{
serMon( schritt, "Zeit gestartet" );
detectTime = jetzt;
schritt++;
}
break;
case 1:
if (digitalRead(sensorPin) == HIGH) // Sensor detektiert etwas
{
serMon( schritt, "Teil Ende erkannt" );
schritt++;
}
break;
case 2:
if (digitalRead(sensorPin) == LOW) // Sensor detektiert etwas
{
serMon( schritt, "Teil Ende erkannt, Zeitdiff: \t", jetzt - detectTime );
if (jetzt - detectTime >= mindestZeit) // letzte detektZeit ist zu kurz? ...
{
serMon( schritt, "Zeit überschritten, Motor dreht weiter" );
Step.rotate( 1 ); // Richtung ist immer vorwärts
detectTime = jetzt;
schritt = 1;
} else {
serMon( schritt, "Zeit unterschritten, Motor Halt" );
Step.rotate( 0 ); // Anhalten mit Rampe
Step.setZero(); // Referenzpunkt setzen, wohl nicht benötigt, aber der Positionszähler läuft dann nicht über
schritt++;
}
}
break;
case 3:
if (jetzt - detectTime >= mindestZeit) // letzte detektZeit ist zu kurz? ...
{
serMon( schritt, "Zeit erreicht, Motor Start" );
Step.rotate( 1 ); // Richtung ist immer vorwärts
detectTime = jetzt;
schritt = 1;
}
break;
default:
schritt = 0;
}
}
void serMon(byte s, const char * text)
{
serMon( s, text, 0 );
}
void serMon(byte s, const char * text, const uint32_t diff)
{
DEBUG_P(jetzt);
DEBUG_P(F("\tSchritt: "));
DEBUG_P(s);
DEBUG_P('\t');
DEBUG_P(text);
if (diff)
{
DEBUG_P('\t');
DEBUG_P(diff);
}
DEBUG_L();
}
Bitte ausprobieren, fragen oder verwerfen.
Bei den MobaTools gibt es auch Zeitgeber, die ich wegen der Vergleiichbarkeit nicht genutzt habe.
"Hier stehe ich, ich kann nicht anders." Luthers berühmte Worte, die er wohl nie gesagt hat.