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

@Uwe: Ich habe für das Beispiel den Code des originalen BlinkWithoutDelay verwendet, damit es leichter vergleichbar ist. Ansonsten hätte ich den Zustandwechsel auch mit einem state = ! state abgekürzt.

Zum Fehler in der IDE0022, hier kann man das new vermutlich durch folgenden Aufruf ersetzen: WaitWithoutDelay mywait = WaitWithoutDelay(1000);. Dann müssen Methoden des Objekts aber mit "." statt mit "->" referenziert werden.

@t-lie:
z.B. so:
Code:
void setColor (int red, int green, int blue) {
 static  WaitWithoutDelay localwait = WaitWithoutDelay(1000);
 
 if(localwait.wait()) {
    Serial.println("setColor called");
    // RGB LED: write inverted value for each color
    analogWrite(ledr, 255 - red);
    analogWrite(ledg, 255 - green);
    analogWrite(ledb, 255 - blue);
  }
}
Damit kann man die Funktion sooft aufrufen wie man will, sie wird nur nach Ablauf einer Sekunde die Farbe der LED ändern. Ich persönlich würde das "Hilfs delay" aber nicht in die Funktion selbst packen, sondern den Aufruf der Funktion in das Wait kapseln. Das hat den Vorteil, das die Funktion setColor() an verschiedenen Stellen im Programm verwendbar ist, wobei es durchaus vorkommen kann, das man gar kein oder ein anderes delay haben möchte als die fixen 1000ms. Das geht natürlich nur, wenn sich die Funktion selbst nicht um das delay kümmert.
Die Funktion setColor() hat die Aufgabe die Farbe eine LED per PWM zu setzen, daher sollte sie auch nicht mehr machen.
Logged

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

@Uwe: Ich habe für das Beispiel den Code des originalen BlinkWithoutDelay verwendet, damit es leichter vergleichbar ist. Ansonsten hätte ich den Zustandwechsel auch mit einem state = ! state abgekürzt.
...
Das gestern war nicht mein bester Tag. Du hast Recht.
Grüße Uwe
Logged

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

Also das ist jetzt der Abgeänderte Code geht aber immernoch nich noch jemand Ideen ?


Code:
#include <TimerOne.h>
#include <IRremote.h>
#include <WaitWithoutDelay.h>


int RECV_PIN = 11;  // IR-Receiver PIN
int led = 12;       // Satus-LED PIN
int ledState = 0;   // Zustand Status LED
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 fadespeed = 10;   // Speed für Fade --> 1: extrem schnell
                      //                --> 10: normal
                      //                --> 100: extrem langsam
  
/////////////////////////////////////////////////////////////////////////////////////

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
}

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;
       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) {
 static  WaitWithoutDelay localwait = WaitWithoutDelay(1000);
 
 if(localwait.wait()) {
    //Serial.println("setColor called");
    // RGB LED: write inverted value for each color
    analogWrite(ledr, 255 - red);
    analogWrite(ledg, 255 - green);
    analogWrite(ledb, 255 - blue);
  }
}
  
  
   ///////////////////
   /// Fade //////////
   ///////////////////
  
 void fade(int Speed){
    static  WaitWithoutDelay localwait = WaitWithoutDelay(Speed);
 
 if(localwait.wait()) {
  
  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++;
 }
 } // Fade ENDE
 
  
void pcambi(){
  ////////////////
 
  ////////////////
  static  WaitWithoutDelay localwait = WaitWithoutDelay(500);
 
   if(localwait.wait()) {
     if(ledState==1){
        digitalWrite(led, LOW);    // Status LED AUS
        ledState = 0;
     }else{
     digitalWrite(led, HIGH);       // Status LED EIN
     ledState = 1;
 }
}
}
void loop() {
  leseIR();
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
}
  
  
  
  } // LOOP  Ende
« Last Edit: October 18, 2012, 04:36:05 pm by uwefed » Logged

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

Wie bereits geschrieben, mußt Du die Struktur Deines Programms ein wenig anpassen. WaitWithoutDealy funktioniert nicht wie ein einfaches dealy, es wird also nicht an der Stelle gewartet. Das Programm merkt sich auch nicht, wo noch etwas zu tun wäre, wenn die Wartezeit abgelaufen ist.
Ein Beispiel: In der Funktion leseIR() wird überall setColor() aufgerufen, aber nur wenn ein bestimmter Wert von der Fernbedienung erkannt wurde. So wie das geänderte setColor() jetzt funktioniert, wird es in 99% der Fälle wo es aufgerufen wird nichts tun, weil die Bedingung (localwait->wait()) nicht erfüllt ist. Das ist der Grund warum ich geschrieben habe, das das Warten nicht in die setColor() Funktion gehört.
Ich würde sämtliche Aufrufe von setColor() in die loop() verlagern, nur dort wird geschaltet. leseIR() sollte nur die Variable modus setzen und zusätzlich 3 Variablen für den Farbwert von rot, grün und blau.
Das WaitWithoutDelay muss aus setColor() raus, wenn Farbe setzen, das sofort ohne Verzögerung. Dort wo Du eine Verzögerung brauchst, kapselst Du den Aufruf von setColor() mit dem WaitWithoutDelay.
Das "modus" ist schon ein sehr guter Ansatz, diese Variable definiert ja in welchem Status sich Dein Programm befindet, nur muss der Modus "0" auch in der lopp() wiederfinden.
Code:
//delay für RGB-LED
WaitWithoutDealy colorWait = WaitWithoutDealy(1000);

//werte für RGB-LED, werden von leseIR() gesetzt
int r,g,b = 0;

void loop() {
  //IR lesen
  leseIR();
 
  switch(modus) {
   case 0:
      if(colorWait.wait()) {
         setColor(r,g,b) 
      }
      break;

   case 1:
      fade(fadespeed);
      break;
 
   case 2:
      pcambi();
      break;
 
   case 3:
      break;
   
  }
 
} // LOOP  Ende
Der Trick beim BlinkWithoutDelay ist, das Dein Arduino wie "irre" immer wieder die Funktion loop() durchläuft, mehrere tausend Mal pro Sekunde. Anhand der Variable "modus" weiss das Programm in welchen Case-Block (switch innerhalb von loop()) es jeweils aktiv werden muss. Dort sorgt dann aber das WaitWithoutDelay (in meiner Beispiel-loop() exemplarisch für setColor()) dafür, das z.B. setColor() nicht tausend Mal pro Sekunde aufgerufen wird, sondern immer nur, wenn eine Sekunde vergangen ist. Allerdings blockiert die setColor() Funktion dabei nicht das komplette Programm. Das leseIR() wird nämlich bei jedem loop() Durchlauf aufgerufen.

Allerdings frage ich mich eh schon die ganze Zeit, warum das "delay" für das setColor() überhaupt gebraucht wird. Wenn ich auf der Fernbedienung der Knopf für "Rot" drücke, sollte das doch gleich umschalten, oder? Beim "fade" macht das schon mehr Sinn. Auch bei der Funktion pcambi() sehe ich das ein, weil hier im 500ms Takt geblinkt werden soll.

Nun zu Deinem "geht aber immer noch nicht". Was genau geht denn nicht? Werden überhaupt Befehle von der Fernbedienung erkannt? Hast Du mal Debugausgaben auf die serielle Schnittstelle gemacht, um zu sehen was Dein Programm überhaupt macht? Hast Du einzelne Teile des Programms mal separat getestet?

Mario.
Logged

Pages: 1 [2]   Go Up
Jump to: