Merkwürdiges Verhalten bei PWM und IR

Hallo zusammen,

habe testweise ein kleines Programm geschrieben, bei dem man mit einer Fernbedienung die Helligkeit von drei LEDs (rot, grün, gelb) steuern kann. Nun zeigt sich ein komisches Verhalten je nach verwendetem PWM-Pin. Verwendet habe ich diese IR-Bibliothek: https://github.com/z3t0/Arduino-IRremote

Bei Pin 9 und 10 funktioniert alles (rot und grün).
Bei Pin 11 “hängt” sich der Arduino auf, sobald analogWrite mit einem Wert > 0 verwendet wird.
Bei Pin 3 funktioniert soweit alles, nur leuchtet die LED erst auf, wenn analogWrite mit 255 angesprochen wird.
Bei Pin 5 funktioniert es jetzt komplett.

Hat jemand eine Idee, woran das liegen könnte?

Gruß

Philipp

#include <IRremote.h>

int RECV_PIN = 8;
int red = 9;
int green = 10;
int yellow = 5;
int brightRed = 0;
int brightGreen = 0;
int brightYellow = 0;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  
  digitalWrite(red, LOW);
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
}

void loop() {
  if (irrecv.decode(&results)) {

    Serial.println(results.value, DEC);
    controlBrightness();
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}


void controlBrightness()  {
  
  switch(results.value) {
    
    case 146225861:
      if (brightRed < 255)  {
        brightRed = brightRed + 51;
      }
      analogWrite(red, brightRed);
      Serial.println(brightRed);
      break;
     
    case 146241671:
      if (brightRed > 0)  {
        brightRed = brightRed - 51;
      }
      analogWrite(red, brightRed);
      Serial.println(brightRed);
      break;
  
    case 146242181:
      brightRed = 0;
      analogWrite(red, brightRed);
      Serial.println(brightRed);
      break; 
        
    case 146217701:
      if (brightGreen < 255)  {
        brightGreen = brightGreen + 51;
      }
      analogWrite(green, brightGreen);
      Serial.println(brightGreen);
      break;
      
    case 146233511:
      if (brightGreen > 0)  {
        brightGreen = brightGreen - 51;
      }
      analogWrite(green, brightGreen);
      Serial.println(brightGreen);
      break;
      
    case 146266661:
      brightGreen = 0;
      analogWrite(green, brightGreen);
      Serial.println(brightGreen);
      break;
      
    case 146266151:
      if (brightYellow < 255)  {
        brightYellow = brightYellow + 51;
      }
      analogWrite(yellow, brightYellow);
      Serial.println(brightYellow);
      break;
      
    case 146250341:
      if (brightYellow > 0)  {
        brightYellow = brightYellow - 51;
      }
      analogWrite(yellow, brightYellow);
      Serial.println(brightYellow);
      break;
      
    case 146234021:
      brightYellow = 0;
      analogWrite(yellow, brightYellow);
      Serial.println(brightYellow);
      break;
    
  }
}

Kann es sein, dass deine IR Lib einen Timer verwendet, und der damit für PWM verloren ist?

Zumindest verwenden 3 und 11 denselben Timer 2, also braucht die Lib wahrscheinlich den Timer 2... Aber wie kann es sein, dass der Arduino hängen bleibt?

hängen bleibt

Ist eine der möglichen Erscheinungen, welche bei Programmierfehlern gerne auftreten.

Wenn du es genau wissen willst, analysiere die Lib und analogWrite()

Das hab ich mir schon gedacht, aber was passiert da genau beim Hängenbleiben? Läuft da der RAM über?

someuser: Das hab ich mir schon gedacht, aber was passiert da genau beim Hängenbleiben? Läuft da der RAM über?

Siehe loop() in deinem Code!

 if (irrecv.decode(&results))

Wenn das nicht wahr wird, dann wird dein Arduino ewig im Loop kreisen, ohne eine Ausgabe zu machen. Für dich sieht das so aus, als ob der Arduino "hängt", tut er aber nicht, er loopt fleißig vor sich hin.

PS: Wenn man einer Lib den Timer kaputt manipuliert, sollte man sich nicht wundern, wenn diese Lib keine Ergebnisse liefert.

OK Vielen Dank für die schnellen Antworten :)

Die IRremote Bibliothek arbeit mit einer festen Interrupt-Rate von 20kHz, und benutzt dafür einen Timer. Die Pins 3 und 11 gehören zu T2 (OC2A/B), und wenn es da Probleme gibt, wird dieser Timer von der Bibliothek benutzt. Das läßt sich zwar ändern, aber dann wird eben T1 benutzt und steht nicht mehr für PWM Ausgänge (OC1A/B, 9, 10) zur Verfügung.

Die Timer ISR sind hart zugeordnet, und wenn die PWM Funktionen dann für zu viele Interrupts sorgen, bleibt praktisch keine Rechenzeit mehr für andere Dinge übrig.

Also nachschauen oder einstellen, welcher Timer benutzt wird, und die zugehörigen Pins nicht für andere Zwecke benutzen. Pin 11 wird übrigens bei SPI für MOSI benutzt, sollte also auch nur mit Bedacht für PWM benutzt werden.

Siehe Pin Zuordnung.

Beim Mega gibt es viel mehr Timer und PWM Ausgänge, falls jemand damit Probleme hat.