INDICE

 

 

·        Prefazione del consiglio di classe

·        Introduzione/Abstract

 

Capitolo 1: Schemi a blocchi                       P. 10 

1.1: Il progetto completo

1.2: Il progetto ridotto

 

Capitolo 2: L’automobilina                         P. 15

2.1: Schema a blocchi

2.2: Le schede di potenza

2.3: Il circuito di comando

 

Capitolo 3: Il software nell’unità centrale   P. 24

3.1: Il programma pilota

3.2: Il programma simulatore

 

 

Capitolo 4: Il programma a bordo del modellino  P. 33

4.1: Schema a blocchi

4.2: Descrizione del mP

4.3: Il Pic del modellino

 

Capitolo 5: Il trasmettitore                       P.47

5.1: Il PC e il radiocomando

5.2: Il radiocomando

5.3: L’interfaccia PC à Radiocomando e la     

       gestione della porta parallela

5.4: La modulazione

5.5: Le modulazioni digitali

5.6: Comunicazioni in FSK


 

Appendici

 

 

1 -   Listato programma pilota                        P.  60

2  -  Listato programma simulatore                P.  75

3  -  Listato programma assembler                 P.  79

4  -  Schema elettrico del PIC                         P.  84

5  -  Data sheet PIC16F84                              P.  86

6  -  Schema elettrico delle schede di potenza        P.  95

7      -  Circuiti stampati delle schede di potenza       P.  97

8      -  Circuiti stampati della scheda di

potenza del Pic                                               P.  99

 

9      -  Schema pratico dei collegamenti nel

telecomando                                           P. 101

 

 

 


Prefazione del Consiglio di Classe

 

Sempre più negli ultimi anni si è reso necessario avvicinare la scuola al mondo del lavoro.

Per ottenere questo risultato sono percorribili varie strade: una è la partecipazione dei futuri periti a stage aziendali (che per evidenti motivi devono avere una durata limitata nel tempo con la conseguenza di un ridotto coinvolgimento degli studenti nelle problematiche dell’azienda).

Una seconda strada potrebbe essere quella di far partecipare attivamente gli alunni allo sviluppo di un progetto come se fossero realmente a lavorare in un’azienda.

Per quanto riguarda la prima metodologia, gli studenti hanno partecipato ad uno stage di cinque settimane presso una importante azienda elettronica della zona, nota a livello mondiale per l’alta tecnologia che produce.

La seconda metodologia ha dato come risultato questa  dispensa: il Consiglio di Classe ha individuato un progetto di una certa complessità da sviluppare nell’intero arco di due anni scolastici nell’ambito delle ore di TDP e dell’area di progetto.

Per lo sviluppo del lavoro gli studenti hanno dovuto seguire il tipico iter aziendale:

 

 

 

·        Analisi delle specifiche

·        Progettazione

·        Realizzazione

·        Documentazione

L’impostazione a blocchi dello sviluppo del progetto, ormai pratica comune in qualsiasi attività produttiva, ha permesso di dividere il lavoro tra i vari studenti: ogni singolo “pezzo” dell’intero sistema è stato affidato di volta in volta a uno o più studenti, responsabili “in toto” della loro parte: alcuni si sono occupati del software (fortemente presente come componente immateriale in tutto questo lavoro), alcuni dell’hardware, altri della documentazione, badando comunque che alla fine tutti avessero fatto un po’ di tutto.

Questa suddivisione ha permesso ulteriormente di assecondare gli interessi personali degli studenti con il risultato accessorio di una maggior produttività.

Il ruolo dell’insegnante è stato di coordinatore dell’attività; l’intervento diretto è stato volutamente ridotto al minimo, e comunque solo per quelle poche parti che oggettivamente erano fuori della portata degli studenti. Questa scelta ha portato ad ottenere un prodotto che, anche se per alcuni aspetti può essere incompleto o evidentemente perfettibile, nell’insieme è più che apprezzabile.


 

 

 

 

 

 

 

 

 

INTRODUZIONE

Il progetto illustrato in questa breve dispensa è stato sviluppato durante questo e il precedente anno scolastico. E’ il progetto di una automobilina che, comandata da un PC con un programma in Qbasic, si deve muovere secondo i comandi ricevuti via radio, la Fig.1 illustra schematicamente la composizione della sistema.


 


Fig. 1

 

 

Questo lavoro ci ha permesso di applicare nella pratica molti concetti teorici studiati nelle varie materie e di sperimentare  dal vivo le varie fasi dello sviluppo di un progetto di una certa complessità.

 

Il lavoro si è sviluppato secondo i seguenti passi:

1)   Stesura delle specifiche.

2)   Stesura di un progetto di massima.

3)   Sviluppo del prototipo dell’hardware e del software.

4)   Stesura della documentazione contestualmente all’avanzamento del lavoro.

5)   Sistemazione definita del prototipo e assemblaggio finale.

 

Il lavoro è costituito di componenti hardware e di componenti software.

Lo sviluppo hardware comprende sia le schede elettroniche che la parte meccanica relativa al prototipo della macchina.

 

Il software comprende il programma per pc relativo alla generazione ed elaborazione dei comandi da spedire alla macchina e il firmware residente nel sistema di controllo a bordo della macchina stessa.                          

 

Abstract

 

The project illustrates in this short leaflets was developed during the previus and current school year.It is the project of a model car which command by a  Q-basic program and it moves as it is driven by radio waves it is shone in a diagram fig.1

 

This work has allowed is to applicatyons in teory co

 

The job was develop in five steps:

 

1)   Draft of specification

2)   Draft of an

3)   Development of software and hardware prototype

4)   Progres reports final

5)   Find prototype and assembly

 

The work consiste of  hardware and software componens.

 

Hardware are made up of electronics cards and meccanical parts of the prototype model.

The  software containe the program for pc which is able tosands commands to the model firmware inside the control sistem of  the model car.


    

 

 

 

 

 

 

 

 

 

Cap 1

Schemi a blocchi

 

 

 

 

 

 

 

1.1: Schema a blocchi completo


 

 

 


1.2 Progetto ridotto

 

Lo schema a blocchi di figura 1.1 può essere rielaborato come in fig.1.2


 


 

 


Il primo macro blocco è composto dal PC in cui gira il programma in Qbasic  che è preposto a dirigere i movimenti della automobilina.

 

Il secondo macro blocco è composto dal collegamento a radiofrequenza: trasmettitore, modem, ricevitore, modem.

 

Il terzo macro blocco è costituito dall'automobilina.

 

Questa suddivisione ci ha permesso di sviluppare un progetto “ridotto”, utile per velocizzare lo sviluppo del lavoro.

 

Il primo macro blocco rimane inalterato rispetto al lavoro completo.

 

Il secondo macro blocco, composto dal collegamento a radiofrequenza, verrà sostituito da una linea seriale su filo.       

 

Il terzo macro blocco è costituito da un Pc che simula l'automobilina.

 

 

Si ottiene quindi quanto illustrato in fig. 1.3:


 


 

 

Fig. 1.3

Questa semplificazione ci permette nella fase iniziale di fare a meno del modulo a radio-frequenza, semplificando drasticamente la fase di messa a punto del software pilota. Per simulare la macchinina abbiamo sviluppato un programma per il Qbasic che, pur essendo un linguaggio di programmazione molto semplice da utilizzare, e’ in grado di realizzare completamente ogni tipo di movimento che vogliamo produrre.

 

 


 

 

 

 

 

 

 

 

 

 

CAPITOLO 2

L’automobilina

 

 

 

 

 

 

 

 

 

 

 

 

2.1  Schema a blocchi

 

La figura seguente mostra lo schema a blocchi del modellino.

 


 



 



 

 

 

 

Fig. 2.1

 
 

 

 

 

 

 

 


Il segnale a radio frequenza viene captato dal ricevitore (Rx) i cui segnali di uscita vengono processati dal mP che


provvede a comandare le schede di potenza, alle quali vengono collegati i motorini elettrici.

Particolare cura è stata adottata per filtrare l’alimentazione: i due motori elettrici dedicati al movimento della automobilina generano un notevole rumore elettrico che impedisce il funzionamento del mp.

Abbiamo risolto il problema inserendo in parallelo all’alimentazione, in posizione la più prossima possibile all’integrato, un condensatore al poliestere da 0.68 mF.

Il ricevitore  utilizzato è quello in dotazione al modellino, la scelta e’ stata dettata da motivi di semplicità.

Il mP è il PIC16F84: dispositivo in single-chip comprendente, oltre ad un  mp RISC,  anche 2 porte di I/O, 1 KB di EEPROM e 32 celle di RAM. Per maggiori particolari si veda il cap. 4

 

 

2.2  Le schede di potenza

 

Non essendo il mp in grado di erogare tutta la corrente necessaria ai motori, si e’ reso necessario mettere a punto gli opportuni circuiti amplificatori di interfaccia, il cui schema elettrico è illustrato nella figura seguente.

 

 

 

 

 

 

 

 

 

 

 

 

Schema elettrico relè

La scelta di utilizzare relais è stata dettata dalle seguenti considerazioni:

 

1)   Per invertire la direzione di rotazione dei motori e’ necessario invertire l’alimentazione.

E’ possibile senz’altro ottenere questo risultato utilizzando elementi attivi, tipo BJT o simili, ma in questo caso le difficoltà progettuali avrebbero rallentato lo sviluppo del lavoro

 

2)   La frequenza con la quale vengono impartiti i comandi     al modellino non e’ sicuramente elevata. In linea di massima possiamo considerare che non saranno impartiti più di 1 o 2 comandi al secondo.

E’ quindi possibile utilizzare anche elementi elettromeccanici. Questa soluzione ha anche il vantaggio di ridurre le cadute dagli  di tensione causate dagli elementi attivi; essendo quella dei relais sono decisamente trascurabili rispetto a quanto si può ottenere con dei BJT. Questa caratteristica e’ particolarmente interessante dovendo alimentare il modellino con delle batterie.

 

Il primo relais provvede allo scambio di polarità della tensione da inviare al motorino, il secondo e’ utilizzato come un doppio interruttore, e impedisce che la tensione di ingresso si presenti all’uscita anche in assenza del segnale di comando.

 

Ne e’ risultato un circuito semplice, funzionale e con probabilità di guasto decisamente bassa.

 

Per rendere compatibile l’uscita del mp con i circuiti di potenza, abbiamo utilizzato il seguente schema di collegamento:


Fig. 2.3

 


Si nota che il canale Dx/Sx è identico all’altro canale. Consideriamo il solo percorso superiore: sia il canale Dx che Sx devono attivare la scheda, quindi saranno    collegati al piedino ON/OFF. Per il comando Sx la polarità della tensione di uscita  deve essere invertita.

2.3  Il circuito di comando

 

E’ basato sul single-chip PIC16F84 le cui caratteristiche di massima sono già state accennate precedentemente.

 

La figura seguente illustra schematicamente come questo modulo si presenta dal punto di vista dei esterni, mentre lo schema elettrico completo è riportato in fig. 2.5.


 


Fig. 2.4

 

Date le caratteristiche del processore utilizzato, i componenti esterni sono ridotti al massimo. A parte la manciata di componenti discreti necessari per il clock esterno e per il reset, gli unici integrati presenti sono i buffer 74HC245 necessari, sia per rendere disponibile all’esterno una corrente sufficiente per pilotare la scheda a relais, che per proteggere il mp da eventuali danneggiamenti causati dall’esterno.  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pic 16f84 per automobilina


 

 

 

 

 

 

 
 
 
CAPITOLO 3

Il software nell’unità

centrale
3.1  Il programma pilota

 

 

 

 

 

 

 

 

 

 


                              

 

 

 

Fig. 3.1

 

Specifiche:

 

1)   Permette l’input grafico del percorso da parte dell’utilizzatore.

2)   Quando il disegno del percorso e’ terminato, spedisce al modello i comandi nella sequenza opportuna.

 

Il programma e’ stato scritto in BASIC essendo un linguaggio ragionevolmente potente e nel contempo facile da apprendere e da applicare.

 

 

 

Dalla lettura delle specifiche, è possibile tracciare il seguente diagramma di flusso:

 

 

 

 

 

 

 

 

 

 


Il programma deve essere strutturato in modo da poter dialogare sia con il modellino che con il programma simulatore. E’ evidente quindi che il programma deve essere dotato di 2 diverse procedure di dialogo.

 

Per il colloquio con il simulatore è necessario stabilire un semplice protocollo di dialogo.

Lo abbiamo fissato come indicato nella tabella seguente:

 

Comando   Stringa spedita

AVANTI      $A

INDIETRO  $I

DESTRA     $D

SINISTRA   $S

 

E’ ora possibile tracciare un diagramma di flusso più dettagliato

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Fig.3.2

 

Il mP a bordo del modellino si limiterà ad eseguire i comandi in arrivo con l’avvertenza di disattivare i motori nel caso non arrivino comandi o che i comandi siano logicamente in contrasto tra loro (ad esempio comando avanti e indietro contemporaneamente)

 

3.2  Il programma simulatore

 

Nel paragrafo precedente abbiamo visto la necessità di simulare il modellino per mezzo di un programma al fine di poter continuare lo sviluppo del progetto anche in mancanza dell’ hardware esterno.

Dal punto di vista esterno, il simulatore è visto esattamente come il modello reale.

 

 

Il programma simulatore riceve dalla seriale i comandi generati dal programma pilota e simula nel video i movimenti dell’automobilina

 
 

 

 

 

 


 

Casella di testo: Il programma è suddiviso in due blocchi fondamentali: un Main-program, la parte centrale, che utilizza delle Sub-routines per realizzare  i propri compiti.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


La figura seguente mostra il diagramma di flusso del programma in BASIC di pilotaggio della macchinina:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Si nota che il comando di svolta darà risultati grafici diversi in funzione della precedente direzione di marcia

 

 

 

 

 

 

 

 

 

 

 

Casella di testo: E

 

 

 

 

 

 

 

 

 


Dal punto di vista logico non è un grosso problema mentre può crearne per quanto riguarda l’implementazione grafica.

 

 

 

Esegui comando. Per ridurre la complessità, si decide di non implementare il comando INDIETRO.

 

 

Le possibili combinazioni sono quindi solo quelle illustrate nella tabella seguente.

 

 CASO

    DIR

COMANDO

    

     N

        A

    

     N

        Dx

    

     N

        Sx

    

     E

        A

      

     E

        Dx

    

     E

        Sx

    

    W

        A

    

    W

        Dx

    

    W

        Sx

    10°

    S

        A

    11°

    S

        Dx

    12°

    S

        Sx

 

 

Che viene espansa come segue:

 

Caso

Dir attuale

Comando

Dir dopo il comando

1° caso :                           

 Dir = (N)                        

$ A

Dir =N

2° caso :                          

 Dir = (N)                        

$ D

Dir =E

3° caso :                          

 Dir = (N)                        

$ S

Dir =W

4° caso :                           

 Dir = (E)                        

$ A

Dir =E

5° caso :                          

 Dir = (E)                        

$ D

Dir =S

6° caso :                          

 Dir = (E)                        

$ S

Dir =N

7° caso :                           

 Dir = (W)                        

$ A

Dir =W

8° caso :                          

 Dir = (W)                        

$ D

Dir =N

9° caso :                          

 Dir = (W)                        

$ S

Dir =S

10° caso :                           

 Dir = (S)                        

$ A

Dir =S

11° caso :                          

 Dir = (S)                        

$ D

Dir =W

12° caso :                          

 Dir = (S)                        

$ S

Dir =E

 


 

 

 

 

Capitolo 4

 

Il Pic 16F84 a bordo del modellino

4.1  Schema a blocchi


 


 


Schema del modellino

 
        

 

Fig. 4.1

Il PIC 16C84 avrà il compito di:

1.Leggere i dati dal ricevitore;

2.     Generare i comandi per i motori;

3.     Inviare i comandi ai motori.

 

 

 

 

 

 

4.2 Descrizione del microprocessore

 

Recentemente l’impiego dei microcontrollori si sta diffondendo, oltre che nelle grandi industrie, anche a livello personale ed hobbistico, sia per la semplicità di programmazione che per l’esiguo numero di componenti esterni richiesto.

Il PIC16C84 è un microcontrollore in tecnologia CMOS a 8 bit caratterizzato dal basso  costo e dalle alte prestazioni.

Tutta la famiglia dei PIC16/17 impiega un’avanzata tecnologia RISC che permette il controllo completo del dispositivo con solamente 35 istruzioni. Quasi tutte le istruzioni sono eseguibili in un solo ciclo di 400 ns. E’ dotato di una memoria programmabile da 1K di tipo EEPROM, 15 registri per funzioni speciali, 64 registri ad 8 bit EEPROM per i dati, 8 livelli di stack, 36 registri interni general pourpouse da 8 bit, 8 livelli di stack e 4 sorgenti di interrupt:

 

·  Pin INT esterno;

·  Overflow del TIMER 0;

·  Cambio di stato sulla porta B <4..7>;

·  Fine ciclo di scrittura in EEPROM dati.

 

 

 

PRESTAZIONI DELLE PERIFERICHE:

 

Esistono 13 I/O pin con controllo individuale di direzione. Possono erogare 20 mA per pin come source e 25 mA come sink.

 

PRESTAZIONI SPECIALI DEL MICROCONTROLLORE:

 

La famiglia dei PIC16XX ha alcune funzioni speciali che permettono di ridurre i componenti esterni e quindi anche i costi, sia economici che di corrente; infatti si possono utilizzare quattro tipi di oscillatori:

 

1.     Oscillatore RC, che comporta una soluzione a basso costo;

2.     Oscillatore LP, che minimizza il consumo di energia;

3.     XT, che è un quarzo standard;

4.     HS, che viene utilizzato per quarzi ad alte frequenze.

 

Per ridurre ulteriormente i consumi è prevista la modalità  SLEEP; l’assorbimento a 5V e 4 MHz minore di 2 mA, mentre l’assorbimento in fase di SLEEP è minore di 1 uA.

 

 

 

L’ HARDWARE:

 

L’hardware del PIC è particolarmente ricco di componenti elettronici; andremo ora a spiegare il funzionamento base dei principali componenti:

    

·  Lo Status Register permette di far conoscere l’esito di una istruzione immediatamente dopo che è stata eseguita.

·  Il Working Register è il più sfruttato, essendo  l’unico che consente il passaggio dei dati da un registro all’altro.

·  Le periferiche sono: i 64 byte di EEPROM, il timer RTCC (Real Time Clock Counter) e i registri delle porte vere e proprie. 

·  I registri SRAM sono suddivisi in due banchi, banco 0 e banco 1; quindi per poter effettuare operazioni su di essi, dovremo prima settare correttamente il bit che seleziona l’uno o l’altro.

 

 

 

 

 

 

 

IL RESET DEL CHIP:

 

Esistono diversi modi per resettare il PIC, il primo è la forzatura a massa del pin MCLR (Master CLeaR) che quando viene collegato a massa provvede a resettare il chip; il secondo sistema consente l’impiego del watchdog timer, che però deve essere abilitato o meno in fase di programmazione. Si può infine generare un segnale di reset dal riconoscimento della tensione di alimentazione, sempre che il chip parta sempre dallo stato che noi abbiamo previsto.

Abbiamo la possibilità, in aggiunta a questo, di abilitare un altro reset all’accensione, di durata maggiore rispetto al precedente; questo meccanismo viene in genere impiegato nel caso in cui il chip riceva l’alimentazione da un dispositivo collegato alla rete con un tempo di salita della tensione relativamente lungo.

 

Set di istruzioni del PIC16C84

 

Le seguenti istruzioni assembler sono comuni anche agli altri chip delle famiglie PIC16/12C/17CXX.

 

 

 

 
 
Gruppo MOVE

 

MOVF f,d

Legge il valore del registro f e lo copia su se stesso se d=1 oppure in W se d=0

MOVWF f,d

Legge il valore di W e lo copia nel registro f.

MOVLW k

Pone nel registro W il valore della costante k

 

Operazioni matematiche

 

ADDWF f,d   

Somma il valore del registro W a quello del registro f e mette il risultato in W se d=0, in f se d=1 (default)

ADDLW k

Somma la costante k al valore del registro W

SUBWF f,d

Sottrae il valore del registro W al valore del registro f e mette il risultato in W se d=0, in f se d=1 (default)

SUBLW k

Sottrae la costante k al valore del registro W

COMF f,d

Complementa il valore del registro f e mette il risultato e mette il risultato in W se d=0, in f se d=1 (default)

 

Operatori logici

ANDWF f,d

Esegue l’operazione booleana AND tra il registro W ed f e mette il risultato in W se d=0, in f se d=1 (default)

ANDLW k

Esegue l’operazione booleana AND tra la costante k ed il registro W

IORWF f,d

Esegue l’operazione booleana OR tra il registro W e il registro f e mette il risultato in W se d=0, in f se d=1 (default)

XORWF f,d

Esegue l’operazione booleana EX-OR tra il registro W ed f e mette il risultato in W se d=0, in f se d=1 (default)

IORLW k

Esegue l’operazione booleana OR tra la costante k ed il registro W

XORLW k

Esegue l’ operazione booleana EX-OR tra la costante k ed il registro W

 

Incremento e decremento

 

INCF f,d

Somma 1 al registro f e mette il risultato in W se d=0, in f se d=1 (default)

INCFSZ f,d

Somma 1 al registro f, poi se il valore di tale registro è divenuto 0, salta l’istruzione altrimenti il risultato viene locato in W se d=0, in f se d=1 (default)

DECF f,d

Sottrae 1 al registro f e mette il risultato in W se d=0, in f se d=1 (default)

DECFSZ f,d

Sottrae 1 al registro f, poi se il valore di tale registro è divenuto 0, salta l’istruzione altrimenti il risultato viene locato in W se d=0, in f se d=1 (default)

 

 

Istruzioni orientate al bit

 

BCF f,b

Pone a 0 il valore del bit b del registro f

BSF f,b

Pone a 1 il valore del bit b del registro f

BTFSC f,b

Testa il valore del bit b del registro f : se tale il valore è 0 e salta l’istruzione immediatamente successiva

BTFSS f,b

Testa il valore del bit b del registro f : se tale il valore è 1 e salta l’istruzione immediatamente successiva

 

Clear

CLRF f

Pone a 0 il valore del registro f

CLRW

Pone a 0 il vcalore del registro W

CLRWDT

Pone a 0 il registro watchdog

 

Rotate

RLF f,d

Esegue l’operazione di shift a sinistra del registro f. Al bit 0 viene assegnato il valore del Carry, mentre il Carry prende il valore del bit 7 

RRF f,d

Esegue l’operazione di shift a destra del registro f. Al bit 7 viene assegnato il valore del Carry, mentre il Carry prende il valore del bit 0 

 

 
 
Chiamata e ritorno da sub, GoTo

CALL k

Effettua una chiamata alla subroutine k

RETFIE

Consente il ritorno dopo interrupt

RETLW k

Consente il ritorno dopo una CALL copiando il valore della costante k nel registro W

RETURN

Consente il ritorno dopo CALL 

GOTO k

Esegue un salto alla label k

 

Varie

OPTION

Copia il valore del registro W nel registro OPTION

TRIS f

Copia il valore del registro W nel registro di settaggio direzione delle porte A e B ; f potrà valere solo 5 (porta A) o 6 (porta B)

SLEEP

Pone il controller in modalità SLEEP

NOP

Non esegue alcuna operazione

SWAPF f,d

Scambia i due nibble del registro f e mette il risultato in W se d=0, in f se d=1 (default)

 


4.3: Il pic nel modellino

 


La fig.4.1 illustra schematicamente come il PIC è inserito nell’insieme del modellino La figura seguente mostra più nel dettaglio le connessioni logiche ed elettriche nel mP

 


Fig. 4.2

 

Il mP deve elaborare i dati in arrivo dal modulo ricevente della macchinina, e quindi pilotare i motori in modo opportuno.

 

 

 

 

Lo schema  a blocchi seguente illustra le funzioni principali che svolge

                                                                                                                             

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Per fare questo abbiamo creato un programma in grado di acquisire i dati dal modulo RX e, con le opportune operazioni, comandare i motori.

Per comprendere meglio il funzionamento partiamo dall’inizio e percorriamo il tragitto di questa elaborazione,

partendo dall’acquisizione  dei dati.

 

 

 

 

 

 

Le porte del mP sono settate come segue: Port A tutta ingresso e Port B tutta uscita.

 

Analizzo la direzione  e l’avanzamento in due  fasi diverse. Il funzionamento è semplice: utilizzando il comando “btfsc”, controllo direttamente il bit controllando se il valore al suo interno è lecito. Se sì accetto il comando. Se no fermo il motore.

Questa procedura viene eseguita sia per la direzione  che per l’avanzamento.


Lo schema a blocchi seguente illustra nel dettaglio quanto esposto.

 

 



 

 


 

 

 

 

 

 

 


Cap 5

Il trasmettitore

 

 

 

 

 

 

 

 

 

 

5.1  Il PC e il radiocomando

 

Coerentemente con le scelte indicate nei capitoli precedenti abbiamo utilizzato il trasmettitore in dotazione al modellino, apportandovi le opportune modifiche tali da renderlo compatibile con le nostre esigenze.

In particolare il radiocomando originale era in grado di essere manovrato esclusivamente in modo manuale, mentre nel nostro caso era necessario poterlo pilotare anche per mezzo di segnali elettrici provenienti dal computer.

Lo schema a blocchi seguente illustra la situazione.


 


Fig. 5.1

 

 

Per prelevare i comandi dal Pc abbiamo utilizzato la porta parallela. L’interfaccia è costituita semplicemente da 2 buffer digitali (74HC245) inseriti per proteggere l’elettronica del PC da eventuali danni causati dall’esterno. Il programma Pilota contiene anche un modulo softwere dedicato al dialogo con la porta parallela. (Si veda anche l’appendice N°1)

 

5.2 Il radiocomando

 


Lo schema a blocchi dell’elettronica all’interno del telecomando è il seguente:

 


Fig. 5.2

 

Il radiocomando è dotato di 2 joistick, uno per la direzione e uno per l’avanzamento. Nel modo manuale i joistick chiudono dei contatti che indicano all’integrato codificatore quale è il comando attuato. Abbiamo aggiunto a valle dei contatti un collegamento elettrico con il computer; questo ci ha permesso di pilotare il telecomando sia normalmente sia con segnali elettrici esterni. Il progetto, la relazione e la messa a punto di un modulo per la trasmissione e la ricezione dati via radio presentano difficoltà non banali anche per un esperto del settore.

Tenuto conto che l’obbiettivo di questa esperienza, come illustrato nel capitolo 2, è indipendente dal tipo di trasmissione dati utilizzato, è sembrato opportuno ricorrere al modulo rx-tx fornito di corredo con il modellino.

Leggendo i data-sheet dell’integrato inserito nel modulo, abbiamo determinato che la modulazione utilizzata è la FSK.

 

5.3 L’interfaccia PC à Telecomando e la gestione della porta parallela

 

Dall’analisi dello schema a blocchi precedente, si evince che per pilotare il telecomando dall’esterno è necessario avere quattro segnali distinti.

Le possibili soluzioni sono sostanzialmente due:


La 1° soluzione implica una gestione software

Fig. 5.3

 

decisamente semplice,ma contemporaneamente anche un hardware non banale.

 

Nella 2° soluzione l’hardware è sostanzialmente semplice, mentre la gestione software è un po’ piu complessa.

Abbiamo optato per la seconda opzione  sia per la semplicita dell’hardware che per la maggiore flessibilità che ci permette. Lo schema a blocchi della scheda nel telecomando è illustrato  nella figura seguente.


Fig. 5.4

 

 


Come buffer sono stati utilizzati dei 74HC245 che hanno la duplice funzione di proteggere l’elettronica del PC da eventuali danni e di amplificare la corrente erogata dalla porta del computer. Nella nostra applicazione la porta di ingresso verso il PC non è stata utilizzata.

 

5.4 Brevi cenni sulla modulazione

 

La modulazione è un processo che consiste nel traslare l'allocazione in frequenza della banda (finita) di un segnale informativo. Di fatto, la modulazione è l'alterazione sistematica di una forma d'onda, chiamata portante, secondo le caratteristiche di un'altra forma d'onda: la modulante, ovvero il messaggio.

I motivi per cui si rende necessario modulare un segnale per trasportare l’informazione sono almeno quattro:

 

·        Assegnazione di bande, cioè ripartizione delle medesime risorse fra più utenti che necessitano di comunicare nello stesso tempo e nello stesso luogo .

·        Agevolare l'irradiazione, cioè meglio adattare il segnale all’onda elettromagnetica.

·        Trasmettere contemporaneamente più segnali differenti, basti pensare alla televisione.

·        Riduzione del rumore e delle interferenze.

 

Possiamo schematizzare un canale di trasmissione nel seguente modo:

 

Sorgente Þ Modulatore Þ Filtro di Trasmissione [HT(f)] Þ Canale [HC(t)] Þ Filtro di Ricezione [HR(f)] Þ Demodulatore.

 

(HT(f), HC(f) ed HR(f) sono le funzioni di trasferimento dei rispettivi blocchi). Generalmente si suppone che il canale sia lineare ed il rumore sia additivo. Per quanto riguarda i filtri di trasmissione e di ricezione, che dovrebbero essere sempre presenti, si assume che siano filtri passa-banda centrati attorno alla frequenza di riferimento della portante f0. Se f0 = 0, i filtri sono di tipo passa-basso e la trasmissione si dice in banda base. In questo ultimo caso, utilizzato ad esempio per le comunicazioni fra due calcolatori via seriale o parallela, non vi è modulazione.

Le modulazioni possono essere divise in due grosse branche: analogiche e digitali. A loro volta, in base alle caratteristiche della modulazione stessa, verranno suddivise in altre tipologie.

Nella figura seguente è illustrato un semplice schema a blocchi delle categorie della modulazione:

 

PAM

 

Portante impulsiva

 

PWM

 

PPM

 

 PCM

 

Portante analogica

 

FSK

 

Frequenza

 

Fase

 

Digitale

 

Angolo

 

Ampiezza

 

Analogica

 

Modulazione

 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

 

Fig. 5.5

 

 

 

 

 

 

5.5 Modulazioni digitali

 

La modulazione digitale, come visto nello schema, si divide anch’essa in due rami: modulazione a portante analogica e a portante impulsiva. Per la modulazione di tipo analogico ci limiteremo solo a descriverne i fondamenti principali, dato che noi useremo la modulazione digitale. La modulazione digitale a portante analogica trasmette il segnale non modificando la banda, ma convertendo il segnale da digitale ad analogico. Nella fase di ricezione si rieffettua una conversione che in questo caso sarà da analogica a digitale; tutto questo viene fatto per utilizzare una banda decisamente più stretta, dato che il segnale digitale possiede una banda nell’ordine dei MHz.

 

Queste modulazioni prendono diverse sigle e sono: ASK, FSK, PSK, DPSK, QAM. Nell’ordine i loro acronimi sono: Amplitude Shift Keying, Frequency Shift Keying, Phase Shift Keying, Differential Phase Shift Keying.

La modulazione a portante impulsiva consiste nel trasmettere un treno di impulsi e variando uno dei parametri dell’impulso (ampiezza, durata, posizione), rispetto ai campioni di segnale modulante. Come per le modulazioni a portante analogica, si hanno varie sigle di identificazione: PWM, PCM, PAM, PPM;  e i loro acronimi sono: Pulse Width Modulation, Pulse Code Modulation, Pulse Amplitude Modulation,  Pulse Position Modulation.

 Un segnale digitale può modulare l'ampiezza, la frequenza o la fase di una portante sinusoidale. Se la forma d'onda modulante consiste in impulsi rettangolari senza ritorno a zero, allora i parametri modulati saranno spostati [in inglese Keyed] da un valore discreto all'altro. Le modulazioni digitali più usate sono l'ASK [Amplitude Shift Keying], praticamente sinonimo di PAM [Pulse Amplitude Modulation], l'FSK [Frequency Shift Keying] e la PSK [Phase Shift Keying].

La modulazione digitale, come già detto prima, riguarda la trasmissione di un treno di impulsi binari in un mezzo qualsiasi; la modulazione usata nella nostra esperienza è una modulazione di tipo FSK.

 

In questo tipo di modulazione la portante viene trasmessa ad una frequenza f2 quando è presente l’impulso, ad una

frequenza f1 in assenza di impulso; in sostanza è una modulazione di frequenza, in cui la portante slitta rapidamente tra le due frequenze f1  e f2.

 

 

 

 

 

 

Esempio:

 

Dato

 

0

 

1

 

1

 
             

                        

                                                          

                                                                                                             

t

 

FSK

 
 

 

 

 


t

 
 

 


Fig. 5.6

 

Lo spettro è rappresentato nella figura seguente e può essere determinato considerando il segnale FSK come la sovrapposizione di due segnali ASK a frequenze diverse. Viene pertanto costruito affiancando due spettri ASK, riferiti uno alla frequenza f1, l’altro alla frequenza f2. Nell’esempio: Df = f2 – f1 = 12 fi.

                                                                                                                                                    

f1

 

f2

 
 

 

 

 

 


       

Fig. 5.7

 

La modulazione FSK richiede una banda maggiore della modulazione ASK a causa della presenza delle due portanti; presenta però il vantaggio di non richiedere, come l’ASK, un livello di soglia variabile al rivelatore per minimizzare la probabilità d’errore: i valori della probabilità d’errore, in funzione del rapporto S/N, sono dello stesso ordine dei valori ottimali dell’ASK. La FSK è pertanto usata quando il mezzo di trasmissione ha caratteristiche variabili nel tempo, che producono variazioni del rapporto S/N: per avere la minima probabilità di errore, nell’ASK occorre variare il livello di soglia del rivelatore, mentre nella FSK il livello è indipendente da S/N.

Per ridurre la banda occupata e la potenza di trasmissione, si ricorre a trasmissioni di tipo SSB o VSB. Per aumentare la velocità di trasmissione si sfruttano tecniche multilivello, consistenti nell'associare a multiplette di bit livelli di tensione differenti, ad esempio, associamo alla parola 00 il livello di 0 V, a 01 1 V, a 10 2 V ed a 11 3 V. Nell'FSK, ai due livelli logici 1 e 0 corrispondono due differenti frequenze. Ad esempio, nella raccomandazione CCITT V.23 si associa allo 0 una frequenza di 2.1 kHz e all'1 quella di 1.3 kHz.

 

 5.6 Comunicazione in FSK

 

La FSK è usata prevalentemente per le trasmissioni telegrafiche e simili; i valori usati della differenza fra le frequenze trasmesse sono: 170 Hz, 200 Hz, 400Hz, 850 Hz. La velocità di trasmissione è limitata di solito a valori inferiori a 100 Baud. A causa delle caratteristiche della propagazione delle onde HF, i segnali possono seguire percorsi multipli, arrivando al ricevitore con ritardi che possono essere anche di alcuni millisecondi; un impulso trasmesso, che ha seguito il percorso più lungo, si può sovrapporre all’impulso successivo, che ha seguito il percorso più breve. Per evitare ciò, è conveniente che gli impulsi abbiano durata superiore a 10 ms, con conseguente necessità di ridurre il numero di impulsi trasmessi al secondo a valori inferiori a 100.

 

 

 

 

 

 

ESEMPIO:                          TRASMETTITORE  FSK

Moltiplicatore   di frequenza

 

Oscillatore

 
 

 


                                                 L

 


Fig. 5.8

 

L’informazione è sotto forma di impulsi. In presenza di un impulso, supposto positivo, il diodo D è in saturazione; il condensatore C è inserito nel circuito risonante di un oscillatore e ne varia la frequenza di oscillazione. Presenza ed assenza di impulsi sono pertanto caratterizzate da due frequenze diverse. Il segnale di uscita dell’oscillatore è applicato ad un moltiplicatore di frequenza, che porta la frequenza al valore di trasmissione e quindi ad un amplificatore di potenza a radio frequenza, che aumenta il livello di potenza del segnale.

La modulazione FSK richiede una banda maggiore rispetto all’ASK, ciò a causa della presenza delle due portanti, tuttavia la si preferisce all’ASK per maggior semplicità dei circuiti di demodulazione e di rivelazione del segnale. Inoltre, essendo l’ampiezza del segnale modulato indipendente dal segnale modulante, questo tipo di modulazione sarà meno sensibile ad un rumore additivo che andrà a variare proprio l’ampiezza del segnale.

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Appendice 1

 

Il programma pilota.


 

'*******************************************************

'* pilota.bas

'*

'* Modulo principale

'*

'*******************************************************

 

DECLARE SUB tira.fuori (dato!, rit!)

 

COMMON SHARED flag.out

COMMON SHARED outport

COMMON SHARED inport1

COMMON SHARED inport2

COMMON SHARED n.dx

COMMON SHARED n.sx

 

'-----------------------------------------------

' num.file.seriale e' una variabile globale.

' e indica il numero del file della seriale

'-----------------------------------------------

DIM SHARED num.file.seriale

DIM SHARED percorso$(0 TO 100)

 

DIM SHARED xold 'vecchia posizione asse x

DIM SHARED yold 'vecchia posizione asse y

DIM SHARED dir$ 'direzione attuale della macchinina (N,S,E,W)

DIM SHARED dx   'numero di pixel nel tratto elementare di linea asse X

DIM SHARED dy   'numero di pixel nel tratto elementare di linea asse y

 

CLS

 

 

'-----------------------------------------------

'FLAG.OUT e' una variabile globale.

'Se vale 1, l'uscita va sulla porta paralela,

'Se  "   0     "     viene simulata sul video

'-----------------------------------------------

flag.out = 1

 

CONST piccolo = 0

CONST grande = 1

 

 

'-----------------------------------------------

' selezione del pc: piccolo o grande

'-----------------------------------------------

tipo.pc = piccolo

tipo.pc = grande

 

IF (tipo.pc = piccolo) THEN

    outport = &H378

    inport1 = &H379

    inport2 = &H37A

ELSE

    outport = &H3BC

    inport1 = &H3BD

    inport2 = &H3BE

END IF

 

 

 

 

 

'------------------------------------------------

' configurazione porta di uscita per CAR

'

' bit   0 1 2 3 4 5 6 7 (configurazione fisica)

'       a i d s n n n n

'

' bit   7 6 5 4 3 2 1 0 (configurazione logica)

'       n n n n s d i a

'

'i = Indietro

'a = Avanti

'd = Destra

's = Sinistra

'n = Non collegato

'------------------------------------------------

 

 

'CALL test

'END

 

num.file.seriale = 100

 

DIM SHARED fermo

DIM SHARED destra

DIM SHARED sinistra

DIM SHARED indietro

DIM SHARED avanti

DIM SHARED rit.motori

 

 

 

fermo = &HFF

destra = &HFB    '1111 1011

sinistra = &HF7  '1111 0111

indietro = &HFD    '1111 1101

avanti = &HFE    '1111 1110

 

destra = &HFA    '1111 1010

sinistra = &HF6  '1111 0110

 

 

CALL tira.fuori(fermo, 0)      'fermo i motori

 

 

 

                 

SCREEN 12

 

'------------------------------------------------

' Main-program

'------------------------------------------------

 

rit.motori = 500

n.dx = 2

n.sx = 3

 

'----------------------------------------------

' dx & dy = segmenti video

'----------------------------------------------

dx = 70

dy = 70

 

gira:

  

    CLS

    '---------------------------------------------------

    ' Disegno il percorso da far fare alla macchinina

    '---------------------------------------------------

    dir$ = "N"

    xold = 250

    yold = 450

    CALL disegna.quadro

    CALL input.percorso(count)

 

 

    '---------------------------------------------------

    ' Questo ciclo spedisce il contenuto dell'array

    ' PERCORSO$() alla macchinina utilizzando

    ' la porta seriale

    '---------------------------------------------------

    count = 1

    PRINT

    PRINT

    PRINT

    CALL send.avanti

    DO

       comando$ = percorso$(count)

     

       PRINT comando$; "-->";

 

       SELECT CASE comando$

            CASE IS = "$F": CALL send.ferma

            CASE IS = "$A": CALL send.avanti

            CASE IS = "$D": CALL send.destra

            CASE IS = "$S": CALL send.sinistra

'            CASE IS = "$I": CALL send.indietro

            CASE ELSE

       END SELECT

     

       count = count + 1

       IF (comando$ = "$F") THEN EXIT DO

       a$ = INKEY$

    LOOP UNTIL a$ <> ""

  

    CALL tira.fuori(fermo, 0)      'fermo i motori

                    

    PRINT "Premi un tasto...."

    DO

        a$ = INKEY$

    LOOP UNTIL a$ <> ""

 

    IF (a$ <> "") THEN

        IF (ASC(a$) = 27) THEN END

    END IF

  

    GOTO gira

END

 

 

 

 

 

 

 

'=================================================================

'Apre la porta seriale (serve per la fuoriuscita dei dati)

'=================================================================

SUB apri.seriale

 

    OPEN "com1:1200,n,8,1,cd0,cs0" FOR OUTPUT AS num.file.seriale

 

END SUB

 

'=================================================================

'Chiude il collegamento della porta

'=================================================================

SUB chiudi.seriale (num.file)

 

        CLOSE num.file

 

END SUB

 

'=================================================================

' Disegna la schermata iniziale.

'=================================================================

SUB disegna.quadro

 

CLS

'--------------------------------------------------

' Disegno il quadro superiore

'--------------------------------------------------

riga.sup = 1

riga.inf = 5

col.dx = 80

col.sx = 1

 

CALL double.rect(riga.sup, riga.inf, col.dx, col.sx)

 

 

'--------------------------------------------------

' Disegno il quadro a destra

'--------------------------------------------------

riga.sup = 6

riga.inf = 24

col.dx = 80

col.sx = 60

 

'CALL double.rect(riga.sup, riga.inf, col.dx, col.sx)

 

LOCATE 2, 3

PRINT "Per disegnare il percorso utilizzare le frecce sul tastierino numerico";

LOCATE 3, 3

PRINT "ESC per fine";

 

END SUB

 

'=================================================================

' Disegna un rettangolo col bordo doppio (ÍÍ)

'=================================================================

SUB double.rect (riga.sup, riga.inf, col.dx, col.sx)

 

 

'----------------------------------------------

' Posiziono i quattro angoli

'----------------------------------------------

LOCATE riga.sup, col.sx

PRINT CHR$(201);       

 

LOCATE riga.sup, col.dx

PRINT CHR$(187)'»

 

LOCATE riga.inf, col.sx

PRINT CHR$(200);   

 

LOCATE riga.inf, col.dx

PRINT CHR$(188);   

 

'----------------------------------------------

' Bordi

'----------------------------------------------

LOCATE riga.sup, col.sx + 1

FOR i = col.sx + 1 TO col.dx - 1

    PRINT CHR$(205);   

NEXT

 

 

LOCATE riga.inf, col.sx + 1

FOR i = col.sx + 1 TO col.dx - 1

    PRINT CHR$(205);   

NEXT

 

 

FOR i = riga.sup + 1 TO riga.inf - 1

    LOCATE i, col.sx

    PRINT CHR$(186); 

NEXT

               

FOR i = riga.sup + 1 TO riga.inf - 1

    LOCATE i, col.dx

    PRINT CHR$(186); 

NEXT

 

 

END SUB

 

'=================================================================

' Assegno al tasto premuto un determinato comando,e lo registro.

'=================================================================

SUB esegui.comando (tasto$)

 

 

    '-------------------------------------------

    ' Azzero i contatori

    '-------------------------------------------

    IF (tasto$ = "INIZIO") THEN

        CALL salva.comando.car(tasto$)

        LINE (xold, yold)-(xold + 10, yold)

        LINE (xold + 5, yold - 5)-(xold + 5, yold + 5)

        EXIT SUB

    END IF

  

    '-------------------------------------------

    ' Fine del percorso

    '-------------------------------------------

    IF (tasto$ = "FINE") THEN

        CALL salva.comando.car(tasto$)

        EXIT SUB

    END IF

  

                           

    IF (tasto$ = "8") THEN

        CALL line.su

        CALL salva.comando.car(tasto$)

    ELSEIF (tasto$ = "6") THEN

        CALL line.destra

        CALL salva.comando.car(tasto$)

    ELSEIF (tasto$ = "2") THEN

        CALL line.giu

        CALL salva.comando.car(tasto$)

    ELSEIF (tasto$ = "4") THEN

        CALL line.sinistra

        CALL salva.comando.car(tasto$)

    END IF

 

END SUB

 

'=================================================================

' Routine per l'input manuale del percorso della macchinina.

'=================================================================

SUB input.percorso (count)

 

    CALL esegui.comando("INIZIO")   'Inizializzo il contatore.

   

 

    DO

        ' Nella variabile TASTO ci va il valore del tasto premuto

        tasto$ = INKEY$

       

        IF (tasto$ <> "") THEN

            CALL esegui.comando(tasto$)

            IF (ASC(tasto$) = 27) THEN EXIT DO

        END IF

    LOOP

 

    CALL esegui.comando("FINE")   'Fine del percorso

 

END SUB

 

'=================================================================

' Va a destra di un passo,partendo dall'ultimo punto visualizzato

' e cioŠ x.old e y.old

'=================================================================

SUB line.destra

 

    SHARED xold, yold, dy

  

    LINE (xold, yold)-(xold + dx, yold)

    xold = xold + dx

   

 

END SUB

 

 

 

 

 

 

 

 

 

 

 

'=================================================================

' va in giu di un passo,partendo per• dall'ultimo punto

‘ visualizzato

' e cioè x.old e y.old

'=================================================================

SUB line.giu

  

    SHARED xold, yold, dy

 

    LINE (xold, yold)-(xold, yold + dy)

    yold = yold + dy

 

END SUB

 

 

 

 

 

 

 

'=================================================================

' Va a sinistra di un passo, partendo dall'ultimo punto

‘ visualizzato

' e cioŠ xold e yold

'=================================================================

SUB line.sinistra

 

    SHARED xold, yold, dy

  

  

    LINE (xold, yold)-(xold - dx, yold)

    xold = xold - dx

 

END SUB

 

'=================================================================

' va in su di un passo,partendo per• dall'ultimo punto

‘ visualizzato

' e cioè x.old e y.old

'=================================================================

SUB line.su

 

    SHARED xold, yold, dy

 

    LINE (xold, yold)-(xold, yold - dy)

    yold = yold - dy

 

END SUB

 

 

'==================================================

' Ritarda N millisecondi

'==================================================

SUB ritmilli (n)

  

    FINE = TIMER * 500 + n

    DO

        IF (TIMER * 500 > FINE) THEN EXIT DO

    LOOP

 

END SUB

 

 

'=================================================================

' Trasforma il valore del tasto premuto in un comando

‘ comprensibile

' dalla automobilina.

'=================================================================

SUB salva.comando.car (tasto$)

 

    STATIC count

    STATIC precedente$

    SHARED percorso$()

 

    IF (tasto$ = "INIZIO") THEN

        count = 1

        precedente$ = "NORD"

        EXIT SUB

    END IF

 

    IF (tasto$ = "FINE") THEN

        percorso$(count) = "$F"

        count = count + 1

        EXIT SUB

    END IF

 

    IF (tasto$ = "8") THEN          'SU

        IF (precedente$ = "NORD") THEN

            percorso$(count) = "$A"

            count = count + 1

            precedente$ = "NORD"

        ELSEIF (precedente$ = "EST") THEN

            percorso$(count) = "$S"

            count = count + 1

            precedente$ = "NORD"

        ELSEIF (precedente$ = "OVEST") THEN

            percorso$(count) = "$D"

            count = count + 1

            precedente$ = "NORD"

        END IF

    ELSEIF (tasto$ = "6") THEN      'DX

        IF (precedente$ = "NORD") THEN

            percorso$(count) = "$D"

            count = count + 1

            precedente$ = "EST"

        ELSEIF (precedente$ = "EST") THEN

            percorso$(count) = "$A"

            count = count + 1

            precedente$ = "EST"

        ELSEIF (precedente$ = "SUD") THEN

            percorso$(count) = "$S"

            count = count + 1

            precedente$ = "EST"

        END IF

    ELSEIF (tasto$ = "2") THEN      'GIU

        IF (precedente$ = "SUD") THEN

            percorso$(count) = "$A"

            count = count + 1

            precedente$ = "SUD"

        ELSEIF (precedente$ = "EST") THEN

            percorso$(count) = "$D"

            count = count + 1

            precedente$ = "SUD"

        ELSEIF (precedente$ = "OVEST") THEN

            percorso$(count) = "$S"

            count = count + 1

            precedente$ = "SUD"

        END IF

    ELSEIF (tasto$ = "4") THEN      'SX

        IF (precedente$ = "NORD") THEN

            percorso$(count) = "$S"

            count = count + 1

            precedente$ = "OVEST"

        ELSEIF (precedente$ = "SUD") THEN

            percorso$(count) = "$D"

            count = count + 1

            precedente$ = "OVEST"

        ELSEIF (precedente$ = "OVEST") THEN

            percorso$(count) = "$A"

            count = count + 1

            precedente$ = "OVEST"

        END IF

    END IF

 

END SUB

 

 

 

 

 

'=================================================================

'Spedisce il comando "AVANTI" tramite la stringa $A

'=================================================================

SUB send.avanti

 

    SHARED avanti

    SHARED rit.motori

    SHARED flag.out

 

    'SHARED num.file.seriale

    'comando$ = "$A"

     

    'PRINT #num.file.seriale, comando$

 

    PRINT "Avanti"

    CALL tira.fuori(avanti, rit.motori)

 

END SUB

 

'=================================================================

'Spedisce il comando "DESTRA" tramite la stringa $D

'=================================================================

SUB send.destra

 

    SHARED destra

    SHARED rit.motori

    SHARED flag.out

    SHARED n.dx

 

    'comando$ = "$D"

    'PRINT #num.file.seriale, comando$

 

    PRINT "destra"

    FOR i = 0 TO n.dx

        CALL tira.fuori(destra, rit.motori)

    NEXT

 

END SUB

 

'=================================================================

'Spedisce il comando "FERMA" tramite la stringa $F

'=================================================================

SUB send.ferma

 

    SHARED avanti

    SHARED rit.motori

    SHARED flag.out

 

 

'   a$ = "$F"

'   PRINT #num.file.seriale, a$

 

    PRINT "fermo"

    CALL tira.fuori(fermo, rit.motori)

 

END SUB

 

 

 

'=================================================================

'Spedisce il comando "INDIETRO".

'=================================================================

SUB send.indietro

 

    SHARED indietro

    SHARED rit.motori

    SHARED flag.out

 

 

    'comando$ = "$I"

    'PRINT #num.file.seriale, comando$

  

    PRINT "indietro"

    CALL tira.fuori(indietro, rit.motori)

 

END SUB

 

'=================================================================

'Spedisce il comando "SINISTRA" tramite la stringa $S

'=================================================================

SUB send.sinistra

 

    SHARED sinistra

    SHARED rit.motori

    SHARED flag.out

    SHARED n.sx

 

'    comando$ = "$S"

  

'    PRINT #num.file.seriale, comando$

  

    PRINT "sinistra"

    FOR i = 0 TO n.sx

        CALL tira.fuori(sinistra, rit.motori)

    NEXT

 

END SUB

 

 

 

 

'*****************************************************************

'* IO.BAS                                                              '*                                                                     '* Programma per la gestione della scheda parallela sperimentale       '*                                                                     '*                                                                     '* Per input  utilizzare call INPP(dato) '* Per output utilizzare

‘ call TIRA.FUORI(dato,rit)                    

'*                                                                     '* Per testare la piastrina e per vedere un esempio ==> sub

‘ TEST().   

'*****************************************************************

 

COMMON flag.out

COMMON outport

COMMON inport1

COMMON inport2

 

 

 

 

SUB hex.to.bin (A$)

'=================================================================

' Routine di servizio.

'

' Trasforma la stringa A$ da cifra esadecimale nel suo

‘ corrispondente

' binario

'=================================================================

 

        SELECT CASE A$

                CASE "0": A$ = "0 0 0 0 "

                CASE "1": A$ = "0 0 0 1 "

                CASE "2": A$ = "0 0 1 0 "

                CASE "3": A$ = "0 0 1 1 "

                CASE "4": A$ = "0 1 0 0 "

                CASE "5": A$ = "0 1 0 1 "

                CASE "6": A$ = "0 1 1 0 "

                CASE "7": A$ = "0 1 1 1 "

                CASE "8": A$ = "1 0 0 0 "

                CASE "9": A$ = "1 0 0 1 "

                CASE "A": A$ = "1 0 1 0 "

                CASE "B": A$ = "1 0 1 1 "

                CASE "C": A$ = "1 1 0 0 "

                CASE "D": A$ = "1 1 0 1 "

                CASE "E": A$ = "1 1 1 0 "

                CASE "F": A$ = "1 1 1 1 "

        END SELECT

 

END SUB

 

'=================================================================

' Routine da utilizzare al posto di IN() del BASIC

'

' In DATO mette il valore letto dalla porta parallela.

'=================================================================

SUB inpp (dato)

 

 

        SHARED inport1

        SHARED inport2

 

 

        A = INP(inport1)

        b = INP(inport2)

        A = A XOR &H80

        A = A AND &HF8

 

        b = b XOR &H3

        b = b AND &H7

 

        dato = A OR b

 

 

END SUB

 

'=================================================================

' Routine per la generazione di un ritardo in millisecondi

'=================================================================

SUB ritardo (rit)

 

        r = rit / 1000

        t = TIMER

        DO

        LOOP UNTIL TIMER > (t + r)

 

END SUB

 

'=================================================================

' Scrive sul monitor il valore binario del numero decimale I

'=================================================================

SUB stampa.binario (i)

 

        ii$ = HEX$(i)

        IF (LEN(ii$) = 1) THEN ii$ = "0" + ii$

        A$ = MID$(ii$, 1, 1)

        b$ = MID$(ii$, 2, 1)

        CALL hex.to.bin(A$)

        CALL hex.to.bin(b$)

        PRINT A$; " "; b$

 

 

 

END SUB

 

'=================================================================

'Routine di esempio per l'output.

'=================================================================

SUB su.e.giu (rit)

      

STATIC count

 

 

 

SELECT CASE count

    CASE 1: CALL tira.fuori(&H1, rit)

    CASE 2: CALL tira.fuori(&H2, rit)

    CASE 3: CALL tira.fuori(&H4, rit)

    CASE 4: CALL tira.fuori(&H8, rit)

    CASE 5: CALL tira.fuori(&H10, rit)

    CASE 6: CALL tira.fuori(&H20, rit)

    CASE 7: CALL tira.fuori(&H40, rit)

    CASE 8: CALL tira.fuori(&H80, rit)

    CASE 9: CALL tira.fuori(&H80, rit)

    CASE 10: CALL tira.fuori(&H40, rit)

    CASE 11: CALL tira.fuori(&H20, rit)

    CASE 12: CALL tira.fuori(&H10, rit)

    CASE 13: CALL tira.fuori(&H8, rit)

    CASE 14: CALL tira.fuori(&H4, rit)

    CASE 15: CALL tira.fuori(&H2, rit)

    CASE 16: CALL tira.fuori(&H1, rit)

    CASE ELSE

 

END SELECT

 

count = count + 1

IF (count = 16) THEN count = 1

 

END SUB

 

'=================================================================

' Sub per i test della piastrina

'=================================================================

SUB test

 

rit = 100

DO

     CALL inpp(i)

     CALL stampa.binario(i)

     CALL su.e.giu(rit)

LOOP UNTIL INKEY$ <> ""

 

END SUB

 

'=================================================================

'Routine da utilizzare al posto di OUT() del BASIC.

'

' Il valore contenuto in DATO viene mandato sulla porta parallela.

' Se RIT e' diverso da ZERO, viene generato un ritardo pari a RIT

'

' Se la variabile globale FLAG.OUT vale 0 ==> uscita su video

' Se la variabile globale FLAG.OUT vale 1 ==> uscita su porta

‘ parallela

'=================================================================

SUB tira.fuori (dato, rit)

 

 

SHARED flag.out

SHARED outport

 

 

 

d = dato

 

 

IF flag.out = 0 THEN

        CALL stampa.binario(d)

ELSEIF flag.out = 1 THEN

        OUT outport, dato

END IF

 

 

IF (rit <> 0) THEN CALL ritardo(rit)

 

END SUB

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Appendice 2

Il programma simulatore


 

'*******************************************************

'* simgra.bas

'*

'* Simulatore di macchinina

'*

'*******************************************************

 

DIM SHARED xold  'vecchia posizione asse x

DIM SHARED yold  'vecchia posizione asse y

DIM SHARED dir$  'Direzione attuale della macchinina (N,S,E,W)

DIM SHARED dx    'Numero di pixel del tratto elementare di linea asse x

DIM SHARED dy    'Numero di pixel del tratto elementare di linea asse y

 

xold = 200

yold = 200

dx = 10

dy = 10

dir$ = "N"

'------------------------------------------------

' Main-program

'------------------------------------------------

 

 

CLS

 

SCREEN 12

 

CALL apri.seriale(100)

DO

    LINE INPUT #100, a$

    IF (a$ = "$A") THEN CALL processa.avanti

    IF (a$ = "$D") THEN CALL processa.destra

    IF (a$ = "$S") THEN CALL processa.sinistra

    IF (a$ = "$F") THEN

        CLS

        xold = 200

        yold = 200

        dir$ = "N"

    END IF

LOOP UNTIL INKEY$ <> ""

CALL chiudi.seriale(100)

END

 

 

 

 

 

 

‘=============================================================

‘ Apre la porta seriale

‘=============================================================

