So hier ist jetzt ein Programm das folgendes macht:
Auf Taster Start warten
Wenn Taster gedrückt wurde Schrittmotor drehen
wenn "unten" angekommen Richtungswechsel auf "oben"
wenn oben angekommen dann Richtungswechsel auf "unten"
ständige TasterAbfrage
Wenn Taster gedrückt wurde vormerken und den momentan aktiven Weg noch zu Ende fahren dann anhalten
lieber Patrick,
Ich war jetzt selbst überrascht wie viel Code das ergibt, wenn man es als Schrittkette programmiert.
Ich habe es im "Trockenlauf" per serial Debug-Ausgaben getestet. Es funktioniert.
Du wirst vermutlich eine Menge fragen zu diesem Code haben.
Dann Frage einfach drauflos
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope
#define dbgi(myFixedText, variableName,timeInterval) \
do { \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
} while (false);
const byte stepPin = 4;
const byte dirPin = 5;
const byte buttonPin = 6;
int SchrittZahl;
const byte nachOben = LOW;
const byte nachUnten = HIGH;
#define losgelassen HIGH
#define gedrueckt LOW
int StepCounter = 0;
boolean IstOben = false;
boolean MerkerTasteGedrueckt = false;
const byte WarteAufStart = 0;
const byte MotorStartRauf = 1;
const byte MotorStartRunter = 2;
const byte SchritteAusgeben = 3;
const byte CheckTastenDruck = 4;
const byte RichtungsWechsel = 5;
byte SchrittNr = WarteAufStart;
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - expireTime >= TimePeriod ) {
expireTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
buttonPressedForSomeTime();
SchrittKetteSchrittMotor();
}
void EinenSchrittAusgeben() {
digitalWrite(stepPin, HIGH);
delayMicroseconds(4000);
digitalWrite(stepPin, LOW);
delayMicroseconds(4000);
}
void SchrittKetteSchrittMotor() {
dbgi("sk", SchrittNr, 1000);
switch (SchrittNr) {
case WarteAufStart:
if (MerkerTasteGedrueckt == true) {
dbg("sk Taster gedrueckt", IstOben);
MerkerTasteGedrueckt = false;
SchrittNr = RichtungsWechsel;
}
break;
case MotorStartRunter:
dbg("sk MotorStartRunter", IstOben);
digitalWrite(dirPin, nachUnten);
SchrittZahl = 180;
SchrittNr = SchritteAusgeben;
break;
case MotorStartRauf:
dbg("sk MotorStartRauf", IstOben);
digitalWrite(dirPin, nachOben);
SchrittZahl = 180;
SchrittNr = SchritteAusgeben;
break;
case SchritteAusgeben:
//dbg("sk SchritteAusgeben", SchrittZahl);
EinenSchrittAusgeben();
SchrittZahl--;
if (SchrittZahl <= 0) {
SchrittNr = CheckTastenDruck;
}
break;
case CheckTastenDruck:
if (MerkerTasteGedrueckt == true) {
dbg("sk CheckTastenDruck", 99);
MerkerTasteGedrueckt = false;
SchrittNr = WarteAufStart;
}
else {
SchrittNr = RichtungsWechsel;
}
break;
case RichtungsWechsel:
dbg("sk RichtungsWechsel", IstOben);
if (IstOben == true) {
IstOben = false;
SchrittNr = MotorStartRunter;
}
else {
IstOben = true;
SchrittNr = MotorStartRauf;
}
}
}
// function for debouncing a button
void buttonPressedForSomeTime() {
// Variables will change:
static byte buttonState; // the current reading from the input pin
static byte lastButtonState;// = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
static unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
const unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
static byte debouncedState = 0;
static byte reading;
// read the state of the switch into a local variable:
reading = digitalRead(buttonPin);
//dbg("b1", reading);
//dbg("b1", digitalRead(buttonPin));
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
//dbg("reading !=lastlastButtonState",reading);
//delay(500);
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
//dbg("3(millis() - lastDebounceTime) > debounceDelay)",millis() - lastDebounceTime);
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
//dbg("reading != buttonState", buttonState);
// ButtonState does state-CHANGE-detection
if (buttonState == gedrueckt) {
MerkerTasteGedrueckt = true;
debouncedState = 1;
}
if (buttonState == losgelassen) {
debouncedState = 0;
}
}
}
// save the reading. Next time through the loop, it'll be the lastButtonState
lastButtonState = reading;
return debouncedState;
}