Versuhe mal ein Volatile vor "int bewegung = 10" // 13.
Versuhe mal ein Volatile vor "int bewegung = 10" // 13.
Nein. Funktioniert auch nicht. Ich habe bei der IF-Anweisung mittlerweile auch mal eine ==1 eingetragen, geht auch nicht. Ich kann es nicht nachvollziehen, alle anderen Daten werden berechnet und ausgegeben. Kann es ein zeitliches Problem sein? Die Verzögerung von 10 Sekunden dürfte nicht stören, denn die betrifft ja nur die Dauer des Blinkens und die Dauer der Anzeige.
- - - Aktualisiert - - -
Ich habe den Fehler gefunden, weiß nur nicht wie ich ihn ausbessern kann. Das Problem, ich drücke die erste Taste, in dem Moment wird die Bedingung des Bewegunsstatus überprüft. Sie wird aber nicht ohne Pause überprüft. Sondern immer nur in dem Moment, wo die Taste 1 gedrückt wird.
Wie kann ich also eine fortlaufende Prüfung einbauen?
Ich kann Dir da nicht im Detail weiterhelfen, aber das klingt mir doch nach einem typischen Kandidat für Interruptverarbeitung. In dem Moment, wo die erste Tastenbetätigung erfolgt muß diese den Interrupt auslösen und der Rest dann in der Interruptroutine weiterverarbeitet werden...
Okay, mit Interrupts kenne ich mich nicht aus, da ich mich erst langsam an das Thema ran taste. Muss ich jetzt erstmal anlesen.
Danke für die Info.
Interruptprogrammierung ist quasi die Königsdisziplin. Du solltest erstmal anfangen kleine Brötchen zu backen, d.h. den Status eines simplen Schalters ohne weitere Funktion abfragen. Dazu benötigst Du INT4 (Pin Change Interrupt Request 0) falls der Schalter an Pin D8..D13 hängt. Dieser INT hat hohe Priorität - Du mußt also nicht befürchten daß Dir die Arduino-IDE mit ihren Timern dazwischenfunkt - sehr pflegeleicht!
Wenn das funktioniert baust Du anstelle des Schalters Deine eigentliche Hardware in den Code ein.
Um das Ganze zu verstehen empfehle ich die Website von Nick Gammon. Ich selbst habe nur ein einziges Arduino-Projekt mit einem einzigen (Timer-)Interrupt realisiert (bin also wirklich nicht DER Programmier-Freak...), aber er hat mir immerhin dies ermöglicht - und das recht schnell. Im Speziellen interessant für Dich ist seine Abhandlung über Interrupts. Die versucht zwar allgemeingültig zu erklären, aber glücklicherweise ist seine Testplattform der Uno.
Bevor Du anfängst solltest Du erstmal den gesamten Thread durchlesen und *halbwegs* verstehen. Die Abschnitte über Timer kannst Du guten Gewissens auslassen. Das allererste Code-Beispiel ("Example of interrupts") kommt Deiner ersten Aufgabe schon ziemlich nahe.
Dann erst versuchen selbst was zu basteln.
Danke. Ich werde mir das durchlesen.
Irgendwie ist es gerade so, dass ich mein gebautes "Gerät" nämlich gerade nicht auseinander nehmen möchte, bevor es nicht wirklich so funktioniert, wie ich es mir vorstelle. Dann werde ich es aufzeichnen und erst dann mit den anderen Sachen weitermachen, die ich noch offen habe.
Das mit den Interrupts ist ein echt haariges Thema. Scheint aber die Lösung zu sein. Ich habe einen Interrupt eingebaut und seit dem funktioniert auch die IF Bedingung. Natürlich kommt jetzt wieder ein ABER. Wenn die Unterbrechung durch eine Bewegung verursacht wird, leuchtet meine LED und mein Text wird ausgegeben. Leider wird dann die Routine nicht abgebrochen. Ich denke, es liegt an dem Befehl.Code:if (irrecv.decode(&results))
Mein Interrupt lässt solange die LED leuchten und den Text erscheinen, bis wieder ein Befehlt über die IR-Schnittstelle gesendet wird, er soll aber automatisch zurückkehren nach z.B. 10 Sekunden und die Temperatur wieder anzeigen. Was auch interessant ist, wenn ich einfach nur den zweiten Case durch Druck auf die zugehörige Taste auslöse, wird mir die Temperatur angezeigt, aber ich kann den ersten Case nicht mehr starten.
So ist momentan mein Code aufgebaut:
Wäre die Lösung etwas wie eine Art Goto last Case? Das ich in der ISR einen Befehle einbaue wie Goto Sprungmarke Case 16724175?Code:#include <LiquidCrystal.h> #include <IRremote.h> int receiverpin = 3; IRrecv irrecv(receiverpin); decode_results results; LiquidCrystal lcd(4,5,6,7,8,9); float sensor = 0; float celsius = 0; float voltage = 0; volatile int bewegungsstatus=0; volatile int bewegung=2; int ledg=11; int ledr=12; //unsigned long zeit=millis(); void setup() { lcd.begin(16,2); lcd.clear(); pinMode(bewegung, INPUT); pinMode(ledg, OUTPUT); pinMode(ledr, OUTPUT); irrecv.enableIRIn(); Serial.begin(9600); attachInterrupt(0, sehdich,CHANGE); } void sehdich() { bewegungsstatus=digitalRead(bewegung); if (bewegungsstatus==HIGH) { lcd.setCursor(0,0); lcd.print("Eindringling"); lcd.setCursor(0,1); lcd.print("erkannt"); digitalWrite(ledr, HIGH); digitalWrite(ledg, LOW); Serial.println("1"); } } void translateIR() { switch(results.value) { case 16724175: { lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatur:"); lcd.setCursor(0,1); lcd.print(celsius,0); lcd.setCursor(3,1); lcd.print("Grad"); digitalWrite(ledr, LOW); digitalWrite(ledg, HIGH); Serial.println("2"); } break; case 16743045: lcd.clear(); noInterrupts(); lcd.setCursor(0,0); lcd.print("Temperatur:"); lcd.setCursor(0,1); lcd.print(celsius,0); lcd.setCursor(3,1); lcd.print("Grad"); digitalWrite(ledr, LOW); digitalWrite(ledg, HIGH); Serial.println("3"); break; } } void berechnung() { sensor = analogRead(0); voltage = (sensor*5000)/1024; voltage = voltage - 500; celsius = voltage/10; } void loop() { if (irrecv.decode(&results)) { irrecv.resume(); berechnung(); translateIR(); } }
Warum kann ich, wenn ich den zweiten Case "Temp-Messung Standalone" aufrufe nicht erneute den erweiterten Fall mit Bewegungssensor aufrufen? Void Loop () müsste doch immer wieder durchlaufen werden, somit müsste die Abfrage nach einem IR Code immer erfolgen und die Funktion translateIR ebenfalls immer durchgeführt werden.
Lesezeichen