Pages: [1] 2   Go Down
Author Topic: IR Sterung Mit Interrupts  (Read 1906 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Leute!
Ich würde gern meinen Mega so programmieren, dass er mithilfe einer Fernbedienung und eines IR Receivers jeweils unterschiedliche "Funktionen" ausführt.
Und zwar sozusagen jeweils in einer Schleife, bis eine andere Taste / Funkion gewählt wird.
Ich bin bereits darauf gestoßen, dass das mit einem Timer bzw. Interrupts funktionieren soll....

Hier mal mein aktueller Code... leider ohne Funktion... es wird kein IR Code mehr empfangen...Vielleicht kann mir einer Helfen... smiley-wink

Lieben dank schonmal!!

Code:

#include <TimerOne.h>
#include <IRremote.h>


int RECV_PIN = 11;  // IR-Receiver PIN
int led = 12;       // Satus-LED PIN
int modus;          // Modus für Interrupt-Abfrage
int ledr = 6;       // RGB LED rot PIN
int ledg = 7;       // RGB LED grün PIN                       
int ledb = 8;       // RGB LED blau PIN
int SerialBuffer = 0;
int RedSum = 0;     // Farbsumme von VLC über serial ROT
int GreenSum = 0;   // Farbsumme von VLC über serial grün
int BlueSum = 0;    // Farbsumme von VLC über serial Blau
int RedVal=1;       // Variablen für Fader
int BlueVal=1;      //  "
int GreenVal=1;     //  "
int i=1;            // Zählervariable für Fader
int timerwert = 50;   // Timer Zeit für Interrupt in ms
int fadespeed = 10;   // Speed für Fade --> 1: extrem schnell
                      //                --> 10: normal
                      //                --> 100: extrem langsam
 
String readString;
/////////////////////////////////////////////////////////////////////////////////////

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  pinMode(ledr, OUTPUT); // Setzen der RGB LED Pins als Output
  pinMode(ledg, OUTPUT); // Setzen der RGB LED Pins als Output
  pinMode(ledb, OUTPUT); // Setzen der RGB LED Pins als Output
 
  pinMode(led, OUTPUT); // Status-LED als Output setzen
 
  Serial.begin(38400); // Serial Verbindung zu VLC
 // Serial.begin(9600);
 
  irrecv.enableIRIn(); // Start vom IR-Empfang
 
//   Ethernet.begin(mac, ip, gateway, subnet); // Server Starteb
//   server.begin();
   
  Timer1.initialize(timerwert); // Initialisieren des Timer-Interrupts
  Timer1.attachInterrupt(leseIR); // IR-Einlesen von Interr. ausführen lassen
}

void leseIR(){
// Ständige Abfrage ob Wert von IR Empfangen, trotz LOOP
  if (irrecv.decode(&results)){
    switch (results.value)  {
     
      case 0xFF10EF: // Modus Fade (DIY 4)
        modus = 1; 
      break;
     
      case 0xFF906F: // Modus pcambi (DIY 5)
        modus = 2; 
      break;
     
     
     
      // DIY 1 FF30CF
      // DIY 2 FBB04F
      // DIY 3 FF708F
      // DIY 4 FF10EF
      // DIY 5 FF906F
      // DIY 6 FF50AF
     
      case 0xFF02FD:  //Power
       modus = 0;
       digitalWrite(led, HIGH);   // Status LED EIN     
       delay(500);                // Pause 0,5s
       digitalWrite(led, LOW);    // Status LED AUS
       setColor(0, 0, 0);         // RGB LEDs ausschalten
      break;
       
       /////////////////////
       //Standart RGB Remote
       /////////////////////
       
      case 0xFFA25D:  //Blau 0,0,255
        modus = 0;
        setColor(0, 0, 255);
      break;
     
      case 0xFF1AE5: //Rot
        modus = 0;
        setColor(255, 0, 0);
      break;
     
      case 0xFF9A65://Grün
        modus = 0;
        setColor(0, 255, 0);
      break; 
     
      case 0xFF22DD: //Weiss
        modus = 0;
        setColor(255, 255, 255);
      break;
     
      case 0xFF2AD5: //orange
        modus = 0;
        setColor(255, 165, 0);
      break;
     
      case 0xFFAA55://Grün mitrtel
        modus = 0;
        setColor(124, 252, 0);
      break; 
     
      case 0xFF926D: //blau mittel
        modus = 0;
        setColor(92, 172, 238);
      break;
     
      case 0xFF12ED: //rosa
        modus = 0;
        setColor(255, 228, 196);
      break;     
     
     
     }             // Switch ENDE
  }                // Empfange IR ENDE
 irrecv.resume();  // Receive the next value
}                  // Lese IR ENDE


