Problema com IRremote

Olá pessoal,

Meu caso é o seguinte: Estou tentando desenvolver um código com o IRremote pra unificar todos os controles remotos que tenho. Atualmente uso um controle remoto pra cada aparelho, um pro ar-condicionado, um pro ventilador, um pra TV, um pro VCR, enfim. A ideia é unificar tudo.

Como a maioria desses controles não são reconhecidos pela biblioteca do IRremote, estou tendo que usar o sendRaw. Até aí nenhum problema, fiz alguns testes com alguns comandos isolados e funcionam bem. O problema surge quando unifico todos os comandos que quero no código final.

O código que resultou foi esse:

#include <IRremote.h>

IRsend irsend;
/*Ligar AR (a)*/
unsigned int aron[100] = {8450,4100,550,1550,550,1550,550,1550,500,550,500,1600,500,550,550,1550,550,1550,550,4150,500,1600,500,1600,500,550,550,1550,550,500,550,550,500,550,500,550,600,19000,8300,4150,550,1550,500,1600,550,1550,550,500,550,1550,550,550,500,1600,500,1600,500,4150,550,1550,550,1550,550,500,550,1600,500,550,500,550,500,550,500,550,600,18950,8300,4150,550,1550,550,1550,550,1550,550,500,550,1600,500,550,500,1600,500,1600,500,4150,550,1550,550,};

/*Define AR como COOL (b)*/
unsigned int arcool[100] = {8450,4100,550,1550,550,1550,550,1550,550,500,550,1550,550,550,500,1600,500,1600,500,4150,550,500,550,550,500,550,500,550,500,550,500,550,550,500,550,550,550,19000,8350,4150,500,1600,500,1600,500,1600,500,550,550,1550,550,500,550,1550,550,1550,550,4150,500,550,500,550,550,500,550,550,500,550,500,550,500,550,550,500,600,18950,8300,4150,550,1550,550,1550,550,1550,550,550,500,1600,500,550,500,1600,500,1600,500,4150,550,550,500,};

/*Liga/Desliga TV (c)*/
unsigned int tvon[100] = {4700,4250,750,1500,700,1500,750,1450,750,400,700,400,650,500,600,500,600,500,600,1650,550,1650,600,1650,550,550,550,550,550,600,500,600,550,550,550,550,550,1700,550,550,550,550,550,550,550,600,550,550,550,550,550,1700,550,550,550,1650,550,1700,550,1650,550,1700,550,1650,550,1700,550,-19086,4450,4550,450,1750,500,1750,450,1750,500,600,500,650,450,650,500,600,500,600,500,1750,500,1700,500,1750,500,600,500,600,500,600,550,};

/*Liga/Desliga VCR (d)*/
unsigned int vcron[100] =  {3650,1550,550,300,550,1200,500,350,500,350,550,300,550,350,500,350,500,350,500,400,450,400,450,400,450,400,450,400,450,1300,450,400,450,400,450,450,400,450,400,450,400,450,450,1300,400,450,400,450,400,1300,450,450,400,450,400,450,450,400,450,400,450,450,400,450,400,450,450,1250,450,450,400,1300,400,1300,450,1300,400,1300,450,400,450,450,400,1300,450,400,450,1300,400,1300,450,400,450,1300,400,450,400,1300,450,};

/*VCR FF (e)*/
unsigned int vcrff[100] = {3650,1500,650,250,600,1100,600,250,550,350,500,350,500,350,500,400,450,400,500,350,500,350,500,400,450,400,450,400,450,1250,450,450,400,450,450,400,450,400,450,400,450,450,400,1300,450,400,450,450,400,1300,400,450,450,400,450,450,400,450,400,450,450,400,450,400,450,450,400,1300,400,1300,450,450,400,450,400,450,450,400,450,400,450,450,400,1300,400,1300,450,450,400,450,400,1300,450,400,450,450,400,1300,450,};

/*VCR REW (f)*/
unsigned int vcrrew[100] = {3650,1500,650,250,550,1150,550,300,550,350,500,350,500,350,500,400,450,400,450,400,450,400,450,450,400,450,450,400,450,1250,450,450,400,450,400,450,400,450,450,400,450,450,400,1300,400,450,450,400,450,1300,400,450,450,400,450,400,450,450,400,450,450,400,450,400,450,450,400,450,400,1300,450,400,450,450,400,450,400,450,400,450,450,400,450,450,400,1300,450,400,450,400,450,1300,400,450,450,400,450,1300,400,};

/*VCR Play (g)*/
unsigned int vcrplay[100] = {3650,1500,600,250,600,1150,550,300,550,300,550,350,500,350,500,350,500,400,450,400,450,400,450,400,450,400,450,450,450,1250,450,400,450,450,400,450,400,450,400,450,450,400,450,1300,400,450,400,450,450,1300,400,450,400,450,400,450,450,400,450,450,400,450,400,450,450,400,450,400,450,1300,400,450,400,1300,450,450,400,450,400,450,450,400,450,400,450,1300,400,450,450,1250,450,1300,400,450,450,400,450,1300,400,};

