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:


-----

--- 




No hay comentarios:

Publicar un comentario en la entrada