Schiebetür mit 2XPIR

Hallo zusammen, versuche eine Schiebetür mit 2 PIR sensoren zu steuern, funktioniert soweit , jedoch möchte ich das beim schliessen wenn eine bewegung statt findet das der servo stopt und wieder öffnet, in diesem fall wird zwar die bewegung erkannt aber die tür schliesst erst und dann öffnet die sich, was oder wie kann man das anstellen?

const int stepPin = 5; 
const int dirPin = 6; 

int NpirPin = 12;    
int SpirPin = 11;
 
void setup() {

  pinMode(NpirPin, INPUT);
  pinMode(SpirPin, INPUT);

  digitalWrite(NpirPin, LOW);
  digitalWrite(SpirPin, LOW);

  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);

}

void loop(){

    int val1 = digitalRead(NpirPin);
    int val2 = digitalRead(SpirPin);

  if(val1 == HIGH) { digitalWrite(dirPin,HIGH); 

  for(int x = 0; x < 2200; x++) 
  {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }

  delay(5000);
 
  digitalWrite(dirPin,LOW); 

  for(int x = 0; x < 2200; x++) 
  {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
 }

  if(val2 == HIGH) {digitalWrite(dirPin,HIGH); 

  for(int x = 0; x < 2200; x++) 
  {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }

 delay(5000);
   
 digitalWrite(dirPin,LOW);

  for(int x = 0; x < 2200; x++) 
  {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
 }
 
}

Hast Du nun Servos oder Schrittmotore?

Sagen wir mal Schrittmotore. Du mußt nach jedem einzelnen Schritt schauen ob ein PIR ein Signal gibt und die Schleife verlassen. Ich würde die Schleife nicht mit for machen sondern manuell mit incrementieren und if. Siehe auch endlicher Automat, millis() und Nachtwächtererklährung.

Grüße Uwe

Halllo,

na ja , so wird das nix,

du fährst in einer for Schleife den Motor immer eine Schritt weiter und warterst dann mit delay 500us . Damit kannst Du wärend des Fahrens den Sensor nicht erkennen. Du willts ja eigendlich wenn der Sensor erkannt wird das hoch- runterzählen stoppen und damit den Motor anhalten.

die for schleifen mussen weg
alle delay() muss raus und durch millis() ersetzt werden.

schau dir das Beispiel blink without delay an , verstehe es , und schreibe Deinen Skeckch um.

Heinz

guccini: ... wie kann man das anstellen?

Du möchtest im Grunde mehrere Sachen gleichzeitig machen: Die Tür bewegen und gleichzeitig kontrollieren, ob da was im Weg ist. Dazu musst Du vermutlich - ich habe Deinen Code nicht gelesen - die „Programmierstrategie“ ändern. Evtl. ist mein Geschreibsel zum endlichen Automat hilfreich.

Gruß

Gregor

uwefed: Hast Du nun Servos oder Schrittmotore?

Ja ist ein Schrittmotor, wie würdest du das machen?

Rentner: na ja , so wird das nix,

ist mir bewusst ,deswegen habe ich hier im forum um hilfe gebeten

gregorss: Du möchtest im Grunde mehrere Sachen gleichzeitig machen....

richtig , gibt es ein ähnlichen code mit schrittmotor am besten mit erklärung?

Danke für eure Hilfe

Wenn Du mehrere Sachen quasi gleichzeitig machen willst, sind diese for-Schleifen (die blockieren für 2,2 Sekunden) und delay(5000) Gift für Deinen Ablauf. Du brauchst keine for-Schleife, Du hast doch loop als große Schleife.

Für die Zeitsteuerung schau Dir BlinkWithoutDelay an und [u]verstehe[/u] es. Dabei kann Dir die Nachtwächtererklärung helfen.

Gruß Tommy

Du möchtest im Grunde mehrere Sachen gleichzeitig machen....

richtig , gibt es ein ähnlichen code mit schrittmotor am besten mit erklärung?

Ich glaube nicht, dass es das gibt.

Lies Dir am besten mein Getexte durch. Wenn Du ein Codeschnipselchen hast, mit dem Du den Schrittmotor einen einzelnen Schritt machen lassen kannst und ein weiteres Schnipselchen zur Abfrage des IR-Sensors, ist die Kombination beider Schnipselchen zu dem, was Du möchtest, kein Hexenwerk.

Gnadenlos gut ist die von Tommy erwähnte Nachtwächter-Erklärung.

Gruß

Gregor

guccini: Ja ist ein Schrittmotor, wie würdest du das machen?

Du hast einmal Schrittmotor und einmal Servo geschrieben. Darum habe ich gefragt. Grüße Uwe

uwefed: Du hast einmal Schrittmotor und einmal Servo geschrieben. Darum habe ich gefragt. Grüße Uwe

Das ist ein Nema 17 an einen A4988 angeschhlossen

guccini: Das ist ein Nema 17 an einen A4988 angeschhlossen

NEMA17 sagt nur was über Baugröße (Flanschgröße) aber rein nichts zu den elektrischen Kenndaten. Darum kann ich Dir nicht bestätigen ob der Freiber für den Motor geeignet ist. Grüße Uwe

Habe versucht das mit millis() , jedoch nicht zu das was ich haben möchte

const int stepPin = 5; 
const int dirPin = 6; 
int NpirPin = 12;    
int SpirPin = 11;
unsigned long startzeit;
#define UMDREHUNG 2200

void setup() {
  pinMode(NpirPin, INPUT);
  digitalWrite(NpirPin, LOW);
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
}

void loop(){
    int val1 = digitalRead(NpirPin);
   
  if(val1 == HIGH) {
    if (millis() - startzeit > 5000){
     fwd(UMDREHUNG);
    startzeit = millis();
    }else{
     rwd(UMDREHUNG);
    }
  }
}

void fwd(int absolut) {
  int i;
  for(i=0;i<absolut;++i) {
    digitalWrite(dirPin,HIGH);
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}

void rwd(int absolut) {
  int i;
  for(i=0;i<absolut;++i) {
    digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}

Hi

Ohne den SKetch kompiliert/geprüft zu haben: Du benutzt immer noch je eine FOR-Schleife zum Öffnen bzw. Schließen der Tür. WAS, wenn während der Fahrt die Tochter sich noch gerade so durch die Tür quetschen will? Ja, einen Wischmopp brauchst Du auch noch!

loop() ist Deine Schleife - Die wiederholt sich IMMER und RASENDSCHNELL (sollte Sie zumindest). Bei JEDEM loop()-Durchlauf prüfst Du, was zu machen ist! Bei JEDEM!! Wenn einer der PIR was erkennt: TÜR-ÖFFNEN-AKTIVIEREN, Startzeit aktualisieren Wenn 'TÜR-ÖFFNEN-AKTIVIEREN' aktiv ist und die Tür noch nicht ganz auf ist, wird die Tür einen Schritt nach 'AUF' gefahren, Startzeit aktualisieren Wenn 'TÜR-ÖFFNEN-AKTIVIEREN' nicht aktiv ist und die Tür noch nicht ganz zu ist, die Tür einen Schritt ZU fahren. Wenn die Tür ganz offen ist, prüfen, ob die Wartezeit abgelaufen ist, wenn JA, 'TÜR-ÖFFNEN-AKTIVIEREN' deaktivieren

Das müsste Es im Groben gewesen sein. Man kann hier noch Zwischenzyklen einbauen - z.B., daß die Tür erst Bremst und ggf. auspendelt, bevor wieder in AUF-Richtung aufgefahren wird (bei Erkennung während der ZU-Fahrt) - Das ist Deiner Phantasie überlassen, was Da am Schluß Alles noch mit rein kommt.

MfG

Hallo,

ich will Dir mal ein wenig auf die Sprünge helfen und hab was aus meiner Bastelkiste zusammengewürfelt. Mein Ansatz ist zwar auch nicht optimal, die Impulsausgabe erfolgt wie bei Dir mit delayMicroseconds() was eigendlich immer noch blokiert, aber bei 500us sollte das keine Rolle spielen. Wenn die Loop Umlaufzeit steigt z.B mit einem Serial.print() der aktuellen Position wird die Ausgabefrequenz sinken und der Motor langsamer fahren. Das bekommt man aber sicher nur mit einem Zeitinterrupt hin.

Zudem habe ich nur einen Eingang als Sensor verwendet, aber du sollst ja auch noch was machen. Da ich keinen Schrittmotor habe hab ich zwei LED zum testen verwendet, sollte aber gehen. Das Sensorsignal bekommt einen Ausschaltverzögerung, Damit die Türe eine Zeit lang offen bleibt.

So jetzt bleibt nur noch das Problem das Du eigendlich beim starten eine Referenzfahrt machen müsstest . In meinem Beispiel fährt die Tür mal ganz auf und dann wieder zu. Damit könnte sie gegen den mechanische Anschlag fahren. Dem Motor schadet das eigendlich nicht, dennoch könnte mechanisch was kaputt gehen. Eigendlich müssten also noch ein paar Endschalter mit rein die bei erreichen der beiden Endlagen abschalten. Langsam beschleunigen und bremsen wurde ja schon angesprochen.

Gruß Heinz

/*
   Hardware UNO
   PIR signal positiv schaltend  mit 2K gegen 0V
   Verwendung einer delayoff Funktion
   Eine Schiebetüre wird mit Schrittmotor auf und zu gefahren

*/
// IN /OUT festlegen
const byte pir = 2;       // Pirsensor 1
const byte richtung = 3; // Ausgang Richtung
const byte puls = 4;     // Ausgang Puls
// Variable
bool sensor;// delayoff Pir signal
int pos;    // aktuelle Position
// Konstante
const int auf = 2200; // max position auf
const int zu = 0;     // min position zu
const unsigned long delayoftime = 5000UL;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pir, INPUT);
  pinMode(richtung, OUTPUT);
  pinMode(puls, OUTPUT);
}

void loop() {
  // Sensor lesen und delayOFF
  sensor = delayoff(digitalRead(pir), delayoftime);

  // -------------Türe öffnen
  if (sensor && pos < auf) {
    pos ++;
    digitalWrite(richtung, HIGH);
    stepout();
    if (pos == zu + 1)Serial.println("Tür öffnen ");
    if (pos == auf) Serial.println("Türe ist auf ");

  }
  // ------------Türe schliessen
  if (!sensor && pos > zu) {
    pos --;
    digitalWrite(richtung, LOW);
    stepout();
    if (pos == zu)Serial.println("Tür ist geschlossen");
    if (pos == auf - 1) Serial.println("Türe schliessen");
  }
}

void stepout() {
  // ------------- step ausgeben
  digitalWrite(puls, HIGH);
  delayMicroseconds(500);
  digitalWrite(puls, LOW);
  delayMicroseconds(500);
  //Serial.println(pos);
}

// function delayoff ---------------------
boolean delayoff(bool in, unsigned long dtime) {
  unsigned long  static alt_t;
  boolean static flag;

  if (in) alt_t = millis();
  if (millis() - alt_t > dtime) flag = false ;
  else flag = true;

  // Serial.print(in); Serial.println(flag);
  return flag ;
}

Rentner: ich will Dir mal ein wenig auf die Sprünge helfen.......

Hallo, ja das hast du , Vielen Dank...! Hat mir sehr geholfen aber da wäre ich nie drauf gekommen da so darzustellen.

Rentner: ....Langsam beschleunigen und bremsen wurde ja schon angesprochen.

Ja genau, wenn man die letzten 200 steps mit langsameren geschwindigkeit fahren möchte müsste ich so vorgehn? wie kann ich das in loop einfügen?

const int auf = 2200;     // max position auf
const int auf_a = 2000; // letzten 200 langsam fahren
const int zu = 0;           // min position zu
const int zu_a = 200;    //letzten 200 langsam fahren


void stepout_slow() {
  digitalWrite(puls, HIGH);
  delayMicroseconds(1500);
  digitalWrite(puls, LOW);
  delayMicroseconds(1500);
}

Hi

delayMicroseconds((step_jetzt>step_ab)?1500:1000);

Wobei ‘step_jetzt’ der aktuelle Schritt ist und ‘step_ab’ die Stelle, ab Der langsam gefahren werden soll.
Diese Variablen müssen entweder global sein, oder man übergibt Sie der Funktion - Letzteres ist vll. ganz sinnvoll, da Du ja in beide Richtungen verzögern willst und Deine Schritte-Zähl-Variable die Position der Tür darstellt.

Das ? ist eine IF-Abfrage, die eigentliche Abfrage steht davor (ich mache immer eine Klammer drum).
Die THEN-Rückgabe steht direkt hinter dem Fragezeichen, die ELSE-Rückgabe hinter dem Doppelpunkt.
An die Funktion delayMicroseconds() wird also als Rückgabewert 1000 oder 1500 gegeben, je nachdem, ob step_jetzt größer als step_ab ist.

Oder, Du baust die ?-Abfrage in Deine entsprechenden Fahrten ein, Da kannst Du dann statt > auch < als Abfrage benutzen und Alles ist wieder, wie’s sein soll.

Benenne Deine Variablen sinnig - zu_a ist nur eine Aufzählung und in zwei Wochen weiß Niemand mehr, was Das eigentlich bedeuten sollte, ohne den Sketch auseinander zu nehmen.

MfG

Hallo,
wie immer gibt es mehrere Möglichkeiten.
Du kannst der Funktion stepout() die Geschwindigleit mit übergeben und in die Bedingung beim auf und zu fahren eine zusätzliche If Bedinung für die position und langsam/schnell einbauen.

ich hab den Code jetzt nicht geteste nur hier im Brauser bearbeitet

schau dir das Thema Funktionen und Parameter an Funktionen (als Wert) übergeben an. Das kostet zwar etwas mehr Speicher als die Verwendung von globalen Variablen, macht manches aber übersichtlicher. Lass dich dabei nicht vom Thema Zeiger verwirren. Zeiger sind dabei sehr wichtig aber das kannst du dir für später aufheben. Wenn Du mehr als eine Variable von der Funktion zurück haben willst dann benutze dazu zunächst globale Variable.

Heinz

// -------------Türe öffnen
  if (sensor && pos < auf) {
    pos ++;
    digitalWrite(richtung, HIGH);
     if (pos > 200 && pos< auf-200]{
       stepout(500);// schnell fahren
       }
     else{
        stepout (1500);// langsam fahren
     }
    if (pos == zu + 1)Serial.println("Tür öffnen ");
    if (pos == auf) Serial.println("Türe ist auf ");
}

.
.
.


void stepout (int speed) {
  digitalWrite(puls, HIGH);
  delayMicroseconds(speed);
  digitalWrite(puls, LOW);
  delayMicroseconds(speed);
}

Wow…Nochmals VIELEN DANK…klappt so wie ich es mir vorgestellt habe, werde mal damit rumspielen und verstehn …!

Frage? könnte man das als TUT hier im Forum einsetzten , wäre echt Klasse und Hilfreich.

guccini: Wow.....Nochmals VIELEN DANK.....klappt so wie ich es mir vorgestellt habe, werde mal damit rumspielen und verstehn ....!

Frage? könnte man das als TUT hier im Forum einsetzten , wäre echt Klasse und Hilfreich.

Ich denke das kannst Du machen, Beschreibe Deine Aufgabenstellunug und etwas genauer und liefere Deine komplette Lösung mit dazu.

Heinz