void setColor (int red, int green, int blue) {
 // RGB LED: write inverted value for each color
  analogWrite(ledr, 255 - red);
  analogWrite(ledg, 255 - green);
  analogWrite(ledb, 255 - blue);

  delay(1000);
}

   
   
   ///////////////////
   /// Fade //////////
   ///////////////////
   
 void fade(int Speed){
  analogWrite(ledr,255-RedVal);
  analogWrite(ledb,255-BlueVal);
  analogWrite(ledg,255-GreenVal);
 
  RedVal =((i<255)*i)+((i>=255)*255)+((i>511)*(512-i))+((i>766)*(i-766))+((i>=1276)*(i-1276))+((i>1530)*(1530-i))+((i>1786)*(1786-i));
  GreenVal =(i<256)*(1)+(i>255)*(i-255)+(i>510)*(510-i)+(i>1020)*(1020-i)+(i>1274)*(i-1274)+(i>1530)*(i-1531)+(i>1785)*(3571-(2*i));
  BlueVal =(i<764)*(1)+(i>765)*(i-765)+(i>1020)*(1020-i)+(i>1786)*(1786-i);

  if(i>2040){
   i = 1;
  }
 
  i++;
  delay(Speed);
 } // Fade ENDE
 
   
void pcambi(){
  ////////////////
 
  ////////////////
 
  digitalWrite(led, HIGH);       // Status LED EIN   
       delay(50);                // Pause 0,5s
      digitalWrite(led, LOW);    // Status LED AUS
         delay(50);
      digitalWrite(led, HIGH);   // Status LED EIN     
       delay(50);                // Pause 0,5s
      digitalWrite(led, LOW);    // Status LED AUS
         delay(50);
      digitalWrite(led, HIGH);   // Status LED EIN     
       delay(50);                // Pause 0,5s
      digitalWrite(led, LOW);    // Status LED AUS
   
   


void loop() {
if(modus==1){    // Abfrage pb Modus:1 in Interrupt gesetzt
fade(fadespeed); // Starte Fade
}

if(modus==2){    // Abfrage pb Modus:2 in Interrupt gesetzt
pcambi();        // pcaMBI
}

if(modus==3){    // Abfrage pb Modus:3 in Interrupt gesetzt
//starteServer();
}
   
   
   
  } // LOOP  Ende
 
     
Logged

AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1128
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du musst alle delays aus dem Pogramm entfernen wie soll der Ardu was auswärten wenn er immer wieder irgendwo warten muss. Die Delay rasuschmeissen und mit millis() vergleichen arbeiten wie in dem Beispiel Blinkwithout delay.
Gruß
Der Dani
Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21647
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich glaube nicht daß, Du das mit einem Interrupt realisieren mußt. Ich würde sagen ein Interrupt stört in diesem Sketch nur.
Ein delay in der unterrupfunktion ist tödlich für die correkte funktion des sketches.
Vergiß den Interrupt und mache alles im loop() ohne delay, nur mit millis().

Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sagt mal... könnte man die delay() Funktion nicht z.B. durch diese Funktion ersetzen? oder meint ihr das wäre nicht sonderlich effektiv?
Code:
void wait_mseconds(long msek){
    unsigned long currentMillis = millis();
    long previousMillis = millis();
   
      while(currentMillis - previousMillis < msek){
        currentMillis = millis();
      }
Logged

Germany
Offline Offline
Edison Member
*
Karma: 47
Posts: 2320
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Diese Funktion bremst den Programmablauf ebenso wie delay. Wozu sollte das gut bzw. besser sein?
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Naja.. wenn in einem sketch mehre delays verwendet werden... ist es doch ziemlich aufwendig, jedes Mal diese "blinkwithout delay Methode" zu nutzen... Oder sehe ich das irgendwie falsch?

Vielleicht liege ich ja komplett falsch.. Aber das Ziel vom Threadersteller hat mich auch schon beschäftigt... vll kann ja mal jemand mit Ahnung den Code von oben "reparieren"..  smiley-roll
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Naja.. wenn in einem sketch mehre delays verwendet werden... ist es doch ziemlich aufwendig, jedes Mal diese "blinkwithout delay Methode" zu nutzen... Oder sehe ich das irgendwie falsch?
Ist es nicht, denn der Aufwand ist immer gleich. Am Anfang der loop() wird das aktuelle millis() Wert gespeichert und an jeder delay() Stelle schaut man ob die gewünschte Wartezeit schon rum ist, wenn nicht, macht man nix, ansonsten merkt man sich den aktuellen millis() Wert für den nächsten Durchlauf und führt die gewünschte Aktion aus.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also sind wir mal ehrlich... wenn man die delays im oberen Code durch diese Methode ersetzen würde... das würde doch eine riesen Verschachtelung werden?!

Kannst mich gern vom Gegenteil überzeugen..
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hast Du Dir das Beispiel http://arduino.cc/en/Tutorial/BlinkWithoutDelay eigentlich mal angesehen? Wenn man den Code in entsprechende funktionale Blöcke teilt, die jeweils einen Status haben, ob sie aktiv sind und jeweils ihren eigenen "delay ohne delay" millis-Wert verwalten, wird es vermutlich sogar übersichtlicher.
Natürlich kann man nicht einfach dealy(xxx) durch einen BlinkWithoutDelay Vergleich ersetzen, der Code muss dafür schon umstrukturiert werden. Aber es geht ja am Ende darum, das nicht ein Block durch das delay alle anderen blockiert.
Logged

Offline Offline
Full Member
***
Karma: 5
Posts: 193
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Würde dieser Code funktionieren:

Code:
void wait(int interval,int led) {
long previousMillis = 0; 
bool once = false;
if (once == false) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
digitalWrite(led, HIGH); // Hier Code einfügen
once = true;
  }
 }
}

Addi
Logged

  / \    _|  _| o
 /--\ (_| (_| |

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21647
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sicher nicht!
Bei jedem Funktionsaufruf wird
Code:
long previousMillis = 0; 
bool once = false;
gesetzt und erreicht somit nie die Endzeit.

Grüße Uwe
« Last Edit: October 17, 2012, 01:56:01 pm by uwefed » Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich hab mal fix eine Library gebaut, die den BlinkWithoutDelay Code kapselt. ZIP-File ist angehängt. Ausgepackt kommt der Ordner WaitWithoutDelay in den libraries Ordner.
Nach dem Neustart gibt es unter "Datei -> Beispiele -> WaitWithoutDelay" ein Example "BlinkWaitWithoutDelay", das im wesentlichen dem BlinkWithoutDelay entspricht, nur ohne das rumrechnen mit den millis. Das macht die Klasse selbst.
Wenn man mehrere "delays" braucht, erzeugt man einfach mehrer Objekte der Klasse.
Evtl. hilft das ja dem Einen oder Anderen.

Mario.

* WaitWithoutDelay.zip (2.23 KB - downloaded 45 times.)
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21647
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
Hallo Mario
das oben ist ein Auszug aus dem Beispiel der WaitWithoutDelay Bibliothek.
Mir entzieht sich der Sinn dieses ELSE-Teils.

Außerdem gibt mir das Beispiel beim kompilieren mit IDE0022 folgende Fehlermeldung:
Quote
sketch_oct17a.cpp.o: In function `setup':
C:\DOKUME~1\alfa\LOKALE~1\Temp\build8797646699440134618.tmp/sketch_oct17a.cpp:16: undefined reference to `operator new(unsigned int)'


Grüße Uwe
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3051
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Mir entzieht sich der Sinn dieses ELSE-Teils.

Soll wohl
ledState = ! ledState;
machen...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Lib mag ja für "die einfache LED" ganz nett und hilfreich sein...
Doch wie würde man das, jetzt mal anhand des Beispiel im Startthread, bei diesem Abschnitt machen?
Code:
void setColor (int red, int green, int blue) {
 // RGB LED: write inverted value for each color
  analogWrite(ledr, 255 - red);
  analogWrite(ledg, 255 - green);
  analogWrite(ledb, 255 - blue);

  delay(1000);
}
Logged

Pages: [1] 2   Go Up
Jump to: