Ansteuerung einer Schiebetür. Brauche Hilfe / Tipps und Verbesserungen

Hallo Zusammen,

ich brauche eure Hilfe bei meinem Sketch!!!!

Mein Ziel ist es eine Schiebetür (Modell) sowie eine Beleuchtung über einen Gestensensor (APDS9960) anzusteuern. Der Motor der Schiebetür soll so lange in den Rechtslauf, bzw. Linkslauf bis die Türe je einen Grenztaster überfährt, dort sollte der Motor gestoppt werden und kann nur noch in die gegengesetzte Richtung drehen. Zwischen den Grenztastern sollte der Motor jederzeit die Richtung wechseln können.

Mein Problem ist nun die Bedingung mit dem Abschalten und der Verweigerung der Richtung zu realisieren. Momentan ist es so, dass wenn ich einen Grenztaster betätigt halte, der Motor nicht mehr bewegt werden kann.

Ich hoffe ihr versteht was ich meine. ^^

Würde mich mega über Tipps und evt. Lösungen freuen!!!

Hier seht ihr den aktuellen Sketch:

// DIC / DIO ist für DOOR IS CLOSE / OPEN,
Wischbewegung nach links = Türe schliesst,
Wischbewegung nach rechts = Türe öffnet

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *LED = AFMS.getMotor(1);
Adafruit_DCMotor *Motor = AFMS.getMotor(2);

//Taster inputs
const int DIC = 2;     
const int DIO = 4;
int buttonstate1 = 0;
int buttonstate2 = 0;

#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;

// the setup function runs once when you press reset or power the board
void setup() {
 
 // Taster einlesen:
 pinMode(DIC,INPUT);
 pinMode(DIO,INPUT);
 
 //Motorshield einlesen:
 AFMS.begin();
 
 //Gestensensor einlesen:
  Serial.begin(115200);
 
 if(!apds.begin()){
   Serial.println("failed to initialize device! Please check your wiring.");
 }
 else Serial.println("Device initialized!");

 //gesture mode will be entered once proximity mode senses something close
 apds.enableProximity(true);
 apds.enableGesture(true);
}

// the loop function runs over and over again forever
void loop() {
 
 //read buttonstate
 buttonstate1 = digitalRead(DIC);
 buttonstate2 = digitalRead(DIO);
 
 if(buttonstate1 == HIGH){
 Motor->run(RELEASE);
}
 if(buttonstate2 == HIGH){
   Motor->run(RELEASE);
}
  
 //read a gesture from the device
 
   uint8_t gesture = apds.readGesture();
   if(gesture == APDS9960_DOWN) Serial.println("LED OFF"),LED->run(RELEASE),Motor->run(RELEASE);

   if(gesture == APDS9960_UP) Serial.println("LED ON"),LED->setSpeed(255), LED->run(FORWARD);

   if(gesture == APDS9960_LEFT) Serial.println("DOOR CLOSE"),Motor->run(RELEASE),delay(1000),Motor->setSpeed(255),Motor->run(BACKWARD);

   if(gesture == APDS9960_RIGHT) Serial.println("DOOR OPEN"),Motor->run(RELEASE),delay (1000),Motor->setSpeed(255),Motor->run(FORWARD); 
   }

BP_Projekt_ET_mit_Taster.ino (1.8 KB)

Du darfst nicht den Zustand der Endtaster abfragen, sondern die Flanke.
Dann reagiert dieser nur beim Flankenwechsel bspw. von HIGH nach LOW. Somit wird die Steuerung anschließend wieder freigegeben.

Hallo Dieter,

Vielen Dank für diesen Tipp! :smiley:

Hallo ,

Irgendwie krieg ich das mit der Flankenerkennung nicht hin, da ich nicht so ganz verstehe wie ich das Programm
anpassen muss.

Kann mir jemand helfen ?

Du musst Dir den alten Zustand merken.

neu = digitalRead(Pin);
if (alt && !neu) { // fallende Flanke alt war HIGH und neu ist LOW -- if (!alt && neu) wäre steigende Flanke
  alt = neu;
  // tu was
}

Gruß Tommy

Hallo,

wenn ich Dich richtig verstanden habe gehts Dir eigendlich um die Logik mit der Du nicht zurecht kommst, Da ich weder so ein Wischding habe und auch keine Motorshield, habe ich was aus meinem Fundus mit 4 Tastern rausgesucht. Die beiden Ausgänge für Motor rechts ein, Motor links ein hab ich zum Testen auf dem UNO mit zwei LED über Widerstand verbunden. Eigendlich gehört noch ein 5 Taster dazu der anhalten kann, den hab ich jetzt mal weggelassen. Gefahren wird also immer bis zum Endschalter oder es wird die Richtung umgeschaltet.

Anpassen must Du das selber. Die Taster schalten nach 0V und werden beim einlesen invertiert damit arbeitet das Programm mit positiver logik. Wenn Deine Endschalter Öffner sind must Du das anpassen und das Negieren für die beiden Signale weg lassen.

Die Taster hab ich zunächst mal eingelesen und auf bool Werte gelegt, das verträgt sich besser mit der Abfrage auf true & false . Am Ende werden die beiden Boolwerte für die beiden LED auf Ausgänge gelegt. Da musst Du dann halt die Ansteuerung für das Motorshield verwenden.

in der Art:

if(mlinks==true){
sollwert setzen;
Motor ein;
}
else{
sollwert=0;
Motor aus;
}

// Eingänge festlegen
const byte T_links = 2; // Taster
const byte T_rechts = 3;
const byte ES_links = 4; // Endschalter 
const byte ES_rechts = 5;

// Ausgänge festlegen
const byte M_links = 11;
const byte M_rechts = 12;

