Programm über Taster starten

Hallo,

Ich bin kompletter einsteiger was das programmieren eines Arduinos betrifft, da ich nen Freund habe der das immer für mich erledigt.
Nun möchte aber selber einmal ans Programmieren ran :slight_smile:

Der Typ der das immer macht hat diesen Code geschrieben, jedoch hat er dies noch nicht mit dem Taster programmiert, so dass ich nur kurz auf den Taster drücken muss, um das Programm zu starten.

Ich find im Internet zwar genug Sachen dafür, aber ich finde keine gute erkärung dafür.
Gibt es vielleicht einen Beitrag den ich dazu übersehen habe?

Zu dem Code:
Wenn ich jetzt auf den Taster drücke, sollte ja das Programm starten.
Wenn ich aber los lasse, was passiert dann? häää? :smiley:

Freu mich über jeden Tipp und jede Info.

Danke,
Valerian

Code hab ich im Anhang oder hier:

#include <IRremote.h> 
IRsend irsend; //definiert irsend vom Typ IRsend
int RECV_PIN = 11; //Der Kontakt der am Infrarotsensor die Daten ausgibt, wird mit Pin 11 des Arduinoboards verbunden.
IRrecv irrecv(RECV_PIN); // An dieser Stelle wird ein Objekt definiert, dass den Infrarotsensor an Pin 11 ausliest.
decode_results results; // Dieser Befehl sorgt dafür, dass die Daten, die per Infrarot eingelesen werden unter „results“ abgespeichert werden.

int Tasterpin = 8;
int schalterzustand = 0;

void setup() {
 Serial.begin(9600); //Im Setup wird die Serielle Verbindung gestartet, damit man sich die Empfangenen Daten der Fernbedienung per seriellen Monitor ansehen kann.
 pinMode(Tasterpin,INPUT);
irrecv.enableIRIn();

}

void loop() {
 
schalterzustand =  digitalRead(Tasterpin);
  Serial.println(schalterzustand,DEC);
  Serial.println(results.value, HEX); //sobald irgendwelche Daten vom Empfänger empfangen werden startet das Programm in der if-Schleife

  if (irrecv.decode(&results) || schalterzustand == 1)

  {
   irsend.sendNEC(0xFFD827, 32); //sendet den Code 0xFFD827(rot) mit der Bitrate 32
   delay(100); // Das Programm pausiert für 100 Milisekunden
   irsend.sendNEC(0xFFD827, 32);
   delay(2850);
   irsend.sendNEC(0xFF8877, 32);
   delay(2150);
   irsend.sendNEC(0xFFE817, 32);
   delay(400);
   irsend.sendNEC(0xFFD827, 32);
   delay(3100);
  irsend.sendNEC(0xFF32CD, 32);
  delay(2700);
  irsend.sendNEC(0xFFB24D, 32);
  }
 {
 
 irrecv.resume(); //nächster Wert kann erhalten werden, also nochmal der Gleiche z. B.
 
 delay(100);
 irrecv.enableIRIn(); //der Infrarotempfänger wird wieder initialisiert damit wieder Daten empfangen werden können
 }
}

ValerianK:
Wenn ich jetzt auf den Taster drücke, sollte ja das Programm starten.
Wenn ich aber los lasse, was passiert dann? häää? :smiley:

Wir wissen es nicht.

Also was passiert, wenn du drückst, was passiert wenn du loslässt?
Wäre schön, wenn du es schreibst.
Das hellsehen haben wir verlernt.

Ja und weitere Informationen findest du in der IDE unter Beispiele-Digital-Button.

HotSystems:
Ja und weitere Informationen findest du in der IDE unter Beispiele-Digital-Button.

Da würde ich besonders StateChangeDetection empfehlen.

agmue:
Da würde ich besonders StateChangeDetection empfehlen.

Das ist richtig, nur ich wollte nicht zu weit in die Tiefe gehen, da wir nicht wissen, was er überhaupt will.

Hi :slight_smile:

Also es passiert genau das:

Wenn ich den Arduino mit Strom versorge, startet das Programm obwohl ich nicht auf meine Fernbedienung gedrückt hab und auch nicht auf meinen Taster. Wenn das Programm fertig ist, startet es einfach neu.

Das war so nicht der Plan haha :smiley:

Ich möchte grundsätzlich eben das Programm entweder mit der IR-Fernbedienung starten (Das klappt schon, da ich es ja nicht programmiert habe) und zusätzlich ist jetzt ein Taster dazugekommen. (Den will ich dazu programmieren)

