info sulla teoria di funzionamento del ricv IR

Ciao a tutti,

tra le cose fantastiche che si possono fare con arduino, mi sono imbattuto nella possibilità della libreria IR trasmissione e ricezione.
Ho provato a capire i concetti da solo navigando qua e la, ma non ho le idee molto chiare comunque.

ho utilizzato lo sketch di Shirriff IRrecvDemo

ho collegato il ricevitore e aprendo il monitor e schiacciando il tasto di un telecomando qualsiasi riceve dei dati che scrive sotto forma di caratteri alfanumerici.
ad esempio 3BF oppure BFP.
la prima domanda: questi dati stampati sono frutto della codifica operata dalla libreria e si possono già usare come elementi di comparazione in uno sketch con l'operatore if per esempio? se si, come si usano nell'operatore if per dirgli di comparare non un numero ma una stringa alfanumerica?

oppure vanno trasformati in numeri per poter essere utilizzati? in questo caso con quale funzione?

un saluto

paverik:
la prima domanda: questi dati stampati sono frutto della codifica operata dalla libreria e si possono già usare come elementi di comparazione in uno sketch con l'operatore if per esempio?

sì, come qualsiasi dato del C

paverik:
se si, come si usano nell'operatore if per dirgli di comparare non un numero ma una stringa alfanumerica?

semplice, metti l'if in un ciclo e testi ogni singola lettera... poi ovvio che esiste una funziona già fatta in C nella libreria string.h ed è la strcmp, oppure l'OGGETTO String.h di arduino possiede il metodo compare()....

[/quote]

lesto grazie della risposta, ma purtroppo il mio livello di conoscenza è così basso che non mi permette di capire le tue, per te ovvie, indicazioni.
provo terra terra a spiegarmi.

dato che premendo un pulsante del telecomando ir mi da una stringa BDF io devo dire ad arduino che quando codifica BDF accenda un led, ogni altra codifica non faccia nulla.
ho provato ad fare un codice come quello allegato:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
#define BDF 1



IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13, OUTPUT);
  
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if((results.value, HEX) == BDF){
    digitalWrite(13,HIGH);
    }
    
    else {
    digitalWrite(13,LOW);
    }
    
    
    irrecv.resume(); // Receive the next value
  }
}

ma non funziona, evidentemente non conosco il linguaggio per eseguire questa funzione.
ho provato a fare un ciclo che testa la singola lettera, ma come la definisco?
ti allego la prova:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
#define B 1
#define D 1
#define F 1

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13, OUTPUT);
  
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if((results.value, HEX) == B)
    if((results.value, HEX) == F)
    if((results.value, HEX) == D){
    digitalWrite(13,HIGH);
    }
    
    else {
    digitalWrite(13,LOW);
    }
    
    
    irrecv.resume(); // Receive the next value
  }
}

non va. Sembra facile…
non denigrarmi ma da parte mia ce la metto tutta,
comunque ti ringrazio per il tempo che perdi con me.

aspetto l’illuminazione.

riccardo

scrivere

#define B 1
#define D 1
#define F 1

vuol dire che da ora in poi nel codice ogni D, F e B saranno sostituite con un 1.... Non è assolutamente quello che ti serve!

il codice

if((results.value, HEX) == B)
    if((results.value, HEX) == F)
    if((results.value, HEX) == D){
    digitalWrite(13,HIGH);
    }

per essere corretto deve essere:

if((results.value, HEX) == 'B')
    if((results.value, HEX) == 'F')
    if((results.value, HEX) == 'D'){
    digitalWrite(13,HIGH);
    }

notare l'apice singolo: vuol dire che quei B F e D vanno considerati come lettera (UNA sola lettera) e non come variabile. ovviamente i #define dovrai toglierli, oppure rischi che quando compili tutte le lettere B D e F vengano sostituite da 1 e poi è ovvio che il tuo codice non funzioni....
però questo funziona solo le results.value() restituisce un carattere alla volta, se inveece te li da tutti insieme la cosa si complica un poco.

scusa per la risposta tardiva ma ero all’estero per lavoro,

grazie Lesto delle delucidazioni, adesso grazie a te ho imparato una cosa nuova.

non sono riuscito però, a risolvere, dato che i telecomandi danno tutti una serie alfanumerica , non una singola lettera.

ho pensato di fare cosi: ho scaricato un sketch già fatto

file:///Users/paverik/Desktop/Arduino%20telecomando%20IR%20%7C%20Dadacode.html

provo a vedere se sostituendo la stringa del telecomando che usa lui, con la stringa che genera il mio nella definizioni delle funzioni speriamo che vada.

allego il pezzettino di sketch dove eseguirò le prove.

ciao e grazie ancora.

// includiamo prima di tutto la libreria IRremote
#include <IRremote.h>
// definiamo i valori che vengono passati dai pulsanti del nostro telecomando
#define SPEGNI1 0X2F59867// Stop LED 1
#define ACCENDI1 0X2F540BF // ACCENDI LED 1
#define ACCENDI2 0X2F548B7 //  ACCENDI LED 2
#define SPEGNI2 0x2F5A05F // Stop LED 2
#define ACCENDI_POLIZIA5 0x2F57887 // ACCENDI MODALITà ALBERO DI NATALE
#define ACCENDI_POLIZIA10 0x2F5F00F // ACCENDI 10 VOLTE DI FILA I LED
#define SPEGNI_TUTTO 0x2F5807F// SPEGNI TUTTI I LED

dopo un pò di spremitura qualcosa ho messo vicino.
sono riuscito a far accendere due led.

le ho provate tutte ma niente da fare non so in motivo ma non funzionava, dopo mi sono detto:
se arduino tratta solo numeri ci sarà un sistema di convertire il risultato alfa numerico.

per prima cosa ho scoperto che la riga che il monitor restituisce è un numero esadecimale.

sono andato a vedere in rete cosa vuol dire e ho scoperto, oltre alla spiegazione, che l’abbreviazione di un numero esadecimale è HEX.
allora mi sono ricordato che sul codice c’era questa scritta.
dalle prove ho visto che se eliminavo dal codice HEX mi restituiva una seria di numeri senza lettere.
adesso non so se è la trasformazione di un esadecimale me lo direte voi che siete gli esperti.

fatto questo il gioco è fatto lo tratto come qualsiasi dato numerico.
bene funziona.

facendo delle prove però a volte i led si accendono entrambi se si schiaccia il pulsante molto velocemente.

allora ho pensato di temporizzare la lettura prima di eseguire, così ho aggiunto un millis di un secondo.

mi date una controllata perchè non sono sicuro di averlo messo al punto giusto e se la teoria del mio ragionamento è corretta.
Fatto stà che il difetto mi sembra più di rado ma è ancora presente.

un saluto.

// sketch test per ricevitore ir con ouput 2 led. telecomando canon WL-D87

#include <IRremote.h>

int RECV_PIN = 11;            // pin segnale ricevitore ir
#define AAA 2708344051       // led rosso
#define BBB 2708389951      // led verde
unsigned long time;        // parte il tempo
unsigned long M;          // contrassegno tempo


IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();                    // Start the receiver
  pinMode(13, OUTPUT);             // pin rosso
  pinMode(10, OUTPUT);            // pin verde
  
  time=millis();        
  M=millis();
}

void loop(){
  
  time=millis();                      // comincia  a contare
  
  
  if (irrecv.decode(&results)) {
    if(time>1000)                      // aspetta un secondo prima di eseguire
    Serial.println(results.value);
    if(results.value == BBB){         // legge/compara il valore trasmesso
    digitalWrite(13,HIGH);           // accende led rosso
    M=millis();
    }
    
    else {
    digitalWrite(13,LOW);          // spegne led rosso
    }
    
    
 
  }
  {
  if (irrecv.decode(&results)) {
    if(time>1000)
    Serial.println(results.value);
    if(results.value == AAA){
    digitalWrite(10,HIGH);
    }
    
    else {
    digitalWrite(10,LOW);
    M=millis();
    }
    
    
    irrecv.resume(); // Receive the next value
    
  }
  }
}

esadecimale, decimale, binario, sono solo vari modi per rappresentare lo stesso numero.

Esiste una tabella, detta ASCII, a cui per ogni numero corrisponde un carattere (lettere, numeri e caratteri speciali): questo ascii è in pratica lo stesso formato dei file .txt

la serial.print() si occupa in automatico di convertire i numeri nel numero corrispondente alla tabella ascii, la conversione a mano la devi fare se usi Serial.write()

la temporizzazione che hai creato si chiama "debounce", ed è una cosa che con i pulsanti bisogna fare sempre, salvo farla via hardware (no, non so come si fa, credo con un condensatore). Credo che il fatto di avere i 2 lòed accesi succeda perchè anche se premi solo 2 volte, il bottone invia N impulsi, quindi i led si accendono e spengono N volte, e se N è > di 25 volte al secondo, allora l'occhio umano viene ingannato dall'immagine residua dando la senzazione di "sempre acceso", in pratica lo stesso trucco usato nel cinema (o qualsiasi altro video) di far scorrere le immagini a più di 25fps(immagini per secondo) in modo da ingannare l'occhio e farti vedere il film, o giocare ai giochi, o vedere il desktop etc... :slight_smile: