python y gmainloop

Miguel Hernández Martos miguel.hernandez en icr-sa.com
Jue Abr 29 10:04:26 CEST 2004


Hector Miuler Malpica Gallegos wrote:

> <>Hola amigos, estoy buscando la forma de usar el puerto serial (pyserial)
> pero no depender de un poll para ver si estan mandando algo a trabes de el

Pues hasta donde yo sé me parece que hay que hacer polling. Pero no todo 
está
perdido :)

> <>Hay alguna otra forma de hacerlo sin tener que depender de glib? todo
> con puro python? me imagino que GMainLoop tendra que comunicarse con el
> mismo SO. Pense en GMainLoop al ver como el entorno de gnome esta atento
> a todo lo que ocurre en mi desktop, el gnome no usa un timer para cada
> cosa si no que usa a gmainloop.

Utilizo pyserial principalmente en windows, pero creo que lo que te voy 
a contar
vale perfectamente para linux. La idea es tener una hebra aparte que 
centralice
el acceso al puerto serie y que se comunique con la hebra principal (u 
otras
hebra) mediante mensajes. La clave aquí es la clase Queue.Queue que es
"thread-safe". El código no es perfecto, pero cumple su misión siempre y 
cuando
el protocolo que tengas que manejar no requiera excesiva precisión de 
timeouts.
Si necesitas más control imagino que tendrás que iniciar el objeto 
"Serial" con  un
timeout 0 y tendrás que usar un contador de tiempo para ir viendo cuando 
llega
cada carácter.


Un poquillo de código:

import serial

import win32api

import threading

import Queue

class SerialThread(threading.Thread):

    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, verbose=None):

        threading.Thread.__init__(self, group, target, name, args, kwargs, verbose)

        self.writeq = Queue.Queue()

        self.readq = Queue.Queue()

        self.quitthr = 0

        

    def run(self):

        ser = serial.Serial(

            0,

            baudrate=9600, 

            bytesize=serial.EIGHTBITS, 

            parity = serial.PARITY_NONE,

            stopbits = serial.STOPBITS_ONE,

            xonxoff = 0,

            rtscts = 0,

            timeout = 1

        )

        print "SerialThr running."

        while not self.quitthr:

            win32api.Sleep(10)

            if not self.writeq.empty():

                s = self.writeq.get()

                ser.write(s)

            else:

                s = ser.readline()

                if len(s) > 0:

                    print "Nueva trama"

                    self.readq.put(s)

                    

        ser.close()

class Program:

    def __init__(self):
        self.thr = SerialThread()
        self.thr.start()
    
    def run(self):
        print "Running..."
        while 1:
            win32api.Sleep(10)
            if not self.thr.readq.empty():
                raw = self.thr.readq.get()
                print(raw)
                if ( raw == "QUIT\r\n" ):
                    self.thr.quitthr = 1
                    break
                self.thr.writeq.put("OK\r\n")

Espero que te sirva de algo.

Nos vemos!
-- 
Miguel Hernández Martos       | Ingeniería y Control Remoto, S.A.
Departamento de Software      | Pol. Ind. Juncaril C/Baza Parc. 207
------------------------------| 18220 Albolote-Granada (España)
<miguel.hernandez en icr-sa.com> | Tels.: + 34 958 43 00 05/10 
http://www.icr-sa.com         | Fax: + 34 958 46 79 08






------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es