/*VCR Stop (h)*/
unsigned int vcrstop[100] = {3600,1600,500,350,500,1200,550,300,550,350,500,350,500,350,500,400,450,400,450,400,450,400,450,450,400,450,450,400,450,1250,450,450,400,450,400,450,400,450,450,400,450,450,400,1300,450,400,450,400,450,1300,400,450,450,400,450,400,450,450,400,450,400,450,400,450,450,450,400,450,400,450,400,450,450,400,450,450,400,450,400,450,450,400,450,400,450,450,400,450,400,450,400,1300,450,450,400,450,400,1300,450,};

/*Sobe luz (i)*/
unsigned int luzsobe[48] = {1450,200,1450,200,1400,200,650,1000,1450,200,600,1050,600,1000,650,1000,600,1050,600,1050,1300,350,450,-31886,1250,400,1250,400,1250,400,400,1250,1200,400,400,1250,400,1250,400,1250,400,1200,450,1200,1250,400,400,};

/*Baixa luz (j)*/
unsigned int luzbaixa[48] = {1450,200,1500,100,1500,150,700,950,1450,200,600,1050,600,1050,600,1050,550,1100,1250,400,400,1250,400,-31886,1200,450,1200,400,1250,400,400,1250,1200,450,400,1200,450,1200,450,1200,400,1250,1200,450,400,1200,450,};

/*Liga/Desliga Luz (k)*/
unsigned int luzonoff[48] = {1450,200,1450,150,1450,200,650,1000,1450,200,600,1050,600,1050,600,1000,1400,250,550,1100,500,1150,450,-30936,1250,350,1250,400,1250,400,400,1250,1200,450,400,1200,400,1250,400,1250,1250,400,400,1200,450,1200,400,};

/*Liga/Desliga Ventilador (l)*/
unsigned int ventonoff[46] = {1450,200,1450,200,2300,950,700,950,1450,200,600,1050,600,1050,1350,300,500,1150,450,1200,450,-31936,1250,400,1200,400,1250,400,400,1250,400,1250,1200,450,400,1200,400,1250,1250,400,400,1250,400,1200,450,};

/*Sobe Ventilador (m)*/
unsigned int ventsobe[48] = {1450,200,1450,150,1500,150,650,1000,600,1050,1450,200,600,1050,600,1000,600,1050,600,1050,1300,350,450,-31786,1250,400,1200,400,1250,400,450,1200,400,1250,1200,450,400,1200,450,1200,400,1250,400,1250,1200,400,450,};

/*Baixa Ventilador (n)*/
unsigned int ventbaixa[48] = {1450,150,1450,250,1300,350,450,1200,400,1200,1250,400,450,1200,400,1250,400,1250,1200,400,400,1250,400,-31786,1250,400,1250,400,1200,400,450,1200,450,1200,1250,400,400,1250,400,1200,450,1200,1250,400,400,1250,400,};

/*Reverte Ventilador (o)*/
unsigned int vent[46] = {1450,200,1500,150,2300,1000,650,950,1450,200,1450,200,600,1050,550,1100,500,1150,500,1150,450,-31786,1250,400,1200,400,1250,400,400,1250,400,1250,1200,400,1250,400,400,1250,400,1250,400,1200,450,1200,400,};

void setup()
{
  Serial.begin(9600);
}

void loop() {
 char z = Serial.read();
 
 if (z == 'a') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(aron,100,38);
      delay(40);
    }
  }	   
 if (z == 'b') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(arcool,100,38);
      delay(40);
    }
  }	   
 if (z == 'c') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(tvon,100,38);
      delay(40);
    }
  }	   
 if (z == 'd') {
    for (int i = 0; i < 2; i++) {
      irsend.sendRaw(vcron,100,38);
      delay(40);
    }
  }	   
 if (z == 'e') {
    for (int i = 0; i < 2; i++) {
      irsend.sendRaw(vcrff,100,38);
      delay(40);
    }
  }	   
 if (z == 'f') {
    for (int i = 0; i < 2; i++) {
      irsend.sendRaw(vcrrew,100,38);
      delay(40);
    }
  }	   
 if (z == 'g') {
    for (int i = 0; i < 2; i++) {
      irsend.sendRaw(vcrplay,100,38);
      delay(40);
    }
  }	   
 if (z == 'h') {
    for (int i = 0; i < 2; i++) {
      irsend.sendRaw(vcrstop,100,38);
      delay(40);
    }
  }	   
 if (z == 'i') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(luzsobe,48,38);
      delay(40);
    }
  }	   
 if (z == 'j') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(luzbaixa,48,38);
      delay(40);
    }
  }	   
 if (z == 'k') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(luzonoff,48,38);
      delay(40);
    }
  }	   
 if (z == 'l') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(ventonoff,46,38);
      delay(40);
    }
  }	   
 if (z == 'm') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(ventsobe,48,38);
      delay(40);
    }
  }	   
 if (z == 'n') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(ventbaixa,48,38);
      delay(40);
    }
  }	   
 if (z == 'p') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(vent,46,38);
      delay(40);
    }
  }	   
	   
 }

