I/O su porta seriale

Sommario
Si può usare la porta seriale per comunicare con dispositivi esterni che utilizzano questo protocollo. Bisogna installare il modulo "serial" descritto nella pagina pyserial.sourceforge.net. Il modulo richiede la presenza delle estensioni per Windows, per entrambe le cose vedere la sezione installazione.


Istanziare oggetto seriale e regolare i parametri di funzionamento
(di default i parametri sono settati 9600 N 8 1).
La porta si apre nel momento in cui si istanzia l'oggetto.

import serial
ser=serial.Serial("com1")
ser.timeout=1


Scrivere sulla seriale:

ser.write("stringa")    # una stringa
ser.write(chr(0))       # un singolo byte 0..255
ser.write("\x00")       # un singolo byte in esadecimale


Leggere dalla seriale:

c=ser.read(1)           # lettura di un carattere
c=ser.read(100)         # lettura di una stringa di 100 caratteri

Se il carattere letto lo si vuole considerare come valore binario usare la funzione ord(c) Per gestire la lettura si può usare il parametro timeout. Se è impostato a None (default) la lettura della seriale è bloccante, cioè se non c'è un carattere nel buffer di ricezione la funzione read() rimane in attesa. Se è impostato a 0 la funzione read() non attende, se c'è un carattere lo riporta, se non c'è ritorna stringa nulla. Se è impostato a N attende al massimo N secondi, poi read() riporta stringa nulla.


Chiudere la porta:

ser.close()



Esempio, lettura 256 bytes da un modulo seriale esterno

Il modulo comunica in 9600,N,8,2 e attende la sequenza di valori binari 33 0 0 0 1. Quando li riceve risponde inviando 256 bytes, vogliamo scrivere questi bytes in formato decimale in un file di testo chiamato "output.txt" disponendoli in una matrice di 16x16 elementi:

import serial
 
ser=serial.Serial("com1")
ser.stopbits=2
ser.timeout=1
ser.write( chr(33)+chr(0)*3+chr(1) )

f=open("output.txt","w")
f.write(" Lettura 256 bytes da terminale seriale programmabile\n")
f.write(" "+"-"*63+"\n")

i=0
for j in range(256):
    c=ser.read(1)
    if len(c)>0:
        f.write("%4s" % ord(c))
        i+=1
        if i==16:
            f.write("\n")
            i=0
    else:
        break

ser.close()
f.write(" "+"-"*63+"\n")
f.close()


Risultato:

 Lettura 256 bytes da terminale seriale programmabile
 ---------------------------------------------------------------
  33   0  32   1   0  32  62 255 119 190 194 136   0 175 119 190
 194 136   0  35  11 120 177  32 237  49 239  63 221  33 240  63
  62 205  50 240  63  62 201  50 243  63 205 160   1 254   1  40
   7 254   2 204   0   2  24 242 122 254  32  32   5 205 167   0
  24 232 254  33  32   5 205 227   0  24 223 254  34  32   5 205
  29   1  24 214 254  31  32   5 205 154   0  24 205 254  35  32
   5 205  67   1  24 196 254  36  32   5 205  94   1  24 187 254
  37  32   5 205 107   1  24 178 254  38  32   5 205 125   1  24
 169 254  39 204 149   1  24 162  14 128 121 238  64  79 211  16
  33  52  58  43 124 181  32 251  24 240 197  14  79 205 229   1
  14  75 205 229   1 193 201 245 197 213 229 205 160   1 254   1
  32  39 106 205 160   1 254   1  32  31  98 205 160   1 254   1
  32  23  74 205 160   1 254   1  32  15  66 205 160   1 254   1
  32   7 114  35  11 120 177  32 242 254   2 204   0   2 225 209
 193 241 201 245 197 213 229 205 160   1 254   1  32  37 106 205
 160   1 254   1  32  29  98 205 160   1 254   1  32  21  74 205
 ---------------------------------------------------------------



Come determinare le porte seriali presenti sul sistema.

#---------------------------------------------------------------
# Ritorna una lista di nomi validi ['com1', 'com2', ....] ecc
#---------------------------------------------------------------

def port_exist(s):
    try:
        z=serial.Serial(s)
        z.close()
        return True
    except:
        return False        


def analizza_porte():
    lista=[]
    for i in xrange(16):
        n="com"+str(i+1)
        if port_exist(n): lista.append(n)
    return lista