Paso 3: La interfaz: aprendiendo Python
Después de completar la parte de hardware de la construcción, fui hacer la parte de software. La GUI para el quiosco tendría que cumplir con unos criterios básicos:Fácil de navegar
Capaz de guardar un formulario en un archivo
Difícil salida
Difícil de hackear (forma de ataques de inyección, etc..)
Cross-Platform (por lo que puedo desarrollar en mi máquina Windows)
Necesitaba un lenguaje o herramienta que esta GUI (relativamente) indolora para montar. Yo no he hecho ningún no-Arduino programación desde... Umm... ¿BASIC? Así que es hora de que aprendí un nuevo idioma, y sabía justo lo que necesitaba: Python.
¿Por qué Python? Porque Python puede hacer nada. Bueno, está bien, no nada, pero es un idioma muy bonito para 'golpear' una aplicación rápida. También hay una gran colección de bibliotecas disponibles para Python en todo tipo de cosas. Para no hablar de que es multiplataforma por lo que pude hacer todo el desarrollo en mi máquina Windows y cargar ese mismo script en el pcDuino sin problemas.
A veces la mejor manera de aprender un nuevo lenguaje de programación es simplemente ir a tu proyecto con los dos pies. Encontrar algunas bibliotecas que creas necesario, abrir todo el código de ejemplo y empezar a desarmarla. Si lees un comienzo de la escritura hasta el final, usando Google para ver cualquier cosa que no entiendo, usted tendrá un conocimiento de trabajo de la sintaxis y métodos finales. Desde allí es la misma vieja rutina: escribir, ejecutar, sale error, depurar. Aunque si se está mudando a Python de C es más como: escribir, ejecutar, 'realmente, que trabajaron, ¿EH?'
Empecé por el acaparamiento de easyGUI, una biblioteca de nombre para Python TkInter (un enlace de python para el kit Tk GUI) se enchufa y hace muy fácil de visualizar y navegar de forma sencilla. Usted puede hacer todo lo que hice sin easyGUI, pero no será tan fácil... INTERFAZ GRÁFICA DE USUARIO... (¿Dónde estoy?)
También es muy fácil de controlar la pcDuino GPIO de Python. Esencialmente sólo está abriendo un archivo y cambiar un valor, es realmente fácil. Copiado/pegado algún código de ejemplo, que algunas definiciones en la parte superior de la secuencia de comandos que permite usar alta, baja, entrada, salida, etc. sin tener que recordar el valor que representa cada uno.
Yo voy adelante registrar mi código a continuación en trozos (no necesariamente en orden escrita pero en orden funcional) e intentar explicar cada bit en beneficio de quien no está familiarizado con Python. Debo advertir a cualquiera que esté familiarizado que yo generalmente código en C para que mi Python no es muy... ¿Pythonic? Funciona, sin embargo.
Muy bien, así que tenemos que hacer primero un poco de configuración:
easygui como por ejemplo, la importación
tiempo de importación, os
# parche rootWindowPosition
eg.rootWindowPosition = "+ 180 + 20"
Así no debería ser demasiado aterrador para los programadores de Arduino. Importar sólo algunas bibliotecas, del mismo modo que usaría "incluir". Ya he explicado la biblioteca de easyGUI, pero la biblioteca de tiempo solo me da la capacidad a retrasa en el código.
El feo se acerca de un parche es algo que robó un pedazo de código de ejemplo para establecer la posición de la ventana de mi GUI. Yo estaba teniendo problemas con mi gestor de ventanas simplemente plopping abajo donde quería, si todo estaba en la pantalla o no. El # indica el comienzo de un Comentario en Python, por cierto.
La siguiente cosa a hacer es listo el GPIO!
GPIO_MODE_PATH = os.path.normpath('/sys/devices/virtual/misc/gpio/mode/')
GPIO_PIN_PATH=os.Path.normpath('/sys/devices/virtual/Misc/GPIO/PIN/')
GPIO_FILENAME = "gpio"
pinMode =]
pinData =]
ALTO = "1"
BAJO = "0"
ENTRADA = "0"
SALIDA = "1"
INPUT_PU = "8"
para que en range(0,18):
pinMode.append (os.path.join (GPIO_MODE_PATH, ' gpio'+str(i)))
pinData.append (os.path.join (GPIO_PIN_PATH, ' gpio'+str(i)))
para el perno en pinMode:
File = open (pin, 'r +') ## Abra el archivo en modo lectura/escritura
File.Write(Output) ## establecer el modo del perno
File.Close() ## importante - debe cerrar el archivo para realizar cambios!
para el perno en pinData:
File = open (pin, 'r +')
File.Write(Low)
File.Close()
Todo eso también fue robada de una secuencia de comandos de ejemplo. Básicamente dice Python donde se guardan los archivos de pin GPIO control en el pcDuino. Define términos como alto y entrada, y luego se utiliza una serie de "bucles for" para establecer los pines GPIO a un estado conocido.
Si eres un programador de Arduino, entonces usted probablemente ha notado algo loco por ahora: no hay ningún punto y coma! O llaves! ¿El mundo se ha vuelto loco? Bueno, sí, pero no por falta de signos de puntuación. Python es dictada por indentación. Bloques de código son separados por el nivel de su sangría.
Bueno, hemos terminado todos con la instalación. Vamos a conseguir algo en la pantalla:
while(1):
mainTurk()
DEF mainTurk():
x = str (eg.buttonbox ("", título = "Chocolate Turco", image="screen1.jpg, opciones = ["Gimme Candy!","¿por qué?"]))
Si x == "¿por qué?":
MSG = "Chocolate turco es un solucionador de Turco mecánico que recompensa a las personas con chocolate! \n \n fue construido utilizando el pcDuino como una demostración de las capacidades del dispositivo. La interfaz y software de control fueron programados en Python con la ayuda de las bibliotecas EasyGUI y PIL. \n \n un tutorial sobre cómo terminó este proyecto estarán disponibles en la página de SparkFun aprender. \n \n ¿por qué no dar mercadotecnia una mano en la publicidad? Hay chocolate en ella para ti ;) \n \n imaginado y ejecutado por: Nick P. \n \n "
title = "Sobre Chocolate Turco"
opciones = ["volver", "Eliminar programa"]
asesino = eg.buttonbox (mensaje, título, opciones = opciones)
Si asesino == "Eliminar programa":
Sys.Exit()
otra cosa:
pasar
otra cosa:
chocoturk()
"Whoa, whoa, whoa... ¿Qué?" Lo sé, si eres un programador de Arduino, esto puede parecer un lío al principio. No te preocupes, te paso a través de él. En primer lugar, empiezo while(1) lazo para que el programa de quiosco se siga corriendo una y otra vez. La siguiente línea es una llamada a eg.buttonbox (si te acordarás de que importamos easyGUI como "eg") que es un método easyGUI que crea un cuadro de diálogo con algunos botones. Se trata de una línea de código condensada, así que es un poco extraño, pero una cosa que le ayudará a averiguar lo que está sucediendo es esto: x tendrá el valor del botón que se pulsa. Si te estás preguntando donde x vino de, no lo hizo! Nos hizo para arriba! Eso es correcto, en Python no tienes que declarar una variable, solo puede comenzar a utilizarlo y Python imaginará lo quiero hacer con él.
Secuencialmente, lo que sucede es que estoy llenando x con la versión de la cadena del valor de la función llamada "eg.buttonbox". Que la función toma algunos argumentos: el título de la ventana, el nombre de la imagen desea mostrar y las opciones que quiero disponible. Cuando esta cadena se ejecuta, aparece una ventana llamada "Chocolate Turco" con una imagen obtenida de screen1.jpg y dos botones etiquetado "Gimme Candy!" y "¿por qué?". Después de uno de los botones es presionado, la función devuelve esa elección a str(), que "stringifies" y rellena en x.
El siguiente paso es poner a prueba x. Si x es igual a "¿por qué?" (En otras palabras, si se presiona el botón "¿por qué?") y luego aparecen una pantalla explicando el proyecto. Sólo para dar un ejemplo ampliado descuida escribir todo esto en una sola línea. Se puede ver que realmente rellena cada variable antes de hacer la llamada a eg.buttonbox. Llamé a la variable retorno "killer" porque es el único lugar en el programa para acabar con él. Haciendo clic la "x" en la ventana aún no, porque no escribo nada para modificarla. Esto es algo bueno, no quiero personas salir de la GUI en mi quiosco.
Las declaraciones más después a manejar qué sucede que si pulsas "Gimme Candy!" que es, por supuesto, vuelca a la siguiente función, que se ve así:
DEF chocoturk():
MSG = "escoger un producto que se siente bastante familiarizado con:"
title = "Seleccionar una tarjeta"
opciones = ["pcDuino", "IOIO-OTG" "SparkFun inventores Kit para Arduino con menor caso", "Makey Makey – Standard Kit", "Placa sencilla de LilyPad Arduino", "Raspberry Pi – modelo B", "9 grados de libertad - maquinilla de afeitar IMU", "RedBoard – programar con Arduino", "XBee Explorer USB", "Controlador de Motor paso a paso EasyDriver"]
choic = eg.choicebox (mensaje, título, opciones)
Si choic == None:
volver
imagen = "% s.jpg" % choic
MSG = "quiero escribir un anuncio para %s"? % choic
opciones = ["Let's Do it!", "esperar, volver atrás!"]
respuesta = eg.buttonbox(msg,image=image,choices=choices)
Si respuesta == "espere, vuelve!":
volver
otra cosa:
val=["","","",""]
compositor (choic, val)
volver
Lo primero que necesita el usuario para hacer es escoger uno de nuestros productos más vendidos, para que les de todo en lo que easyGUI llama una choicebox. Obtener una oportunidad de ser un poco inteligente, después de que el usuario selecciona un producto. He guardado una imagen de cada producto con el nombre del producto como el nombre del archivo. Así que cuando fui a recuperar la imagen de la ventana siguiente, yo sólo apareció ".jpg" en el extremo de la respuesta de choicebox en el argumento de la imagen de buttonbox.
También me dio al usuario oportunidad de cambiar su mente si querían al retornar de la función. Si confirma que quieren seguir después deje caer en la siguiente función, la función del compositor.
autor de la definición (producto, retainVal):
MSG = "escribir la copia de AdWords para el \n \n %s formato: \n \n-titular de \n limitado a 25 caracteres. Enlaces a la página del producto. \n \n-\n Descripción tienes 2 líneas de 35 caracteres cada una para describir un producto de SparkFun a compradores específicos utilizando Google search \n \n-palabras clave: \n 5 ¿Qué términos de búsqueda o frases en Google, cuando debe devolver su anuncio? (Comma-Separated) \n \n "% producto
title = "Compositor de AdWords"
Nombres = ["Titular", "Descripción línea 1", "Descripción línea 2", "Palabras clave"]
fieldValues = [retainVal [0], retainVal [1], retainVal [2], retainVal [3]]
fieldValues = eg.multenterbox (mensaje, título, nombres de campos, fieldValues)
Si fieldValues == None:
volver
Si len(fieldValues[0]) > 25:
EG.MsgBox ("tienes demasiados caracteres en su titular. Pare lo.")
compositor (producto, fieldValues)
Si len(fieldValues[1]) > 35:
EG.MsgBox ("tienes demasiados caracteres en la descripción (línea 1). Pare lo.")
compositor (producto, fieldValues)
Si len(fieldValues[2]) > 35:
EG.MsgBox ("tienes demasiados caracteres en la descripción (línea 2). Pare lo.")
compositor (producto, fieldValues)
composereview (fieldValues, producto)
volver
La función de compositor es bastante sencillo. Solo necesito que el usuario introduzca algún texto, esta es la tarea que está siendo recompensados por. Si no había calculado lo que por ahora, se deletrea hacia fuera en el argumento de msg: tratábamos de conseguir gente de fuera de nuestro Departamento de marketing para escribir copia de ad. Puesto que éstos teóricamente iban a aparecer como anuncios de AdWords, debían cumplir con un determinado formato. He añadido algunas if declaraciones que Compruebe la longitud de caracteres de cada campo antes de premiar al usuario. Si hay demasiados caracteres en un campo, permitiría que el usuario sabe que uno y volver a la forma. Por último, si lograron llenar el formulario les di una oportunidad para revisar lo que habían escrito al lado de un cuadro del producto:
DEF composereview(adcopy, prod):
imagen = "% s.jpg" % prod
MSG = "aquí está lo que usted escribió sobre el % s: \n \n %s \n %s \n %s \n \n con las palabras clave: \n \n %s" % (prod adcopy [0], adcopy [1], adcopy [2], adcopy[3])
opciones = ["Gimme Chocolate NAO!", "Déjame intentarlo..."]
respuesta = eg.buttonbox(msg,image=image,choices=choices)
Si respuesta == "Déjame intentarlo...":
compositor (prod, adcopy)
otra cosa:
f = open ('AdWordsDump.txt', 'a')
f.Write(Prod)
f.Write('\n')
f.Write(adcopy[0])
f.Write('\n')
f.Write(adcopy[1])
f.Write('\n')
f.Write(adcopy[2])
f.Write('\n')
f.Write(adcopy[3])
f.Write('\n')
f.Write('\n')
f.Close()
givethemthechocolate()
El "redactar informe" es una forma simple que pueblan con las respuestas del compositor y una foto del producto usando el mismo truco de nombre como en la ventana de selección de producto. Si el usuario decide que les gusta lo que han escrito, lo guarde en un archivo .txt grande donde guardar toda la información recopilada desde el quiosco. Oh sí, y los descarga en la función final:
DEF givethemthechocolate():
File = open (pinData [6], 'r +')
File.Write(High)
Time.Sleep(1)
File = open (pinData [6], 'r +')
File.Write(Low)
File.Close()
imagen = "thanks.jpg"
MSG = ""
opciones = ["final"]
EG.buttonbox(MSG,Image=Image,Choices=Choices)
mainTurk()
En esta función, simplemente enviar al dispensador del caramelo un pulso alto, entregando ese caramelo dulce, dulce. También mostrar al usuario una imagen gracias y volver a la pantalla de inicio.