Anfänger Problem mit IR Ferbedienung - Arduino Uno

Hallo,

ich habe seit längerer Zeit nichts mit dem Arduino gemacht und mich jetzt mal versucht mit einer IR Fernbedienung 2 LEDs einzuschalten, zwischen den Beiden umzuschalten (also je 1 an, Beide an, oder Beide aus) und die Helligkeit zu verstellen.

Das Umschalten funktioniert auch so wie ich das wollte, allerdings hängt sich der Arduino beim Versuch die Helligkeit zu verstellen auf.
Ich hoffe ihr könnt mir helfen und es handelt sich bei dem Problem nur um eine Kleinigkeit… :wink:

hier der Code:

/*LED Stripe*/

#include <IRremote.h>

int IRpin = 11;
int LEDst1 = 5;
int LEDst2 = 6;
int StripeCase = 0;
int Mvalue = 255;

IRrecv irrecv(IRpin);
decode_results results;

 
void setup()
{
 irrecv.enableIRIn();
 pinMode(LEDst1, OUTPUT);
 pinMode(LEDst2, OUTPUT);
}
 
void loop() 
{
 
 if (irrecv.decode(&results)) 
 {
 
 irrecv.resume();
 }
 
 switch(results.value)
 {

  case 16752735:// Stripe Auswahl +
  delay(250);
   StripeCase++;
   if (StripeCase > 3) {
     StripeCase = 1;
   }
   StripeSwitch(StripeCase, Mvalue);
  break;
 
  case 16743045:// Stripe Auswahl -
  delay(250);
   StripeCase--;
   if (StripeCase <1) {
     StripeCase = 3;
   }
     StripeSwitch(StripeCase, Mvalue);
  break;

  case 16755285: //Helligkeit +
  delay(250);
    Mvalue = brighter(Mvalue);
    StripeSwitch(StripeCase, Mvalue);
  break;
  
  case 16769055: //Helligkeit -
  delay(250);
    Mvalue = darker(Mvalue);
    StripeSwitch(StripeCase, Mvalue);
  break;
   
  case 16722135: //PowerOff
  delay(250);
    poweroff();
  break;
 }
 
}

void StripeSwitch(int xCase, int yvalue)
{
  switch(xCase) {
    case 1:
      analogWrite(LEDst1, yvalue);
      analogWrite(LEDst2, 0); 
    break;
    
    case 2:
      analogWrite(LEDst1, 0);
      analogWrite(LEDst2, yvalue); 
    break;
    
    case 3:
      analogWrite(LEDst1, yvalue);
      analogWrite(LEDst2, yvalue); 
    break;
}
}
int brighter(int bvalue)
{
  if (bvalue > 4 && bvalue < 255) {
    bvalue=bvalue+50;
  }
  return bvalue;
}

int darker(int dvalue)
{
  if (dvalue > 5 && dvalue <256) {
    dvalue=dvalue-50;
  }
  return dvalue;
}

void poweroff()
{
  analogWrite(LEDst1, 0);
  analogWrite(LEDst2, 0);
}

MFG

int darker(int dvalue)
{
  if (dvalue > 5 && dvalue <256) {
    dvalue=dvalue-50;
  }
  return dvalue;
}

Das funktioniert wohl vermutlich, weil du bei 255 anfängst und immer in 50er Schritten gehst.

Was meinst du mit “hängt sich auf”?

Mach doch zum Test mal ein

   Serial.print(results.value); Serial.print(" : "); Serial.println(Mvalue);

oder so, vor den switch…

(Und natürlich Serial.begin(9600); usw … ; ) )

Hallo Michael,

Was meinst du mit "hängt sich auf"?

Ich meinte der Arduino friert ein. Ich kann die LEDs ein und ausschalten, aber wenn ich die Helligkeit verstelle friert er ein und es leuchten die LEDs nur mehr in der letzten Konfiguration.
Also dürfte das Problem wohl bei den Funktionen "brighter" und "darker" oder der Übergabe vom neuen Wert "Mvalue" liegen, vermute ich. Wenn ich mir das ganze nur am Serial Monitor anzeigen lasse und das analogWrite weglasse funktioniert auch alles, also es werden mir die gewünschten Werte ausgegeben.

Mach doch zum Test mal ein
Serial.print(results.value); Serial.print(" : "); Serial.println(Mvalue);
oder so, vor den switch...

hier erhalte ich beim Programmstart 0 : 255, wenn ich zwischen den LEDs durchschalte erhalte ich den Code für die jeweilige Taste und auch die 255 für Mvalue. Beim Versuch die Helligkeit zu verstellen friert das Programm wieder ein.

