Linux + Arduino Leonardo + Conexión Ethernet + WIFI + SD = YÚN
El Yún es una de las mejores placas disponibles en el catálogo de Arduino, su versatilidad es realmente increíble, fusiona dos tecnologías totalmente diferentes, un Arduino Leonardo y un sistema en Linux, de una forma trasparente al usuario, que puede elegir lo mejor de ambos mundos en una sola placa, si a todo esto le añades una excelente conexión a internet integrada, mediante WIFI o con cable y una lectora de tarjetas micro SD, obtienes esta maravilla de placa que de un plumazo soluciona todos los problemas que nos encontramos en los proyectos profesionales.


La mejor forma de conocerlo es probarlo, para eso hemos desarrollado este proyecto, un contador de Likes de tu página en Facebook, que consulta el número de Likes mediante un script en Python y lo imprime, junto con la hora, en un Display de 2×16 y cuando hay nuevos likes, hace sonar un beep.
Material necesario
- 1 x Arduino Yún
- 1 x Display LED 16×2 con bus I2C
- 6 x Cables Male/Female
- 1 x Buzzer de 5V
- 1 x Caja para proyectos.
Las conexiones son muy fáciles, solamente es necesario conectar los cuatro cables del Display I2C al Yún
- DAT (SDA) Pin digital 2
- CLK (SCL) Pin Digital 3
- 5V
- GND
El Buzzer (es optativo) se conecta el negativo a GND y el positivo al Pin 12 de nuestro Yún


El Arduino Yún se alimenta mediante el conector USB con 5V, si piensas utilizar directamente la entrada VIN de la placa para alimentar el proyecto, es MUY importante que tengas en cuenta que a diferencia con otros modelos, es necesario utilizar una fuente regulada de 5V, si utilizas un voltaje superior, estropearás tu placa inmediatamente.
Code
En este código utilizamos varias funciones de Linux desde el Yún, al arrancar la placa, después de conseguir la conexión a internet, lo primero que hace es copiar el código python a un fichero y volverlo ejecutable, este código se encarga de leer la página de datos de una página en Facebook, convertirla en datos Json e imprimir el número de Likes, este es el valor que recibirá la parte Arduino del Yún.
También ejecuta otro proceso linux (sh) que lee la hora del sistema y la presenta en pantalla.
El resto del código es muy fácil de entender, cada 30 segundos comprueba el número de Likes, si es diferente al último leído lo imprime y emite un pitido.
También hemos añadido un carácter al display con forma de corazón que se enciende y apaga cada segundo.
/*
Facebook Likes counter
www.openhardware.pe
Gets the time from the linino processor via Bridge
then parses out hours, minutes and seconds for the Arduino
using an Arduino Yun.
created 27 Jan 2014
Basado en el codigo de los ejemplos de Arduino By Tom Igoe
This example code is in the public domain.
*/
#include <Process.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <FileIO.h>
uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; // Heart char
Process date; // process used to get the date
int hours, minutes, seconds; // for the results
int lastSecond = -1; // need an impossible value for comparison
int lastLikes = -1; // need an impossible value for comparison
int likes = 0;
bool heartStatus = false ;
LiquidCrystal_I2C lcd(0x20,16,2); // set the LCD address to 0x20 for a 16 chars and 2 line display
void setup() {
pinMode(12,OUTPUT); // beep
pinMode(13,OUTPUT);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
Bridge.begin(); // initialize Bridge
Serial.begin(9600); // initialize serial
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.createChar(0, heart);
lcd.home();
lcd.print("openhardware.pe");
lcd.setCursor(0, 1);
FileSystem.begin();
uploadScript(); // Upload the python script to LINIO
// run an initial date process. Should return:
// hh:mm:ss :
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
digitalWrite(13, LOW);
}
void loop() {
if(lastSecond != seconds) { // if a second has passed
lcd.setCursor(0, 1);
// print the time:
if (hours <= 9) lcd.print("0"); // adjust for 0-9
lcd.print(hours);
lcd.print(":");
if (minutes <= 9) lcd.print("0"); // adjust for 0-9
lcd.print(minutes);
lcd.print(":");
if (seconds <= 9) lcd.print("0"); // adjust for 0-9
lcd.print(seconds);
// on/off Heart symbol
lcd.print(" ");
if (heartStatus)
lcd.write(byte(0));
else
lcd.print(" ");
heartStatus = !heartStatus;
// restart the date process:
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
if ((seconds % 30) == 0) { // check every 30 secs modify to change the interval
likes = runScript(); // run the python script
lcd.print(likes);
if (lastLikes != likes ) {
// Cambia el numero de likes
lastLikes = likes;
// codigo a ejecutar
// En este caso produce un pitido con un buzzer
digitalWrite(12, HIGH);
delay(75);
digitalWrite(12, LOW);
}
}
}
//if there's a result from the date process, parse it:
while (date.available()>0) {
// get the result of the date process (should be hh:mm:ss):
String timeString = date.readString();
// find the colons:
int firstColon = timeString.indexOf(":");
int secondColon= timeString.lastIndexOf(":");
// get the substrings for hour, minute second:
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon+1, secondColon);
String secString = timeString.substring(secondColon+1);
// convert to ints,saving the previous second:
hours = hourString.toInt();
minutes = minString.toInt();
lastSecond = seconds; // save to do a time comparison
seconds = secString.toInt();
}
}
void uploadScript() {
// Write our shell script in /tmp
// Using /tmp stores the script in RAM this way we can preserve
// the limited amount of FLASH erase/write cycles
File script = FileSystem.open("/tmp/likes.py", FILE_WRITE);
// Shell script
script.print("#!/usr/bin/python\n");
// import libs
script.print("import urllib2,json \n");
// read the Facebook data page
script.print("data = urllib2.urlopen('http://graph.facebook.com/open.hardware.labs/').read() \n");
// convert to Json
script.print("json_data = json.loads(data)\n");
// print the likes value
script.print("print ('%s') % (json_data['likes'])\n");
script.close(); // close the file
// Make the script executable
Process chmod;
chmod.begin("chmod"); // chmod: change mode
chmod.addParameter("+x"); // x stays for executable
chmod.addParameter("/tmp/likes.py"); // path to the file to make it executable
chmod.run();
}
// this function run the script and read the output data
int runScript() {
// Run the script and return the results
Process myscript;
myscript.begin("/tmp/likes.py");
myscript.run();
String output = "";
// read the output of the script
while (myscript.available()) {
output += (char)myscript.read();
}
// remove the blank spaces at the beginning and the ending of the string
output.trim();
return output.toInt() ;
}
En este enlace puedes descargar el código completo.
Descarga el código
Hola,
Tengo una pregunta, ¿se puede realizar este mismo proyecto con Arduino UNO u otros modelos mas pequeños?
Gracias!
José, no se puede con otros modelos, el Arduino YUN tiene una configuración muy diferente al resto, incluye un módulo en Linux que es la parte que se utiliza para acceder a internet y procesar los datos mediante un programa en Python.
Creo que de poder se debe poder sólo requieres conocimientos de programación para emular las llamadas rest al api de facebook. Yo he integrado Arduino Uno con Web Services sin problema. Lo que si el YUN te da una ventaja de tener librerias listas y hacen que el tiempo de habilitación de estos programas sean muy rápidos.
César
Hola, que libreria LiquidCrystal_I2C se esta usando ? yo uso esta https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads y me da error el ejemplo.
gracias!!
Hay varias librerías diferentes, son en función de la interface de Display que utilices.
Asegúrate que el puerto de I2C que has seleccionado en el setup es el correcto.
Esta es la cabecera de las últimas que estamos usando:
//www.DFRobot.com
//last updated on 21/12/2011
//Tim Starling Fix the reset bug (Thanks Tim)
//wiki doc http://www.dfrobot.com/wiki/index.php?title=I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
//Support Forum: http://www.dfrobot.com/forum/
//Compatible with the Arduino IDE 1.0
//Library version:1.1
Teniendo en cuenta esta configuración:
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x20 or (0x27) for a 16 chars and 2 line display
Me gusta mucho. yo lo he construido. Pero ahora tengo una pregunta. yo tengo una pagina en Facebook como se ace por visualizar el numero de likes en la mi pagina? Qual es la parte del codigo que se debe modificar.
Hola Giovanni, por desgracia Facebook cambio los métodos y privilegios de acceso para consultar los datos y el código ya no funciona.
Estamos trabajando una nueva versión, en cuanto esté disponible la publicaremos.