Hablando con el Arduino desde el PC
Hace unos días por fin abrí el Arduino Starter Kit que tenía desde Noviembre guardado en un cajón. Impulsado por los avances de @crazystress vi claro que era el momento de volver a la acción y a disfrutar del mundo de los chips y de los controladores.
El Arduino es un pack formado por un microcontrolador (un ATMEGA) optimizado para hablar con el “mundo exterior” mediante un conjunto de puertos de entrada y salida ya configurados. Además, a nivel de programación, cuenta con un entorno de desarrollo que permite programas en un pseudo-lenguaje muy cercano a los lenguajes de programación tradicionales, huyendo de la programación a bajo nivel (registros, pilas y demás…) haciendo que con pocos conocimientos de electrónica y de programación puedas empezar a disfrutar como un hobby más.
El primer reto no parecía muy complicado, y @crazystress ya lo tenía más que superado: conseguir que el PC y el Arduino hablaran entre ellos a través de una aplicación web. Parecía sencillo, pero con un Windows de por medio lo sencillo se convierte en una aventura y al final he necesitado un par de noches para conseguir que funcione…
Vamos con el ejemplo: una página en PHP corriendo en el PC de casa pregunta al usuario que introduzca un dígito y se lo envía al Arduino. Si es par, un led situado en la patilla 13 parpadeará una vez, y si es impar parpadeará dos veces.
El archivo index.php corre en Localhost, sobre un IIS montado en un Windows XP con la extensión para soportar PHP.
El Arduino, aunque se conecta por USB, simula un puerto serie y Windows le asigna el COM correspondiente. En este caso concreto utilizo el COM2.
Sobre los códigos: el del Arduino es bastante sencillo. A nivel de Hardware, el único elemento existente es un Led situado en el Pin 13, único pin que permite conectar directamente un Led sin necesidad de añadirle una resistencia. A nivel de software, lo único que hace es escuchar por el puerto serie. Cuando le llega un dígito, calcula el resto de dividirlo por 2, y bien parpadea una vez cuando es par, bien parpadea dos veces cuando es impar.
El código de la página PHP posiblemente sea mejorable, pero para el ejemplo funciona de sobra (por ejemplo, el puerto vale con abrirlo una vez, no es necesario estar abriéndolo y cerrándolo cada vez que se usa, pero bueno). Además, he dejado unas cuantas líneas comentadas que me han sido muy útiles para encontrar una solución al error que me impedía abrir el puerto COM12. De todas formas, cualquier ayuda para mejorar el código, bienvenida será.
Dejo los archivos en un .zip para descargarlos directamente.
Y lo más importante: la lista de pequeñas cosas que he aprendido por el camino:
- Descomprimí el .zip con el software del Arduino en el Escritorio, corté la carpeta y la pegué en C:/Archivos de Programa. A partir de ahí dejó de compilar por un tema de permisos de directorios, así que la tengo de vuelta en el Escritorio.
- Montar el IIS en Windows XP es bastante trivial: Inicio -> Configuración -> Panel de Control -> Agregar o quitar programas -> Agregar o quitar componentes de Windows -> Internet Information Services (IIS). Eso sí, el CD de Windows XP hay que tenerlo a mano.
- La extensión para soportar PHP la descargué de la web oficial, seleccionando el paquete “VC9 x86 Thread Safe” para PHP 5.3 (desde el completo desconocimiento entre la versión 5.2 y 5.3. Es necesario instalar las librerías Microsoft 2008 C++ Runtime x86 (x86 en mi caso).
- En el PHP.ini sólo activé la depuración de errores “display_errors = On”, y añadí una línea para configurar el timezone y evitar el infierno de los warnings de los timezones: date.timezone = (‘Europe/Madrid’);
- Una de las cosas que más tiempo me llevó fue entender que Windows no permite abrir el puerto serie del Arduino si está por encima del COM9, y por defecto lo tuve en COM12. Siempre obtenía un Permission Denied hasta que lo cambié al COM2 (botón derecho en Mi PC -> propiedades -> hardware -> administrador de dispositivos -> Ports (COM y LPT) -> seleccionar Arduino UNO -> botón derecho en propiedades -> configuración del puerto -> opciones avanzadas. Una vez cambiado, reiniciar el equipo. Gracias Windows.
- Una vez abierto el puerto, lo normal es utilizar la clase php_serial.class.php para realizar las comunicaciones. Pero de nuevo Windows lo de leer y escribir en los puertos serie no lo lleva muy bien y esta clase me ha dado muchos quebraderos de cabeza, así que he terminado haciendo las comunicaciones “a mano” mediante fopens.
- Lo he comentado antes, pero es importante: el Pin 13 es el único que permite conectar directamente un led sin necesidad de resistencia. De ahí que muchos de los ejemplos que existen por Internet utilicen este pin para pruebas con leds.
En resumen, que gracias a Windows he tenido más quebraderos de cabeza de los esperados, pero no he sido el único en tener que superarlos, y ya son parte del pasado. Y ahora a por los siguientes pasos: mientras me llegan las matrices de Leds, voy a trastear un poco con el 74HC595 y con las conversiones int -> char y viceversa porque hay algunos detalles por aclarar para poder trabajar con las matrices de leds.
manolo, tengo problemas, el led, hace lo que quiere, aveces parpadea 2 veces y otras veces no parpadea, aunque le ponga dos veces el mismo numero el resultado parece ser aleatoreo
Hola Fernanda, últimamente me paso el día volando de un sitio para otro y tengo este tema un tanto abandonado. Lo que te diría es, primero de todo, que te asegures de que el circuito funciona SIN conectar al PC. Es decir, coge el ejemplo y pásale directamente la variable al arduino, y te aseguras de que es capaz de saber si el número es par o impar. Y aquí pueden pasar 2 cosas:
1. Si sigue sin funcionar, lo mejor es que te pases por la página oficinal de Arduino y bajes alguno de los programas que tienen de ejemplo hasta asegurarte de que funciona.
2. Si funciona, el problema está en la comunicación con el PC por el puerto serie. Esto a mí me dio bastantes dolores de cabeza hasta el extremo de “resetearlo” antes de hacer cualquier prueba por muy parecida que fuera a pruebas anteriores.
Prueba alguna de estas 2 soluciones y me cuentas, a ver si puedo echarte una mano.
ayuda manolo
Intento ayudar en la medida del tiempo libre del que dispongo, que cada vez es más escaso =)
Fijate que ahora me sale este error:
Warning: fopen(COM2) [function.fopen]: failed to open stream: No such file or directory in C:\AppServ\www\jaja.php on line 9
Not connected
ok, mágicamente regreso a como estaba , ahora en arduino cambie el valor de comparacion:
if (usbnumber % 2 == 0){
por…
if (1 % 2 == 0){
y después con…
if (2 % 2 == 0){
y el código funciona perfectamente,
no se que estaré haciendo mal, ayuda por favor!!!
Debería funcionar. Posiblemente haya algún problema de comunicaciones. En mi caso, no pude utilizar las funciones de comunicación entre el PC y el Arduino ya desarrolladas sobre PHP y tuve que hacerlo “a mano”.
De todas formas, te recomiendo que te pases por los foros oficiales de Arduino, que allí hay mucha gente que sabe mucho más que yo con un poco de suerte han visto algo parecido a lo que te está pasando y pueden echarte una mano.
Esta es la URL: http://arduino.cc/forum/
una pregunta… esto funciona con appserver? es lo que estoy usando
En mi caso utilicé la extensión PHP sobre el IIS, pero vamos, entiendo cualquier servidor de aplicaciones debería ser válido con tal de que interprete el código en el que estás programando.
Tengo muchos doleres de cabeza =S, me salen warnig y eso que ya descomente en el php.ini
Warning: fopen(): It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘America/Chicago’ for ‘-6.0/no DST’ instead in C:\inetpub\wwwroot\goo.php on line 9 Warning: fopen(COM2): failed to open stream: Permission denied in C:\inetpub\wwwroot\goo.php on line 9 Not connected
Manolo agradecido por tu aporte. Visto que me he encontrado con los mismos problemas de Fernanda, aqui la solución por si a alguien le sirve, mis cordiales saludos. (test brealizado con AppServ).
= i =< 9 “;
}
//Modificar el puerto según
if ($port = fopen(“COM6”, “w+”)) {
if (fwrite($port, $str)) {
fclose ($port);
echo “OK “;
echo “$str”;
}
else {
echo “NOT OK”;
}
}
else {
echo “Not connected”;
}
}
?>
Arduino : Par o impar
function set_focus() {
//document.formname.textboxname.focus()
document.arduino.numero.focus()
}
Par o Impar : escribe un Nº entre 0 y 9
Parpadea 1 vez con un número Par, y 2 veces con un número Impar.
Solo son válidos los números comprendidos entre 0 al 9.
Si escribes un número fuera de rango se recibe un mensaje de error.
<form method="post" name="arduino" action="”>
Escribe un número:
¡Gracias Carlos por compartir tu solución!
Hola.. muchas gracias por el aporte me parece muy bueno, quisiera saber como puedo hacer para leer el puerto?¿
Hola Diego, gracias a ti por el comentario. ¿Puedes concretar un poco más la pregunta?
· Si te refieres a cómo se configura a nivel de Hardware: botón derecho en Mi PC -> propiedades -> hardware -> administrador de dispositivos -> Ports (COM y LPT) -> seleccionar Arduino UNO -> botón derecho en propiedades -> configuración del puerto -> opciones avanzadas. Una vez cambiado, reiniciar el equipo
· Si te refieres a cómo se leen los datos mediante software, por lo general se utilizan lecturas de datos del puerto serie (bastante estándar), aunque a mi me dio bastantes problemas yo tuve que utilizar una no tan estándar (está en el PHP dentro del .zip)
vale, muchas gracias por tu respuesta, me refería a leer datos mediante software, estuve probando tus dos codigos y no me funciona cuando realizo la comunicacion desde la pagina web, cuando envió un dato siempre se ilumina solamente una vez el led, en cambio si uso el monitor serial de arduino para enviar los datos si funciona correctamente, te agradecería si me puedes ayudar a encontrar el problema .. Gracias
Asegúrate de que en la línea 9 del archivo index.php está puesto el puerto COMx que ha asignado tu equipo al puerto serie y que es COM9 o menor. Vuelve a ejecutar el PHP des-comentando las líneas 12 y 13 y dime qué valor te da.
Gracias por la ayuda!, logre por fin enviarle datos al arduino mediante el cable seria que tiene, pero ahora estoy intentando usarlo con un modulo bluetooth conectado a el, para lo cual lo único que hice fue cambiarle el puerto COMX correspondiente, el problema es que al correr la pagina me da el siguiente error:
Warning: fopen(COM2): failed to open stream: Invalid argument in C:\xampp\htdocs\arduino\index.php on line 10
Not connected
Agradecería que alguien que hubiese tenido un problema similar me ayudara con alguna solución.. Gracias!
Hola Manolo, y l@s demás.
He probado el montaje pero no funciona: te paso a relatar el proceso que he seguido:
1-He montado el arduino con el led en el pin 13 y le he compilado el programa que has puesto para ello.
2-He mandado con el “serial monitor” del arduino para enviarle valores numéricos y funciona correctamente.
3- He copiado los archivos php en una carpeta de mi servidor apache y con una pequeña modificación (un “echo” dentro del “if” de “fopen” me aseguro que no devuelve error.
El problema está en que lo que “parece” que manda php, no llega al arduino.
he comprobado los datos de configuración del COM3 que es el que uso, pero no consigo nada.
Se te ocurre algo que pueda hacer o probar para ver cuál e el problema y cómo puedo solucionarlo?
Gracias!