Incompatibilidad entre librería IRremote.h y analogWrite

Saludos a todo el Foro, en esta ocasión me corresponde compartir una situación de "incompatibilidad" que no he podido resolver, aquí la historia.

IMG_20191207_221820.jpg

Por motivo de las fechas navideñas, mi sobrino me trajo un trenecito que de buenas a primera dejo de funcionar para que revisara que sucedía con el, sucedió que indagando; su hermano inserto 12 Volts donde deberían ir 6 Volts. Sin hacer mas historia el "Modulo" que maneja el motor, luces, sonido, etc, pues simplemente se fulmino. Sin embargo al hacer pruebas de la demás circuiteria asociada que consta de un "Puente H" que maneja el motor, un transistor NPN para encender las luces, otro par de transistores para "amplificar" el sonido musical y un receptor infrarrojo de los tipo TSOP-1738 (que si se daño y cambie), llegue a la conclusión que la manera mas rápida seria comprar un arduino de los mas baratitos y con unas cuantas lineas de código dejar listo el juguetito. Al fin y al cabo ya hay librerías para todo, asi que sera cosa de un par de horas....bueno eso pensé yo :unsure:.

IMG_20191207_223806.jpg
Aquí pueden observar el modulo Dañado y el "Arduino" que tenia en mano.

Bien, pues pasemos al programa, con el siguiente código tengo control y sin ningún problema

C++:
                                                                                                                                                                                                                                        /*
* Programa para comandar tarjeta electronica del Trenecito
*
* comenzamos por definir y relacionar las salidas
* y entradas de nuestro microcontrolador
*
*
*/

#define Faro 4    // el pin 4 para que encender el Faro
#define Avance  5 // el pin 5 para que el tren avance
#define Reversa 6 // el pin 6 para que el tren este en reversa
#define Bocina 9 // el pin 9 para accionar la musica

// utilizamos una libreria para gestionar la informacion del infrarrojo

#define IR_USE_TIMER0

#include <IRremote.h>
int RECV_PIN = 10; //en el Pin 10 conectamos el Infrarojo

IRrecv irrecv(RECV_PIN);
decode_results results;
uint32_t codigo=0;


void setup() {

Serial.begin(115200);
  irrecv.enableIRIn(); // se habilita la libreria del infrarojo

pinMode(Faro, OUTPUT);



}

void loop() {

  if (irrecv.decode(&results))
    {
     codigo=results.value;
     digitalWrite(Faro,HIGH);  //encender el led
     delay(500);              //espero
     digitalWrite(Faro,LOW);   //apago el led
     Serial.println(codigo);
     irrecv.resume();} // esperamos el siguiente comando
  
      
    if (codigo==3044540814) {
              Serial.println("Avance");
                analogWrite(Avance,98);           
                    delay(1550);           
                analogWrite(Avance,0);
    }

          if (codigo==2278928878) {
              Serial.println("Reversa");
              analogWrite(Reversa,98);           
                   delay(1550);           
                 analogWrite(Reversa,0);
          }

           if (codigo==2735184250) {
              Serial.println("Faro");
              digitalWrite(Faro, HIGH);
              delay(1550);
              digitalWrite(Faro, LOW);
           }

            if (codigo==1538172922) {
              Serial.println("Paro");
              analogWrite(Avance,0);
              analogWrite(Reversa,0);
              digitalWrite(Faro, LOW);
            }
        if (codigo==3766512318) {
              Serial.println("Avance_Lento");
                analogWrite(Avance,63);           
              delay(1550);           
                analogWrite(Avance,0);
           }

            if (codigo==2764430686) {
              Serial.println("Regreso_Lento");
              analogWrite(Reversa,63);           
                    delay(1550);           
                 analogWrite(Reversa,0);
            }


          
       codigo=0; /limpio la variable en cero para esperar un codigo del IR nuevo   
  
  

}
Si, ya se que esta lleno de Dealy´s, y que con una estructura con "Switch...Case" queda mas elegante, pero esta en proceso de depuración. :rolleyes:

Ahora bien, el problema que tengo es el siguiente:

Si yo modifico el programa para que quede activo el PWM del respectivo pin (Avance o Reversa), con el comando
analogWrite con la idea de que así quede hasta recibir una nueva orden desde el control remoto. Sucede que en efecto, se ejecuta la orden, sin embargo a partir de ahí pierdo el control total del programa, es decir; me parece que la librería <IRremote.h> y el analogWrite no se llevan, posiblemente por que usan el mismo Timer. El síntoma o comportamiento es que la librería IRremote da "acuse" como si estuviera recibiendo señal del control remoto con un codigo "XXXXXXX" que obviamente hace que se pierda totalmente el control del programa.

Para comprobar, lo que hice fue usar en lugar del "analogWrite" la instrucción "digitalWrite" de esta manera no pierdo el control del programa, pero obviamente con esta ultima instrucción me seria imposible dar "velocidad" al motor, que es parte del funcionamiento original del tren.

Ya he intentado usar otros pines tanto para el Motor como para el receptor IR, incluso definir que la librería use otro Timer (#define IR_USE_TIMER0), pero no he logrado solucionar el problema.

¿alguna idea o propuesta?

Como siempre, muchas gracias.
 

Adjuntos

Última edición:
Bien, finalmente quedo solucionado con la librería original (ultima que baje del sitio) y anexando que se utilice el "TIMER 3" con la siguiente linea:

#define IR_USE_TIMER3

De cualquier manera dejo el código completo que ahora funciona de maravilla.


C++:
                                                                                                                                                                                                                                        /*
 * Programa para comandar tarjeta electronica del Trenecito
 *
 * comenzamos por definir y relacionar las salidas
 * y entradas de nuestro microcontrolador
 *
 *
 */

#define Faro 4    // el pin 4 para que encender el Faro
#define Avance  5 // el pin 5 para que el tren avance
#define Reversa 6 // el pin 6 para que el tren este en reversa
#define Bocina 9 // el pin 9 para accionar la musica

// utilizamos una libreria para gestionar la informacion del infrarrojo

#define IR_USE_TIMER3

#include <IRremote.h>
int RECV_PIN = 10; //en el Pin 10 conectamos el Infrarojo
boolean foco=false;
byte Valor_PWM=64; //Variable para que contiene el valor pwm para el motor
byte direccion=0; /*Variable para saber el sentido del motor

      0=Deteneido
      1=Avanzando
      2=En reversa*/


IRrecv irrecv(RECV_PIN);
decode_results results;
uint32_t codigo=0;


void setup() {
 
Serial.begin(115200);
  irrecv.enableIRIn(); // Iniciamos el servicio del Infrarojo
 
pinMode(Faro, OUTPUT);

}

void loop() {

  if (irrecv.decode(&results))
    {
     codigo=results.value;
     //     Serial.println(codigo); //linea que sirve para depuracion
     irrecv.resume();} // esperamos el siguiente comando
    
        
    if (codigo==3044540814) {
        // Serial.println("Velocidad ++");
      if(Valor_PWM<244){
                        Valor_PWM=Valor_PWM+10;
                        //Serial.print("Valor_PWM=");
                        //Serial.println(Valor_PWM);
                        }
                        }
    
     if (codigo==2278928878) {
              // Serial.println("Velocidad --");
          if(Valor_PWM>64){
                           Valor_PWM=Valor_PWM-10;
                           //Serial.print("Valor_PWM=");
                         // Serial.println(Valor_PWM);
                          }
                          }

           if (codigo==2735184250) {
              //Serial.println("Faro");
              if (foco==false){
                              digitalWrite(Faro, HIGH);
                              foco=true;
                              }else {                           
                                    digitalWrite(Faro, LOW);
                                    foco=false;}
                                    }

            if (codigo==1538172922) {
              //Serial.println("Paro");
              direccion=0;
              }
        if (codigo==3766512318) {
              //Serial.println("Avance");
                direccion=1;
           }

            if (codigo==2764430686) {
              //Serial.println("Reversa");
                direccion=2;
            }

 
 //============con estos IF´s controlamos sentido del motor dependiendo del contenido de la variable direccion
  if (direccion==1) {
                analogWrite(Reversa,0);
                analogWrite(Avance,Valor_PWM);             
                }

  if (direccion==2) {         
                analogWrite(Avance,0);
                analogWrite(Reversa,Valor_PWM);
                 }
                    
   if (direccion==0) {
                analogWrite(Reversa,0);
                analogWrite(Avance,0); 
                  }
//=====================================================
            
       codigo=0; //dejamos el valor de la variable en ceros hasta que llegue un nuevo comando IR
          

}

Solo mencionar que todos los Serial.println("xxxxx"); solo sirven de depuración y no son necesarios para nada.

Agradezco su atención, y que sirva este código a alguien; a manera de "fe de errata" para sus proyectos.

Saludos y felices fiestas decembrinas.
 

Arriba