Ok ich werd mir das mal anschauen mit der Button Tutorial-Reihe.

LG Valerian

Das liegt an dem schlecht programmierten Sketch.
Es fehlt die Abfrage bei welchen IR-Code dein Programm starten soll.

Dazu musst du den IR-Code herausfinden, den du nutzen möchtest.

Dann kannst du diese Abrage mit deiner Tasterabfrage oder-verknüpfen.

Und was das neue Starten betrifft, liegt an der Struktur.
Die Loop läuft immer durch, also das Programm startet immer, das geht auch nicht anders.

Also bitte beschäftige dich mit den Arduino Grundlagen.

Hallo,
Du müßtest einmal "startet das Programm" genauer definieren.
Wie HotSystems schon bemerkte, startet der Sketch (ist das "Programm" auf dem
Arduino) so bald dieser mit Spannung versorgt wird.

Das möchtest Du ja nicht, aber es geht nicht anders.

Was Du machen kannst, ist eine bestimmte Funktion im Sketch so lange zu
blockieren- bis eine Taste gedrückt ist.

z.B. so- der Ablauf mal aus dem Kopf, wenn denn etwas drinne ist, im Kopf.

Arduino einschalten
Sketch startet
die Loop läuft immer durch

mit "while" kannst Du den Arduino in LauerStellung versetzen

while {Taster drücken}

Arduino einschalten
Sketch startet
while {Taster drücken}
die Loop läuft bis while, dann steht der Sketch wie die Wacht am Rhein- nichts
rührt sich.

Wenn Du jetzt den Taster drückst, läuft die Loop durch. Bis sie wieder auf
while kommt- alles steht.

Du mußt Dir also auch merken, das der Taster gedrückt worden ist.

Taster nicht gedrückt, while wartet
Taster gedrückt, Loop läuft
ist Taster gedrückt worden, dann-
while überspringen

while die Erste

while die Zweite

Gruß und Spaß
Andreas

Bei mir funktioniert der Sketch aus #0 sogar :slight_smile: Fehlt möglicherweise ein PullUp- oder PullDown-Widerstand (Taster am Arduino)? So habe ich getestet:

...
  pinMode(Tasterpin, INPUT_PULLUP);
...
  schalterzustand =  digitalRead(Tasterpin);
  Serial.print("Schalterzustand: ");
  Serial.print(schalterzustand,DEC);
  Serial.print("\tFernbedienung: ");
  Serial.println(results.value, HEX); //sobald irgendwelche Daten vom Empfänger empfangen werden startet das Programm in der if-Schleife

Ausgabe:

Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
[color=green]Schalterzustand: 1[/color] Fernbedienung: 0    [i]<< hier gibt es eine Pause[/i]
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0
Schalterzustand: 0 Fernbedienung: 0

agmue:
Bei mir funktioniert der Sketch aus #0 sogar :slight_smile: Fehlt möglicherweise ein PullUp- oder PullDown-Widerstand (Taster am Arduino)? So habe ich getestet:

Und was passiert, wenn du die IR-Fernbedienung betätigst, da fehlt die Auswertung.

HotSystems:
Und was passiert, wenn du die IR-Fernbedienung betätigst, da fehlt die Auswertung.

Nö. Du wirst es kaum glauben, aber

  • Der Sketch basiert auf IRremote\examples\IRrecvDemo\IRrecvDemo.ino
  • Der Sketch tut, was ich vermute, was er tun soll. :grin:

So habe ich getestet:

#include <IRremote.h>
IRsend irsend; //definiert irsend vom Typ IRsend
int RECV_PIN = 11; //Der Kontakt der am Infrarotsensor die Daten ausgibt, wird mit Pin 11 des Arduinoboards verbunden.
IRrecv irrecv(RECV_PIN); // An dieser Stelle wird ein Objekt definiert, dass den Infrarotsensor an Pin 11 ausliest.
decode_results results; // Dieser Befehl sorgt dafür, dass die Daten, die per Infrarot eingelesen werden unter „results" abgespeichert werden.

int Tasterpin = 8;
int schalterzustand = 0;

void setup() {
  Serial.begin(9600); //Im Setup wird die Serielle Verbindung gestartet, damit man sich die Empfangenen Daten der Fernbedienung per seriellen Monitor ansehen kann.
  Serial.println("Anfang");
  pinMode(Tasterpin, INPUT_PULLUP);
  irrecv.enableIRIn();
}

