Controllo di apparecchiature con VB - (prima parte)
a cura di Antonio Giuliana (requisiti: conoscenza generica VB e VC, elementi di elettronica digitale,
programmazione dei microprocessori Microchip)

Introduzione
Molto si è letto ultimamente in lista circa il controllo di apparecchiature elettriche e elettroniche tramite PC e sulla possibilità di utilizzare il Visual Basic per realizzare software appositi.
Questi articoli vogliono solo essere una semplice introduzione all'argomento, corredata di esempi pratici e non limitata al solo punto di vista software. Anche senza spingermi così innanzi da invadere il campo delle realizzazioni professionali - dato che non ne ho le possibilità - tratterò i problemi nella maniera più approfondita possibile, pur entro i limiti delle mie esperienze.
Tutti i consigli saranno, chiaramente, ben accetti e ogni commento vorrete fare al contenuto degli articoli o miglioramento penserete di introdurre, saranno i benvenuti.

Gli obiettivi e le basi
Prima di procedere, è opportuno definire sia gli obiettivi che ci proponiamo di raggiungere, sia le nozioni di base necessarie a conseguirli.

  1. Per quanto riguarda gli obiettivi di questi articoli, questi sono principalmente due:
    1. utilizzare la porta parallela in uscita per poter controllare apparecchiature di diverso tipo e in ingresso per rilevare segnali di vario genere (sarà lo scopo di questo articolo);
    2. servirsi della porta seriale per effettuare le stesse operazioni di cui al punto precedente, garantendo un maggior raggio di intervento rispetto a quello ottenibile con la porta parallela (questa realizzazione sarà discussa nel secondo articolo).
  2. Per quanto riguarda invece le nozioni di base necessarie a conseguire gli obiettivi suindicati:
    1. Data la natura dei progetti, non è solo necessario avere un minimo di basi di programmazione in Visual Basic, ma anche in linguaggio C e (molto poco) Assembler.
      Per evidenti ragioni di riutilizzo del codice, ci serviremo della libreria INOUT32, magari in una versione nuova e semplificata utilizzabile con Win9X, NT, W2000 e XP. Il software sarà realizzato in VB6 (in VC6 dove necessario), ma sarà molto semplice adattare il tutto a VB.NET. Il device driver necessario per l'utilizzo del software con sistemi operativi di classe NT, sarà quello utilizzato con la INOUT32 scritta per .NET.
    2. Ma non è finita. Oltre a queste minime cognizioni di base relative al software, dovendo affrontare anche problemi hardware, sarà necessario avere un minimo di confidenza con (semplici) dispositivi e concetti dell'elettronica digitale (oltre a possedere un saldatore, lo stagno e un tester digitale).
      Per utilizzare la porta seriale del PC al fine di gestire un I/O di dati simile a quello realizzato con la porta parallela, ho pensato di realizzare completamente un dispositivo convertitore dotato di 'intelligenza' in modo che sia facilmente programmabile ed espandibile. Naturalmente il dispositivo si deve basare su un microcontrollore e tra quelli presenti sul mercato (tutti affidabili e potenti) ho scelto quelli della serie PIC16Fxxx della Microchip in quanto molto diffusi (si possono reperire in tutti i negozi di elettronica di un certo livello e anche attraverso Internet), facilmente programmabili (gli strumenti di sviluppo sono gratuiti e scaricabili dal sito del produttore), potenti (in quanto implementano in hardware parecchie funzioni complesse) e comodi da utilizzare (grazie alla memoria flash che ne permette il riuso senza dover fare ricorso alle lampade ad ultravioletti per cancellarli e alla diffusione di semplici dispositivi per leggerli/scriverli). Essendo dispositivi programmabili, sarà necessario realizzare un programma ed inserirlo nei componenti; tale programma (firmware) sarà realizzato direttamente nel linguaggio macchina proprio del microcontrollore e tradotto in opcode dall'assemblatore apposito.

E' molto probabile, tuttavia, che il maggiore scoglio, per la più parte dei lettori che vorranno cimentarsi nel seguire questi articoli, sia quello relativo al montaggio dei piccoli circuiti realizzati e qui schematizzati, ma confido nell'esperienza di chi mi legge. Del resto, se si è interessati a questo tipo di articoli, si ha, in qualche misura, esperienza con saldatore e stagno. L'unico consiglio che penso di potervi dare per il montaggio dei circuiti, è quello di utilizzare le basette di sviluppo (quelle con le mollettine per inserire i componenti, per intenderci) o, se fate prima col saldatore, le basette preforate.

Tutto il software, sia residente sul PC sia residente nei microcontrollori, è stato da me testato più volte e non ha mostrato anomalie evidenti (anche se nessun software è esente da bug, non dovreste avere grossi problemi nel suo utilizzo). Anche gli schemi elettrici dei circuiti sono stati provati ripetutamente e si sono rilevati affidabili (ovviamente, non sono immuni a disturbi causati da scariche elettriche di 10 KV, ma sarei sorpreso del contrario essendo le realizzazioni non professionali...) e cattivi funzionamenti sono da ricercarsi solo in errati collegamenti, componenti guasti o cattive saldature. I dispositivi possono essere alimentati con batterie (per testarli) o anche con alimentatori da rete (comuni nei negozi di elettronica). In quest'ultimo caso però, occhio al collegamento con la rete elettrica (in quanto sempre pericolosa) e assicuratevi che il vostro alimentatore sia dotato di trasformatore con avvolgimenti separati.

I sorgenti di tutti i programmi citati in questo articolo, e della libreria INOUT32 da essi usata, sono scaricabili dall'Area Download.

Fatte queste doverose premesse, iniziamo.

Il PC e la porta parallela
Penso che nessuno dei lettori abbia difficoltà ad individuare la porta parallela del PC e che tutti ne conoscano le funzionalità. Per le prove che seguiranno è sufficiente utilizzare la porta parallela nelle sue funzionalità standard.
Per prima cosa dovremo individuare l'indirizzo di I/O (che, ricordo per i più distratti, nell'architettura x86 è un set di indirizzi distinti da quelli della memoria) della porta da utilizzare, che può essere diverso da sistema a sistema.

In genere è uno tra 0x378, 0x278 o 0x3BC ma può essere facilmente ricavato esaminando le risorse assegnate alla porta LPT1.

