jueves, 26 de marzo de 2015

OpenWRT Router MR-3020 Controlar por puerto serie un dispositivo (Arduino)

La intención de este post es documentar el mejor escenario para dotar a un dispositivo de interfaz serial (en mi caso un Arduino uno) de capacidad para la comunicación inalámbrica que permita ser consultado y controlado.
Hay mucha documentación en ingles, pero este escenario es el que me funcionó a mi (después de probar muchas opciones), y que permite el control por el servidor Web que trae el OpenWRT.  Además de contribuir con  material en español.

Se usa router MR3020, aprovechando su puerto serial, se le conectan pines y una resistencia de 10Kohm entre vcc y tx



Router TP-Link MR3020, y su tarjeta mostrando el puerto serie.


Resistencia de 10Kohms entre VCC t tx


Se conecta el router y el arduino por sus puertos seriales mediante los pines GND, Tx y RX... NO se conecta VCC. Así:



Se flashea el rouert con OpenWRT. Así, se tiene así la interfaz /dev/ttyATH0 a 115200 bauds, para la comunicacion.


Se colocó el siguiente script en /etc/rc.local para que inicie a ejecutarse apenas el router finalice el booteo

cat /dev/ttyATH0 2>/dev/null | while read v1; do
    echo "$v1" >> /tmp/reporte
done

con esto, cada dato que llegue se va a grabar como una nueva línea del archivo /tmp/reportes
Como esto significa que el tamaño del archivo va a aumentar muchisimo, entonces se colocó una tarea cada minuto para que desocupe el archivo. En cron se coloca:

root@OpenWrt:/www/cgi-bin# crontab -e
*/1 * * * * echo "" > /tmp/reporte

Así ya se tiene que el archivo cada minuto se desocupa.

Con el codigo de Arduino del final se hace que el microcontrolador envie datos de la lectura del puerto analógico A0 cada 100mS y también esté verificando la entrada de comunicaciones seriales para accionar o no un LED segun le llegue un 1 o 0.

Para la visualización Web se usa el servidor web de OpenWRT con la opcion cgi-bin.

en  /www/cgi-bin/ se crea un archivo llamado lectura con esto:

root@OpenWrt:/www/cgi-bin# cat /www/cgi-bin/lectura

#!/bin/sh
#!/www/cgi-bin/volts
# simple CGI to tail most recent info from an arduino
/root/hora.sh
echo "Content-type: text/html"
echo ""
echo "<html><head><meta http-equiv="refresh" content="1">"
echo "<h2>Voltmeter</h2>"
echo "<pre>
</pre>"
echo "<h4>Lectura del puerto A0</h4>"
echo "<font size=24><pre>"
head -n -1 /tmp/reporte | tail -1
echo "</pre></font><br><br>"
   echo '<form action="ledon">'
    echo '<input type="radio" name="on" value="encender" checked>ON'
    echo '<br><input type="submit" value="Submit"></form><br><br>'
   echo '<form action="ledoff">'
    echo '<input type="radio" name="on" value="encender" checked>OFF'
    echo '<br><input type="submit" value="Submit"></form>'

echo "</html>"
echo ""

---
Hay que darle permisos 775 al archivo lectura

chmod 755 /www/cgi-bin/lectura

Lo anterior levanta un sencilla pagina web. Lo especial es la linea "head -n -1 /tmp/reporte | tail -1" que lee la penúltima línea del archivo reportes mencionado anteriormente. Esto ya que siempre queda una linea en blanco al final del archivo.
Se imprime esa lectura.

Los dos formularios sirven para implementar dos botones, para encender o apagar un led. Para esto se llaman a los archivos "ledon"  y "ledoff" respectivamente, lo unico que tienen esos archivos es la orden de enviar un 1 o un 0 por puerto serial:

archivo ledon:

#!/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html><head><meta http-equiv="refresh" content="1">"
echo "<h2>LED encendido</h2>"
echo "<pre>
</pre>"
echo "<font size=24><pre>"
echo -n "1" > /dev/ttyATH0
echo "</pre></font></html>"

Mediante la linea echo -n "1" > /dev/ttyATH0  se envia un 1 por el puerto serie

archivo ledoff:

#!/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html><head><meta http-equiv="refresh" content="1">"
echo "<h2>LED apagado</h2>"
echo "<pre>
</pre>"
echo "<font size=24><pre>"
echo -n "0" > /dev/ttyATH0
echo "</pre></font></html>"

Mediante la linea echo -n "0" > /dev/ttyATH0  se envia un 0 por el puerto serie


Se accede mediante un navegador web

http://192.168.1.1/cgi-bin/lectura (o la ip del enrutador)

Esta página se actualiza cada segundo

Código Arduino Uno:

int led = 13; // Pin 13
   
void setup()
{
    pinMode(led, OUTPUT); // Set pin 13 as digital out
   
    // Start up serial connection
    Serial.begin(115200); // baud rate
    Serial.flush();
}
   
void loop()
{
    String input = "";
   
    // Read any serial input
    while (Serial.available() > 0)
    {
        input += (char) Serial.read(); // Read in one char at a time
        delay(5); // Delay for 5 ms so the next char has time to be received
    }
   
    if (input == "1")
    {
        digitalWrite(led, HIGH); // on
        Serial.print("encendido");
    }
    else if (input == "0")
    {
        digitalWrite(led, LOW); // off
        Serial.println("apagado");
    }
   
        int sensorValue = analogRead(A0);
        float voltage = sensorValue * (5.0 / 1023.0);
        Serial.println(voltage);
        delay(100);
}

Resultados:


-----

--- 




jueves, 19 de marzo de 2015

SISTEMA GNU/LINUX COMO FIREWALL




En GNU/Linux existen muchas distros listas para aplicar funcionalidades de firewalll con bonitas interfaces de usuario, es más, desde la distro de un sistema embebido (openWRT, Raspbian, etc) tiene por defecto (aunque no es obligatorio) el modulo del kernel que le permite esta funcionalidad.


Sin embargo es necesario estudiar el diagrama de flujo de los paquetes del protocolo IP y entender como se aplica en la capa 3 (OSI) los conceptos del firewall y sus  funcionalidades. PAra esto he realizado un manual con muchos ejemplos, diagramas y ejercicios para hacer una primera aproximación de fondo sobre el funcionamiento de un firewall en sistemas GNU/Linux.


Aqui: Ver Manual

miércoles, 11 de marzo de 2015

Convirtiendo una impresora USB en impresora de red gracias a un pequeño router y OpenWRT

Tengo una impresora Kiosera FS-1120D, a la que se le puede instalar una tarjeta Ethernet para tenerla como impresora de red, pero en mi caso no la trae, solamente trae interfaz USB.

Paralelamente he venido jugando con los enrutadores TP-Link MR3020 y con el grandioso firmware OpenWRT La idea es poder imprimir por red desde cualquier lado de una red IP (local o remota).

así:

+ 

=


Esto no es más que la adaptación de otra guia a el router TP-Link MR3020 y en español.

Primero hay que cambiar el firmware del MR3020. Se conecta por la IP de administración del router mediante un navegador web (no vamos a explicar como hacerlo ya que es un procedimiento estandar).
Yo he bajado la imagen para este router compilada por OpenWRT en su version Barrier Breaker que la pueden obtener aqui.

Por la opción de Firmware Upgrade del router es simplemente subir el archivo descargado y esperar unos 3 minutos.
Luego de lo anterior el router es accesible por medio de la IP 192.168.1.1

Accedemos por un navegador Web usando dicha IP, lo primero que encontrarán es que el firmware solicita que sea configurada una clave para acceso como  root. Pongan una que puedan recordar.

Adicionalmente el enrutador debe estar configurado en una dirección IP que tenga salida a internet, es decir, como un computador más. Por ejemplo mi red LAN está en el rango 192.168.30.0/24 por eso le puse una IP estática 192.168.30.101 con gateway 192.168.30.1 (el router local) y DNS de mi preferencia.

Conectar el Router MR3020 con un cable ethernet a nuestra red local, o también pueden habilitar la configuración WiFi para imprimir de forma inalámbrica.

Luego pueden acceder por SSH al router. Yo usé el software  libre PuTTY; obtendrán esta consola:

Ya desde aqui debe introducir los siguientes comandos sin obtener errores:


opkg update
opkg install kmod-usb2
opkg install usbutils

Instalar soporte de impresoras:
opkg install kmod-usb-printer

Instalar en servidor de impresoras p910nd, el cual es un pequeño demonio que no pone los trabajos en cola en el disco, sino que pasa directamente a la impresora.
opkg install p910nd

Con ello se tiene todo lo necesario, ahora a modificar los archivos de configuración.
Con el siguiente comando se debe editar el archivo. Si no sabe usar vi es necesario que busque ejemplos en la internet antes.

# vi /etc/config/p910nd

El archivo debe quedar así:

config p910nd
        option device        /dev/usb/lp0
        option port          0
        option bidirectional 1
        option enabled       1


Ahora se debe configurar el firewall del MR3020 para que acepte peticiones del puerto 9100

Con el siguiente comando se debe editar el archivo.

# vi /etc/config/firewall

Al FINAL del archivo debe agregarse:


#Allow attached network printer
config 'rule'
option 'src' 'lan'
option 'proto' 'tcp'
option 'dest_port' '9100'
option 'target' 'ACCEPT'

OK. Para finalizar se habilita el servidor de impresoras y se reinicia el router:
#/etc/init.d/p910nd enable
# reboot

Para configurar la impresora en un entorno Windows se debe hacer lo siguiente:

1. Instalar por USB la impresora en el equipo, con todos sus drivers archivos conrrespondientes. Hacer prueba de impresión por USB y que funcione todo. Luego desconectar el cable USB.









Ahora hay que ir a la configuración de la impresora que se instaló por USB y cambiar el puerto al TCP/IP recién creado.




Listo!!! Ya pueden hacer pruebas.