Comunicación USB Pinguino + PyGTK

Ver el tema anterior Ver el tema siguiente Ir abajo

Comunicación USB Pinguino + PyGTK

Mensaje por aztk el Dom 26 Feb 2012 - 0:58

Hace ya un ratote que usé PyGTK para comunicarme con un PIC por medio del puerto serie (ver manejo del puerto serie con Python), y desde aquel entonces me llamó la atención hacer algo parecido pero con el USB. Pss bien, en ultimas fechas he estado hojeando un leve lo que es Pinguino (http://pinguino.cc/) y éste tiene implementado funciones para la comunicación USB desde el lado del PIC claro, y en la misma documentación de Pinguino se dan ejemplos de cómo realizar la interfaz de comunicación para la PC (con el PIC con Pinguino) por medio de python (usando pyUSB, en Debian y derivados instalar python-usb) (pinguino.cc - Interfacing with Python).

Realicé un pequeño ejemplo para que vean que fácil es hacer la comunicación USB PIC - PC con Pinguino y Python.

Del lado de Pinguino tenemos:

Código:


// File: pyGTK_toogle
//
// February 2012
// aztk <aztecaymaya@gmail.com>
//
// Recibe información del puerto USB y dependiendo del comando
//  enviado pone en alto o en bajo alguna salida.

char received_char;
char i;

void setup()
{
    for (i=0 ;i<8 ;i++){
        pinMode(i,OUTPUT);
        digitalWrite(i,LOW);
    }
}
 
void loop()
{
  if (USB.available())
    {
        received_char = USB.read();
        if (received_char == 'A') digitalWrite(0,HIGH);
        if (received_char == 'B') digitalWrite(1,HIGH);
        if (received_char == 'C') digitalWrite(2,HIGH);
        if (received_char == 'D') digitalWrite(3,HIGH);
        if (received_char == 'E') digitalWrite(4,HIGH);
        if (received_char == 'F') digitalWrite(5,HIGH);
        if (received_char == 'G') digitalWrite(6,HIGH);
        if (received_char == 'H') digitalWrite(7,HIGH);

        if (received_char == 'a') digitalWrite(0,LOW);
        if (received_char == 'b') digitalWrite(1,LOW);
        if (received_char == 'c') digitalWrite(2,LOW);
        if (received_char == 'd') digitalWrite(3,LOW);
        if (received_char == 'e') digitalWrite(4,LOW);
        if (received_char == 'f') digitalWrite(5,LOW);
        if (received_char == 'g') digitalWrite(6,LOW);
        if (received_char == 'h') digitalWrite(7,LOW);
    }
}


** Los pines 0 - 7 en Pinguino son los referentes al RB0 - RB7. Para ver disposición de pines de Pinguino revisar documentación.

Del lado de la PC tenemos:

Código:


#! /usr/bin/python
# -*- coding: utf-8 -*-
 
#-------------------------------------------------------------------------------
# File: pingu_usb_toogle.py
#
# Pone en alto o en bajo bits por medio de instrucciones al puerto USB
#  Envía los cómandos:
#                        A -> Bit0 ON
#                        B -> Bit1 ON
#                        C -> Bit2 ON
#                        D -> Bit3 ON
#                        E -> Bit4 ON
#                        F -> Bit5 ON
#                        G -> Bit6 ON
#                        H -> Bit7 ON
#
#                        a -> Bit0 OFF
#                        b -> Bit1 OFF
#                        c -> Bit2 OFF
#                        d -> Bit3 OFF
#                        e -> Bit4 OFF
#                        f -> Bit5 OFF
#                        g -> Bit6 OFF
#                        h -> Bit7 OFF
#
# aztk, february 2012
#
# aztecaymaya@gmail.com
#
# References:
#  http://wiki.pinguino.cc/index.php/Interfacing_with_Python
#-------------------------------------------------------------------------------
 
import usb        # requires pyusb available at https://sourceforge.net/projects/pyusb/files/

import pygtk
pygtk.require('2.0')
import gtk

#-------------------------------------------------------------------------------
# Pinguino Class by Marin Purgar (marin.purgar@gmail.com)
#-------------------------------------------------------------------------------
class Pinguino():
 
    VENDOR = 0x04D8
    PRODUCT = 0xFEAA
    CONFIGURATION = 3
    INTERFACE = 0
    ENDPOINT_IN = 0x82
    ENDPOINT_OUT = 0x01
 
    device = None
    handle = None
 
    def __init__(self,):
        for bus in usb.busses():
            for dev in bus.devices:
                if dev.idVendor == self.VENDOR and dev.idProduct == self.PRODUCT:
                    self.device = dev
        return None
 
    def open(self):
        if not self.device:
            print "Unable to find device!"
            return None
        try:
            self.handle = self.device.open()
            self.handle.setConfiguration(self.CONFIGURATION)
            self.handle.claimInterface(self.INTERFACE)
        except usb.USBError, err:
            print >> sys.stderr, err
            self.handle = None
        return self.handle
 
    def close(self):
        try:
            self.handle.releaseInterface()
        except Exception, err:
            print >> sys.stderr, err
        self.handle, self.device = None, None
 
    def read(self, length, timeout = 0):
        return self.handle.bulkRead(self.ENDPOINT_IN, length, timeout)
 
    def write(self, buffer, timeout = 0):
        return self.handle.bulkWrite(self.ENDPOINT_OUT, buffer, timeout)
       

class Ventana:
 
    # This callback write a data in USB port
    def writex(self, widget, data):
        INTERVAL = 100
        # When a button is hold on
        if (widget.get_active()):
            print "Bit%s ON" %(data - ord('A'))
            pinguino.write(chr(data), INTERVAL)
     
        # When a button is hold off
        else:
            data = data + 32
            print "Bit%s OFF" %(data - ord('a'))
            pinguino.write(chr(data), INTERVAL)
 
    # This callback quits the program
    def delete_event(self, widget, event):
        INTERVAL = 100
        pinguino.write('abcdefgh', INTERVAL)
        pinguino.close()
        print "All bits OFF"
        print "Good Wave!!! :)"
        gtk.main_quit()
 
    def destroy(self, widget):
        INTERVAL = 100
        pinguino.write('abcdefgh', INTERVAL)
        pinguino.close()
        print "All bits OFF"
        print "Good Wave!!! :)"
        gtk.main_quit()
       
    def main(self):
        gtk.main()
        return 0
 
    def __init__(self):
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("PinguinoUSBX")
        self.window.connect("delete_event", self.delete_event)
        self.window.set_border_width(20)
        self.window.set_resizable(False)
     
        # Create a vertical box
        vbox = gtk.VBox(True, 2)
        self.window.add(vbox)
     
        for i in range(8):
            bx = "Bit%d" % i
            dx = gtk.ToggleButton(bx)
            dx.connect("toggled", self.writex, ord('A') + i)
            vbox.pack_start(dx, True, True, 2)
     
        # Add a separator for the quitbutton
        separator = gtk.HSeparator()
        separator.set_size_request(90, 1)
        vbox.pack_start(separator, False, True)
     
        # Create the "Quit" button
        buttonq = gtk.Button("Quit")
        buttonq.connect("clicked", self.destroy)
        vbox.pack_start(buttonq, True, True, 2)
     
        self.window.show_all()
     
        print "Hey Hoo, Let's go!"

if __name__ == '__main__':
    pinguino = Pinguino()
    if pinguino.open() == None:
        print "Unable to open Pinguino device!"
        exit(1)
    ventana = Ventana()
    ventana.main()


** No se olviden de tener instalado pyUSB y pyGTK

Saludos!!!




aztk
Participante Activo
Participante Activo

Mensajes : 52
Fecha de inscripción : 08/06/2009
Edad : 29
Localización : Tenochtitlan

Volver arriba Ir abajo

Re: Comunicación USB Pinguino + PyGTK

Mensaje por Pikitin el Dom 26 Feb 2012 - 18:26

Buena solucion.. gracias. :-)

