Telecomando universale, bozze del programma.

Ciao a tutti!
Nonostante debba ancora comprare arduino, sto buttando giù i codici per il mio telecomando universale, non sono nemmeno lontanamente quelli finali, li scrivo per cercare di apprendere il meccanismo.Comunque, il codice è commentato e spiega a grandi linee come funziona questa prima routine, il problema è semplice, la tastiera di un telecomando penso sia una matrice, come le altre tastiere, come faccio ad interfacciarla con arduino? c'è qualche link che potreste passarmi che spiega come fare? :slight_smile: ci sono errori logici nel codice qui sotto?

ah già ci sono punti con parecchie righe di commenti, sono quelle dove devo ancora scrivere il codice, che sarà dipendente da come si registra il "nome del tasto".

Grazie a tutti in anticipo!

/* uso la libreria infrarossi di ken shirriff
per memorizzare il codice corrispondente al tasto
occorre premere il tasto mem per 3 secondi, il tasto su cui si
vuole memorizzare il codice, e il tasto sul
telecomando originale*/

int PIN_IR = 11;
IRrecv irrecv(PIN_IR);
int memPin = 7;
decode_results results;
int butNumber = X; /*numero dei tasti del telecomando, da decidere*/
int butInf = 2;
int buttonCode [butNumber][butInf]; /*in un indice memorizzo il nome del tasto
                                   nel secondo memorizzo il codice*/
unsigned long pressTime = 0;
int previous = LOW;
int memFunc = LOW;
long delayPress = 3000;
                                    
void setup()
{  
   pinMode(memPin, INPUT);
   Serial.begin(9600);
   irrecv.enableIRIn(); // inizializza il ricevitore
}
void loop() 
{  
   memFunc = digitalRead(memPin);
   if (memFunc != previous)
   {
      pressTime = millis();
   }
   
   if ((millis() - pressTime) > delayPress)
   {  
      /*leggo il tasto dove devo memorizzare il codice*/
          
      if (irrecv.decode(&results)) 
      {
         /*memorizzo il codice del pulsante
         nella posizione 0 del secondo indice
         dell'array, e il codice nella posizione 1*/
         irrecv.resume();
      }   
   }

   previous = memFunc;
}

Ho pensato a come risolvere il problema, posto di seguito la soluzione:

Utilizzo una tastiera a matrice di X righe ed Y colonne, quindi ho bisogno di X+Y pin per poterla controllare.

imposto i pin X come output, mentre gli Y come input, tutti i pin output sono settati LOW, eseguo questo ciclo (scritto in pseudocodice):

porto uno alla volta ad HIGH i X
per ogni pin X leggo uno alla volta i pin Y

Se trovo un pin Y che sia HIGH allora ho trovato il tasto premuto :slight_smile:

dite che così funziona? :slight_smile:

Perché non usi uno shift register? Un parallel-in/serial-out come il 74HC165 ed usi solo 3/4 pin per leggere tutti i tasti?
http://arduino.cc/playground/Code/ShiftRegSN74HC165N

Grazie :slight_smile:

in realtà non è così essenziale risparmiare pin, dato che poi programmerò un atmega328 da saldare dentro al telecomando, comunque potrebbe tornare sempre utile per altre applicazioni :slight_smile:

Sto cercando di capire come funziona dal datasheet, ma non è che ci sia poi così vicino :smiley: sopratutto non riesco a capire come ci dovrei collegare la tastiera :slight_smile:

Ogni shift register ha 8 pin di input. Dando il segnale di load, il chip trasferisce i segnali dai pin esterni ai registri interni. A questo punto puoi leggere i dati. Gli shift register li puoi collegare in cascata così da leggere più di 8 bit per volta.

Aaaan, io metto tutti i pulsanti collegati a +5v ed a un pin in dello shift register, mando il segnale di load e in base a quello che ricevo sull'arduino capisco che tasto è stato premuto giusto?

ma se esce seriale non mi basta un pin per leggere l'ingresso?

No gustav gli altri pin servono per mandare agli shift il segnale per leggere i dati e per mandarli all'arduino :grin:

Gustav, ti ha già risposto Gustav :smiley:

non è male come idea, la studierò per bene, grazie!

Altra domanda, quando scriverò il codice completo, non ci sono problemi di risorse se organizzo tutto in funzioni e poi le chiamo dal loop principale?

Beh, dipende quanto sarà grande il tuo sketch e quante variabili crei. Normalmente le risorse non si esauriscono con programmi di media grandezza, solo quando inizi a fare cose assurde puoi andare a corto di RAM prima e di Flash dopo.

chiaro, ed è anche meglio evitare anche di usare millis() perchè dopo 50 giorni va in overflow?
Perchè per l'anti rimbalzo sui tasti normali avevo pensato di usare un deelay di qualche centinaio di millisecondi, mentre il pulsante mem generava un interrupt, solo che non so come gestire il tenerlo premuto per 3 secondi se non ricorrendo al timer interno...ci sono altre soluzioni?

Tempo fa lesto spiegò bene la cosa dell'overflow.
Il contatore va in overflow ma non viene generato nessun errore, semplicemente riparte da 0.

Questo modus operandi non va bene se su millis si fanno calcoli per tenere il trascorrere del tempo reale (ma per questo c'è la mia lib swRTC che non ha di questi problemi) ma va bene per pianificare operazioni basate sul tempo relativo.
Quindi per sapere se sono passati 10/50/100 ms va bene, per tenere un orario "vero" no.

oh perfetto :slight_smile: credevo che andasse in crash tutto con l'overflow, quindi posso usarlo tranquillamente per quel tipo di operazione, grazie!

man mano che mi vengono i dubbi li posterò su questo topic, per esempio, quali ricevitori IR devo usare? quelli che ho trovato erano divisi in base a una frequenza, cosa vuol dire?

Tutti ti consiglieranno i TSOP perché sono schermati per lavorare con la sola frequenza a 38 KHz, così da poterli usare anche in presenza di luce. Ma mi fermo qui perché non ne conosco i dettagli. Cerca "barriera infrarossi", un thread vecchiotto aperto dal Menniti: troverai tante info utili.

faccio un up con il nuovo codice, questo prevede un interrupt generato dal pulsante memorizza, me sembra migliore del precedente :slight_smile:

/* uso la libreria infrarossi di ken shirriff
per memorizzare il codice corrispondente al tasto
occorre premere il tasto mem per 3 secondi, il tasto su cui si
vuole memorizzare il codice, e il tasto sul
telecomando originale*/

#include <IRremote.h>

#define PIN_IR = 11;
#define PIN_LED = 10;
#define PIN_MEM = 7;
#define delayPress = 3000;

int butNumber = X; /*numero dei tasti del telecomando, da decidere*/
int butInfo = 2;
int buttonCode [butNumber][butInfo]; /*in un indice memorizzo il nome del tasto
                                   nel secondo memorizzo il codice*/
unsigned long pressTime = 0;
volatile int active = LOW;
volatile int pressed = LOW;

decode_results results;
IRrecv irrecv(PIN_IR);
                                    
void setup()
{  
   pinMode(PIN_MEM, INPUT);
   Serial.begin(9600);
   irrecv.enableIRIn(); // inizializza il ricevitore
   attachinterrupt (PIN_MEM, mem, RISING);
}
void loop() 
{  
   
   void mem()
   {
      active = !active;
      if (active == HIGH)
      {
         pressTime = millis();
         while ((millis() - pressTime) < delayPress)
         { 
            if (digitalRead(PIN_MEM) != HIGH)
            {
               pressed = LOW;
               break;
            }
            else
            {
               pressed = HIGH;
            }
            
         }
      
         if (pressed == HIGH)
         {
            /*leggo il tasto dove devo memorizzare il codice*/
          
            if (irrecv.decode(&results)) 
            {
               /*memorizzo il codice del pulsante
               nella posizione 0 del secondo indice
               dell'array, e il codice nella posizione 1*/
               irrecv.resume();
            }   
         }
         
      }  
      
   }
   
}

scusate, allego anche questi errori che mi da l'ide di arduino quando provo a compilare il programma sopra, ho aggiunto le librerie IRremote ad /usr/share/arduino/libraries/IRremote

/usr/share/arduino/libraries/IRremote/IRremote.cpp:137: error: missing terminating ' character

/usr/share/arduino/libraries/IRremote/IRremote.cpp:139: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:139: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:139: error: stray ‘\221’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:140: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:140: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:140: error: stray ‘\223’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: stray ‘#’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: stray ‘#’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1131: error: stray ‘#’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1131: error: stray ‘#’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1144: error: stray ‘#’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1299: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1299: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1299: error: stray ‘\220’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1303: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1303: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1303: error: stray ‘\222’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1307: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1307: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1307: error: stray ‘\221’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1311: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1311: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1311: error: stray ‘\223’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1321: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1321: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1321: error: stray ‘\220’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1325: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1325: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1325: error: stray ‘\222’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1329: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1329: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1329: error: stray ‘\221’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1333: error: stray ‘\342’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1333: error: stray ‘\206’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1333: error: stray ‘\223’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1376:3: error: invalid preprocessing directive #This

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1377: error: stray ‘##’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1378: error: stray ‘##’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1378: error: stray ‘##’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1378: error: stray ‘##’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1395:10: error: invalid suffix "a" on integer constant

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1396:10: error: invalid suffix "b" on integer constant

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1402:11: error: invalid suffix "a" on integer constant

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1403:11: error: invalid suffix "b" on integer constant

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1419: error: missing terminating ' character

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1430: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1430: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1430: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1433: error: stray ‘$’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1436: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1436: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1436: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1452: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1452: error: stray ‘`’ in program

/usr/share/arduino/libraries/IRremote/IRremote.cpp:4: error: expected unqualified-id before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:119: error: expected constructor, destructor, or type conversion before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:146: error: expected unqualified-id before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: expected constructor, destructor, or type conversion before ‘.’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: expected unqualified-id before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: expected constructor, destructor, or type conversion before ‘.’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1054: error: expected unqualified-id before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1089: error: expected constructor, destructor, or type conversion before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1130: error: expected unqualified-id before numeric constant

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1139: error: expected unqualified-id before ‘<’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1377: error: expected constructor, destructor, or type conversion before ‘&’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1377: error: ‘tag’ does not name a type

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1378: error: expected constructor, destructor, or type conversion before ‘&’ token

/usr/share/arduino/libraries/IRremote/IRremote.cpp:1378: error: expected constructor, destructor, or type conversion before ‘<’ token

Dopo aver reinstallato ho risolto il problema :slight_smile: riporto qui una domanda:

Però, se ti serve ad uso telecomando forse il TSOP non ti va bene, visto che ha un comportamento digitale, cioè per tutta la durata del fascio IR genera un segnale LOW, per passare ad HIGH quando il segnale viene interrotto;

Significa che per ottenere gli impulsi inviati dal telecomando devo invertire ciò che leggo?

Cioè se leggo 0 vuol dire che il telecomando ha inviato 1 e viceversa?

Doh!

stavo cercando la discussione e sono entrato con gustav, e per sbaglio ho postato con l'altro utente!

// le segg righe generano 38KHz sul pin 11
OCR2A = 208;
TCCR2A = 0b01000011;
TCCR2B = 0b00001001;

Se uso questo, poi come posso regolare per esempio 10uS di segnale verso un led, 10uS senza segnale, 409uS di segnale, 34 uS senza segnale ecc?

Potresti attivare/disattivare la generazione dell'onda sul pin di output semplicemente dando un pinMode(pin, INPUT) per spengere il segnale e OUTPUT per riaccenderlo controllando l'intervallo con un delayMicroseconds(). Dovrebbe funzionare.

Quando il pin PWM è settato come output il timer è agganciato allo stesso ed il segnale viene fatto uscire sul pin, altrimenti no.

Ciao,
relativamente alla tastiera, se ti può servire, tempo fa mi ero salvato un paio di link per gestire più pulsanti su 1 solo analog input:
http://tronixstuff.wordpress.com/2011/01/11/tutorial-using-analog-input-for-multiple-buttons/
qui un'estremizzazione:
http://fritzing.org/projects/18-switches-on-one-analog-arduino-input/

Un altro paio di link del "collega" spagnolo sull'argomento: