Conflitto Interrupt ?

Buona sera,
ho un problema e sono qui a chiedere aiuto.
Vorrei fare uno sketch che riceva codici da telecomandi IR, ma nel contempo possa generare un PWM sul pin D11.

Lo sketch allegato fa un ciclo faading sul led D11 tramite il pwm.

Succede che se abilito gli interrupt (tolgo // rigo 46) il PWM non funziona più.

Suggerimenti?
Molte grazie

/*
  Fading

  This example shows how to fade an LED using the analogWrite() function.

  The circuit:
  - LED attached from digital pin 9 to ground.

  created 1 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Fading
*/

#include <IRremote.h>

#include <EEPROM.h>
//indirizzi EEProm
int EEPROMaddr = 10; // 10 = Mode

int RECV_PIN = 10; // UNO input IR pin  11
bool ProtocolOK;

IRrecv irrecv(RECV_PIN);

decode_results results;



int ledPin = 11;    // LED connected to digital pin 9

void setup() {
  // nothing happens in setup
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  
  //RIGA INCRIMINATA INIZIO
  //irrecv.enableIRIn(); // Start the receiver
  //RIGA INCRIMINATA FINE


}



void dump(decode_results *results) {
  // Dumps out the decode_results structure.
  // Call this after IRrecv::decode()
  int count = results->rawlen;

  ProtocolOK = false;
  
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");

  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    ProtocolOK = true;



    Serial.print("Decoded RC5: ");


  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {
    Serial.print("Decoded PANASONIC - Address: ");
    Serial.print(results->address, HEX);
    Serial.print(" Value: ");
  }
  else if (results->decode_type == LG) {
    Serial.print("Decoded LG: ");
  }
  else if (results->decode_type == JVC) {
    Serial.print("Decoded JVC: ");
  }
  else if (results->decode_type == AIWA_RC_T501) {
    Serial.print("Decoded AIWA RC T501: ");
  }
  else if (results->decode_type == WHYNTER) {
    Serial.print("Decoded Whynter: ");
  }





    if (ProtocolOK == true)
    {
  
      Serial.print(results->value, HEX);
      Serial.print(" (");
    

      
    }
    else
    {
        Serial.println("prot-error");
    }
  



ProtocolOK = false;
results->decode_type = UNKNOWN;

  
}












void loop() {

  if (irrecv.decode(&results)) {
    dump(&results);    
    irrecv.resume(); // Receive the next value
  }


  
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
    Serial.println(fadeValue);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
    Serial.println(fadeValue);
  }
}

Su Arduino UNO (che do per scontato tu stia usano, visto che non specifichi nulla) per il PWM sui pin 3 ed 11 viene utilizzato il Timer2; di base, se non modificata, anche la IRremote usa su Arduino UNO il Timer2 ed il pin 3 per il LED di ricezione, quindi ...

... vai nella IRremote e modifica il file boarddefs.h (ci sono apposite #define) in modo che il timer usato NON sia il Timer2 ma il Timer1 (che, attenzione, viene usato anche dal PWM sui pin 9 e 10 e dalla libreria Servo). Ovviamnete devi anche spostare il LED di ricezione sul pin 9 e non più sul pin 3:

...
#else
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
	//#define IR_USE_TIMER1   // tx = pin 9
	#define IR_USE_TIMER2     // tx = pin 3

#endif

Guglielmo

Grazie,
già che siamo in argomento:

  • come faccio a sapere tutti i timer connessi con i 6 PWM su UNO, quelli che si azionano con analogWrite(Pin, Value); ?
  • E su Mega cambia ?
  • Che libreria bisogna aprire per capire questo ?
    Cordialità.

... ogni MCU ne ha differenti ed ovviamente vengono usati in modo diverso. L'unico modo è studiarsi bene i vari moduli del "core" Arduino e ricavare questi dati.

Te ne riassumo un po' ...

Arduino UNO Timers (ATmega328P)

Timer0
Usato da millis() e delay() e per il PWM sui pin 5 e 6
fast hardware pwm
(default 976.5625 Hz)
Pin 5 è anche usato per il “pulse counting”
Pin 8 è usato per il “input capture”

Timer1
Usato dalla libreria Servo e per il PWM sui pin 9 e 10. Libreria e PWM mutuamente esclusivi.
8-bit phase correct pwm mode
(default 488.28125 Hz)

Timer2
Usato per il PWM sui pin 3 e 11
8-bit phase correct pwm mode
(default 488.28125 Hz)

Arduino Leonardo Timers (ATmega32U4)

Timer0
#bits = 8
Clock speed = 16 MHz (system clock speed)
Default prescaler = 64
Pins D3 & D11

Timers 1 and 3
#bits = 16
Clock speed = 16 MHz (system clock speed)
Default prescaler = 64
Pins D5, D9 & D10
Pin D11 can also be set to use timer 1 output (OC1C), but the Arduino library uses it for timer 0 (8-bit). To use it on timer 1, it must be done by setting the appropriate registers.

Timer 4
#bits = 10
Clock speed = 64 MHz
Default prescaler = 64
Pins D6, D13
Pin D10 (PB6) also has a timer 4 output (OC4B), but the Arduino library uses it for timer 1 (16-bit). To use it on timer 4, it must with the registers.

Arduino Mega2560 Timers (ATmega2560)

Timer0
Usato per il PWM sui pin 4 e 13
fast hardware pwm

Timer1
Usato per il PWM sui pin 11 e 12
8-bit phase correct pwm mode

Timer2
Usato per il PWM sui pin 9 e 10
8-bit phase correct pwm mode

Timer3
Usato per il PWM sui pin 2, 3 e 5
8-bit phase correct pwm mode

Timer4
Usato per il PWM sui pin 6, 7 e 8
8-bit phase correct pwm mode

Timer5
usato per il PWM sui pin 45 e 46
8-bit phase correct pwm mode
Pin 47 è usato per il “pulse counting”
Pin 48 è usato per il “input capture”

... sono le schede più diffuse :slight_smile:

Guglielmo

Confermo Arduino UNO.

Ho spostato il comando PWM sul pin D9 e mi sembra convivere con IRREMOTE e con millis.

Farò altre prove.

Grazie 1000

Saluti