# Control del Puerto Paralelo con Python GNU/Linux



## sangreaztk (Dic 17, 2008)

Pss bien hoy dejare constancia de mi primer contribución al OpenSource, hace tiempo andaba en busca de información sobre el control de puertos en GNU/Linux y me encontré con el foro de 'munguis' y este interesante articulo sobre manipular el puerto paralelo con Python y una librería llamada parport (disponible aquí). El buen de munguis escribió un pequeño programa pero de mucha utilidad para los aficionados a la robótica y electrónica como yo. Así que decidí mejorarlo y para ello me tuve que estudiar este tutorial de PyGTK. Básicamente el programa es una ventana con 8 botones biestable uno para cada bit del bus de datos (desde el D0 hasta el D7) en el que si se presiona se manda un '1' lógico y si se vuelve a presionar vuelve al '0' lógico. También cuenta con un botón de salida que antes de salir apaga totalmente el bus de datos (pone a '0' todos los bits). Munguis me hizo el favor de subir mi código (aquí) pero aquí también lo pondré:
Para poder ejecutarlo es necesario Python, las librerias del escritorio GTK+, las librerías PyGTK y la librería parport. Python es un lenguaje portable por lo que es muy probable que este programa también se pueda ejecutar en 'Ventanas' (Windows) pero yo no lo he probado en dicha plataforma, yo lo hice en Ubuntu 8.04.


```
#!/usr/bin/env python
#
#       pparaleloaztk.py
#       
#       CopyLeft 2008 Aztk
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

# IMPORTANT - To run the program you need superuser permissions

# "parport" is a library from
# [url]http://pyparport.sourceforge.net/[/url]
# Thanks to the parport's developers
from parport import ParallelPort 

import pygtk
pygtk.require('2.0')
import gtk
p = ParallelPort(0x378)
pdatax = 0

class ParalellX:
	
	# This callback write a data in parallel port
    def callback(self, widget, data=None):
    	global pdatax
    	
    	# When the button is hold on
    	if (widget.get_active()):
    		pdatax = pdatax + data
    		print "data = %s" %(pdatax)
    		p.write(pdatax)
    		
    	# When the button is hold off
    	else:
    		pdatax = pdatax - data
    		print "data = %s" %(pdatax)
    		p.write(pdatax)
	
    # This callback quits the program
    def delete_event(self, widget, event, data=None):
        p.write(0)
        return gtk.FALSE
        
    def destroy(self, widget, data=None):
    	p.write(0)
    	print "data = 0"
    	print "Good Wave"
        gtk.main_quit()
        
    def __init__(self):
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("ParalellX")
        self.window.connect("delete_event", self.delete_event)
        self.window.set_border_width(20)
        # Create a vertical box
        vbox = gtk.VBox(gtk.TRUE, 2)
        self.window.add(vbox)
		
		# Create the data buttons (D0...D7)
        #D0
        button = gtk.ToggleButton("D0")
        button.connect("toggled", self.callback, 1)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D1
        button = gtk.ToggleButton("D1")
        button.connect("toggled", self.callback, 2)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D2
        button = gtk.ToggleButton("D2")
        button.connect("toggled", self.callback, 4)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D3
        button = gtk.ToggleButton("D3")
        button.connect("toggled", self.callback, algooooo
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D4
        button = gtk.ToggleButton("D4")
        button.connect("toggled", self.callback, 16)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D5
        button = gtk.ToggleButton("D5")
        button.connect("toggled", self.callback, 32)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D6
        button = gtk.ToggleButton("D6")
        button.connect("toggled", self.callback, 64)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        #D7
        button = gtk.ToggleButton("D7")
        button.connect("toggled", self.callback, 128)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
        
        # Add a separator for the quitbutton
        separator = gtk.HSeparator()
        separator.set_size_request(120, 5)
        vbox.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)

        # Create "Quit" button
        button = gtk.Button("Quit")
        button.connect("clicked", self.destroy, None)
        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)

        self.window.show_all()
           
def main():
    gtk.main()
    return 0       

if __name__ == "__main__":
    ParalellX()
    main()

# This code is inspirated in a munguis' code
# Thanks munguis

# [url]http://www.pygtk.org/pygtk2tutorial-es/[/url]
# A great tuto about pygtk
```

Para correr el programa necesita permisos de superusuario y la librería parport debe de estar contenida en el mismo directorio donde se encuentra el programa.

Es algo sencillo el programa pero estoy orgulloso de él, jejeje, espero pronto aprender y compartir cosas más complejas.
Buena Vibra!


----------



## Dr. Zoidberg (Dic 17, 2008)

> ...Para correr el programa necesita permisos de superusuario...



