Motor mit millis ansteuern

Moin,
ich bin jetzt seit etwa einem Monat mit dem Arduino am "rumgespielt" und hab viel aus Foren oder Büchern abgeschaut.
Außerdem bin ich gelernter Elektroniker für Automatisierungstechnik und wollte mich jetzt an die Mikrocontoller und der C# Programmierung zuwenden.

Nun wollte ich ein eigenes Projekt Starten, welches den Eingang Zählt und nach 10 Impulsen einen Motor für eine bestimmte Zeit ansteuert. Da das Programm wärend der Motor dreht weiterhin die Schritte zählen soll, kommt einen delay abfrage ja nicht in frage.
Leider komme ich mit der millis abfrage nicht ganz zurecht.

Zu meinem Problem:
Momentan hab ich zum Testen alles auf einem Steckbrett mit Leds aufgebaut.

Ich hab es soweit geschafft das der Ausgang nach jedem 10. Impuls angesteuert wird.
Zur Übersicht hab ich eine Led für den Zähler genommen, die auf LOW gesetzt wird sobald der Zähler die 10 Impulse hat.
Für den Motor hab ich eine 2. Led an Pin 5 angeschlossen, die nach den ersten 10 Schritten auch anfängt zu leuchten.
Da ich im Internet aber nur millie abfragen gefunden habe, wo etwas zum blinken gebracht wird, wundert es mich eigentlich nicht das mein Ausgang nun auch in einem Interval blinkt.
Ich bekomme es einfach nicht hin,dass nach der eingestellten Zeit der Ausgang wieder auf Low gesetzt wird und auf die nächsten 10 Schritte wartet.

Kann so etwas überhaupt mit millis realisiert werden?
Über Tipps und Hilfe wäre ich dankbar.

Gruß Niklas

// Taster
const int Taster = 2;

//Taster Werte für Zähler
int tasterWert = 0;
int vorherTasterWert = 0;

//Taster Werte für LED
int Zaehlerhoch = 0;
int vorherZaehlerhoch = 0;

//Zählervariable

int zaehler = 1; // Zähler bis 10
int zaehlerM = 0; // Zähler für Motor

//Ausgang Led
const int LED10 = 6;    // LED für Zähler = 10 ?
const int Motor = 5;    // LED für Motor

// Led Start zustand

boolean value = LOW;    // LED Motor 1 oder 0 Wert speicher
boolean LED = LOW;


unsigned long previousMillis = 0;   // speichert den aktuellen Led Wert
unsigned long interval = 3000;    // Interval zwischen zwei Änderungen

void setup() {

Serial.begin(9600); // Übertragung Seriel Monitor

pinMode(Taster, INPUT);
pinMode (LED10, OUTPUT);
pinMode (Motor, OUTPUT);
digitalWrite(5, value);
digitalWrite (6, LED);
}

void loop() {

  unsigned long currentMillis = millis(); // grab current time

  // Serial Abfrage Zähler
  Serial.print("zaehler = " );
  Serial.println(zaehler);

  // Serial Abfrage ZählerMotor
  Serial.print("zaehlerMotor = " );
  Serial.println(zaehlerM);
 

  // Abfrage LED
  
    Zaehlerhoch = digitalRead(LED10);
    
// Zähler Led hochzählen
if(vorherZaehlerhoch != Zaehlerhoch){
  if (Zaehlerhoch == HIGH) {
    zaehlerM++; // Zähler hochzählen (+1)
      }
}
// Speicher aktueller Zählwert Motor
vorherZaehlerhoch = Zaehlerhoch;


// Taster Zählen


  // Abfrage des Tasters
  tasterWert = digitalRead(Taster);
  
//Ist vorheroger Tastwert ungleich aktuellem Tasterwert ?

  if(vorherTasterWert != tasterWert){
  if (tasterWert == HIGH) {
    zaehler++; // Zähler hochzählen (+1)

      }
}

// Speicher aktueller Tastwert
vorherTasterWert = tasterWert;



// ist Zähler durch 10 Teilbar
if(zaehler%10 == 0) 
digitalWrite(LED10, LOW);

else
digitalWrite(LED10, HIGH);
delay (150);

// Motor für eine bestimmte Zeit ansteuern

  
if(zaehlerM != Zaehlerhoch){
  
  if ((unsigned long)(currentMillis - previousMillis) >= interval) {
  
   value = !value; // Led Zustand wechseln
   digitalWrite(5, value); // Led wert am Ausgang setzen
   // Aktuelle Zeit speichern
   previousMillis = millis();

   }
  }
}

Gehen wir mal davon aus, dass Dein Eingangssignal prellfrei ist.

Dann zählst Du die Impulse hoch, und erst beim 10. Impuls startest Du den Motor und merkst Dir millis.
Jetzt erst kommt dann die Abfrage, ob die Zeit schon wieder für den Motor abgelaufen ist, wenn ja wird selbiger wieder abgeschaltet und das Spiel beginnt von vorne.

Was ist eigentlich, wenn innerhalb der Motorlaufzeit weiter Impulse kommen? Ignorieren, Zeit verlängern?

Hallo,
endlich mal jemand, der bei einem Taster eine Flankenabfrage macht :smiley:

previousMillis = millis(); hat die falsche Position, hinter digitalWrite(LED10, LOW); wäre möglicherweise besser und wo wird zaehlerM verändert?

Willkommen im Forum!

