IR.Remote voglio capire

Ho deciso di aprire un nuovo Topic perchè il mio problema nulla ha a che fare col precedente (NANO 33 BLE primi passi).

Sto tentando di studiare la libreria ho trovato un esempio su cui partire, ho fatto molte prove (alcune andate bene altre andate male) poi ho ricopiato l'originale che carica perfettamente.

Ora tralasciando la mia comprensione del codice e di quello che leggo sul monitor (ho appena iniziato la fase di studio),
ricopiando e rileggendo l'esempio originale mi sono chiesto come fà a caricare senza errori e funzionare pure.

/*___________________________________________________________________________*/
/*INFRAROSSO VARIABILI-ISTANZE*/

#include <IRremote.h>               /*LIBRERIA*/
 
// Definisco lo schema di rappresentazione dell'1 e dello 0
#define IR_1_A 700
#define IR_1_B 1600
#define IR_0_A 700
#define IR_0_B 400
#define D 130 // Margine di errore nella lettura

int RECV_PIN = 6; // Pin di ricezione
IRrecv irrecv(RECV_PIN);
 
void setup()
{
 Serial.begin(9600);
 irrecv.enableIRIn(); // Inizializzo il ricevitore
}

unsigned int Decodifica(decode_results results)          
           {
            unsigned int c=0, r1, r2;
            int e=7, p2=128; // 2^7
            String d="", r="", base2="", Frase="";
            r=r+(results.rawbuf[1]*USECPERTICK)+" ";
            r=r+String(results.rawbuf[2]*USECPERTICK)+" "; // posso anche usare String
            
            for(int i=3; i<(results.rawlen-1) ; i=i+2)// Salto i primi 2 (Start of trasmission)
               {  
                r1=results.rawbuf[i]*USECPERTICK;
                r2=results.rawbuf[i+1]*USECPERTICK;
                r=r+r1+" "+r2+" ";
                if( (r1<=(IR_1_A+D)) && (r1>=(IR_1_A-D)) && (r2<=(IR_1_B+D)) && (r2>=(IR_1_B-D)) ) 
                  {
                   d=d+"1";                   
                   if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e;                 
                  } 
                else if ( (r1<=(IR_0_A+D)) && (r1>=(IR_0_A-D)) && (r2<=(IR_0_B+D)) && (r2>=(IR_0_B-D)) ) d=d+"0";           
                else d=d+"?"; e--; p2=p2/2;
               }
              
                // Descrivo la sequenza ricevuta
                Frase="Codifica IR ricevuta: "+r+"\n";
                Frase=Frase+"Decodifica in BIT: "+d;
                Frase=Frase+" - Somma potenze di 2: "+base2+" = "+c;
                Frase=Frase+" - Ascii: '"+(char)c+"'\n";
                Serial.println(Frase);
           }

void loop() 
{
  decode_results results;
  if (irrecv.decode(&results)) // Se ho qualcosa da decodificare ...
  {
     Decodifica(results);
     irrecv.resume(); // Ricevo il prossimo valore
     delay(40);
  }
}

2 cose non ho capito (prima delle altre):

-Dalla riga 23 alla 53 è racchiuso tra parentesi graffe una FUNZIONE che mi
sembra legata ad una VARIABILE

unsigned int Decodifica(decode_results results)          
           {
            unsigned int c=0, r1, r2;
            int e=7, p2=128; // 2^7
            String d="", r="", base2="", Frase="";
            r=r+(results.rawbuf[1]*USECPERTICK)+" ";
            r=r+String(results.rawbuf[2]*USECPERTICK)+" "; // posso anche usare String
            
            for(int i=3; i<(results.rawlen-1) ; i=i+2)// Salto i primi 2 (Start of trasmission)
               {  
                r1=results.rawbuf[i]*USECPERTICK;
                r2=results.rawbuf[i+1]*USECPERTICK;
                r=r+r1+" "+r2+" ";
                if( (r1<=(IR_1_A+D)) && (r1>=(IR_1_A-D)) && (r2<=(IR_1_B+D)) && (r2>=(IR_1_B-D)) ) 
                  {
                   d=d+"1";                   
                   if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e;                 
                  } 
                else if ( (r1<=(IR_0_A+D)) && (r1>=(IR_0_A-D)) && (r2<=(IR_0_B+D)) && (r2>=(IR_0_B-D)) ) d=d+"0";           
                else d=d+"?"; e--; p2=p2/2;
               }
              
                // Descrivo la sequenza ricevuta
                Frase="Codifica IR ricevuta: "+r+"\n";
                Frase=Frase+"Decodifica in BIT: "+d;
                Frase=Frase+" - Somma potenze di 2: "+base2+" = "+c;
                Frase=Frase+" - Ascii: '"+(char)c+"'\n";
                Serial.println(Frase);
           }

-Nel bel mezzo di questa FUNZIONE (tra la riga 38 e la riga 41) mi ritrovo un IF senza parentesi graffe.

if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e;  

non capisco .

L'indentazione è sbagliata. Un if vero esegue solo la prima istruzione che segue, o il primo blocco tra {}.

Puso,
te l'ho spiegato e rispiegato che DEVI INTENTARE IL CODICE CORRETTAMENTE CON L'APPOSITO COMANDO DELL'IDE !!! Non a mano come sembra giusto a te ... :roll_eyes:


/*___________________________________________________________________________*/
/*INFRAROSSO VARIABILI-ISTANZE*/

#include <IRremote.h>               /*LIBRERIA*/

// Definisco lo schema di rappresentazione dell'1 e dello 0
#define IR_1_A 700
#define IR_1_B 1600
#define IR_0_A 700
#define IR_0_B 400
#define D 130 // Margine di errore nella lettura

int RECV_PIN = 6; // Pin di ricezione
IRrecv irrecv ( RECV_PIN );

void setup() {
   Serial.begin ( 9600 );
   irrecv.enableIRIn(); // Inizializzo il ricevitore
}

unsigned int Decodifica ( decode_results results ) {
   unsigned int c = 0, r1, r2;
   int e = 7, p2 = 128; // 2^7
   String d = "", r = "", base2 = "", Frase = "";
   r = r + ( results.rawbuf[1] * USECPERTICK ) + " ";
   r = r + String ( results.rawbuf[2] * USECPERTICK ) + " "; // posso anche usare String

   for ( int i = 3; i < ( results.rawlen - 1 ) ; i = i + 2 ) { // Salto i primi 2 (Start of trasmission)
      r1 = results.rawbuf[i] * USECPERTICK;
      r2 = results.rawbuf[i + 1] * USECPERTICK;
      r = r + r1 + " " + r2 + " ";
      if ( ( r1 <= ( IR_1_A + D ) ) && ( r1 >= ( IR_1_A - D ) ) && ( r2 <= ( IR_1_B + D ) ) && ( r2 >= ( IR_1_B - D ) ) ) {
         d = d + "1";
         if ( base2 != "" )
            base2 = base2 + "+";
         c = c + p2;
         base2 = base2 + "2^" + e;
      } else if ( ( r1 <= ( IR_0_A + D ) ) && ( r1 >= ( IR_0_A - D ) ) && ( r2 <= ( IR_0_B + D ) ) && ( r2 >= ( IR_0_B - D ) ) ) d = d + "0";
      else d = d + "?"; e--; p2 = p2 / 2;
   }

   // Descrivo la sequenza ricevuta
   Frase = "Codifica IR ricevuta: " + r + "\n";
   Frase = Frase + "Decodifica in BIT: " + d;
   Frase = Frase + " - Somma potenze di 2: " + base2 + " = " + c;
   Frase = Frase + " - Ascii: '" + ( char ) c + "'\n";
   Serial.println ( Frase );
}

void loop() {
   decode_results results;
   if ( irrecv.decode ( &results ) ) { // Se ho qualcosa da decodificare ...
      Decodifica ( results );
      irrecv.resume(); // Ricevo il prossimo valore
      delay ( 40 );
   }
}

... ecco come deve essere il codice e come viene correttamente indentato quel if.

Guglielmo

Non capisco il senso della domanda ... cosa ti sembra strano? Come è definita la funzione "Decodifica"? Di quale "variabile" parli?

La funzione "Decodifica" ritorna un intero non segnato e vuole in ingresso il parameto "result" che è di TIPO "decode_results" ("tipo" definito come struttura all'interno di IRremoteInt.h, linea 157).

Guglielmo

ho solo fatto copia incolla di un esempio trovato sul web
non ho capito innanzitutto le parentesi graffe con un codice dentro dopo

unsigned int Decodifica(decode_results results)          
           {
            unsigned int c=0, r1, r2;
            int e=7, p2=128; // 2^7
            String d="", r="", base2="", Frase="";
            r=r+(results.rawbuf[1]*USECPERTICK)+" ";
            r=r+String(results.rawbuf[2]*USECPERTICK)+" "; // posso anche usare String
            
            for(int i=3; i<(results.rawlen-1) ; i=i+2)// Salto i primi 2 (Start of trasmission)
               {  
                r1=results.rawbuf[i]*USECPERTICK;
                r2=results.rawbuf[i+1]*USECPERTICK;
                r=r+r1+" "+r2+" ";
                if( (r1<=(IR_1_A+D)) && (r1>=(IR_1_A-D)) && (r2<=(IR_1_B+D)) && (r2>=(IR_1_B-D)) ) 
                  {
                   d=d+"1";                   
                   if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e;                 
                  } 
                else if ( (r1<=(IR_0_A+D)) && (r1>=(IR_0_A-D)) && (r2<=(IR_0_B+D)) && (r2>=(IR_0_B-D)) ) d=d+"0";           
                else d=d+"?"; e--; p2=p2/2;
               }

poi non ho capito IF contenuto all'interno senza paretesi graffe

if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e

http://www.brescianet.com/appunti/Elettronica/Arduino/corso/esempio_IR.htm

questo è
da dove sono partito.

Senza le graffe l'if esegue solo la prima istruzione.
L'indentazione che hai messo tu è "sbagliata". È corretta come nel post di Guglielmo.

Datman quindi quest' IF è inutile???

if (base2!="") 
                      base2=base2+"+";
                      c=c+p2;
                      base2=base2+"2^"+e;  

Guglielmo, fratt non sò cosa vuol dire INDENTAZIONE

Non è inutile. Dentro l'if c'è solo la prima riga
base2=base2+"+";
Le altre due sono fuori dall'if e vengono eseguite comunque.

allora perchè metterci IF?

allora IF è inutile se ci metto solo la riga non dovrebbe cambiare nulla??

se per IDENTARE correttamente intendi NON modificare le posizioni delle righe tra parentesi e le parentesi stesse........se non le sposto mi confondo e non riesco a leggere neppure quelle che capisco.

Ma hai visto il mio codice? hai visto le spaziature dal bordo delle varie righe (quello significa indentare)? Ti sembra come quello tuo? Le spaziature sono FONDAMENTALI per la leggibilità del codice ... per questo NON devi fare a mano, ma con la "formattazione automatica" del IDE (come ti ho scritto, evidenziando in giallo, nell'altro thread).

Guglielmo

P.S.: Se non sai un termine ... basta che lo cerchi con Google ... "indentatura del codice" ... non ci vuole molto eh !!!

Ma non mi dire, dal 2017 ancora non hai capito a cosa servono le graffe?
Male male.

if (base2!="") { 
    base2=base2+"+";
}
c=c+p2;
base2=base2+"2^"+e;

questo è uguale a:

if (base2!="")  
    base2=base2+"+";

c=c+p2;
base2=base2+"2^"+e;

Per la if, for, while ecc il blocco di codice associato implicitamente è grande una sola istruzione. Se si vuole estendere il blocco di codice associato a più di una istruzione occorre raggruppare queste tra le graffe.

Ciao.

Maurotec ..... dai ammettilo dal 2017 sono migliorato (non nella forma ..infatti Guglielmo continua a sgridarmi) mi fa piacere ritrovarti.

poi nell esempio copiato ed incollato le graffe non ci sono....questo mi ha portato fuori strada,

quindi se dopo IF devo fare una sola cosa non importa che la metto tra le graffe???------situazione forviante.

NO, in realtà la situazione è che ti mancano le basi del C e quelle del C++ ...

Fossi in te mi andrei a studiare, quanto meno, il reference di Arduino :roll_eyes:

Uso delle graffe QUI

Sintassi del IF QUI

Guglielmo

Esatto, ma ricorda una sola istruzione che termina con il ;

Però molte volte ci si ritrova a scrivere codice step by step e potremmo avere la necessità di eseguire due o più istruzioni e in questo caso se ci dimentichiamo di raggrupparle tra le graffe il compilatore prende solo la prima.

L'esperienza ci porta ad usare le graffe anche quando non servono, in questo modo durante l'evoluzione del codice possiamo aggiungere più istruzioni e non dobbiamo fare altro poiché le graffe ci sono già.

Io lo faccio quasi sempre, e quando non lo faccio lascio una riga vuota prima della if e una dopo l'istruzione. Poi per risparmiare qualche riga o preso l'abitudine di mettere la graffa nello stesso rigo della if, l'alternativa usata da alcuni invece è questa:

if (base2!="") 
{ // rigo vuoto con la sola graffa di apertura
    base2=base2+"+";
}
c=c+p2;
base2=base2+"2^"+e;

Altri ancora usano una indentazione particolare che mi confonde:

if (base2!="") 
    { // rigo vuoto con la sola graffa di apertura
       base2=base2+"+";
    }

Ricordiamoci che oltre a compilare e ad essere eseguito correttamente il codice che scriviamo sarebbe bene sia comprensibile anche agli altri programmatori.

Si lo ammetto.Ma diciamo che c'è ancora un graaaaande margine di miglioramento. :smile:

Ciao.