No conozco el pinguino, pero creo que es la versión pic de arduino. El hardware arduino si lo uso, pero el entorno de programación tiene algunas desventajas, por ejemplo esa función: digitalWrite() solo le veo sentido si quieres acceder a los pines por variable, por ejemplo en un bucle for.
El tema es que genera un código asm larguísimo, ocupa bastante memoria, pero sobre todo es muy lento, en la mayoría de los casos no hay problema, pero si necesitas velocidad o precisión no sirve.
Se ve facilmente si compilas un simple blink led... te genera un ejecutable de más de 1000 bytes, cuando lo normal serían alrededor de 100.
Yo normalmente uso una tabla de defines y simplemente pin6 = 0.. por ejemplo.

Pero la librería esta USB está cojonuda jeje..

Buen día.

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Comunicación USB Pinguino + PyGTK

Mensaje por aztk el Lun 27 Feb 2012 - 7:25

Supongo que lo del digitalWrite() lo dices porque sólo te permite escribir en un pin y tu estás pensando en todo el puerto. La verdad arduino sólo lo he usado un par de veces y no lo conozco mucho, pero creo puedes escribir en todo un puerto http://www.arduino.cc/en/Reference/PortManipulation

Aunque la implementación de pinguino no se puede hablar de una equivalencia del compilador de arduino al PIC. Si no yo lo veo cómo usar el lenguaje de arduino para traducirlo a SDCC y luego sí compilarlo para el PIC.

Yo me siento muy cómodo programando en asm porque tengo total control de tiempo máquina y memoria, pero sin duda el usar lenguajes de alto nivel ahorra mucho trabajo. Por ejemplo esta comunicación con USB se hace muy fácil.

Saludos!

aztk
Participante Activo
Participante Activo

Mensajes : 52
Fecha de inscripción : 08/06/2009
Edad : 29
Localización : Tenochtitlan

Volver arriba Ir abajo

Re: Comunicación USB Pinguino + PyGTK

Mensaje por Pikitin el Lun 27 Feb 2012 - 13:04

Supongo que lo del digitalWrite() lo dices porque sólo te permite escribir en un pin y tu estás pensando en todo el puerto

No, maś bien lo decia porque estas funciones son muy largas para lo que hacen, normalmente poner un pin alto o bajo cuesta una instrucción, con esa función cuesta 20 o 30 instrucciones.
No sé cómo será en pinguino, pero en arduino esta es la función:

Código:

void digitalWrite(uint8_t pin, uint8_t val)
{
    uint8_t timer = digitalPinToTimer(pin);
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    volatile uint8_t *out;

    if (port == NOT_A_PIN) return;

    // If the pin that support PWM output, we need to turn it off
    // before doing a digital write.
    if (timer != NOT_ON_TIMER) turnOffPWM(timer);

    out = portOutputRegister(port);

    if (val == LOW) {
        uint8_t oldSREG = SREG;
                cli();
        *out &= ~bit;
        SREG = oldSREG;
    } else {
        uint8_t oldSREG = SREG;
                cli();
        *out |= bit;
        SREG = oldSREG;
    }
}

Entonces los programas son más largos y sobre todo bastante más lentos.

De todas formas arduino vá sobre avr-Gcc y pinguino creo que usa SDCC, así que se pueden usar las funciones de estos.
Lo que te comentaba es que yo suelo hacer una tabla de defines para la placa que uso, por ejemplo para pic igual sería:

#define pin1 RB0
#define pin2 RB1
....

y para ajustar un pin:
pin1 = 0;

Para escribir un puerto se puede hacer como siempre:
PORTB = 154;

La ventaja que le veo a esa función es por ejemplo para algo como esto:

Código:

for( uint8_t pin=1; pin<=10; pin++ )
{
    digitalWrite( pin, HIGH );
    delay( 100 );
}

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Comunicación USB Pinguino + PyGTK

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


 
Permisos de este foro:
No puedes responder a temas en este foro.