Wow danke für die schnellen Antworten.

@Klaus_ww
ja genau Eingang ist entprellt.
Die abfrage der Zeit hab ich jetzt unter den Zähler gesetzt wie agmue geschrieben hat.

und dann kommt mein problem, dass ich dem Motor irgendwie sagen muss das er nach der Zeit wieder aufhören kann zu drehen. In moment ist es so, das er nach den ersten 10 Impulsen zwar an geht aber dann immer im Interval weiter an bleibt.

Die Impulse sollen beim Motor laufen weiter gezählt werden, damit er dann nach den nächsten 10 wieder anfängt zu drehen.

Es geht um eine Drahtführung, wo nach jedem 10. Impuls wieder Draht nachgegeben werden soll.

@agmue
Ist da etwas falsch dran? hab mich an andere gehalten die so etwas gemacht haben und hielt es für Sinnvoll :smiley:
Hab die Abfrage der Zeit jetzt umgesetzt und bekomme jetzt nach den ersten 10 Impulsen ein schnelles blinken wo ich nicht weiß wo die schnelle Frequenz her kommt und anschließend ein etwas langsames Blinken kontinuierlich, bis ich bei 10 Impulsen wieder das schnelle Blinken habe.

zaehlerM soll der Zähler sein, der die LED10 abfragt und dann immer einen nach oben zählt.
wird der zaehlerM um einen Wert verändert, soll der Motor für eine bestimmte Zeit angehen.
Mir viel nicht anderes eingefallen wie ich unten die Abfrage machen soll, das scheint aber soweit zu funktionieren, zumindest verändert sich die LED die in moment den Motor simuliert bei einem wechsel des Zählwerts.

// Abfrage LED

Zaehlerhoch = digitalRead(LED10);

// Zähler Led hochzählen
if(vorherZaehlerhoch != Zaehlerhoch){
if (Zaehlerhoch == HIGH) {
zaehlerM++; // Zähler hochzählen (+1)
}
}

// ist Zähler durch 10 Teilbar
if(zaehler%10 == 0){
digitalWrite(LED10, LOW);
previousMillis = millis();

}

else{
digitalWrite(LED10, HIGH);
delay (150);
}
// Motor für eine bestimmte Zeit ansteuern

if(zaehlerM != Zaehlerhoch){

if ((unsigned long)(currentMillis - previousMillis) >= interval) {

value = !value; // Led Zustand wechseln
digitalWrite(5, value); // Led wert am Ausgang setzen
// Aktuelle Zeit speichern
// previousMillis = millis();

}
}
}

Ich werde noch einmal weiter Probieren etwas an der Abfrage der Zeit zu verschieben

Danke für eure Hilfe. Ich hab es hinbekommen
Hab das komplette Programm noch einmal erneut geschrieben nach diesem Aufbau hier:

Nur hab ich noch ein kleines "Problem".
Bleibt der Zähler bei Ablauf des Intervals durch 10 teilbar, schaltet sich die Led nur kurz aus und dann wieder an, weil alle Bedingungen dafür erfüllt sind.

Mir würde nur einfallen den Zähler automatisch einen hoch zählen zu lassen,
somit wäre ja die Bedingung "durch 10 Teilbar" nicht mehr gegeben.

Da die Lösung mir nicht optimat vorkommt, hat jemand vielleicht eine bessere Idee?
oder kann ich das so umsetzen ?

edit: Zähler einfach wieder auf Startwert ändern.

Hier der fertige Code falls noch jemand dabei Probleme hat.

Dankeschön

// Taster
int Taster = 2;

//Taster Werte für Zähler
int tasterWert = 0; // Aktuell
int vorherTasterWert = 0; //alter Tasterwert

// Ausgang
int Motor = 6;
int Motorstatus = LOW; // Zustand bei Start

//Zählervariable

int zaehler = 1; // Zähler bis 101

unsigned long Motor_timestore;     // Motor Zeitspeicher
unsigned long interval = 5000;    // Interval zwischen zwei Änderungen festlegen

void setup() {

  Serial.begin(9600);

  pinMode (Taster, INPUT);
  pinMode (Motor, OUTPUT);
  
}

void loop() {
{
   // Serial Abfrage Zähler
  Serial.print("Zaehler = " );
  Serial.println(zaehler);

}
{{
  // Abfrage des Tasters
  tasterWert = digitalRead(Taster);
  
//Ist vorheroger Tastwert ungleich aktuellem Tasterwert ?

  if(vorherTasterWert != tasterWert){
  if (tasterWert == HIGH) {
    zaehler++;}}} // Zähler hochzählen (+1)

   // Speicher aktueller Tastwert
    vorherTasterWert = tasterWert;}

    if (Motorstatus == LOW){          // Wenn Motor LOW
     if (zaehler == 11){              // und Zähler bei 11
        digitalWrite (Motor, HIGH);   // dann Motor HIGH
        Motor_timestore = millis();   // Einschaltzeit des Motors in millis merken
        Motorstatus = HIGH;           // Ändern des Motorstatus
        zaehler = 1;                  // Zähler wieder auf 1 setzen

  }}  else {
    if (millis() - interval > Motor_timestore){ // Wenn millis - Interval = Einschaltzeit 
      digitalWrite(Motor, LOW);                 // Motor ausschalten
      Motorstatus = LOW;                        // Status Motor LOW
    }     
  }

}

Ich sehe keine LED in deinem Code.