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

Premessa
Eccoci all'ultima puntata di questa piccola serie in cui descriverò alcune tecniche di controllo di hardware tramite PC utilizzanti programmi in Visual Basic e interfacce parallele, seriali e USB.
Per fare ciò utilizzerò un circuito di base, una scheda relè adatta al controllo di piccole apparecchiature alimentate a 220 V, e una serie di circuiti ausiliari atti a collegare la scheda stessa al PC utilizzando diversi protocolli.
Nella prima e nella seconda parte abbiamo esaminato in dettaglio il collegamento tramite porta parallela (che verrà ripreso all'inizio di questa terza parte). In questo articolo esamineremo l'interfacciamento seriale e quello USB.
Naturalmente il software di controllo sarà realizzato in VB6 e, questa volta, sarà anche necessario realizzare e programmare un microprocessore; per questo ci avvarremo del linguaggio macchina proprio dei microcontrollori della Microchip.

Il progetto
Con questa scheda, dicevo, potremo pilotare 8 relé con cui gestire dei carichi a 220 V di discreta potenza.
Le applicazioni sono svariate e dipendono unicamente dalla fantasia di chi utilizza il circuito.
Lo schema seguente mostra i blocchi funzionali che compongono il progetto.

È necessario intendere che non tutti i blocchi di questo sistema devono essere montati, ma solamente quelli relativi al tipo di interfaccia prescelta e quello dell'alimentazione. I blocchi da montare a seconda dell'interfaccia sono i seguenti (le lettere maiuscole fanno riferimento alla figura precedente):

Porta parallela
F + E + G + A
Interfaccia parallela/gestione freeze
Registro a scorrimento a 8 bit
Buffer di potenza relè
Alimentazione
USB
D + E + G + A
Interfaccia USB
Registro a scorrimento a 8 bit
Buffer di potenza relè
Alimentazione
Porta seriale
B + C + G + A
Interfaccia seriale/adattatore RS232
Convertitore Seriale/Parallelo a uP
Buffer di potenza relè
Alimentazione

I componenti utilizzati sono di facile reperibilità, di costo (complessivamente) accettabile e il loro montaggio non presenta particolari difficoltà. Alcuni problemi potrebbero venire riscontrati nel reperimento del modulo USB e nella programmazione del microcontrollore, ma ne parleremo in seguito.

Il primo blocco che esamineremo è quello relativo all'alimentazione stabilizzata del circuito, mostrato nella figura accanto:

Molto semplicemente, questo si avvale di due integrati stabilizzatori a 12 e a 5 volt utilizzati per alimentare, il primo, le bobine dei relè e il circuito integrato buffer e, il secondo, tutti i circuiti rimanenti. Notare che è stato previsto un interruttore per l'alimentazione di tutto il circuito e un diodo di protezione per eventuali errori di inserimento dell'alimentazione primaria. All'ingresso dell'alimentatore deve essere disponibile una tensione continua compresa tra i 15 e i 25 V prelevabile da un piccolo alimentatore facilmente reperibile in commercio. È importante installare delle piccole alette di raffreddamento per i circuiti integrati LM7805 e LM7812 che, specialmente quando sono attivi i relè e i LED, riscaldano un po'. Continuiamo l'esame del progetto esaminando il blocco G, ovvero il circuito pilota di potenza dei relé. Questi, assorbendo una certa quantità di corrente, devono essere attivati attraverso transistor o circuiti integrati adatti; noi useremo un comune circuito integrato ULN2083, driver di potenza capace di pilotarne 8 contemporaneamente. Il circuito è il seguente:

.

Sebbene possa apparire complesso, è in realtà abbastanza semplice perché, a parte l'integrato pilota di cui ho detto, il resto è costituito da 8 blocchi identici facenti capo ai vari relè utilizzati. Come si può vedere, ogni uscita dell'integrato pilota una delle 8 bobine dei relè e un LED che ci indica, con la sua accensione, l'attivazione del relè corrispondente. I diodi sono utilizzati per proteggere le uscite dell'integrato da sovratensioni indotte dagli avvolgimenti anche se il particolare integrato usato dispone di protezione interna. Gli ingressi (da D0 a D7) sono pilotabili a livello TTL dall'esterno, il loro stato non viene memorizzato dall'integrato e il livello logico zero (collegamento alla massa) consente di attivare la coppia relè/LED. Sarà compito delle varie interfacce mostrate in seguito far giungere a questo circuito, e mantenere, le informazioni relative all'attivazione dei relè.

L'interfaccia parallela
Il primo tipo di interfaccia utilizzabile per pilotare la scheda relè è quella che sfrutta la porta parallela del PC secondo quanto detto nelle precedenti puntate. Il tipo di circuito adottato risente dell'esigenza di utilizzare un cavetto di collegamento non particolarmente complesso. Non è infatti comodo utilizzare un collegamento parallelo completo (ovvero utilizzante tutti gli 8 fili corrispondenti ai singoli segnali per i relè) anche se la seguente figura mostra come questo collegamento potrebbe essere realizzato.

Se si utilizza questo collegamento, non bisogna dimenticare di collegare la massa (GND) alla scheda relè. In questo caso, l'alimentazione a 5 V non è utilizzata e quindi il circuito integrato LM7805 dell'alimentatore può non essere montato.

Questo tipo di interfaccia presenta alcuni inconvenienti che ne limitano l'utilizzo. Per primo, come già detto, il cavo di collegamento che deve utilizzare 8 fili, non può essere molto lungo per problemi di interferenze e degrado del segnale. Inoltre, lo stato dei relè dipende direttamente da quello delle uscite della porta parallela (non esiste memoria intermedia) e questo fatto può comportare problemi durante l'accensione e lo spegnimento del computer, fasi durante le quali il valore in uscita dalla parallela non è definito in ogni momento.

Per ovviare a quest'ultimo inconveniente e ridurre il numero di fili presenti nel cavo di collegamento, è necessario utilizzare i circuiti che seguono (blocchi E e F).
In particolare, lo schema accanto (blocco E) è utile sia per permettere il collegamento con soli tre fili della porta parallela, sia per implementare una memoria dello stato dei relè.
Il circuito integrato CD4094 (o 74HC4094, equivalente) è infatti uno shift register a 8 bit dotato di latch ed è pilotato tramite i tre segnali DATA, CLOCK e STROBE. I dati sono trasferiti bit per bit (dal più significativo al meno significativo) ad ogni transizione positiva del segnale di CLOCK.

I dati sono memorizzati all'interno del registro fino a che non si fornisce un impulso positivo alla linea di STROBE. Questo permette di porre in uscita tutti i dati appena ricevuti.

Il programma VB utilizza i segnali D0, D1 e D2 della porta parallela collegati come nello schema a fianco (blocco F), opportunamente pilotati, per trasferire i dati nel registro. Come detto in precedenza, l'attivazione e/o lo spegnimento del PC ha come conseguenza il fatto che si presentano segnali non controllabili sulla porta parallela e tali da essere interpretati dal registro come validi. Per evitare questo fenomeno (che può alterare lo stato dei relè in maniera non desiderata) il segnale di STROBE (pin 3 della porta parallela) passa attraverso un interruttore (FRZ) che permette di non far arrivare tale segnale al registro; in questo caso non è possibile modificare lo stato delle uscite collegate ai relè in maniera accidentale. Lo stato dell'interruttore viene visualizzato da un LED (FRZ ON, se acceso lo stato dei relè non è modificabile) e inviato al PC tramite il pin 11 della porta parallela (in modo che possa essere conosciuto dal programma VB di controllo).

Per quanto riguarda il software (programma ORELAIS) questo, naturalmente, è scritto in VB6 e per quanto riguarda la libreria da utilizzare per accedere all'I/O, è bene riferirsi al paragrafo La libreria INOUT32 alla fine di questo articolo.

L'interfaccia USB
Per permettere il collegamento della scheda relè tramite USB è stato utilizzato un circuito integrato della Future Technology Devices Intl. (modello FT8U245) che, con pochi componenti, permette di realizzare un convertitore USB/parallelo ad alta velocità (1 MB/s). Per la difficoltà relativa alla reperibilità e al montaggio dell'integrato (componente SMD), è stato scelto un modulo premontato con tutti i componenti necessari che presenta i segnali su uno zoccolo DIL. Questo modulo è facilmente reperibile in Internet (modello USBMOD2, Gigatechnology.com Pty Ltd. oppure Ravar) a prezzo moderato e, soprattutto, dispone di driver gratuiti per Windows (prelevabili anche dal sito della FTDI) facilmente utilizzabili da programmi VB.

Il modulo dispone di buffer separati per la ricezione (384 byte) e la trasmissione (128 byte) che permettono le velocità di cui dicevo ma un suo sfruttamento completo si ottiene solamente tramite il controllo di alcuni segnali per mezzo di un microcontrollore.

Per semplificare ho adottato il circuito mostrato a lato (blocco D) collegandolo allo shift register (blocco E).
Il condensatore da 47 nF è utilizzato per derivare un impulso di lettura da quello generato dal modulo quando arriva un byte, mentre l'alimentazione è prelevata dal PC tramite il connettore USB.
Questo tipo di collegamento limita la massima velocità d'utilizzo del modulo e impone una temporizzazione dei segnali apposita da parte del programma VB controllore.

Infine, per eliminare disturbi che possono pregiudicare il funzionamento dell'interfaccia è necessario montare il condensatore da 1 nF sul pin 3 del CD4094 (ingresso di clock).

Naturalmente per utilizzare il modulo si devono utilizzare appositi driver tramite i quali un programma scritto in VB può gestire l'interfaccia. Esistono due tipi di driver, il primo (Virtual COM) permette di gestire l'interfaccia USB simulando una normale porta seriale (COMx) che deve essere gestita dal programma VB con il noto controllo MSComm. Appena installato, il driver crea una porta seriale virtuale utilizzando il primo numero libero (ad esempio, COM6) e gestisce lo scambio di dati tra il programma e la vera e propria interfaccia USB.

Nel programma di controllo della scheda relais (ORELAISUSB) utilizzante questo tipo di driver, è stato incluso un controllo MSComm (MSC) che lavora sulla porta COM6 (ognuno dovrà chiaramente modificare questo numero, se necessario) e l'invio delle informazioni binarie è delegato alla seguente procedura

  Private Sub USBOut(b As Byte)
    MSC.Output = Chr(b)
    Sleep 8
  End Sub

Il ritardo utilizzato è necessario per garantire il corretto funzionamento del meccanismo di generazione dell'impulso da parte del condensatore. Questo (come detto in precedenza) limita la velocità dello scambio dati ma ci evita di dover utilizzare un microcontrollore per il controllo del modulo USB.

Il secondo programma di controllo del modulo USB (ORELAISUSB2) utilizza il secondo tipo di driver USB installabile al quale è possibile accedere tramite la chiamata di funzioni di una apposita DLL (FTD2XX.DLL) utilizzabili da VB. In questo caso la procedura per l'uscita dei dati diventa la seguente

  Private Sub USBOut(b As Byte)
    Dim strWBuffer As String * 256
    Dim lBWritten As Long
    Dim lWStat As Long
    strWBuffer = Chr(b)
    lBWritten = 0
    lWStat = FT_Write(hdUSB, strWBuffer, Len(Trim(strWBuffer)), lBWritten)
    FT_Purge hdUSB, FT_PURGE_RX Or FT_PURGE_TX
  End Sub

Naturalmente il numero di funzioni utilizzabili è elevato ed è necessario studiare bene la documentazione relativa per utilizzare appieno le potenzialità del modulo.

L'interfaccia seriale
Per poter pilotare la scheda relè tramite la porta seriale è necessario un circuito che espleti funzioni di conversione seriale/parallela.

Data la differenza dei livelli di tensione tra lo standard RS232 (che prevede tensioni positive e negative per rappresentare i valori logici 1 e 0) e quello TTL (0 ... 5 V), bisogna prima di tutto usare il circuito adattatore mostrato a lato (blocco B) che, sebbene alimentato con una singola tensione di 5 V, provvede a convertire i valori delle tensioni dei segnali di trasmissione (TX) e ricezione (RX) dell'interfaccia seriale.

Il connettore a 9 poli, di cui sono utilizzati i pin 2, 3 e 5, viene collegato alla porta seriale del PC mentre i contatti RX e TX al convertitore del protocollo realizzato con un microcontrollore PIC16F628.

Questo convertitore (blocco C), mostrato a lato, riceve i dati seriali dall'ingresso RX (il cui livello di tensione è già stato adattato) convertendoli in paralleli sulle uscite D0...D7.
Anche se per la scheda relè non è necessario che il convertitore possa lavorare in direzione contraria (ovvero, leggendo i segnali paralleli e trasmettendoli in seriale tramite la linea TX), questa interfaccia permette anche questo tipo di operazione per avere la possibilità di essere impiegata in altri progetti.

Per questo motivo il firmware inserito all'interno del microcontrollore è un po' più complesso di quello che sarebbe sufficiente e le modalità di comunicazione tra PC e microcontrollore sono più articolate. In compenso, sarà facilmente sfruttabile in altri contesti.

L'uso di un microcontrollore programmabile rende molto più semplice realizzare questa funzione (piuttosto difficile da ottenere, con le stesse caratteristiche, con componentistica standard) e il PIC16F628 è stato prescelto per i seguenti motivi

  • compatibilità con il più famoso, ma obsoleto, modello PIC16F84
  • basso costo (minore del PIC16F84)
  • facile reperibilità (anche migliore del PIC16F84)
  • maggiore disponibilità di memoria per il codice
  • disponibilità dell'interfaccia seriale hardware
  • disponibilità del clock interno a 4 MHz

Il firmware del convertitore seriale/parallelo
Il flusso di programma che viene eseguito all'interno del microcontrollore è mostrato nel seguente schema a blocchi

ed è implementato nel linguaggio macchina del microcontrollore all'interno del file SERPAR.ASM (e, una volta assemblato, all'interno del file SERPAR.HEX).
Anche se non tutti in lista saranno interessati (per vari motivi) a seguire in dettaglio le indicazioni relative al firmware, può essere utile per tutti esaminare il codice assembler relativo alla comunicazione con il programma VB. Controlleremo il codice relativo ai singoli blocchi del diagramma generale visto in precedenza, sorvolando su alcune regole specifiche relative al linguaggio usato.

  clrf   INTCON
  clrf   PORTA
  movlw  0x07
  movwf  CMCON
	
  ToBank 1
  movlw  b'00001000'
  movwf  OPTION_REG
  clrf   TRISA
  movlw  b'00000010'
  movwf  TRISB
  ToBank 0
  clrf   PORTA
  movlw  b'00000110'
  movwf  PORTB

