Wenn ich 3mal auf den Schalter gedrückt habe.

OP #3025897
Lesenswert?

Natürlich kann ich bis drei zählen aber es nicht meinem Arduino bei 
bringen weil bei diesem Thema stehe ich auf dem Schlauch: muss ich while 
einsetzen oder for???
Da ich von diesen Befehlen nur die grobe Ahnung wie sie funktionieren 
und was sie bedeuten aber ich kann sie nicht genau anwenden.
So, zufrieden?
#3025901
Lesenswert?

In C vielleicht so, unter der annahme, dass ein drücken einen interrupt 
hervorruft:
1
// ....
2
volatile unsigned int counter = 0;
3
// ....
4

5

6
ISR(PCINT0_vect) {
7
   counter++;
8
   if(counter==3) {
9
      PORTB ^= (1<<PB0); //toggle PB0
10
      counter=0;
11
   }
12
}

oder kürzer:
1
// ....
2
volatile unsigned int counter = 0;
3
// ....
4

5

6
ISR(PCINT0_vect) {
7
   if(++counter==3) {
8
      PORTB ^= (1<<PB0); //toggle PB0
9
      counter=0;
10
   }
11
}
#3025909
Lesenswert?

Simon Name schrieb:
> Natürlich kann ich bis drei zählen aber es nicht meinem Arduino bei
> bringen weil bei diesem Thema stehe ich auf dem Schlauch: muss ich while
> einsetzen oder for???
> Da ich von diesen Befehlen nur die grobe Ahnung wie sie funktionieren
> und was sie bedeuten aber ich kann sie nicht genau anwenden.

Ich würde einen Zähler nehmen, auf neudeutsch "counter".
Gruss
Harald
Gast #3025911
Lesenswert?

Simon Name schrieb:
> Da ich von diesen Befehlen nur die grobe Ahnung wie sie funktionieren
> und was sie bedeuten aber ich kann sie nicht genau anwenden.
Dann wird es Zeit für den Klassiker (KHB wo bist du?): Kernighan & 
Ritchie, Programmieren in C, 2. Edition

Adrian Figueroa schrieb:
> volatile unsigned int counter = 0;
Wenn die Variable nur im Interrupt verwendet wird ist das volatile 
überflüssig.

Simon Name schrieb:
> Was bedeutet "ISR (PCINT0_vect)"???
GCC-Syntax für Interrupts. Keine Ahnung wie das beim Arduino geht.
Gast #3025914
Lesenswert?

Simon Name schrieb:
> Hi,
> ich wollte einen kleinen nützlichen Codeblock einbauen aber ich weiß
> nicht genau wie ich es schreibe:

Du hast so ziemlich ALLES vergessen was notwendig ist:
Was genau ist dein Problem?
Die Programmiersprache? Erlerne Sie zunächst, bevor du konkrete 
Eigenaufgaben angehen willst
Die Hardware? Die ist nur dir Bekannt, offensichtlich weißt du darüber 
aber auch nichts, geschweige denn kannst du sie ansteuern.

Nimm einen Counter (74xx4059) und ein paar Und-Gatter und beschalte sie 
entsprechend. Da benötigt es keinen Code (denn davon hast du keine 
Ahnung)

MFG
#3025918
Lesenswert?

die "ISR" ist eine Funktion, die aufgerufen wird, wenn ein Interrupt 
ausgelöst wird (etwa durch die Reaktion auf die Änderung eines PINs oder 
von einem Timer), wobei "PCINT0_vect" für eine Zustandsänderung der 
zuvor als "überwacht" festgelegten PINs steht. Dabei ist PCINT0 nicht 
etwa ein einzelner Pin, sondern die Zusammenfassung all derer, die du 
vorher zum Abfragen eingeschaltet hast. Die von mir vorgegebene Funktion 
schaltet bei jedem Ändern des Zustandes am Eingangspin, deswegen ist sie 
für dich gerade nicht geeignet, sie zählt auch das loslassen des 
schalters mit (und ein schwingen des schalters (--> 
http://arduino.cc/en/Tutorial/Debounce ):

Dass du mit Arduino arbeitest, hatte ich nicht gesehen, dazu gibt es was 
leichteres:

http://arduino.cc/en/Reference/AttachInterrupt
Gast #3025924
Lesenswert?

Simon Name schrieb:
> Da ich von diesen Befehlen nur die grobe Ahnung wie sie funktionieren
> und was sie bedeuten aber ich kann sie nicht genau anwenden.

Hmm... In diesem Falle: Wie wäre es damit, sich mit der Bedeutung dieser 
Befehle vertraut zu machen, sprich: Zu lernen, was diese bedeuten? Ich 
denke nicht, dass die Sprache C so komplex ist, dass man das nur mit 
Habilitation begreifen kann...
Zu meiner Zeit gab es so zusammengetüddeltes Papier mit schwarzen 
Hieroglyphen drauf - nannte sich wohl Buch bzw. Bücher. Aber heutzutage 
sollte eine einfache Google-Suche reichen, um ein C-Tutorial bzw. eine 
-Referenz zu finden...
OP #3025944
Lesenswert?

void setup () {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(13, OUTPUT);

}

void loop() {
  int Schalter;
  Schalter=digitalRead(2);
  Serial.println(Schalter, DEC);
  int zeahler=0;

  if(digitalRead(Schalter)==HIGH){
    zeahler++;
  }
    if(zeahler==3){
      digitalWrite(13, HIGH);
      delay(300);
      digitalWrite(13, LOW);
}
}

Mein Code aber er funktioniert nicht.
Gast #3025950
Lesenswert?

Da fehlt die Hälfte. Wie/Wo wird loop aufgerufen? Wenn das ganze 
mehrfach funktionieren soll muss noch eine Schleife drum. Und wenns in 
einer Extrafunktion ist die ständig aufgerufen wird muss die Variable 
static sein...
#3025953
Lesenswert?

doch doch, der funktioniert, die schleife läuft aber auf deinem 16Mhz 
prozessor ziemlich schnell! wenn du den schalter gedrückt hälst, zählt 
der zähler hoch und ist nur sehr kurz bei "3". du kannst ja noch einen 
delay einbauen:

du brauchst nicht zweimal den taster abzufragen.
1
void setup () {
2
  Serial.begin(9600);
3
  pinMode(2, INPUT);
4
  pinMode(13, OUTPUT);
5

6
}
7

8
void loop() {
9
  int Schalter=digitalRead(2);
10
  Serial.println(Schalter, DEC);
11
  int zeahler=0;
12

13
  if(Schalter==HIGH){
14
    zeahler++;
15
  }
16
    if(zeahler==3){
17
      digitalWrite(13, HIGH);
18
      delay(300);
19
      digitalWrite(13, LOW);
20
    }
21
  delay(200);
22
}
Gast #3025962
Lesenswert?

@Simon: Fehlt da nicht generell etwas drumherum was zunächst setup() und 
dann in einer Endlosschleife loop() aufruft?

Oder nimmt das der Arduino einem ab? Ich kenne mich leider nur mit 
echtem C aus...
#3025999
Lesenswert?

entschuldige, ich habe einen fehler übersehen. du setzt in dem code bei 
jedem durchlauf den counter auf 0. setz die initialisierung nach setup.
1
int zeahler=0;
2

3
void setup () {
4
  Serial.begin(9600);
5
  pinMode(2, INPUT);
6
  pinMode(13, OUTPUT);
7
}
8

9
void loop() {
10
  int Schalter=digitalRead(2);
11
  
12
  if(Schalter==1){
13
    zeahler++;
14
    delay(200);
15
  }
16
    if(zeahler==3){
17
      digitalWrite(13, HIGH);
18
      delay(300);
19
      digitalWrite(13, LOW);
20
    }
21
}
Gast #3026001
Lesenswert?

Simon Name schrieb:
> Ja was while ist weiß ich schon aber sorry wenn ich es doch nicht so
> genau anwenden kann

Wenn du in ein paar Jahren mal den Führerschein machen willst, wirst du 
doch auch nicht in der ersten Minute losfahren dürfen, weil du schon 
weißt, wie man die Hupe betätigt.
Du mußt vorher lernen, wozu das Lenkrad und die drei Pedale gut sind.
Gast #3026017
Lesenswert?

> unter der annahme, dass ein drücken einen interrupt hervorruft:

Bitte liebe Kinder macht das nicht, denn Taster prellen und ein uC macht 
daraufhin dutzende von Interrupts. Man erfasst Tster NIEMALS mit 
Interrupts.

Ausserdem: Wie lange dürfen denn die 3 Tastendrücke auseinanderliegen ? 
Jeden Tag einer ? Nicht vielleicht in 10 Sekunden alle 3 ?
1
#define TASTER 2
2
main()
3
{
4
  char taster;
5
  int dauer;
6
  char letzter=digitalRead(TASTER);
7
  while(1)
8
  {
9
    char dieser=digitalRead(TASTER);
10
    if(dieser&&!letzter) 
11
    {
12
      taster++;
13
      if(taster==3)
14
      {
15
        // mach das was du bei 3 Tastendrücken willst
16
        taster=0;
17
        dauer=0;
18
      }
19
    }
20
    letzter=dieser;
21
    delay(10); // länger als die Prellzeit
22
    if(taster>0)
23
    {
24
      dauer++;
25
      if(dauer>1000) /7 1000 x 10msec = 10 sec
26
      {
27
        taster=0;
28
        dauer=0;
29
      }
30
    }
31
 }
32
}
Gast #3026074
Lesenswert?

Adrian Figueroa schrieb:
> Der Timer interrupt ist ja sehr kurz, dann muss ich ja so kleine
> abtastabstände nehmen, dass die "drückzeit" des schalters höher ist
> (100ms vielleicht).. da kommt ja auch eine menge zusammen

Nein, da kommt keine Menge zusammen.
Man nimmt z.b. einen Timer interrupt alle 50 ms, wenn der Taster in 
diesem Interrupt 3 mal hintereinander gedrückt ist kann man davon 
ausgehen, dass er auch wirklich gedrückt ist und nicht prellt. Dann 
setzt du ein Flag das du dann in deinem Hauptprogramm auswertest.
Das alles frisst vielleicht 0.5% der Rechenzeit deines Controllers. Wohl 
eher noch weniger. Das tolle daran ist auch, dass man (fast) beliebig 
viele Taster verwenden kann.
Gast #3026078
Lesenswert?

> ich kann doch nicht die ganze zeit meine taster abfragen

Du vielleicht nicht, gute Programmierer aber schon.
Timer ist zwar eine Methode aber nicht die einzige.

> dann muss ich ja so kleine abtastabstände nehmen,
> dass die "drückzeit" des schalters höher ist

Natürlich. Für einen uC ein Klacks. Lernt programmieren.
Gast #3026110
Lesenswert?

Es gibt hier C-Tutorials über Entprellung, das ist ganu das was Du 
brauchst.
Mit den Arduino-Bibliotheken kenne ich mich nicht aus, aber die "loop" 
dürfte der Endlosschleife im main entsprechen.
http://www.mikrocontroller.net/articles/Entprellung#Warteschleifen-Verfahren
Das Prinzip ist einfach, der Timer läuft vor sich hin und wenn eine 
Taste länger als eine vorgegebene Zeit High-Wert hat wird sie in einer 
volatilen globalen Variable gespeichert.
In Deiner loop() wertest Du un diese globale Variable aus und zählst 
eine lokale variable hoch und prüfst ob sie dreimal, viernal usw. erhöht 
wurde.
#3026118
Lesenswert?

Adrian Figueroa schrieb:
> Der Timer interrupt ist ja sehr kurz, dann muss ich ja so kleine
> abtastabstände nehmen, dass die "drückzeit" des schalters höher ist
> (100ms vielleicht).. da kommt ja auch eine menge zusammen
Taster werden 1000 Mal pro Sekunde abgefragt. Wenn sich ein Tastzustand 
geändert hat, lässt man ihn für ein paar Millisekunden in Ruhe. Das 
nennt man Entprellen. Und der arme µC macht das klaglos mit. Im 
Gegenteil. Der freut sich sogar. Sonst würden ihm nämlich irgendwann vor 
lauter Langeweile die Pins abfaulen.

Und nur dadurch bekommt er wirklich jeden Tastendruck mit. Denn die 
reine Abfrage eines Tasters dauert nur einen Prozessortakt. Egal wie oft 
oder selten man das macht. Mit Delays und Interrupts schafft man sich 
erst richtige Probleme. Der einzige Einsatzzweck  eines Tasters mit 
Interrupt ist das Aufwecken aus dem Sleepmode. Aber auch nur dafür. Der 
erste Befehl nach dem Sleep lautet dann PCICR = 0.
Und dann geht es mit der ganz normalen Entprellung weiter.

mfg.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren