Pages: [1]   Go Down
Author Topic: TELECOMANDO DTMF  (Read 2525 times)
0 Members and 1 Guest are viewing this topic.
Oristano
Offline Offline
Sr. Member
****
Karma: 0
Posts: 252
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ho praticamente concluso la rima versione funzionante del telecomando DTMF.

Funziona in questo modo.
Il segnale DTMF viene decodificato da un MT8870 (http://pdf1.alldatasheet.com/datasheet-pdf/view/77085/MITEL/MT8870.html), cablato secondo lo schema che c'è a pagina 4.20 e  connesso ad arduino così:
Quote
//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:
XXXXXX*1#1*12#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 - downloaded 63 times.)
« Last Edit: July 30, 2012, 12:39:01 am by Paolo S » Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

interesting!!
Logged

Oristano
Offline Offline
Sr. Member
****
Karma: 0
Posts: 252
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley
Logged

0
Offline Offline
Shannon Member
****
Karma: 131
Posts: 10474
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Oristano
Offline Offline
Sr. Member
****
Karma: 0
Posts: 252
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: August 23, 2012, 04:12:27 am by Paolo S » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.17 KB - downloaded 23 times.)
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22817
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

scrivo il codice così ad occhio, come facevo nel 1984 con il commodore 16 (e sì... non sono giovanissimo!!!) ....
Anch'io avevo il C16  smiley-lol
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.18 KB - downloaded 20 times.)
Logged

Oristano
Offline Offline
Sr. Member
****
Karma: 0
Posts: 252
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ....
http://arduino.cc/forum/index.php/topic,123046.msg925215.html#msg925215
ciao
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 psw*0#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 smiley

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 smiley Però funziona!!

* telecomando_dtmf.ino (17.43 KB - downloaded 36 times.)

* IMG_20121128_152548.jpg (998.71 KB, 1920x2560 - viewed 68 times.)
Logged

Oristano
Offline Offline
Sr. Member
****
Karma: 0
Posts: 252
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bravo SID...
Logged

0
Offline Offline
Shannon Member
****
Karma: 131
Posts: 10474
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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
Code:
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:
Code:
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.
« Last Edit: October 20, 2013, 09:55:49 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: