Ifrarouge passage de Duemilanove a Mega 2560

Bonjour,

Voila mon probleme, j'utilise le code ci dessous sur une carte Duemilanove pour gerer de l'infrarouge (TSOP1838), tous fonctionne correctement. Et je viens d'acheter une carte Mega2560 et avec le meme code rien ne fonctionne.
Est ce que vous pouvez m'aider???

Merci d'avance.

#include <avr/io.h>
#include <avr/interrupt.h>


#define IR_PIN  14



// time definition @ TIMER1 interval @ 16us 
#define TIME_9MS 562
#define TIME_4_5MS 281
#define TIME_2_25MS 141
#define TIME_0_56MS 35
#define TIME_1_69MS 106
#define TOLERANCE		10
#define FRAME_TIMEOUT 12500   // timeout 200ms


typedef enum{
	FRAME_IDLE = 0,
	FRAME_START1,
	FRAME_START2,
	FRAME_REPEAT,
	FRAME_DAT1,
	FRAME_DAT2
} IR_FRAME_STATE;



volatile unsigned char bit_count;
volatile unsigned char ir_dat[4];
volatile unsigned int t_start, t_high, t_low;
volatile  IR_FRAME_STATE frame_state = FRAME_IDLE;

volatile byte ir_data_ready , ir_data_repeat;

byte trigger_edge;   // 1- rising edge; 0 - falling edge

int val_recu;

void setup(){
	
  
	// setup timer1
	TCCR1A = 0;   // normal mode
	TCCR1B = 0x4; // Timer1 frequency = 16MHz / 256 = 62.5KHz (16us)
	TCCR1C = 0;
	
	// enable Port change interrrupt on IR_PIN 
	DDRC &=~(1<<IR_PIN);
	PCICR |= (1<<PCIE1);
	PCMSK1 |= (1<<IR_PIN);
	
	trigger_edge = 0;   // start with falling edge
	SREG|=1<<SREG_I;
	
	// initialize 
	bit_count = 0;
	ir_dat[0]=ir_dat[1]=ir_dat[2]=ir_dat[3]=0;
	
	
	ir_data_ready = 0;
	ir_data_repeat = 0;

  Serial.begin(9600);
  Serial.println("IR remotr controller decode");	
}

void loop()
{
	
	if( (frame_state != FRAME_IDLE)&& (TCNT1-t_start>FRAME_TIMEOUT)){
			frame_state = FRAME_IDLE;
			trigger_edge = 0;
	}
	
	if(ir_data_ready){
		ir_data_ready =0;
		
	if(ir_dat[2]^ir_dat[3]== 0xff){
      
  val_recu = ir_dat[2], HEX;

        switch(val_recu){
          
          case 0:
              Serial.println("Touche ON/OFF");
              break;
          case 1:
              Serial.println("Touche Menu");
              break; 
          case 2:   
              Serial.println("Touche Play/pause");
              break;
          case 4:
              Serial.println("Touche RPT");
              break;
          case 5:  
              Serial.println("Touche Ch-");
              break;
          case 6:
              Serial.println("Touche Ch+");
              break;
          case 8:
              Serial.println("Touche Eq");
              break;
          case 9:
              Serial.println("Touche Vol-");
              break;
          case 10:
              Serial.println("Touche Vol+");
              break;
          case 13:
              Serial.println("Touche |<<");
              break;
          case 14:
              Serial.println("Touche >>|");
              break;
          case 12:
              Serial.println("Touche 0");
              break;
          case 16:
              Serial.println("Touche 1"); 
              break;  
          case 17:
              Serial.println("Touche 2");
              break;
          case 18:
              Serial.println("Touche 3");
              break;
          case 20:
              Serial.println("Touche 4");
              break;
          case 21:
              Serial.println("Touche 5");
              break;              
          case 22:
              Serial.println("Touche 6");
              break;
          case 24:
              Serial.println("Touche 7");
              break; 
          case 25:
              Serial.println("Touche 8");
              break;              
          case 26:
              Serial.println("Touche 9");
              break;
        }
		}	
	}
	
	if(ir_data_repeat){
		ir_data_repeat =0;
		Serial.println("REPEAT");		
               
	}
		
}




byte in_range(unsigned int t1, unsigned int t2, unsigned int time_range)
{
	unsigned int t_diff;
	
	t_diff = t1- t2;

		
	if( (t_diff >= (time_range - TOLERANCE)) && (t_diff <= (time_range + TOLERANCE)))
		return 1;
	else
		return 0;
}




ISR(PCINT1_vect)
{

if ((PINC & (1<<IR_PIN)) == (trigger_edge<<IR_PIN)){

// IR NEC PPM state machine
switch(frame_state)
{
	case FRAME_IDLE:
		t_start = TCNT1;
		frame_state = FRAME_START1;
		trigger_edge = 1;
		break;
	
	case FRAME_START1:
		t_high = TCNT1;
		if(in_range(t_high, t_start, TIME_9MS)){
			frame_state = FRAME_START2;
			trigger_edge = 0;  
		}
		else{
			frame_state = FRAME_IDLE;
			trigger_edge = 0;  
		}
		break;
	
	case FRAME_START2:
		t_low = TCNT1 ;
		trigger_edge = 1;
		if(in_range(t_low, t_high, TIME_4_5MS)){
			frame_state = FRAME_DAT1;  // start state finished, now if dat state
			bit_count = 0;
			ir_dat[0]=0;
			ir_dat[1]=0;
			ir_dat[2]=0;
			ir_dat[3]=0;
		}
			
		else if(in_range(t_low, t_high, TIME_2_25MS))
			frame_state = FRAME_REPEAT;
		else
			frame_state = FRAME_IDLE;
		break;
		
	case FRAME_DAT1:
		t_high = TCNT1;
		trigger_edge = 0;
		if(in_range(t_high, t_low, TIME_0_56MS))
			frame_state = FRAME_DAT2;
		break;
		
	case FRAME_DAT2:
		t_low = TCNT1;
		
		if(in_range(t_low, t_high, TIME_0_56MS)){
		  ir_dat[bit_count>>3] &= ~( 1<< (bit_count&0x7));
			bit_count++;
		}	
		else if(in_range(t_low, t_high, TIME_1_69MS)){
			ir_dat[bit_count>>3] |= ( 1<< (bit_count&0x7));
			bit_count++;
		}
		
		if(bit_count>=32){
			ir_data_ready = 1;
			frame_state = FRAME_IDLE;
			trigger_edge = 0;
		}
		else{
			frame_state = FRAME_DAT1;
			trigger_edge = 1;
		}		
		break;
		
	case FRAME_REPEAT:
		ir_data_repeat = 1;
		frame_state = FRAME_IDLE;
		trigger_edge = 0;
		break;
		
	default:
		frame_state = FRAME_IDLE;
		trigger_edge = 0;
		break;
	}	
	
	}
}

Bonjour,

Les ports et les registres ne sont pas les même entre une arduino 2009 (ATmega328p) et une mega2560 (ATmega2560) :

Bonjour,

Merci pour cette info, mais je nage un peu devans ces shémas, pouvez vous m'aider ??

Que dois je changer dans mon code ?

Merci d'avance.

Il faut que tu regarde sur quel broche était cablé "normalement" ton capteur IR sur une Duemilanove (PORTC donc une des broches analogique de A0 à A5).
Puis que tu le recable sur la même broche du port C de la mega2560, comme celui ci ne se trouve pas au même endroit se sera une broche entre A8 et A15.

En gros si il était sur A0 tu devra le recablé sur A8, A1 -> A9, ...
Je n'ai pas regardé les possible différences dans les registres d'interruption entre ATmega328p et ATmega2560 mais ça doit être les même.

PS: c'est un code maison ou un truc pompé sur internet ? Parce que il existe la lib IRremote qui permet d'utiliser des émetteur/récepteur IR.

Ok Ok je comprend mieu maintenant, je vais tester cela demain.

Pour le code je l'ai trouvé sur le site ou j'ai acheté le capteur IR j'ai juste modifié qq truc mais j'ai aucun mérite, j'ai bein vue la librairie Ifremote mais je n'ai pas testé.
Je ne comprenais pas pourquoi le code ne marché pas d'une carte a l'autre.

Merci bcp.

Bonjour,

Alors je viens de tester le recablage, mais il ne veut rien savoir, j'ai meme testé sur toutes les pin analogique une a la foi et rien.

Ca me rend fou ce truc.

matth59:
Alors je viens de tester le recablage, mais il ne veut rien savoir, j'ai meme testé sur toutes les pin analogique une a la foi et rien.

Ca me rend fou ce truc.

Essaye la librairie IRremote tu n'as rien a y perdre, le truc avec les sketch utilisant directement les registres comme le tient c'est qu'ils sont vraiment pas portable.

Voila je m'en suis sortie en utilisant la librairie IRremote, effectivement c plus simple.

Merci bcp .

Bon weekend