SUB apri.seriale (num.file)

  

    OPEN "com2:1200,n,8,1,cd0,cs0" FOR INPUT AS num.file

 

END SUB

 

 

 

 

‘=============================================================

‘ Chiude la porta seriale

‘=============================================================

SUB chiudi.seriale (num.file)

 

    CLOSE num.file

 

END SUB

 

 

‘=============================================================

‘ E’ arrivato il comando AVANTI

‘=============================================================

SUB processa.avanti

 

    SHARED dir$

 

    CALL traccia.linea.avanti

 

END SUB

 

‘=============================================================

‘ E’ arrivato il comando DESTRA

‘=============================================================

SUB processa.destra

 

    SHARED dir$

 

    IF (dir$ = "N") THEN

        dir$ = "E"

    ELSEIF (dir$ = "E") THEN

        dir$ = "S"

    ELSEIF (dir$ = "S") THEN

        dir$ = "W"

    ELSEIF (dir$ = "W") THEN

        dir$ = "N"

    END IF

 

 

 

END SUB

 

‘=============================================================

‘ E’ arrivato il comando SINISTRA

‘=============================================================

SUB processa.sinistra

 

    SHARED dir$

 

  

    IF (dir$ = "N") THEN

         dir$ = "W"

    ELSEIF (dir$ = "S") THEN

         dir$ = "E"

    ELSEIF (dir$ = "E") THEN

         dir$ = "N"

    ELSEIF (dir$ = "W") THEN

         dir$ = "S"

 

    END IF

 

END SUB

 

SUB ritmilli (r)

'================================================================

' Esegue un ritardo di R millisecondi

'================================================================

  

    init = TIMER

    DO

    LOOP UNTIL TIMER > (init + r / 1000)

 

END SUB

 

‘=============================================================

‘=============================================================

SUB stampa.stringa.ricevuta

 

 

CALL apri.seriale(100)

 

DO

    LINE INPUT #100, a$

    PRINT ">"; a$; "<"

    FOR s = 1 TO 10

    NEXT

    IF (VAL(a$) = (s * 10)) THEN BEEP

LOOP UNTIL INKEY$ <> ""

 

CALL chiudi.seriale(100)

 

END SUB

 

‘=============================================================

‘=============================================================

SUB traccia.linea.avanti

 

    SHARED dir$

    SHARED xold, yold

    SHARED dx, dy

 

  

    IF (dir$ = "N") THEN

        LINE (xold, yold)-(xold, yold - dy)

        yold = yold - dy

    ELSEIF (dir$ = "S") THEN

        LINE (xold, yold)-(xold, yold + dy)

        yold = yold + dy

    ELSEIF (dir$ = "E") THEN

        LINE (xold, yold)-(xold + dx, yold)

        xold = xold + dx

    ELSEIF (dir$ = "W") THEN

        LINE (xold, yold)-(xold - dx, yold)

        xold = xold - dx

    END IF

 

END SUB

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Appendice 3

 

Il programma assembler.


;*******************************************************************

;* Car1.asm

;*

;* CONVENSIONE

;* Nomi delle variabili : Pippo

;* Nomi delle costanti : PIPPO

;*******************************************************************

 

;------------------------------------------------------------------

; Registri interni al micro

;-------------------------------------------------------------------

Stat                            EQU  03H                   ;Registro di stato

Porta                           EQU  05H                   ;Porta A

Portb                           EQU  06H                   ;Porta B

Intcon                          EQU 0BH                   ;Registro abilitazione interrupt

Tr_a                            EQU  85H                  ;Tris A

Tr_b                            EQU  86H                  ;Tris B

 

;-------------------------------------------------------------------

;Definizione Variabili

;-------------------------------------------------------------------

Import                       EQU   0CH     ; Contiene il valore letto dalla porta di ingesso

 

;-------------------------------------------------------------------

             ORG            0

             goto          START                  ;Reset vector

             nop

             nop

             nop

             goto           INTERP                ;interrupt vector

 

;*******************************************************************

;MAIN PROGRAM

;*******************************************************************

 

START    call set_dir_porte           ; vai a set_dir_porte

 

Ciclo         clrwdt                    ; clear watcht dog timer

call leggi_porta          ;mette nella variabile            

                          ;INPORT il valore letto

              call set_dir

              call set_vel

              goto ciclo

                           

;*******************************************************************

;* end main

;*******************************************************************

set_dir_porte    bsf         Stat,5       ;Seleziona SRAM banco 1

                 movlw       b’11111’     ; porta A tutta ingresso

                 movwf       Tr_a         ;

                 movlw       b’00000000’  ;porta B tutta uscita

                 movwf       Tr_b         ;

                 clrf        intcon       ; disabilita interrupt

                 bcf         Stat,5       ; seleziona SRAM banco 0

                 clrf        Porta        ;Uscite della porta A

                                          ;tutte a 0

                 clrf        Portab       ;Uscite della porta B

                                          ;tutte a 0

                 return

 

;-------------------------------------------------------------------

; Legge la porta A e mette il risultato nella variabile INPORT

;-------------------------------------------------------------------

leggi_porta      bcf         stat,5                  ;Seleziona 1

                 movf        Porta,0                 ; W ß PORTA

                 andlw       b’00001111        

                 movwf       Inport                  ;Wàinport

                 return

;-------------------------------------------------------------------

;Controllo quale è la posizione degli switch che impostano la

;direzione.

;Per fare questo utilizzo la sottrazione

;Il valore degli interruttori è in >inport<.

;-------------------------------------------------------------------

 

 

 

 

 

set_dir        ;------------------------------------------------

               ; controllo DX

               ;----------------------------------------------------

               btfsc                Inport,0

               goto                 gira_dx       

                                        

             

   ;----------------------------------------------------

              ; controllo SX

              ;-----------------------------------------------------

              btfsc                Inport,1

              goto                 gira_sx

     

              ;-----------------------------------------------------

              ; Negli altri casi, fermo tutto.

              ;-----------------------------------------------------

fermo_dir     bcf                   Stat,5       ;Seleziona

                                                 ;SRAM banco 0

              bcl                   port b,0      

              return

              ;-----------------------------------------------------

 

gira_sx       bcf                   Stat,5       ;Seleziona SRAM

                                                 ;banco 0

              bcl                   port b,1      

              return

              ;-----------------------------------------------------

 

 gira_dx      bcf                   Stat,5       ;Seleziona SRAM

                                                 ;banco 0

              bcl                   port b,0      

              return

              ;-----------------------------------------------------

 

;-------------------------------------------------------------------

;Controllo quale è la posizione degli switch che impostano la

;velocità.

;Per fare questo utilizzo la sottrazione

;Il valore degli interruttori è in >inport<.

;-------------------------------------------------------------------

 

 

 

set_vel       ;-----------------------------------------------------

              ; controllo AVANTI

              ;-----------------------------------------------------

              btfsc                Inport,2

              goto                  dir_up       

                                       

              ;-----------------------------------------------------

              ; controllo INDIETRO

              ;-----------------------------------------------------

              btfsc                Inport,3

              goto                  dir_dw

     

              ;-----------------------------------------------------

              ; Negli altri casi, fermo tutto.

              ;-----------------------------------------------------

fermo_mot     bcf                   Stat,5         ;Seleziona

                                                   ;SRAM banco 0

              bcl                   port b,3      

              return

           

              ;-----------------------------------------------------

dir_dw        bcf                   Stat,5         ;Seleziona SRAM

    ;banco 0

              bcl                   port b,4     

              return

       

              ;----------------------------------------------------

 dir_up       bcf                   Stat,5            ;Seleziona

 ;SRAM banco 0

              bcl                   port b,3    

              return

                        

;--------------------------------------------------------

;interrupt vector

;---------------------------------------------------------

INTERP              retfie

                    end

;*******************************************************************

;*******************************************************************

;*******************************************************************

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Appendice 9

 

Schema pratico delle modifiche apportate al telecomando.


Collegamenti interni al telecomando

 

 

 

AVANTI                Rosso          -        Blu

                            Nero            -        Grigio

 

INDIETRO            Rosso          -        Blu

                            Nero           -        Giallo

 

DESTRA               Rosso         -        Blu

                            Nero           -        Bianco

 

SINISTRA             Rosso                   -        Blu

                            Nero           -        Verde

 

 

 

 

Collegamento telecomando à interfaccia PC

 

 

Blu

                   Avanti / Indietro

Viola

 

 

Rosso

                   Destra / Sinistra

Verde