TELECOMANDO DTMF

ho praticamente concluso la rima versione funzionante del telecomando DTMF.

Funziona in questo modo.
Il segnale DTMF viene decodificato da un MT8870 (MT8870 pdf, MT8870 Description, MT8870 Datasheet, MT8870 view ::: ALLDATASHEET :::), cablato secondo lo schema che c'è a pagina 4.20 e connesso ad arduino così:

//ARDUINO PD3 PD4 PD5 PD6 PD7
//MT8870 PIN 15(STD) PIN 11(Q1) PIN 12(Q2) PIN 13(Q3) PIN 14(Q4)

su PD3 (pin digitale 3) di arduino, viene impostato l'interrupt in modo RISING... sugli altri 4 pin viene "raccolto", tramite i 4 bit Q1-Q4, il codice del carattere decodificato ...

Il telecomando è organizzato in tre banchi di 8 comandi ciascuno, per n° 24 comandi di tipo ON/OFF, controllabili separatamente.
I comandi di tipo ON/OFF vengono eseguiti attraverso 3 integrati tipo 74HC595 (http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf) collegati come da qui: (http://www.arduino.cc/en/Tutorial/ShiftOut) con il terzo 74HC595 collegato esattamente come il secondo...

i pin utilizzati per lo shift out sono questi:
const byte dataPin = A3; // PIN utilizzati per lo shift register
const byte latchPin = A4; // 24 uscite indipendenti
const byte clockPin = A5; //

Per fare le prove io uso questo semplicissimo software, scaricabile gratuitamente da qui (http://www.roadkil.net/program.php/P35/DTMF%20Keypad). Questo software genera i codici con la scheda audio, simulando un tastierino telefonico.
Quindi i comandi vengono inviati al telecomando mandando il segnale audio con i toni DTMF all'ingresso dell'MT8870.

Il comando generico è costituito da una sequenza di caratteri. I caratteri, corrispondenti al tastierino telefonico, sono questi: (0,1,2,3,4,5,6,7,8,9,A,B,C,D,*,#) ovvero 16 caratteri diversi decodificati tramite i 4 bit dall'MT8870 ...

la sequenza generica di caratteri avrà la seguente forma:
XXXXXX1#112#0** dove

  • XXXXXX è una generica password constituta da n caratteri (da impostare nel codice prima di compilarlo)..
  • l'asterisco è un carattere separatore per separare i vari comandi
  • il cancelletto separa il generico comando nelle sue due parti, cioè l'"indirizzo" e l'"azione". L'indirizzo (0...23) corrisponde al pin da accendere| spegnere, e l'azione (0|1) determina l'impostazione del livello alto (1) o basso (0) del generico pin ...

il sistema memorizza sulla eeprom l'ultimo stato di funzionamento eseguito così che all'accensione ripete l'ultimo stato di funzionamento attivato,

nella configurazione, prima di compilarlo, bisogna stabilire, oltre alla password, il numero max di caratteri del buffer ricevili, ed il numero max di comandi che si possono inviare nella medesima sequenza ...

la sequenza deve terminare con due asterischi per inviare la stringa all'analisi, oppure se si supera il n° max di caratteri del buffer, comunque la stringa viene inviata all'analisi ...

Siccome questa è la prima versione funzionante mi farebbe piacere che qualcuno volesse provarlo (anche se non credo sia possibile se non avete in casa un MT8870 con il suo quarzo) , o semplicemente dare una controllata al codice per segnalrmi ogni punto dove si potrebbe migliorare, ottimizzare etc....

per facilitare la (mia) lettura ho suddiviso tutto il codice in sub schede ... e raggrupato le istruzioni collegate da una certa logica, anche più di una sulla stessa riga fino a giungere il risultato atteso (lo so che è contro le regole, ma credo che comunque sia più leggibile)...

adesso aggiungo il sorgente... siccome sono più schede .ino le ho zippate in un'unico file
NB .. non infierite è solo la prima versione destinata ad essere migliorata in ogni sua parte ..

grazie per l'interessamento ciao

TelecomandoDTMF_0_2.zip (4.83 KB)

interesting!!

grazie mri.... ma gli hai dato un'occhiata al codice????..

e nessun'altro gli ha dato un'occhiata????

si un'occhiata molto veloce..vedi che hai l'abitudine di usare diversi .ino per lo stesso sketch..

sai com'è,molti sono anche in vacanza :slight_smile:

di solito non si usano tanti ino, ma si divide il codice in librerie (.h) o in classi (.h e .cpp)

il vantaggio della classe è che in pratica è una variabile che in realtà continene più variabili e anche funzioni; per esempio Serial è una classe. Volendo potresti dire che sono variabili che al loro interno contengono un mini-programma!

Grazie lesto.... ma non ho mai capito bene la programmazoine ad oggetti... classi... metodi etc...

scrivo il codice così ad occhio, come facevo nel 1984 con il commodore 16 (e sì... non sono giovanissimo!!!) ....

ho ricominciato da poco ... lo sò... dovrei adeguarmi ai tempi.... ma così, suddividendo in gruppi, più o meno omogenei riesco a tenere facilmente sott'occhio il tutto e questo mi aiuta non poco ....

grazie del tuo parere.. comunque!!!

ciao

Ecco qua.. in allegato lo sketch modificato per le mie esigenze. Ho usato un secondo arduino e una tastiera a matrice per simulare l'8870 (che arriverà fra poco..)

Se volete lo sketch della tastiera fatemi sapere

telecomando_dtmf.ino (18.2 KB)

Anch'io avevo il C16 XD

scusate, lo sketch è questo..ho modificato una cosetta inutile. Ah, non ho scritto che questo sketch modificato serve per comandi on/off tramite le porte digitali e analogiche di arduino e non tiene conto dell'uso degli shift register

telecomando_dtmf.ino (18.2 KB)

Grazie SID... ho trascurato per qualche mese a causa di impegni di lavoro... ma sto lavorando alla nuova implemnatzione ovvero:

  • risponditore audio che ti guida nell'invio dei comandi ...
  • conferma audio dell'esecuzione del comando ON/ OFF
  • interrogazione e risposta audio sullo stato dei comandi...

lo sto facendo con questa schedina che ormai mi pare di controllare benino ....

ciao

Ciao, io ho modificato ulteriormente il tuo sketch. In quello che posterò ora ho "aggiunto":
-uscita audio (per ora simulato con un buzzer) che mi dice se il comando è corretto o no (variabile comando_tono). Se è corretto fa un bip breve, altrimenti lo fa più lungo. Questo tono verrà poi trasmesso via radio (comando_ptt)
-interrogazione stato delle uscite on/off: con la tua sintassi ho aggiunto, oltre alle azioni 0 e 1, l'azione 3. Se lo stato è on, bip breve, se è off bip lungo (praticamente come sopra).
-Possibilità di cambiare la password con la sintassi psw0#new_psw**, cioè, quello che viene digitato dopo il # sarà la nuova password
-Possibilità di resettare via software arduino con la sintassi psw
13#0**, così se non ci si ricorda la psw si può reimpostarla a quella di default :slight_smile:

Non sono un fine programmatore, anzi, non sono proprio un programmatore, quindi le mie sono modifiche molto semplici. Ho adattato lo sketch al mio bisogno.
Lo metto in allegato.

Ho fatto anche una specie di shield da mettere su arduino uno. Provvisoria anche questa :slight_smile: Però funziona!!

telecomando_dtmf.ino (17.4 KB)

bravo SID...

scusa se mi permetto, però se usi un array per contenere il pin, la dichiarazione e inizializzazione dei pin diventa:

int comando[] = {8, 9, 10, 12, 2, 1};

void setup (){
  for (int i=0; i < sizeof(comando); i++){  //ATTENZIONE AL SIZEOF! da usare sempre e SOLO con l'array mai con un puntatore all'array
    pinMode(comando[i],OUTPUT);
    digitalWrite(comando[i],LOW);
    [...] //altro codice tuo
  }

a questo punto a finecodice hai una serie di

if (str_I=="1" && str_A=="1") {
        digitalWrite(comando_1,HIGH);
        }
      
     if (str_I=="1" && str_A=="0") {
        digitalWrite(comando_1, LOW);
      }
      
      if (str_I=="1" && str_A=="3") {
        if(digitalRead(comando_1)==HIGH) {
          digitalWrite(comando_tono,HIGH); 
          delay(100); 
          digitalWrite(comando_tono,LOW);
        }
        if(digitalRead(comando_1)==LOW) {
          digitalWrite(comando_tono,HIGH); 
          delay(1000); 
          digitalWrite(comando_tono,LOW);
        }
        
          
      }

(a priori, il fatto di usare "0" è errato, perchp con le " fai una stringa, con le ' fai un carattere! così facendo rischi di confrontare l'indirizzo della stringa (che ricordo, è un array di char) con la lettera-numero.
quindi usa le '.)

che diventano una sola volta e generica:

for (int i=0; i < sizeof(comando); i++){  //ATTENZIONE AL SIZEOF! da usare sempre e SOLO con l'array mai con un puntatore 
  if (str_I==i+'0' && str_A=="1") {
        digitalWrite(comando[i],HIGH);
        }
      
     if (str_I==i+'0' && str_A=="0") {
        digitalWrite(comando[i], LOW);
      }
      
      if (str_I==i+'0' && str_A=="3") {
        if(digitalRead(comando[i])==HIGH) {
          digitalWrite(comando_tono,HIGH); 
          delay(100); 
          digitalWrite(comando_tono,LOW);
        }
        if(digitalRead(comando[i])==LOW) {
          digitalWrite(comando_tono,HIGH); 
          delay(1000); 
          digitalWrite(comando_tono,LOW);
        }
        
          
      }

notare che uso un bel trucco: al carattere '0' zero sommo un numero; infatti i caretteri-numero sono uno dopo l'altro nella tabella ascii. PERO' dopo il 9 riprendono altri caratterei della tabella ascii, quindi questo sistema funziona solo da 0 a 9... ma visto che stiamo confrontando UN carattere, il problema non si pone, visto che era una limitazione già intrinseca nel codice.

con questi accorgimentoi il codice dovrebbe essere dimezzato, dal punto di vista sorgente, non so che effetti può avere sul compilato.

wow! è stato riesumato questo topic!
ora leggo le correzioni di lesto, sperando di capirci qualcosa! :slight_smile: