INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Arduinotaster
11.03.2015, 08:36
Beitrag #1
Arduinotaster
Ich versuche mich gerade an einer Ampelschaltung mit Taster.
Ich habe das Problem, dass der Taster nur funktioniert, wenn er dauerhaft gedrückt wird. Das normale Ampelprogramm läuft ohne Probleme.
Weiß jemand eine Lösung?
Vielen Dank schonmal
LG Cola
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.03.2015, 11:17 (Dieser Beitrag wurde zuletzt bearbeitet: 11.03.2015 11:33 von marcus.)
Beitrag #2
RE: Arduinotaster
Hallo Cola,

ohne den Quellcode (und ggf. die Schaltung) wird es schwierig dein Problem zu identifizieren.

Ich nehme an dass Du eventuell mit delay() gearbeitet hast?

In der Zeit kann nichts anderes geschehen.

Code:
delay(3000); //Alles pausiert 3 Sekunden
if(digitalRead(TASTE)){  } //wird erst nach dem Delay abgefragt

Nützlich ist millis(), denn es gibt die Millisekunden seit Programmstart aus. So kann man ohne Delay die Zeit messen.

Hier ein schnelles Beispiel für Blink ohne Delay (achtung, es wird getrickst)
Code:
    if(millis()  > gespeicherteZeit+1500  ) //edit:besser millis()-1500 >zeit wg. overflow
    {
        digitalWrite(13,!digitalRead(13));
        gespeicherteZeit=millis();
    }
millis() muss hier größer als gespeicherteZeit (Anfangs 0) plus 1500 Millisekunden sein.
Wenn das zutrifft, wird der Zustand der LED an Pin 13 negiert ("!"), also aus HIGH wird LOW und umgekehrt.

Mit einer Ampelschaltung wird das natürlich etwas komplizierter.
Hier ebenfalls ein Schnellschuss, der nicht ganz korrekt ist (Die LED wird unnötiger Weise ständig geschaltet).


Hier mal ein schnell heruntergetipptes Beispiel, dass zumindest in UnoArduSim funktioniert. Die Formatierung hat es z.T. beim Kopieren und Einfügen zerschossen.
Es geht sicher effizienter, aber ich muss jetzt weg :-)
Code:
unsigned long zeitvariable,ZyklusZuletztKomplett;
byte rot=1, gelb=2, gruen=3, eingang=9;
boolean taster;
int        
GruenGelb=5000, //Gruenphasendauer
GelbRot=500,
RotGelb=4000, //Rotphase
GelbGruen=500,
FussgaengerModifikator ;


void setup()
{

//Das Programm unten benötigt absolute Zeitwerte (Grün nach X Sekunden Gesamtzeit, Rot nach Y Sekunden Gesamtzeit)     
    GelbGruen+=RotGelb; //addieren der Abfolgen um absolute Zeitwerte zu erhalten
    GruenGelb+=GelbGruen;
    GelbRot+=GruenGelb;
    
    pinMode(rot ,OUTPUT);
    pinMode(gelb ,OUTPUT);
    pinMode(gruen ,OUTPUT);
    
    pinMode(eingang ,INPUT);
    
    digitalWrite(rot,HIGH);            // o Rogänger Totgänger
    
    
}

void loop()
{
    
    taster=digitalRead(eingang); // JE nach Pullup oder Pulldownwiderstand mit ! negieren
    
    //berechnet die Millisekunden seit dem der Ampelzyklus das letzte mal durchlief. Der Taster wird später die Zeit verkürzen.
    zeitvariable=millis()-(ZyklusZuletztKomplett-FussgaengerModifikator );
    
    
    //Am besten liesst man die folgende IF-Konstruktion von unten, da der kleinste Zeitwert unten steht
    // (Quasi so: if(>800)aufrot/reset <- else if(>600)aufgelb <- else if (>400)aufgrün <- else if (>200)aufgelb) <--hier anfangen zu lesen
    
    //prüft den Timer mit den angebebenen Ampelphasenzeiten
    if(zeitvariable>GelbRot)
    {
        zeitvariable=0; FussgaengerModifikator=0; //Zurücksetzen
        ZyklusZuletztKomplett=millis();
        
        digitalWrite(rot,HIGH);            // o
        digitalWrite(gelb,LOW);            //
        //    digitalWrite(gruen,LOW);    //
        
    }
    else if(zeitvariable>GruenGelb)
    {
        //    digitalWrite(rot,LOW);        //  
        digitalWrite(gelb,HIGH);            // o
        digitalWrite(gruen,LOW);            //
    }
    else if(zeitvariable>GelbGruen)
    {
        //    digitalWrite(rot,LOW);        //  
        digitalWrite(gelb,LOW);            //  
        digitalWrite(gruen,HIGH);            // o
    }
    else if(zeitvariable>RotGelb)
    {
        digitalWrite(rot,LOW);            //  
        digitalWrite(gelb,HIGH);            // o
        //    digitalWrite(gruen,HIGH);    //  
    }
    
    //wenn der Taster betätigt wird UND die (Auto)Ampel gerade grün ist, aber noch nicht kurz vorm Umspringen, sorge dafür
    // (ZyklusZeit um die Differenz zum Ampelaumschaltzeit erhöhen)
    if( taster && zeitvariable>GelbGruen && zeitvariable<GruenGelb ){    FussgaengerModifikator = GruenGelb-zeitvariable; }
    
}
Ich weiß, nicht hübsch, aber mal so als schnelles Beispiel. Es gibt zig (Bessere) Lösungen, zudem kann man mit Interrupts und Timern arbeiten.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste