Emisión de pulsaciones IR

Hola a todos, solicito su ayuda para comprobar si el código que tengo de un photon para emitir pulsaciones IR es correcto, ya que estaba funcionando y de repente dejo de funcionar, pueden decirme si es un error de código??? Cuando le envió una instrucción a photon con mimmb

el código

#include <IRremoteLearn.h>
int led1 = D0;
int led2 = D7;
//int cap = A0;
int SENSOR = D1;
//IRrecv irrecv(SENSOR);
//decode_results codigo;
int IRledPin = D5;
void pulseIR(long microsecs) {
// Haremos una cuenta regresiva desde la cantidad de microsegundos que se nos dice que esperemos
// cli(); // esto apaga las interrupciones de fondo
while (microsecs > 0) {
// 38 kHz el alrededor de 13 microsegundos en alto y 13 microsegundos en bajo
digitalWrite(IRledPin, HIGH); // toma alrededor de 4 microsegundos ejecutar esta instrucción
delayMicroseconds(9); // esperamos 10 microsegundos
digitalWrite(IRledPin, LOW); // this also takes about 4 microseconds
delayMicroseconds(9); // hang out for 10 microseconds

// entonces 26 microsegundos en total
microsecs -= 26;
}
// sei(); // esto vuelve a encender las interrupciones
}


void setup() {
    Particle.function("estado",estado_funcion);
  Serial.begin(9600);
    pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
 // pinMode(SENSOR, INPUT);
  //Serial.begin(9600);
    pinMode (IRledPin, OUTPUT);
}
void loop() {
// ENCENDERAIRE();
// delay(7000);
// digitalWrite(led2, HIGH);
//   ENCENDERM();
//   delay(7000);
//   digitalWrite(led2, LOW);
}
int estado_funcion(String recibido){
    

    
    //INICIO GHIA
    if(recibido=="EncenderM"){
        digitalWrite(led1, HIGH);
        digitalWrite(led2, HIGH);
      ENCENDERAIRE();
    }else{
        if(recibido=="ApagarM"){
            digitalWrite(led1, LOW);
            digitalWrite(led2, LOW);
          APAGARAIRE();
        }
        
        else{
            if(recibido=="SubirG"){
            digitalWrite(led1, LOW);
            digitalWrite(led2, LOW);
            SUBIRG();
            
              }else{
                  if(recibido=="BajarG"){
                    digitalWrite(led1, LOW);
                    digitalWrite(led2, LOW);
                    BAJARG();
                    
                  }//FIN GHIA
                  //INICIO LANIX
                  else{
                      if(recibido=="EncenderL"){
                            digitalWrite(led1, HIGH);
                            digitalWrite(led2, HIGH);
                            ENCENDERL();
                        }else{
                            if(recibido=="ApagarL"){
                                digitalWrite(led1, LOW);
                                digitalWrite(led2, LOW);
                                APAGARL();
                            }else{
                                if(recibido=="SubirL"){
                                digitalWrite(led1, LOW);
                                digitalWrite(led2, LOW);
                                SUBIRL();
                                  }else{
                                      if(recibido=="BajarL"){
                                        digitalWrite(led1, LOW);
                                        digitalWrite(led2, LOW);
                                        BAJARL();
                                      }
                                      //FIN LANIX
                                      //INICIO MAC
                                      else{
                                          if(recibido=="EncenderM"){
                                                digitalWrite(led1, HIGH);
                                                digitalWrite(led2, HIGH);
                                              ENCENDERM();
                                            }else{
                                                if(recibido=="ApagarM"){
                                                    digitalWrite(led1, LOW);
                                                    digitalWrite(led2, LOW);
                                                    APAGARM();
                                                }else{
                                                    if(recibido=="SubirM"){
                                                    digitalWrite(led1, LOW);
                                                    digitalWrite(led2, LOW);
                                                    SUBIRM();
                                                      }else{
                                                              if(recibido=="BajarM"){
                                                            digitalWrite(led1, LOW);
                                                            digitalWrite(led2, LOW);
                                                            BAJARM();
                                                          }
                                                      }
                                                }
                                            }
                                      }
                                      //FIN MAC
                                  }
                            }
                        
                  
                  }      
              }
        }
    }
}

}
               

void APAGARAIRE(){
pulseIR(9320);
delayMicroseconds(4580);
pulseIR(700);
delayMicroseconds(1660);
pulseIR(660);
delayMicroseconds(580);
pulseIR(660);
delayMicroseconds(580);
pulseIR(680);
delayMicroseconds(560);
pulseIR(660);
delayMicroseconds(580);
pulseIR(680);
delayMicroseconds(560);
pulseIR(660);
delayMicroseconds(1720);
pulseIR(680);
delayMicroseconds(560);
pulseIR(660);
delayMicroseconds(1700);
pulseIR(700);}

(ScruffR: added Google Translate version for general consumption :wink: )

Hello everyone, I ask for your help to check if the code I have for a photon to emit IR beats is correct, since it was working and suddenly it stopped working, can you tell me if it is a code error ??? When he sent an instruction to photon with mimmb

Hallo Juan,

kannst du uns erst einmal erklären welches Problem dein Code genau hat?
Beim überfliegen des Codes sind mir ein paar Ungereimtheiten aufgefallen, die unterschiedliche Auswirkungen haben würden.
Ohne genau zu wissen, welches Problem du genau angehen möchtest ist es schwer dir eine Lösung anzubieten.

BTW: Vielleicht wäre diese Seite hilfreich
https://translate.google.com/?hl=en&sl=es&tl=en&op=translate


(added English version)

Hello Juan,
first of all, can you explain for us which problem your code is having?
While skimming over the code, I noticed a few inconsistencies that would have create a number of different outcomes.
Without knowing exactly what problem you want to address, it is difficult to offer a solution.

BTW: Maybe this page would be helpful
Google Translate :wink:

a diaxulpa in advance for posting the same question 2 times, The problem I present is that the code I designed (I clarify that I am a beginner) is to receive instructions through an Android application and depending on the instruction I receive, it executes a different emission of keystrokes, until 2 days ago, my code executed the instructions that are inside VOID, but just yesterday, suddenly I stop executing them and it does not emit the pulsations through the infrared LEDs, and when from my Android application I press the button so that you emit a pulsation it does not do it and a few seconds later The LED stops flashing and remains in static cyan, I would like to know, is it a problem with my code? How can I solve this problem?

One thing that stuck out to me was the lack of a return statement in your estado_funcion().
If you were using device OS version 2.0.0 I’d have expected your device to go into an SOS panic crash. But since you are not reporting such a thing, there may be other things wrong.

On the other hand, the code you posted is also lacking multiple function definitions which also suggests that’s not the exact code you are compiling, otherwise you’d also get loads of error messages as I did.

The next thing I noticed that you don’t actually use the IRremoteLearn library but rather do the bit banging yourself.
There is nothing wrong with that in itself, but then it would be good to remove any distractions from your code.
Additionally I’d let the PWM hardware on the Photon do some of the heavy lifting
Along that line you could give this alternative approach a try

// let the PWM hardware do the heavy lifting (IRledPin needs to be PWM enabled e.g. D3)
void pulseIR(uint32_t pulse, uint32_t gap = 0) {  // using 38kHz PWM 
  analogWrite(IRledPin, 127, 38000);    // start PWM with 50% duty cycle 
  delayMicroseconds(pulse);             
  digitalWrite(IRledPin, LOW);          // off
  delayMicroseconds(gap);
}

void APAGARAIRE() {
  pulseIR(9320, 4580);
  pulseIR( 700, 1660);
  pulseIR( 660,  580);
  pulseIR( 660,  580);
  pulseIR( 680,  560);
  pulseIR( 660,  580);
  pulseIR( 680,  560);
  pulseIR( 660, 1720);
  pulseIR( 680,  560);
  pulseIR( 660, 1700);
  pulseIR( 700,    0);
}

Finally, your style in estado_function() could benefit from a different indentation scheme like this

int estado_funcion(String recibido) {
  int retVal = __LINE__ * -1;           // indicate an invalid choice by a negative line number (also tells you the base line for valid ones)
  
  if(recibido == "EncenderM") {         // INICIO GHIA
    retVal = __LINE__;                  // to indicate which branch was executed return the line number 
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    ENCENDERAIRE();
  }
  else if(recibido == "ApagarM") {
    retVal = __LINE__;
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    APAGARAIRE();
  }
  else if(recibido == "SubirG") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    SUBIRG();
  }
  else if(recibido == "BajarG") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    BAJARG();
  }                                     //FIN GHIA
  else if(recibido == "EncenderL") {    //INICIO LANIX
    retVal = __LINE__; 
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    ENCENDERL();
  }
  else if(recibido == "ApagarL") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    APAGARL();
  }
  else if(recibido == "SubirL") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    SUBIRL();
  }
  else if(recibido=="BajarL") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    BAJARL();
  }                                     //FIN LANIX
  else if(recibido == "EncenderM") {    //INICIO MAC
    retVal = __LINE__; 
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    ENCENDERM();
  }
  else if(recibido == "ApagarM") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    APAGARM();
  }
  else if(recibido == "SubirM") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    SUBIRM();
  }
  else if(recibido == "BajarM") {
    retVal = __LINE__; 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    BAJARM();
  }                                     //FIN MAC

  return retVal;
}

which makes reading somewhat easier.

However, I’d do the whole thing even more concise and more maintainable IMO.
The same behavour could easily be coded in less than 60 lines.

BTW, we also need to keep the Android side and the Photon firmware separated.
What Android app are you talking about?
Currently we’d only focus on the firmware and to exclude any contribution to the issue from the Android app you may either want to use the Particle Tinker App, console.particle.io/devices or CLI to test the functionality of the firmware.

1 Like

Entiendo, solo que en la función pulseIR incluye un analogWrite, entonces debo cambiar el pin de salida por un pin analogico o lo puedo dejar como digital?

We can go back to our individual native languages if you wish :wink:

Wie in dem Kommentar angegeben ist für analogWrite() ein PWM-fähiger Pin nötig.
Welche das am Photon sind, kannst du in der Referenz-Dokumentation nachlesen - das sind nicht nur A#-Pins (und davon auch nicht alle) sondern auch manche D#-Pins.

1 Like

I thank you very much for the support provided, I will try the options that you provide me, very grateful of you Scruffr

1 Like

If you are interested in the alternative approach I suggested above I can show you how it’s done.

Yes, please, it would be very helpful for my project

With this code I tried to replicate your one shared command APAGARAIRE() and from it I derived that the standard length for any given command should be 11 pulse/gap combinations (hence lenCode = 22).
With these assumptions I’d simplify your code to this

const int lenCode  = 2 * 11;                        // 11 pulse/gap combos
const int led1     = D0;
const int led2     = D7; 
const int IRledPin = D3; 

// command and IR code definition 
struct cmd_t { 
  char     id[12];                                  // command ID to be called via Particle.function
  uint8_t  state;                                   // LED state 
  uint16_t code[lenCode];                           // IR pulse/gap timing in µs
};
const cmd_t cmd[] =      //pulse,  gap,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g,    p,    g
{ { "EncenderG"   , HIGH, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "ApagarG"     ,  LOW, { 9320, 4580,  700, 1660,  660,  580,  660,  580,  680,  560,  660,  580,  680,  560,  660, 1720,  680,  560,  660, 1700,  700,    0 } } 
, { "SubirG"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "BajarG"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "EncenderL"   , HIGH, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "ApagarL"     ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "SubirL"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "BajarL"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "EncenderM"   , HIGH, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "ApagarM"     ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "SubirM"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
, { "BajarM"      ,  LOW, {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 } } 
};
const int numCmd = sizeof(cmd) / sizeof(cmd[0]);    // derive number of defined commands from [] array

// function prototypes
void pulseIR(uint32_t pulse, uint32_t gap);
int  fnEstado(const char* recibido);

void setup() {
  Serial.begin();
  Particle.function("estado", fnEstado);
  pinMode(IRledPin, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

int fnEstado(const char* recibido) {
  for (int i = 0; i < numCmd; i++) {                // iterate over command array
    if (!strcmp(cmd[i].id, recibido)) {             // looking for a match
      digitalWrite(led1, cmd[i].state);             
      digitalWrite(led2, cmd[i].state);
      for (int c = 0; c < lenCode; c += 2)          // pulse out IR code 1 pulse 1 gap at a time
        pulseIR(cmd[i].code[c], cmd[i].code[c+1]);  
      return i;                                     // return index of found match in array
    }  
  }
  return -1;                                        // no match found
}

void pulseIR(uint32_t pulse, uint32_t gap = 0) {    
  if (!pulse) return;                               // ignore when there is no pulse duration
  analogWrite(IRledPin, 127, 38000);                // start PWM with 50% duty cycle at 38 kHz 
  delayMicroseconds(pulse);                         // let PWM keep pulsing as long as needed
  digitalWrite(IRledPin, LOW);                      // off
  delayMicroseconds(gap);                           // ensure minimum length of gap
}

If you need any guidance on how this code works you are welcome to ask further questions.

@JuanC, any feedback on this?