Inizializzazione Port A, B

Sono disabilitati tutti gli interrupt.

Viene inizializzata la Porta A (che al reset è collegata a due comparatori analogici interni), in modo che lavori correttamente come I/O digitale, sia configurata e presenti tutte le uscite a zero.

In seguito vengono attivate le resistenze di pull-up per la Porta B e non viene assegnato il prescaler al timer interno.

La Porta B, infine, viene inizializzata in modo che lavori tutta in uscita fatta eccezione per la linea B1 che viene utilizzata per ricevere i dati dalla porta seriale del PC. Tutte le uscite della Porta B presentano in uscita lo zero logico, tranne la B2 posta a uno (utilizzata per la trasmissione dei dati su seriale).

  ToBank 1
  movlw  0x19
  movwf  SPBRG 
  movlw  0x24 
  movwf  TXSTA 
  ToBank 0 
  movlw  0x90 
  movwf  RCSTA 

Inizializzazione USART

L'USART (il blocco hw del micro che si occupa della comunicazione seriale) viene inizializzata impostando il baudrate 9600 considerando che verrà usato un clock interno a 4 MHz. Sono abilitate la trasmissione e la ricezione (continua) asincrone a 8 bit (nessuna parita', 1 bit di stop).

  Check_RS232
  bcf   LEDPORT,LEDACT
  call  RSRX
  bsf   LEDPORT,LEDACT