Reparem que na primeira parte do código eu distribuí cada comando Raw em um int diferente.
E na segunda parte do código seria onde são enviado os comandos, dependendo do que for inserido na serial, nesse caso caracteres de a até j

O problema acontece que de acordo com que eu vou adicionando mais if na segunda parte do código, os comandos param de funcionar.

Por exemplo, nesse código que postei, o caractere c quando enviado pela serial deveria ligar/desligar a TV. Mas do do modo como esta ali, ele não funciona, o led infra-vermelho pisca normalmente, mas o aparelho de tv não reconhece o comando.
Mas se eu excluí parte desse segundo código, os comandos voltam a funcionar a medida que eu vou removendo os if.
Por exemplo, se eu deixar a segunda parte do código como abaixo (sem mexer nas int), ele funciona perfeitamente:

void loop() {
 char z = Serial.read();
 
 if (z == 'a') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(aron,100,38);
      delay(40);
    }
  }	   
 if (z == 'b') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(arcool,100,38);
      delay(40);
    }
  }	   
 if (z == 'c') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(tvon,100,38);
      delay(40);
    }
  }	   
}

Mas se ou for incluindo mais if abaixo desses, esses primeiros param de funcionar.

Provavelmente estas a gastar toda a RAM.
Qual modelo de arduino estas a usar?

/Ligar AR (a)/
unsigned int aron[100] =

Só esta declaração consome 200 bytes de RAM ( um int sao 2 bytes).
Pelas minhas contas por alto senão me enganei estas a consumir 1088 bytes de RAM, logo se estas a usar um micro 328 estas claramente acima da RAM.

SRAM 2 KB (ATmega328)

Se queres mesmo avançar com isso assim procura por progmem para alojares esses arrays na flash e nao na RAM.

Estou usando o Arduino UNO.

Não creio que seja as int, pois como expliquei acima, se eu manter todas as int da maneira como esta no código, e excluir alguns if do loop ele volta a funcionar, a media que vou excluindo mais if, ele vai voltando a funcionar mais eficazmente. Imagino então que deve ser alguma coisa errada no loop dos if.

Faz bem as contas nos teus Ints e veras que estas acima da tua RAM.
Os teus arrays estao a gastar 2264 bytes de RAM !!! e o teu NANO so tem 2048 bytes de RAM.
No teu loop tens um erro sim

void loop() {
char z = Serial.read(); //Como sabes que tens algo para ler ?? Nao devias primeiro confirmar se o buffer tem algo para ser lido primeiro??
//Devias verificar primeiro usando um if(Serial.available() >0);char z= Serial.read();

if (z == 'a') {
for (int i = 0; i < 1; i++) {
irsend.sendRaw(aron,100,38);
delay(40);
}
}

Ok.

Fiz algumas mudanças e implementei o PROGMEM. Porém não estou conseguindo ler a int que gravei na memória flash.

Já li vários artigos pela internet, mas não estou conseguindo aplicar no meu projeto.

Código:

#include <avr/pgmspace.h>
#include <IRremote.h>

IRsend irsend;

PROGMEM prog_uint16_t tvon[100] = {4700,4250,750,1500,700,1500,750,1450,750,400,700,400,650,500,600,500,600,500,600,1650,550,1650,600,1650,550,550,550,550,550,600,500,600,550,550,550,550,550,1700,550,550,550,550,550,550,550,600,550,550,550,550,550,1700,550,550,550,1650,550,1700,550,1650,550,1700,550,1650,550,1700,550,-19086,4450,4550,450,1750,500,1750,450,1750,500,600,500,650,450,650,500,600,500,600,500,1750,500,1700,500,1750,500,600,500,600,500,600,550,};

void setup()
{
  Serial.begin(9600);
}

void loop() {
 if(Serial.available() >0);char z= Serial.read();
 if (z == 'c') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(tvon,100,38);
      delay(40);
      
    }
  }	   
    
 }

Tens usar um Progmem read quando queres usar essa "variavel"
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Há um outro problema no código que o HugoPT te passou. Tenta esse:

void loop() {
 char z = 0;
 if(Serial.available() >0) z= Serial.read();
 if (z == 'c') {
    for (int i = 0; i < 1; i++) {
      irsend.sendRaw(tvon,100,38);
      delay(40);
      
    }
  }
}

poderia postar o código utilizado para receber o raw dos controles? estou tendo muita dificuldade em utilizar o infrared, ainda não consegui nem ligar e desligar a TV.