MFG

wozu das:
return dvalue;

wozu das:
return dvalue;

die Funktion "darker" übergibt den berechneten Wert ans Hauptprogramm wo er dann zum neuen Wert "Mvalue" und an die Funktion "stripeSwitch" übergeben wird. Oder habe ich da generell einen Denkfehler?

Oder habe ich da generell einen Denkfehler

Nö, seh erstmal auch keinen.

Du hast in jedem Fall ein delay(250) und ein Serial.println(...); ?
Was passiert ohne eine erkannte Taste ? ( Mach da mal auch ein delay(250); println("nix"); rein... )

also die delay(250) hab ich eingebaut weil es die gedrückte Taste immer gleich 10 mal erkannt hat. ich denke aber das liegt an meiner China-Fernbedienung bei der man etwas kräftiger und länger drücken muss..

wo genau meinst du soll ich das einbauen? in welche Zeile?

 switch(results.value)
 {
    // ...
      break;

   default:
   Serial.print(results.value); Serial.println(" ignored");
   delay(250);
   break;
 }

Ich rate mal, "eingefroren" ist er dauernd da...

Und dass eine Taste, während sie gedrückt ist, dauernd sendet, ist eigentlich normal. Sinnvoll z.B. beim Lautstärke einstellen.
Musst halt, wenn das nicht gewünscht ist, jede Aktion nur einmal ausführen, bis wieder ein anderer Code kommt. Üblicherweise sieht man für die gleiche Taste beim zweiten Mal auch gern einen anderen Code, damit man das "losgelassen" besser erkennt. Aber da gibt es unterschiedliche Protokolle.

ich dachte urpsrünglich dass das mit dem dauerhaften senden Probleme macht, darum hab ich mal das delay rein.

bei deiner Codezeile kommt das hier raus:

0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored
0 ignored

nach Tastendruck geht es so weiter:

0 ignored
0 ignored
16743045 : 255
4294967295 ignored
4294967295 ignored
4294967295 ignored

Schön, dann mach doch einfach den

case 0: // keine Taste
  break;

vor den default Zweig und du hast ein schönes Testprogramm, was die FB wirklich sendet.
Besser als denken, sie sei eingefroren :wink:

[Nachtrag]4294967295 ist übrigens das gleiche wie -1, auch ein Sonderfall und keine echte Taste.

Ich persönlich mag übrigens lieber die Hex-Darstellung:

switch(result.value) {
    // ...

case 0xFF7A85:// Stripe Auswahl -
   // ...
   break;

case 0xFFAA55: //Helligkeit +  (?)
  // ...
  break;

case 0xFFE01F: //Helligkeit -   (?)
   //  ...
   break;

 case 0:
 case 0xFFFFFFFF:  // = -1 = 4294967295
    break; // ignore no key 

default: 
    Serial.println( " ignoring  0x"); Serial print(result.value,16);
   delay(250);
   break;
}

ich habs dir mal umgeändert, das ganze schaut dann so aus:

FFA05F : 255 //Auswahl +
FF7A85 : 255 //Auswahl -
FFAA55 : 255 //Helligkeit +
FFE01F : 205 //Helligkeit -
ignoring 0x8CEDC523
ignoring 0x24AE7D4F
ignoring 0x24AE7D4F
ignoring 0x24AE7D4F
ignoring 0x24AE7D4F
ignoring 0x24AE7D4F
ignoring 0x24AE7D4F

Du verwendest doch diese Library:
https://www.pjrc.com/teensy/td_libs_IRremote.html

Da würde ich die Programm-Struktur diesem Beispiel anpassen:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    auswerten(results.value); // Deine Funktion hier
    irrecv.resume(); // Receive the next value
  }
}

void auswerten(unsigned long ircode) {
   switch (ircode) {
   case 0xFF7A85:// Stripe Auswahl -
      // ...
      break;
   }

}

Insbesondere results.value nur auswerten, wenn decode() vorher true geliefert hat.

Sorry, dass mir das vorher nicht aufgefallen ist…

ja ist ein guter Ansatz. Nur leider hat es das Problem nicht gelöst..

vielleicht sollte ich das Programm generell anders aufbauen, oder eine andere Library verwenden?

Nur leider hat es das Problem nicht gelöst..

Dann nimm das unmodifizierte Beispiel aus deiner Library und spiel damit rum:
Wann hängt es sich auf?

Oder hast du inzwischen ein anderes Problem ?