void loop() {
  schalterzustand =  digitalRead(Tasterpin);
  if (irrecv.decode(&results) || schalterzustand == 1)
  {
    Serial.print("Schalterzustand: ");
    Serial.print(schalterzustand, DEC);
    Serial.print("\tFernbedienung: ");
    Serial.println(results.value, HEX); //sobald irgendwelche Daten vom Empfänger empfangen werden startet das Programm in der if-Schleife
    Serial.print("IRsend .");
    irsend.sendNEC(0xFFD827, 32); //sendet den Code 0xFFD827(rot) mit der Bitrate 32
    delay(100); // Das Programm pausiert für 100 Milisekunden
    Serial.print(".");
    irsend.sendNEC(0xFFD827, 32);
    delay(2850);
    Serial.print(".");
    irsend.sendNEC(0xFF8877, 32);
    delay(2150);
    Serial.print(".");
    irsend.sendNEC(0xFFE817, 32);
    delay(400);
    Serial.print(".");
    irsend.sendNEC(0xFFD827, 32);
    delay(3100);
    Serial.print(".");
    irsend.sendNEC(0xFF32CD, 32);
    delay(2700);
    Serial.print(".");
    irsend.sendNEC(0xFFB24D, 32);
    Serial.println(" fertig");
    irrecv.resume(); //nächster Wert kann erhalten werden, also nochmal der Gleiche z. B.
    delay(100);
    irrecv.enableIRIn(); //der Infrarotempfänger wird wieder initialisiert damit wieder Daten empfangen werden können
  }
}

Mit dieser Ausgabe:

Anfang
Schalterzustand: 0 Fernbedienung: FF629D
IRsend ....... fertig
Schalterzustand: 0 Fernbedienung: FFA25D
IRsend ....... fertig
Schalterzustand: 1 Fernbedienung: [color=green]FFA25D[/color]
IRsend ....... fertig
Schalterzustand: 0 Fernbedienung: FF02FD
IRsend ....... fertig

Die markierte Anzeige könnte man durch Löschen der anzuzeigenden Variablen vermeiden, stört den Ablauf aber nicht.

Ja, ok. Du hast die Auswertung ja auch eingebaut.

Ich hatte verstanden, der originale Sketch aus Post #1 funktioniert komplett.
Und das ist ja nicht so, da fehlte was. Das hatte ich dem TO ja auch geschrieben.

Und da ich nicht wusste (Raten will ich nicht mehr, verbrennt man sich ja leicht) was er erreichen will, mochte ich nicht einfach was hinzubauen.

Ok, vielen Dank erstmal!

Ein paar Sachen versteh ich leider nicht ganz was ihr geschrieben habt.

Aber erstmal zur IR Fernbedienung:

Es ist kein genauer Knopf auf der IR-Fernbedienung zugewiesen, da mir das grundsätzlich egal ist.

Das Programm soll einfach starten wenn ich einen beliebige Taste drückte auf der IR Fernbedienung die dann irgendein Hexadezimalsignal an meinen Arduino (IR-Empfänger) schickt.

Dies hat auch schon super geklappt, jedoch seit ich den Taster miteinbezogen habe, klappt dies auch nicht mehr.
Das Programm ist irgendwie durch meine ODER-Verknüpfung in der IF-Bedingung mit dem Taster gestört, und somit denkt es das die IF-Bedingung, durch den Taster der dazugekommen ist erfüllt worden ist und somit ins Programm springt.

Das mit dem Programm, dass es immer wieder von vorne beginnt nach dem ich einmal den Taster oder die Fernbedienung gedrückt habe, finde ich in Ordnung.
Also muss nicht so sein, dass wenn das Programm einmal durchgelaufen ist, wieder auf eine Eingabe warten muss.

Mit der Elektronik kenn ich mich super aus und habe darum auch nicht auf den Pulldown vergessen :smiley:

Gut, ich werde mich jetzt mal mit den Basics beschäftigen.

Aber kurz gesagt, was muss ich in der Oder-funktion (IF-Bedingung) miteinbinden.
Das kann doch net so schwer sein, das wenn ich meinen Taster drücke oder wenn ich eine beliebige Taste auf der IR-Fernbedienung drücke, mein Programm weiter springt.

Es soll doch einfach wenn beim Input 8 eine 1 (True) daherkommt, soll meine If-Bedingung erfüllt sein, oder eben durch eine beliebe Taste an der IR-Fernbedienung :frowning:

@agmue:

Funktioniert der Code bei dir? :slight_smile: Was hast du da jetzt genau umgeändert?

EDIT: Ich hab mich jetzt mal mit der while-schleife beschäftigt. Die klingt doch gut für meine Anwendung. Oder?