Es es precisamente el problema que tienes que evitar. Hace un tiempo diseñé un circuito con un conversor A/D de 8 canales y cuatro relays para manejarlo desde el puerto paralelo...y tuve que escribir un driver en modo kernel para poder usarlo en modo "no-superusuario".
El driver que escribí usa de base el driver estandar del puerto paralelo de Linux (pero yo usé un kernel 2.2.19) y se monta sobre él para controlar el conversor A/D y los relays.
Un buen agregado que podrías hacer es analizar el driver estándar del puerto paralelo y diseñar un wrapper en C para poder invocarlo en modo usuario desde Python.

Saludos!


----------



## sangreaztk (Dic 17, 2008)

ezavalla!
Gracias por el comentario! 
Apenas estoy dando mis primeros pasos por el mundo de la programación y aun más por el universo GNU/Linux, por lo que desconozco muchas cosas, con decirte que ni sé lo que es un 'wrapper', jajaja.
Pero me haz dado una dirección que se ve muy interesante seguir, usar el puerto paralelo sin permisos de superUsuario, investigaré sobre eso y si obtengo buenos resultados ya les contare.
Buena Vibra!


----------



## pic-man (Dic 18, 2008)

Muy buen proyecto sangreaztk, voy a leer los enlaces que pusiste en el primer post, yo tambien quiero aprender a controlar el puerto paralelo en linux.


----------



## Dr. Zoidberg (Dic 18, 2008)

sangreaztk dijo:
			
		

> ...por lo que desconozco muchas cosas, con decirte que ni sé lo que es un 'wrapper'...



En este contexto, un wrapper es un conjunto de funciones (escritas en C) que llaman a funciones específicas de los drivers usando la system-call *ioctl(...)*. Entonces vos podrías hacer una función "wrapper" que se llame "ActivarPin(int numero_de_pin)" que tiene una forma simple de acordarse y de llamarla y que internamente use llamadas a ioctl para activar el pin correspondiente del puerto paralelo.

Yo no usé el puerto paralelo de esta forma por que tengo mi driver que se comunica con el del puerto directamente, pero la biblioteca de funciones en C que permiten usar seleccionar el canal a convertir, disparar la conversión A/D, leer el resultado, activar, desactivar los relays y todo el circo, usan llamadas ioctl para comunicarse con el driver y esto lo hacen en modo "usuario normal".

Saludos!


----------



## sangreaztk (Dic 19, 2008)

Hey 'ezavalla'! busque por internet sobre el manejo del paralelo sin permisos de superVaca, pero no he encontado mucho (sera porque no sé buscar?), habra posibilidad que me proporciones alguna referencia o un código (eso sería estupendo)?
Nos leemos luego! 

pic-man: Gracias por el comentario, con la librería que use no hay mucho problema para controlar el puerto, lo difícil es programar la interfaz gráfica.

Buena Vibra!


----------



## tiopepe123 (Dic 19, 2008)

Vaya, veo que no soy el unico interesado en python, justo en estos momentos lo estoy estudiando, he jugado con wxpython.

Me parece que en windowsXP no le gustara mucho qque le toqueteen el puerto paralelo, pero mirare si logo hacerlo funcionar, soy muy novato en el tema de la programacion en entorno windows, lo mio es picar piedra desde msdos.

¿Que tal el python3? ¿Vale la pena diseñar programas para la 3  o mejor seguir desarrollando con la 2.6?


----------



## Moyano Jonathan (Dic 19, 2008)

Para el control del puerto paralelo en windows xp necesitas la io.dll que que podés utilizar en lenguajes como visual basic (bastante  facil) o visual c.


----------



## sangreaztk (Dic 19, 2008)

> ¿Que tal el python3? ¿Vale la pena diseñar programas para la 3 o mejor seguir desarrollando con la 2.6?




jejejeje, yo aún sigo en la V2.5


----------



## gabxeon (Abr 12, 2009)

Muy buen programa justo lo que buscaba, pero tengo una duda, funcionara igual con un adaptador usb-paralelo? es que mi computadora no tiene puerto paralelo y tengo que exponer en una semana como probar el puerto paralelo bajo linux, y lo que tegno es un adaptador de usb a paralelo (centronics) y aun no me eh armado el circuito para probarlo pero me gustaria saber si tengo que hacer alguna modificacion al programa para poder utilizar el convertidor...

utilizo  linux mint 6 y python V2.5


----------



## sangreaztk (Abr 13, 2009)

gabxeon dijo:
			
		

> Muy buen programa justo lo que buscaba, pero tengo una duda, funcionara igual con un adaptador usb-paralelo? es que mi computadora no tiene puerto paralelo y tengo que exponer en una semana como probar el puerto paralelo bajo linux, y lo que tegno es un adaptador de usb a paralelo (centronics) y aun no me eh armado el circuito para probarlo pero me gustaria saber si tengo que hacer alguna modificacion al programa para poder utilizar el convertidor...
> 
> utilizo  linux mint 6 y python V2.5




...................pss ni idea de si te funcione el adaptador usb-paralelo, como yo no tengo alguno de esos no lo he probado ni investigado.
Pero he de suponer (aunque suponer es malo, uno debe estar seguro) de que para arrancar dicho convertidor debe estar configurado/instalado el controlador, puede que se necesite agregarlo al kernel. Y tal vez la dirección a acceder sea diferente (en el programa ocupe la 0x378 que es el bus de datos del primer puerto paralelo).

Por cierto, este código ya tiene tiempo que lo escribí y la neta se puede simplificar/mejorar aún mucho más. Si tu le haces alguna mejora espero que la publiques (así como yo lo hice, tiene licencia CopyLeft, jejeje)

Buena Vibra!


----------



## gabxeon (Abr 14, 2009)

No funciono con el adaptador, pero directo en el puerto funciono perfectamente, ya estuve leyendo el tutorial PyGTK quisera hacer programarlo para que los leds hagan una rutina, no se si me podrias indicar como hacer los retarnos o algun tutorial donde pueda venir lo que estoy buscando


----------



## mockba (May 6, 2009)

Hola, yo he hecho algunas secuencias simples de leds con el puerto paralelo para verificar el fucionamiento de ciertos circuitos de prueba. Para hacer retardos puedes utilizar la función _time.sleep(xxx)_ del módulo estandar _time_:

```
import time
time.sleep(xxx)
```
donde xxx es el número de segundos que quieres prolongar el retardo, puedes utilizar una variable float para proponer retardos de milisegundos o menos. Por ejemplo si quieres un retardo de medio segundo puede usar 0.5 o si quieres un milisegundo puedes usar 0.001:

```
time.sleep(0.5)
time.sleep(0.001)
```
Espero te sriva de referencia. Saludos...


----------



## pipoforos (Jul 31, 2009)

buenas, primero agradecer por la ayuda que brindan a novatos como nosotros. 
quisiera saber como puedo capturar los datos de un A/D que se conecta al puerto paralelo, almacenarlos en un vector, para luego poder hacer la conversion intena a decimal y poder mostrarlo en una grafica.
como ejemplo pongo un sensor de temperatura.
en c, utilizaba inport(0x37b) y lo almacenada en un vector, y luego empezaba a configurarlo para que se muestre en una grafica.
quisiera hacer eso mismo pero y pygtk


----------



## ariastermosolar (Dic 10, 2021)

Para los que cacharrean con el puerto paralelo. 
Yo programaba en BASIC y desde basic es facil usar el puerto paralelo. Windows XP no reconoce el puerto paralelo como lo hacía DOS. Hay que bajarse una .sys y pegarla en system32/drivers. Con esto, el puerto paralelo en XP funciona igual que en DOS. 
Es posible que esto sea lo que necesitas para correr el paralelo en Python.
Pero no me ha quedado claro cómo hacéis en Python
En basic, si dices OUT 888,1 estas mandando que el pin 1 del puerto paralelo sea 5V, y cualquier numero que pongas despues de 888, hace que los primeros pines del paralelo produzcan el binario del numero que pongas, hasta 256 (11111111), o sea todos los pines a 5V.
Alguien sabe hacer algoasí en Python?
Voy a ser mas conciso en eso del .SYS
El programa a bajarse es UserPort.exe. Te viene un zip con el programa y los ficheros, incluyendo ejemplos etc.
Hay que copiar UserPort.sys en WIndows/system32/drivers
Esto se hace una sola vez y a partir de ese momento, al arrancar windows, el puerto paralelo queda activado para que se use directamente desde basic, como he descrito.


----------



## mcrven (Dic 10, 2021)

Python Programming Controlling PC Parallel Port Data Bits
					

Additional functions for pyparallel to control bits on data port.




					www.bristolwatch.com
				












						How to send data through parallel port in Python?
					

I need to send some data via parallel port using Python. And for this I am using psychopy.parallel module.    I have two Windows 7 x64 machines connected via parallel port. This connection is teste...




					stackoverflow.com
				




Lo único que te falta es aprender a utilizar un buscador y... me luce que aprender algo del idioma inglés.

Además de estos dos enlaces debe haber un millón o más de ellos...


----------



## ariastermosolar (Dic 10, 2021)

mcrven dijo:


> Python Programming Controlling PC Parallel Port Data Bits
> 
> 
> Additional functions for pyparallel to control bits on data port.
> ...


Bueno: si, he buscado en google y ya he encontrado lo que buscaba. Y francamente, preguntaba por aqui como pude,preguntar en otros sitios. NO hay que ponerse así. 
Regarding my level of english I'm pretty sure my english is far better than yours.


----------



## mcrven (Dic 10, 2021)

ariastermosolar dijo:


> ...
> NO hay que ponerse así.
> ...



Muy de acuerdo con usted, señor...


----------

