Electrónica y Programación en Personal
«Si no se soluciona con un script en Python entonces no es viable»

por Yeison Cardona el 08 de junio de 2012 a las 00:15 UTC
No les ha pasado que necesitan hacer interfaces con Pinguino en las que requieren ejecutar comandos en la terminal, bueno, a mi si me ha pasado, y mucho.
Por éste motivo he hecho un pequeño script en Python que se encarga de leer constantemente el puerto serie (CDC) y ejecuta en segundo plano los comandos que le enviemos desde Pinguino.

El script en cuestión es el siguiente, sólo basta con ejecutarlo, preferiblemente en una terminal, conceder los permisos adecuados (sudo chmod a+rw /dev/ttyACM0) y dejarlo «hacer su trabajo».
Descargar...
#!/usr/bin/env python
#-*- coding: utf-8 -*-

"""-------------------------------------------------------------------------
    Script to "read" serial port and execute commands in GNU/Linux.

    author:  Yeison Cardona
    contact:  yeison.eng@gmail.com 
    first release: 06/June/2012
    last release: 07/June/2012

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-------------------------------------------------------------------------"""


import serial, os, time

########################################################################
class CommandReader:
    
    #----------------------------------------------------------------------
    def __init__(self):
        self.EXIT = False
        self.process()

    #----------------------------------------------------------------------
    def process(self):
        while not self.connect():
            time.sleep(0.5)
        print "Connected..."
        self.readPinguino()
        
    #----------------------------------------------------------------------
    def connect(self):
        for i in range(20):
            try:
                self.pinguino = serial.Serial("/dev/ttyACM%i" %i, timeout=1)
                print self.pinguino.readline()
                return True
            except: pass
        return False
        
    #----------------------------------------------------------------------
    def execute(self, command):
        if command[0] == "end-script": return True, "end-script"
        else: os.system(command)
        return False
    
    #----------------------------------------------------------------------
    def getCommand(self):
        try:
            self.pinguino.flushInput()
            return self.pinguino.readline()
        except:
            self.EXIT = True
            self.process()
        
    #----------------------------------------------------------------------
    def readPinguino(self):
        self.EXIT = False
        while not self.EXIT:
            command = self.getCommand().replace("\n", "").replace("\r", "").replace("shell: ", "")
            print command
            if len(command) > 0: self.EXIT = self.execute(command)
                
cmr = CommandReader()
cmr.process()
Para usar el script se procede de una manera muy sencilla, sólo basta con enviar una linea por CDC mediante el comando CDC.println en el siguiente formato: "shell: comando -a -b" y el script que se está ejecutando en Python lo recibirá y ejecutará.
void setup() {
    }

void loop() {
    //Abrir terminal
    CDC.println("shell: gnome-terminal");
    delay(1000);
    
    //Tomar pantallazo
    CDC.println("shell: gnome-screenshot");
    delay(1000);
    }
«Les advierto que el anterior código puede ser algo molesto» Una de las utilidades de este script se nota cuando se usa junto con el programa xdotool el cual sirve para «emular» pulsaciones del teclado y clicks del ratón. Por ejemplo "el comando para insertar texto desde Pinguino"
void setup() {
    }

void loop() {
    //Abrir terminal
    CDC.println("shell: xdotool type 'Pinguino Rules!!!'");
    delay(1000);
    }
Ahora si conectamos un pulsador al pin 2, y lo configuramos como normalmente en alto, podremos tomar pantallazos desde el pulsador con el siguiente código.
void setup() {
    pinMode(2,INPUT);
    }

void loop() {
    //Tomar un pantallazo
    if (digitalRead(2)==0){
    CDC.println("shell: gnome-screenshot");
    delay(500);
    }
}
Y si modificamos el anterior ejemplo podremos insertar un texto con un pulsador desde Pinguino.
void setup() {
    pinMode(2,INPUT);
    }

void loop() {
    //Insertar texto
    if (digitalRead(2)==0){
    CDC.println("shell: xdotool type 'Pinguino Rules!!!'");
    delay(500);
    }
}

Y así, todo tipo de comando puede (en teoría) ser ejecutado desde Pinguino, un sencillo modo de establecer pequeñas interfaces con GNU/Linux ;)

También podría interesarte:

Comentarios:
Anonymous dijo:
12 de agosto de 2012 16:56
Hola! Genial! Muy interesante.El tema es que nunca me aparece /dev/ttyACM0 al estar conectado. Nunca pude trabajar con conexión a la PC. Si logro compliar y cargarlo al pinguino, pero no existe mi pinguino en /dev/ bajo ningún nombre. Alguna sugerencia? Gracias!
Responder a Anonymous
Añadir un nuevo comentario:
Si desean una respuesta para su comentario sólo deben agregarme en G+ y hacer una mención a Yeison Cardona, así les podré responder lo antes posible.