Check activity RS232

Spegne il LED ACT (activity) in assenza di dati ricevuti dalla seriale e attende.
All'arrivo di un byte, accende il LED ACT (activity) e continua.
  sublw 'O'
  btfss STATUS,ZERO
  goto  IsCmdI
  call  Get2Hdig
  call  Hex2Nbin
  movf  VBinNL,W
  movwf PORTA
  movf  PORTB,W
  andlw 0x0F
  iorwf VBinNH,W
  movwf PORTB
  goto  Check_RS232

Check ed esecuzione comando O [Out byte]

Controlla che sia stato ricevuto il comando O. Se non è così, continua con il test successivo (comando I).

All'arrivo del comando O, legge due caratteri ASCII di un valore esadecimale dalla porta seriale e li converte in due nibble binari. Pone in uscita il nibble basso su Porta A e il nibble alto su Porta B.


Continua il loop principale di programma.

  IsCmdI
  movf  RSCmd,W
  sublw 'I'
  btfss STATUS,ZERO
  goto  IsCmdD
  movf  PORTB,W
  andlw 0xF0
  movwf VbinNH
  swapf VBinNH,FILE
  movlw 0x36
  addwf VbinNH
  movlw -0x06
  btfsc VBinNH,6
  movlw 0x01
  addwf VbinNH
  movf  VBinNH,W
  call  RSTX
  movf  PORTA,W
  andlw 0x0F
  movwf VbinNL
  movlw 0x36
  addwf VbinNL
  movlw -0x06
  btfsc VBinNL,6
  movlw 0x01
  addwf VbinNL
  movf  VBinNL,W
  call  RSTX
  call  EOLine
  goto  Check_RS232

Check ed esecuzione comando I [Input byte]

Controlla che sia stato ricevuto il comando I. Se non è così, continua con il test successivo (comando D).

All'arrivo del comando I, viene letto il valore esadecimale del nibble alto della Porta B, convertito in ASCII e trasmesso su porta seriale.









In seguito viene letto il valore esadecimale del nibble basso della Porta A, convertito in ASCII e trasmesso su porta seriale.












Viene trasmesso il carattere '*' indicante la fine della linea.
Continua il loop principale di programma.

  IsCmdD
  movf   RSCmd,W
  sublw  'D'
  btfss  STATUS,ZERO
  goto   IsCmdV
  call   Get2HDig 
  call   Hex2Nbin
  movf   VBinNL,W 
  ToBank 1
  movwf  TRISA
  movf   TRISB,W
  ToBank 0
  andlw  0x0F
  iorwf  VBinNH,W
  ToBank 1
  movwf  TRISB
  ToBank 0
  goto   Check_RS232

Check ed esecuzione comando D [Direction]

Controlla che sia stato ricevuto il comando D. Se non è così, continua con il test successivo (comando V).

All'arrivo del comando D, legge due caratteri ASCII di un valore esadecimale dalla porta seriale e li converte in due nibble binari. Copia il nibble basso nel registro Direzione Dati Porta A e il nibble alto nel registro Direzione Dati della Porta B.









Continua il loop principale di programma.

  IsCmdV
  movf   RSCmd,W
  sublw  'V' 
  btfsc  STATUS,ZERO
  goto   SV
  movlw  '?' 
  call   RSTX
	
  SV
  movlw  'S' 
  call   RSTX 
  movlw  '2' 
  call   RSTX 
  movlw  'P' 
  call   RSTX 
  movlw  ' ' 
  call   RSTX 
  movlw  'V' 
  call   RSTX 
  movlw  '1' 
  call   RSTX 
  movlw  '.' 
  call   RSTX 
  movlw  '0' 
  call   RSTX
  call   EOLine
  goto   Check_RS232

Check ed esecuzione comando V[Version]

Controlla che sia stato ricevuto il comando V.

In caso affermativo trasmette, uno per uno, i seguenti caratteri:

S 2 P V 1 . 0

per indicare al programma VB che il firmware che ha risposto alla richiesta del programma VB, è il Serial To Parallel Versione 1.0.

Dato che il comando V è l'ultimo tra quelli esaminati, la richiesta di un comando diverso ha come effetto la trasmissione degli stessi caratteri visti in precedenza ma preceduti dal simbolo ?

In caso di comando non riconosciuto, la stringa in risposta sarà quindi

? S 2 P V 1 . 0

il primo carattere indica il mancato riconoscimento del comando, il resto della stringa il tipo e versione di firmware che ha prodotto la risposta.






Viene trasmesso il carattere '*' indicante la fine della linea.
Continua il loop principale di programma.

Il codice utilizza le 4 subroutine seguenti
  Get2HDig
  call   RSRX
  movwf  HexH
  call   RSRX
  movwf  HexL
  return
Sub Get2Hdig

Riceve due byte dalla porta seriale e li memorizza nelle variabili HexH e HexL.
I byte ricevuti sono le due cifre (ASCII) di un valore esadecimale.
  Hex2NBin
  movf   HexH,W
  addlw  -0x3A
  btfsc  STATUS,CARRY
  addlw  -7
  addlw  0x0A
  movwf  VBinNH
  swapf  VBinNH,FILE
  movf   HexL,W
  addlw  -0x3A
  btfsc  STATUS,CARRY
  addlw  -7
  addlw  0x0A
  movwf  VBinNL
  return

Sub Hex2NBin
Converte i due due byte contenuti nelle variabili HexH e HexL in binario e le memorizza, rispettivamente, nelle variabili VBinNH e VBinNL.

Nella VBinNH il valore è nei 4 bit alti.

Nella VBinNL il valore è nei 4 bit bassi.

  EOLine
  movlw  '*'
  goto   RSTX
Sub EOLine

Trasmette il carattere '*' di fine linea.
  RSRX
  btfss  PIR1,RCIF
  goto   RSRX
  movf   RCREG,W
  movwf  RSCmd
  return
Sub RSRX

Attende finché non viene ricevuto un byte dalla porta seriale.
Il byte viene restituito nel registro W e nella variabile RSCmd.
  RSTX
  btfss  PIR1,TXIF
  goto   RSTX
  movwf  TXREG
  return
Sub RSTX

Trasmette su porta seriale il byte contenuto nel registro W.
La routine attende che la trasmissione del byte precedente sia terminata.

Il firmware va inserito nel microcontrollore tramite un normale programmatore (facilmente reperibile in commercio).

Per comodità viene mostrato (a lato) il file .HEX, risultante dalla compilazione del sorgente, da inserire nel microcontrollore

  :020000040000FA
  :020000000528D1
  :0800080009008B01850107309E
  :100010009F0083160830810085010230860083121C
  :100020008501043086008316193099002430980029
  :100030008312903098008615862086114F3C031D50
  :100040002A28712076202408850006080F39230409
  :1000500086001B282008493C031D48280608F03963
  :10006000A300A30E3630A307FA30231B0130A307E9
  :1000700023088B2005080F39A4003630A407FA3076
  :10008000241B0130A40724088B202A308B201B2836
  :100090002008443C031D592871207620240883162B
  :1000A0008500060883120F39230483168600831205
  :1000B0001B282008563C03195F283F308B20533003
  :1000C0008B2032308B2050308B2020308B205630CC
  :1000D0008B2031308B202E308B2030308B208420B1
  :1000E0001B288620A1008620A20008002108C63E09
  :1000F0000318F93E0A3EA300A30E2208C63E0318C9
  :10010000F93E0A3EA40008002A308B288C1E86285F
  :0E0110001A08A00008000C1E8B289900080099
  :084000000100080000000800A7
  :02400E00383F39
  :104200002B002D002D002D002D002D002D002D0048
  :104210002D002D002D002D002D002D002D002D0036
  :104220002D002D002D002D002D002D002D002D0026
  :104230002B007C002000200020002000530065009F
  :104240007200690061006C002F0050006100720074
  :1042500061006C006C0065006C00200020002000F4
  :1042600020007C007C0043006F006E00760065003B
  :104270007200740065007200200076002E0020009D
  :104280003600320038002E0030003000300032009E
  :104290002E0030007C007C00200020002000430025
  :1042A0006F00700079007200690067006800740098
  :1042B0002C00200041004700200032003000300078
  :1042C0003300200020007C002B002D002D002D004D
  :1042D0002D002D002D002D002D002D002D002D0076
  :1042E0002D002D002D002D002D002D002D002D0066
  :1042F0002D002D002D002D002B002000200020007F
  :00000001FF