Also:

while(Taster gedrückt || beliebige Taste auf der IR-Fernbedienung gedrückt)
{Code}

Und wenn ich einmal drauf Drücke auf den taster, dann springt er mir ja ins Programm. Macht dies einmal durch und wenn der controller das Programm fertig hat, springt er wieder zur While schleife.
Nun sieht er wieder ob der Taster gedrückt ist. Wenn nein startet er nicht ins Programm, sonst schon.

Hmmm Ist doch irgendwie wie eine If-Bedingung, nur das IF keine Schleife ist.

Oooh, ich muss denk ich echt von ganz vorne anfangen :smiley:

ValerianK:
@agmue:

Funktioniert der Code bei dir? :slight_smile: Was hast du da jetzt genau umgeändert?

Ja, siehe #9. Wenn ich den Taster oder einen Knopf der Fernbedienung drücke, wird das Senden gestartet. Ob beim Senden die richtigen Werte übertragen werden, habe ich allerdings nicht getestet.

Wenn Du einen Dateivergleich machst, siehst Du, daß ich in der 6. und 7. Zeile von hinten zwei geschweifte Klammern gelöscht habe. Sonst habe ich nur mehr Text an den seriellen Monitor geschickt.

Ich widerspreche Kollegen, von denen ich annehme, sie wissen, was sie schreiben, nur äußerst ungerne, halte den Vorschlag mit while aus #6 aber für nicht so günstig. Aber zu lernen, wie es funktioniert, kann natürlich nie schaden :slight_smile:

Ok, darf ich mir dann deinen Code mal schnappen und probieren?! Ich hoffe ja, weil ich probiers jetzt :smiley:

Ja die richtige Werte kommen, die habe "ich" alle schon ausgewertet :slight_smile:

Ok, ja ich hab jetzt in Zukunft einige Projekte vor und will nicht ständig meinem Freund das programmtechnische aufschieben, auch wenn ers gerne macht. Aber wenn ich schnell mal was umgeändert haben will, kann ichs dann halt selber machen. :smiley:

LG Valerian

Tatsächlich, es funktioniert :smiley: Vielen lieben Dank!

Eine Frage noch.
Jetzt ist es so, ich kann das Programm jetzt mit der Fernbedienung oder mit dem Taster starten. Ist schon einmal mega geilomatico für mich :smiley:

Wenn ich aber jetzt will, dass das Programm nach einem Durchlauf stoppen soll, und dann wieder auf einen Befehl (Taster oder Fernbedienung) warten soll um neu zu beginnen.

Grundsätzlich als Hintergrund Info:

Damit sollen LEDs geschalten werden für eine Show.
Diese Show dauert 10 Minuten. Danach kann das Gerät wieder ausgeschaltet werden. Es soll nur am Schluss der Show aufhören die LED´s mit Signalen zu steuern.

Meine Lösung wäre (Ist halt echt erbärmlich).. haha :smiley:

Ein delay von einer halben Stunde am Schluss zu setzten. xD

Schönere Lösung?

Wenn dein Freund diese Zeile verfasst und kommentiert hat, ist es sowieso besser sich aus seinen Fängen zu befreien. :wink:

decode_results results; // Dieser Befehl sorgt dafür, dass die Daten, die per Infrarot eingelesen werden unter „results" abgespeichert werden.

Wie könnte ein korrekter Kommentar lauten?

Wenn bei dir loop() nur einmal durchlaufen soll, weil sie voll mit delays ist, welche den "Programmablauf" darstellen, sollte man dich zwar prinzipiell ganz fürchterlich ignorieren, aber statt

   delay(30*60*1000L); // halbe Stunde Pause

geht auch

   while (1) {} // Ende und Aus !

Dann ist Schluss für immer (bis zum nächsten Reset).

Aber rate mal, warum die Funktion loop() heisst...

ValerianK:
Ok, darf ich mir dann deinen Code mal schnappen und probieren?!

Aus diesem Grund veröffentliche ich ja einen Sketch :slight_smile:

ValerianK:
Ok, ja ich hab jetzt in Zukunft einige Projekte vor und will nicht ständig meinem Freund das programmtechnische aufschieben, auch wenn ers gerne macht. Aber wenn ich schnell mal was umgeändert haben will, kann ichs dann halt selber machen. :smiley:

Guter Ansatz :slight_smile:

ValerianK:
Tatsächlich, es funktioniert :smiley: Vielen lieben Dank!

Bitte gerne!

ValerianK:
Wenn ich aber jetzt will, dass das Programm nach einem Durchlauf stoppen soll, und dann wieder auf einen Befehl (Taster oder Fernbedienung) warten soll um neu zu beginnen.

Das macht das Programm bereits, zumindest bei mir. Es läuft einmal durch und wartet dann wieder wie zu Anfang.

Für Dich und, wenn er mag, auch Deinen Freund habe ich mal den Sketch so umgeschrieben, daß er ohne blockierendes delay auskommt. Alle Zeiten und Codes stehen in Feldern und werden über einen Index ausgewählt.

Die LED an Pin 13 macht einen "Herzschlag", um zu zeigen, daß die Schleife loop im Sketch ständig durchlaufen wird.

#include <IRremote.h>
IRsend irsend; //definiert irsend vom Typ IRsend
const int RECV_PIN = 11; //Der Kontakt der am Infrarotsensor die Daten ausgibt, wird mit Pin 11 des Arduinoboards verbunden.
IRrecv irrecv(RECV_PIN); // An dieser Stelle wird ein Objekt definiert, dass den Infrarotsensor an Pin 11 ausliest.
decode_results results; // Dieser Befehl sorgt dafür, dass die Daten, die per Infrarot eingelesen werden unter „results" abgespeichert werden.

const int Tasterpin = 8, ledPin = 13;
const unsigned long zeit[] = {100, 2850, 2150, 400, 3100, 2700, 100};
const unsigned long code[] = {0xD827, 0xD827, 0x8877, 0xE817, 0xD827, 0x32CD, 0xB24D};
const byte max = sizeof(code) / sizeof(code[0]);
byte index;
unsigned long aktMillis, sendeMillis, blinkMillis, sendeIntervall = 100, blinkIntervall = 300;
bool aktTaster, altTaster, senden;

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  pinMode(Tasterpin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  aktTaster = digitalRead(Tasterpin);
  altTaster = aktTaster;
  irrecv.enableIRIn();
}

void loop() {
  aktMillis = millis();
  altTaster = aktTaster;
  aktTaster = digitalRead(Tasterpin);
  if ((irrecv.decode(&results) || (!altTaster && aktTaster)) && !senden)  {
    senden = true;
    index = 0;
    sendeIntervall = 0;
    sendeMillis = aktMillis;
    Serial.print("IRsend ");
  }
  if (aktMillis - sendeMillis >= sendeIntervall) {
    sendeMillis = aktMillis;
    if (senden) {
      Serial.print(".");
      irsend.sendNEC(0xFF0000 | code[index], 32); //sendet den Code mit der Bitrate 32
      Serial.print(0xFF0000 | code[index],HEX);
      sendeIntervall = zeit[index];
      index++;
      if (index < max) {
      } else {
        senden = false;
        sendeIntervall = 100;
        irrecv.enableIRIn(); //der Infrarotempfänger wird wieder initialisiert, damit Daten empfangen werden können
        Serial.println(" fertig");
      }
    } else {
      irrecv.resume(); //nächster Wert kann erhalten werden, also nochmal der Gleiche z. B.
    }
  }
  if (aktMillis - blinkMillis >= blinkIntervall) {
    blinkMillis = aktMillis;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}

Der Sketch darf frei verwendet werden, wenn jemand was lernt, wäre es prima. Viel Spaß :slight_smile:

agmue:
Aus diesem Grund veröffentliche ich ja einen Sketch :slight_smile: Guter Ansatz :slight_smile: Bitte gerne!Das macht das Programm bereits, zumindest bei mir. Es läuft einmal durch und wartet dann wieder wie zu Anfang.

Für Dich und, wenn er mag, auch Deinen Freund habe ich mal den Sketch so umgeschrieben, daß er ohne blockierendes delay auskommt. Alle Zeiten und Codes stehen in Feldern und werden über einen Index ausgewählt.

Die LED an Pin 13 macht einen "Herzschlag", um zu zeigen, daß die Schleife loop im Sketch ständig durchlaufen wird.

Der Sketch darf frei verwendet werden, wenn jemand was lernt, wäre es prima. Viel Spaß :slight_smile:

Hi,
Das wäre ja echt mega super!
Könntest du es hier posten? :smiley:

Dannach kann man denk ich diesen Theard abschließen und ich schmeiß mich ans programmieren lernen :wink:

ValerianK:
Könntest du es hier posten? :smiley:

Sorry, ich Schnarchnase bin gestört worden und habe es dann vergessen :-[

Bei Fragen bitte fragen!