// interne Flags
bool tlinks, trechts, elinks, erechts;
bool mlinks, mrechts;
bool debug = false ;// zum testen auf true setzen 

void setup() {
  Serial.begin(9600);

  pinMode(T_links, INPUT_PULLUP);
  pinMode(T_rechts, INPUT_PULLUP);
  pinMode(ES_links, INPUT_PULLUP);
  pinMode(ES_rechts, INPUT_PULLUP);
  pinMode(M_links, OUTPUT);
  pinMode(M_rechts, OUTPUT);
}

void loop() {
  //eingänge lesen und invertieren

  tlinks = !digitalRead(T_links);
  trechts = !digitalRead(T_rechts);
  elinks = !digitalRead(ES_links);
  erechts = !digitalRead(ES_rechts);

  if ( debug) {
    // Anzeige Eingänge zu testen
    Serial.print(tlinks); Serial.print("\t");
    Serial.print(trechts); Serial.print("\t");
    Serial.print(elinks); Serial.print("\t");
    Serial.print(erechts); Serial.print("\t");
    Serial.print(mlinks); Serial.print("\t");
    Serial.print(mrechts); Serial.println();
    delay(100);
  }
  if (tlinks == true) { // nach links fahren
    mrechts = false;
    delay(100);
    mlinks = true;
  }

  if (trechts == true) { // nach rechts fahren
    mlinks = false;
    delay(100);
    mrechts = true;
  }

  if (elinks)mlinks = false; // wenn Endschalter erreicht dann aus
  if (erechts)mrechts = false;

  digitalWrite(M_links, mlinks); // auf Ausgänge legen 
  digitalWrite (M_rechts, mrechts);

}

Du darfst nicht den Zustand der Endtaster abfragen, sondern die Flanke.
Dann reagiert dieser nur beim Flankenwechsel bspw. von HIGH nach LOW. Somit wird die Steuerung anschließend wieder freigegeben.

Verstehe ich nicht. ( Oder ich sehe das anders )
In Endlage sollte der jeweilige Schalter permanent betätigt bleiben, und ein Weiterfahren (nur in diese Richtung) verhindern?

Ich verstehe es so, dass die Gesten als Ereignisse kommen
Und der Motor bis zum Endschalter läuft, oder bis evtl. ein anderer Befehl kommt.

Bei dir stoppt jeder Endschalter alles, und jede Geste stoppt den Motor kurz und lässt ihn dann in jedem Fall erstmal weiterlaufen. (Wenn auch evtl. nur so kurz, dass man es nicht merkt)

Das willst du nicht.

Musst du nur die if Bedingungen ändern...

Hallo
@Michael
ich sehe das genauso wie Du , die Enschalter Flanke auswerten macht keinen Sinn. Wenn er dann drauf steht könnte man ja in die gleiche Richtung noch mal weiterfahren.

@Mavic99
Ich habe aber auch den Sketch nicht verstanden, vermute das ist was beim past&kopie verloren gegangen, ich sehe nicht wo der Motor überhaupt wieder ausgeschaltet wird. Ich kenne aber auch die LIb nicht. Mir ist auch nicht klar ob die Endschalter bei H oder L anschalten sollen ??

die 4 If Abfragen unten machen auch keinen Sinn Vor zurück ja , aber warum noch hoch runter Vermute da soll nur eine LED mit ein und aus geschaltet werden und das ist übrig geblieben von einem Beispiel , da hast Du was falsch kopiert.

@Rentner: Bei Deinem Programm aus #5 erschließt sich mir die Bedeutung der delays nicht:

  if (tlinks == true) { // nach links fahren
    mrechts = false;
    delay(100);
    mlinks = true;
  }

  if (trechts == true) { // nach rechts fahren
    mlinks = false;
    delay(100);
    mrechts = true;
  }

Hallo
@Michael, @Rentner, @agmue

Erstmals Danke das ihr euch die Zeit nehmt um mir zu helfen!

Die Steuerung sollte so funktionieren wie Michael das beschrieben hat.
Die Endschalter werden permanent betätigt werden sobald die Schiebetür drauf fahrt. (Die Endschalter sind Schliesser Kontakte bzw. ein HIGH). Es sollte nur die Weiterfahrt in diese Richtung verhindert werden.

Z.B. Türe ist offen = Wischbewegung nach rechts wird verhindert, Wischvewegung nach links, oben und unten gehen weiterhin.
Und das Ganze dann einfach auf der anderen Seite auch.

Die LED hab ich auf den Motorshield M1 angegängt, weil es praktisch war und damit ich den Motor abschalten kann hab ich nur provisorisch diese Befehle eingebaut, der Motor sollte nur durch die Endschalter angehalten werden können.

Gruss Mavic

MAVIC99:
Die Steuerung sollte so funktionieren wie Michael das beschrieben hat.

Dann schnappe Dir das Programm aus #5 und passe es an Deine Hardware an.

michael_x:
Verstehe ich nicht. ( Oder ich sehe das anders )
In Endlage sollte der jeweilige Schalter permanent betätigt bleiben, und ein Weiterfahren (nur in diese Richtung) verhindern?
.....

Ich bezog mich mit meiner Aussage auch auf den vom TO geposteten Sketch.

Natürlich kann man es auch anders/besser lösen. :wink:

Hi

Ich will hier ja niemandem den Spaß am Programmieren nehmen, aber ein simples 'Fahren, bis der Endschalter erreicht' - sogar mit auszuwählender Richtung (sowohl AC wie DC), lässt sich ganz stupide mit Relais realisieren.

Klar: Nicht Alles, was man 'irgendwie' auch machen kann, ist deshalb für eine µC-Lösung gestorben.
(und eine H-Brücke ist wohl eher vorhanden nebst Arduino, als ein Sack voll Relais)

MfG