Il convertitore ascolta continuamente i dati che arrivano dalla seriale e ne interpreta il primo carattere come un comando e i seguenti come eventuali parametri. In base al tipo di comando ricevuto, esegue una delle seguenti operazioni:

  • comando OUT - (formato: Oxx) - pone in uscita i bit espressi con due cifre esadecimali seguenti il comando sulla porta di uscita (parte alta su porta B, parte bassa su porta A);
  • comando INP - (formato: I) - permette di ottenere dal microcontrollore i valori digitali presenti sugli ingressi (parte alta porta B, parte bassa porta A) in formato esadecimale a due cifre terminate dal carattere '*';
  • comando DIRECTION - (formato: Dxx) - predispone la direzione dei dati delle singole linee del microcontrollore (parte alta su porta B, parte bassa su porta A) tramite due cifre esadecimali; ogni bit a 1 indica una linea in ingresso, ogni bit a 0 indica una linea in uscita;
  • comando VERSION - (formato: V) - restituisce una stringa con il nome e la versione del firmware (utile per il controllo della connessione); l'invio di qualsiasi altro comando non compreso tra quelli supportati comporta la risposta del microcontrollore con un carattere '?' e la versione del firmware.

Il programma VB per l'interfaccia seriale
Una volta collegato un cavo seriale tra il PC e la scheda con il microcontroller e attivata l'alimentazione del circuito, può essere eseguito il programma VB (ORELAISSERPAR) di comunicazione e controllo. Questo sfrutta il conosciuto controllo MSCOMM che deve essere impostato sulla porta usata con i parametri 9600,N,8,1 (velocità, parità, bit dati, bit stop).

Il suo funzionamento è molto semplice in quanto la maggior parte del lavoro viene svolto dal controllo MSCOMM; in trasmissione usufruendo della Sub SendCmd

  With MSC
    RSRBuff = ""
    .Output = Cmd
    Do
      DoEvents
    Loop Until .OutBufferCount = 0
  End With

che permette di trasmettere un comando al microcontrollore attendendo la sua effettiva trasmissione da parte del PC; in ricezione attraverso l'evento OnComm e una variabile usata come buffer di ricezione (RSRBuff)

  If MSC.CommEvent = comEvReceive Then
    RSRBuff = RSRBuff & MSC.Input
  End If

da cui è possibile 'estrarre' i dati in risposta dal microcontrollore.

La libreria INOUT32
In quest'ultima parte di questo articolo voglio fare un po' di chiarezza ed ordine relativamente all'installazione e uso della libreria INOUT32 necessaria per accedere a basso livello alle porte di I/O. Un po' di confusione è nata dal susseguirsi di varie versioni della libreria (la prima dedicata a VB5 e VB6, la seconda a VB.NET, la terza dedicata ai progetti elettronici) che ha creato non pochi problemi a diversi 'lettori' che hanno chiesto la mia assistenza tramite posta elettronica.

Facciamo il punto della situazione attuale partendo da quello che si trova sul sito:

  • INOUT32.zip 30/03/2001 (332 KB) - è la prima versione della libreria funzionante con sistemi operativi di classe Win9X e WinNT/2000 e con VB5 e VB6. Si serve di un device driver di terze parti da installare su sistemi operativi di classe NT. Il suo utilizzo non è molto intuitivo e purtroppo l'uso del driver di terze parti ne limita l'uso nei progetti di tipo commerciale. Non è adatta a progetti in ambiente .NET;
  • INOUT32245.zip 11/07/2002 (91 KB) - questa versione della libreria lavora unicamente con sistemi operativi di classe NT/2000/XP ma il driver è stato sviluppato da me e quindi non esistono le limitazioni d'uso della prima versione. Questa libreria può lavorare con VB5, VB6 e qualsiasi linguaggio .NET (VB.NET, C# e CPP.NET) ma è necessario, in ogni caso, installare il framework di .NET;
  • AGVBHW.zip 06/10/2002 (41 KB) - contiene (anche) i sorgenti della versione della libreria (INOUT32_HW) usata dai programmi di test usati negli articoli di questa serie. Questa libreria lavora solamente con VB5 e VB6 e sistemi operativi di classe NT/2000/XP con il device driver della versione INOUT32245.

Per riassumere, ecco le versioni della libreria con le relative caratteristiche

 
VB5/VB6
.NET
Win9X
NT/2000/XP
Driver
INOUT32
SI
NO
SI
SI
Di terze parti
INOUT32245
SI
(+framework .NET)
SI
NO
SI
Proprietario
INOUT32_HW
SI
NO
NO
SI
Proprietario

Come si vede la maggiore difficoltà si ha quando si vuole usare la libreria sia su Win9X che su NT/2000/XP con VB6 con un driver che non sia di terze parti. Per risolvere definitivamente il problema ho deciso di presentare con quest'ultima puntata della serie degli articoli dedicati all'elettronica, una nuova versione della libreria che ho chiamato New INOUT32 (NINOUT32) di cui è possibile scaricare (vedi in fondo all'articolo) anche i sorgenti e che presenti queste caratteristiche:

 
VB5/VB6
.NET
Win9X
NT/2000/XP
Driver
NINOUT32
SI
NO
SI
SI
Proprietario

In questo modo avremo la possibilità di utilizzare su qualsiasi sistema operativo con VB5/VB6 la libreria servendoci, eventualmente, di un driver proprietario per NT/2000/XP. Solo per la versione .NET sarà ancora necessario utilizzare la versione INOUT32245 ma potremo smettere di utilizzare le altre due versioni.

Per installare la nuova libreria bisognerà effettuare i seguenti semplici passaggi:

  • copiare in una cartella di sistema (C:\Windows\System o C:\Winnt\System32) la libreria NINOUT32.DLL (deve essere disponibile la libreria MSVBVM60.DLL);
  • registrare la libreria NINOUT32.DLL con il comando RegSvr32 path\NINOUT32.DLL;
  • se si usa un sistema operativo NT/2000/XP, copiare il file INOUT32D.SYS nella cartella DRIVERS di sistema, eseguire il file INOUT32D.REG (unire al registro) e riavviare il computer.

Sul funzionamento della NINOUT32 non mi soffermo in quanto alcune tecniche usate per consentirne l'uso sia in sistemi Win9X sia in sistemi NT/2000, saranno oggetto di un prossimo articolo.

Tutti i programmi presentati in questa puntata che accedono all'I/O fanno uso di questa nuova libreria; non è difficile adattare i programmi delle puntate scorse in modo da usare la NINOUT32. Di essi sono scaricabili i sorgenti (vedi in fondo all'articolo).

Conclusioni
E questa volta abbiamo proprio terminato (almeno questa serie di articoli ...).
L'uso del microcontrollore apre moltissime porte per realizzare progetti di ogni tipo. Proprio per questo motivo ho pensato che un ulteriore sviluppo in questa direzione potrà costituire lo spunto di futuri articoli dedicati. Vedrò un po' il da farsi anche basandomi sui vostri riscontri e commenti che mi potrete anche inviare in privato (oltre che, naturalmente, in lista).

Come sempre scrivetemi per qualche consiglio o per risolvere problemi che bloccano le vostre realizzazioni. Vi risponderò (possibilmente) nel più breve tempo possibile e se qualcosa non va nei progetti, vi prego di farmelo notare.

Bibliografia
Datasheet circuiti integrati e modulo USB:

  • PIC16F628
  • MAX232
  • ULN2803
  • 74HC4094
  • LM7805
  • LM7812
  • USBMOD2

Allegati
Dall'Area Download del sito sono scaricabili

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