Nel caso del portatile con cui scrivo e con Windows 2000, questo indirizzo è 0x378 come mostrato nella figura accanto (l'intervallo di I/O relativo agli indirizzi 0x778-0x77A è riservato alle funzionalità ECP della porta che, attualmente, non ci interessano). Se il vostro sistema ha più di una porta parallela, non è difficile identificare il set di indirizzi di I/O associati; in ogni caso, ad una prima prova con il circuito che seguirà, si possono testare i tre indirizzi prima indicati per capire la corrispondenza.
La porta parallela è costituita, dalla parte del PC, da un connettore DB25 (a 25 poli) femmina, con i contatti disposti su due righe parallele di 13 (superiore) e 12 (inferiore). Il pin numero 1, guardando di fronte il connettore, si trova in alto a destra, il numero 25 in basso a sinistra. Per le prove che seguiranno avremo necessità di utilizzare un connettore DB25 maschio con i fili già saldati (ricordate che i segnali sono speculari e quindi state attenti ai numeri dei pin che, in genere, sono scritti sulla parte isolante del connettore stesso). Per risparmiare tempo e 'scottature', potete usare un cavo per stampante dotato di piattina a 25 poli già pronto o sfruttare i connettori a pressione e un metro di piattina a 25 poli (il tutto reperibile presso un normale rivenditore di prodotti per l'elettronica).
In possesso di tale cavo, individuate il pin 2 e il pin 18 e collegateli come nella figura accanto utilizzando una resistenza da 1/4 W (R del valore di 470 ohm) e un LED rosso (o del colore che preferite). In questo modo il LED rispecchierà il valore del bit 0 della porta parallela, accendendosi se tale bit è 1, spegnendosi se è 0.
Il test può essere effettuato con il programma TSTLED.EXE (mostrato accanto) scritto in VB6 e utilizzante la INOUT32.DLL.

Solo per i sistemi operativi di classe NT, è necessario installare il device driver INOUT32D.SYS come indicato nell'articolo "Versione .NET della libreria INOUT32" e scaricabile dall'Area Download (il driver non è legato al framework .NET e quindi può essere utilizzato anche per i nostri scopi).

I segnali della porta parallela che prenderemo in considerazione nelle nostre prove, sono mostrati nella figura accanto. Naturalmente non sono tutti i segnali disponibili ma questi ci basteranno per realizzare tutti i progetti relativi a questo articolo.
Nella figura è mostrato, per ogni segnale, il numero di pin sul connettore, il verso (output o input) il nome del segnale, il registro e il bit assegnati al segnale stesso.
Ad esempio, al pin numero 2 del connettore corrisponde il segnale D0 (dati bit 0 in uscita) il quale è assegnato dal bit 0 del registro dei dati (0x378); oppure, al pin numero 11 corrisponde il segnale BUSY (in ingresso) che è attribuito al bit 7 del registro di stato (0x379). Notare che questo segnale, come lo STROBE e il LFEED, è negato - cioè gli viene applicato un NOT: se il segnale BUSY (pin 11) viene posto a massa, il bit corrispondente nel registro assegnato (SR b7) assume valore 1; viceversa per un segnale di output: se il bit 0 del Control Register (CR b0) assume valore 0, al pin 1 corrispondente (STROBE) c'è tensione. Noi lavoreremo con i segnali della SPP (Standard Parallel Port) assumendo che i primi 8 (i dati da D0 a D7) siano solo in uscita (nella modalità di espansione PS/2 queste linee possono funzionare da input e praticamente tutte le porte parallele adesso lo permettono; molte porte inoltre, consentono di lavorare in modalità avanzate come EPP e ECP; noi non ce ne occuperemo in questo articolo). Per l'input dei dati sfrutteremo alcuni segnali che normalmente sono usati dalle stampanti per comunicare il loro stato al PC. Con un minimo di componenti elettronici esterni, vedremo come le potenzialità della porta parallela possono aumentare.

Per il corretto funzionamento dei nostri circuiti, naturalmente, bisogna collegare la loro massa a quella del computer e questo avviene tramite il pin 18 della porta parallela (GND). I segnali della porta parallela rispettano, dal punto di vista elettrico, lo standard TTL; al bit 1 viene fatta corrispondere la tensione di +5V, al bit 0 il potenziale di massa. Per i circuiti esterni, quando ce ne sarà bisogno, bisognerà provvedere un'alimentazione separata in quanto non disponibile attraverso la porta. Si potrebbe ottenere questa tensione tramite il connettore della tastiera, su cui è disponibile, ma è preferibile essere indipendenti e non caricare tale sorgente. Per i nostri scopi, non è necessario isolare con fotoaccoppiatori la porta parallela dai nostri circuiti; bisogna avere cura, per evitare danneggiamenti ai circuiti della porta (che comunque dispongono di un minimo di protezione) di inserire e disinserire il connettore a PC spento.

Primi circuiti
Per iniziare, come mostrato in precedenza per un singolo LED, la figura mostra il circuito per collegare 4 LED e 4 pulsanti alla parallela in modo da pilotarli tramite un piccolo programma VB (FOURLED.EXE). I 4 LED (collegati tramite resistenze, da R1 a R4, da 1/4 W del valore di 470 ohm) sono pilotati dai bit 0, 1, 2 e 3 dei dati della parallela mentre i pulsanti (da P1 a P4, normalmente aperti) sono collegati agli ingressi che sono tenuti a +5V dalle resistenze da R5 a R8 (anch'esse da 1/4 W del valore di 4700 ohm; potrebbero non essere necessarie in quanto previste all'interno di una porta parallela). Per la tensione di +5V per le resistenze di pullup dei pulsanti non è stato previsto alcun alimentatore ma, data l'esigua corrente richiesta, si frutta il segnale del bit 7 posto a 1 (ricordo infatti che, in uscita, un bit a 1 corrisponde alla tensione di +5V sul pin corrispondente).

Il semplice programma mostra in maniera visuale lo stato dei LED interrogando continuamente la parallela. Appena rileva la pressione di uno (o più pulsanti) provvede ad accendere il LED corrispondente e a darne 'notizia' sul form (l'interrogazione avviene tramite un timer che effettua il 'polling' dei pulsanti).

Una variante del circuito precedente prevede l'utilizzo di un relè (con avvolgimento a 6 V, 1 scambio) pilotato da un transistor BC547 protetto da un diodo dalle extratensioni della bobina del relè.

In figura, per semplicità, è mostrato in dettaglio un solo blocco relativo alla prima uscita (associata al LED 1 e pilotata dal pulsante P1); gli altri blocchi sono uguali e sono gestiti dalle altre tre uscite. È necessaria l'alimentazione stabilizzata (e filtrata da condensatori) a 5 V fornita dal circuito LM7805 il cui ingresso è protetto da un diodo.

Per pilotare il nuovo circuito, basta adattare il vecchio programma inserendo una 'memoria' dello stato delle uscite. Il nuovo programma (FOURLEDM.EXE) consente di memorizzare lo stato delle singole uscite in modo che i relè possano restare attivati anche dopo il rilascio dei pulsanti.

Più linee di I/O
Molto spesso si ha la necessità di un grande numero di linee di I/O e le linee della porta parallela non bastano più. Per quanto riguarda l'input, è possibile aumentare il numero di linee in entrata sfruttando dei comuni circuiti integrati della serie TTL di basso prezzo (nell'esempio accanto si usa il 74LS157, "Quad 2-Line to 1-Line Data Selector/Multiplexer" il cui datasheet è ottenibile in rete, o anche un 74LS257, equivalente per i nostri scopi) e di facile reperibilità. In questo modo è possibile utilizzare 8 linee di ingresso con i relativi pulsanti e selezionare il primo gruppo di 4 o il secondo semplicemente pilotando l'uscita 1 della parallela (segnale Strobe) in maniera appropriata. In particolare, ponendo a 0 tale uscita, il circuito integrato presenta sulle uscite 4, 7, 9 e 2 i segnali presenti agli ingressi 2, 5, 11 e 14, mentre, ponendo a 1 l'uscita di Strobe, vengono riportati gli ingressi 3, 6, 10 e 13.

Il programma VB che provvede a pilotare tale circuito (EIGHTLED.EXE), effettua appunto tale lavoro in modo da prelevare i singoli nibble in sequenza e accendere i LED secondo le indicazioni ricavate. Naturalmente, lo stesso tipo di circuito realizzato in precedenza con 4 relè, può essere attuato con questa versione a 8 uscite.

È anche possibile che si debbano utilizzare più di 8 linee di uscita e nel caso in cui non siano richieste velocità di risposta eccessive (per applicazioni che - comunque - non potrebbero essere realizzate in Visual Basic), è possibile costruire un semplice circuito, ad esempio, per l'espansione a 16 uscite mostrato a fianco.

Per le resistenze (tutte da 470 ohm) è possibile utilizzare due reti resistive mentre i due integrati sono due comuni 74LS373 ( "Octal D-Type transparent latch; 3-state" ).

Il programma VB (16OUT.EXE) che piloterà il circuito utilizzerà il seguente semplice algoritmo per controllare le 16 uscite:

  1. pone gli 8 bit bassi in uscita sulla porta dati della parallela;
  2. emette un impulso positivo di latch sul pin 1 della parallela (bit 0 Control Register; ricordo che questo pin lavora in modo negato e quindi va posto prima ad 1 e poi a 0);
  3. pone gli 8 bit alti in uscita sulla porta dati della parallela;
  4. emette un impulso positivo di latch sul pin 14 della parallela (bit 1 Control Register; anche questo pin lavora in modo negato e anch'esso va posto prima ad 1 e poi a 0).

Operando con la velocità ottenibile con il Visual Basic si può tranquillamente pilotare le 16 uscite senza accorgersi che esse sono attivate in due tempi. Il circuito può essere esteso facilmente fino a 32 uscite sfruttando altri due integrati 74LS373 e due ulteriori uscite di controllo non utilizzate in questi articoli (pin 16 e 17).

Ma anche per gli ingressi è necessario, talvolta, doverne utilizzare 16 e ciò è possibile, con pochi componenti, con il circuito mostrato a lato.

I circuiti integrati utilizzati sono, questa volta, due 74LS244 (Octal buffer/line-driver; 3-state) che garantiscono la lettura di ingressi suddividendoli in 4 gruppi di 4 bit letti tramite i 4 ingressi già utilizzati. I singoli gruppi di 4 bit sono letti ponendo a 0 il segnale di controllo corrispondente, generato tramite le prime 4 uscite dati (da D0 a D3). È importante che solo una di queste sia a livello 0 in un determinato momento in modo che gli altri 3 gruppi di buffer abbiano le uscite in 3-state.

L'algoritmo di input è semplice e prevede che il segnale di abilitazione dei buffer ruoti periodicamente in modo da abilitare, in maniera ciclica, i 4 gruppi di 4 buffer per ottenere gli stati di tutti i 16 ingressi. Il programma che mostra il valore dei singoli ingressi (16INP.EXE) è pilotato da un timer che registra gli ingressi (a gruppi di 4) ogni 100 ms. Anche questo circuito può essere facilmente espanso per controllare 32 ingressi. Il blocco con la resistenza (R=100 ohm) e i diodi (D1, D2 = 1N4148) può essere replicato per ogni ingresso in modo da proteggere l'integrato da tensioni eccessive che si possono presentare per sbaglio agli ingressi. Naturalmente il circuito è adatto a rilevare ingressi di tipo digitale (livello logico TTL, 0..+5V) e per rilevare valori analogici è necessario utilizzare un convertitore analogico-digitale.

Conclusioni
Questa parte si conclude sperando che gli esempi siano serviti per capire le potenzialità offerte dalla porta parallela e dai programmi VB utilizzati per pilotare hardware esterno. Naturalmente tutti i circuiti presentati sono di tipo 'didattico' e vanno adattati alle esigenze diciamo ' di produzione ' di ciascuno. In ogni caso, rappresentano un valido punto di partenza e dimostrano che anche lavorando a livello hobbistico è possibile realizzare sistemi validi.

Nella prossima parte vedremo altri circuiti e codice relativo alla porta parallela e ai dispositivi seriali che possono garantire un maggior numero di ingressi/uscite a patto di complicare un tantino gli algoritmi per il pilotaggio.

Come sempre, sono disponibile a fornire chiarimenti e, per quanto possibile, anche ad aiutare coloro che avranno la necessità di progettare in proprio hardware pilotato da software.

FeedBack
Per ogni chiarimento, critica, suggerimento, potete fare riferimento all'autore, Antonio Giuliana, anche attraverso la Mailing List.