LINKDUINO: Controlar LCD desde web embebida

.


Siguiendo cómo realizar páginas embebidas, las cuales interactuen con Arduino, veremos un ejemplo de cómo usar formularios. (Se debe leer primero el siguiente post)

Nuestro ejemplo se trata del envio de texto a un display lcd 4x20, a través de internet/local via página web embebida en el router.

Para ello, crearemos una página web que contenga un formulario, al cual se enviará la información de 4 controles de tipo INPUT a un script, que sacará dicha información por el puerto serie hacia Arduino.




El código html de dicha página es el siguiente:

form_lcd.html

<html>
<head>

</head>
<div style="text-align:left;">
<img src="/user/lcd.jpg">

</div>
<div style="color:blue;text-align:left;">
<span style="font-size:x-large;">
<p>DATOS A ENVIAR: </p>

<p> </p>
</span></div>
<form action="/user/cgi-bin/lcd.sh" method="POST">
 LCD line 1:

 <input type= "text" name= "L0" size=25 maxlength=20 ><p>
 LCD line 2:
 <input type= "text" name= "L1" size=25 maxlength=20><p>

 LCD line 3:
 <input type= "text" name= "L2" size=25 maxlength=20><p>
 LCD line 4:

 <input type= "text" name= "L3" size=25 maxlength=20><p>
 </br>
 </br>
 <INPUT type="submit" value="ENVIAR">

</form>



</body>
</html>

 




Ahora veamos que hace nuestro script:
lcd.sh

#!/bin/sh
read QUERY_STRING
n_campos=$(echo $QUERY_STRING|awk 'BEGIN {FS="&"} {print NF}')
#------------------------------------------------------------------
echo "<HTML>"

echo "<HEAD>"
echo "Datos POST: "
echo $QUERY_STRING
echo "<br/>"
echo "<br/>"
echo "Has recibido:"
echo $n_campos
echo " campos"

echo "<br/>"
echo "<br/>"
i=1
while [ $i -le $n_campos ]
do
 data=$(echo $QUERY_STRING|cut -f$i -d '&'|sed s/'+'/' '/g)

 echo $data
 echo $data|sed s/'='//g > /dev/cua/1
 echo "<br/>"
 i=`expr $i + 1`
done
# -----FIN ------
echo "<div style='color:blue;text-align:center;'>"

echo "<p><span style='font-size:50px;'>SE HAN ENVIADO LOS DATOS</span></p>"
echo "</div>"
echo "<META HTTP-EQUIV=Refresh CONTENT=3;URL=/user/form_lcd.html>"

echo "</HEAD><BODY>"
echo "</BODY></HTML>"
 


En el script, recojo los datos recibidos por método POST (variable $QUERY_STRING). Para saber cuantos campos recibo, hago un awk separando campos por el caracter delimitador '&'.
La variable $QUERY_STRING dispone los datos separados por '&' y los espacios con el carácter '+'.
La variable NF es interna de awk, y son el número de campos de entradas (en nuestro caso, se ha especificado que el separador de campos es '&').
Con la ayuda de cut y sed, se ha modificado la cadena recibida para obtener formato deseado.

Un buen tutorial  acerca "Linux Shell Scripting" :

Recordad que dicho script tiene que tener permisos de ejecución (chmod +x lcd.sh)

Ahora nos toca el código de Arduino:

// Linkduino: LCD controlado por serie
// By Igor Real
// 03-Enero-2010
// http://real2electronics.blogspot.com/


#include <LiquidCrystal.h>


LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int byte_received;

void setup() {

  lcd.begin(20, 4);
  delay(100);
  Serial.begin(9600);
  Serial.println("Empezamos...");



}

void loop() {

  while (Serial.available()>0){
    byte_received=Serial.read();

    if (byte_received=='L'){

      Serial.println("Dentro de l");
      byte_received=Serial.read();
      switch (byte_received){
        case '0':
        {
          byte cont1=0;
          byte data[20];
          while (Serial.available()>0){

            byte_received=Serial.read();  
            if ( (byte_received>31) &&(byte_received<127) ){
              data[cont1]=byte_received;
              cont1=cont1+1;
              delay(1);
              if (cont1==20)  break;
            }

          }  
          lcd.setCursor(0,0);
          for (int i=0;i<cont1;i++)    lcd.print(data[i]);
          for (int i=cont1;i<20;i++)   lcd.print(" ");
          break;
        }        
        case '1':

        {
          byte cont1=0;
          byte data[20];
          while (Serial.available()>0){
            byte_received=Serial.read();      
            if ( (byte_received>31) &&(byte_received<127) ){

              data[cont1]=byte_received;
              cont1=cont1+1;
              delay(1);
              if (cont1==20)  break;
            }
          }  
          lcd.setCursor(0,1);
          for (int i=0;i<cont1;i++)    lcd.print(data[i]);
          for (int i=cont1;i<20;i++)   lcd.print(" ");
          break;
        }      
        case '2':

        {
          byte cont1=0;
          byte data[20];
          while (Serial.available()>0){
            byte_received=Serial.read();      
            if ( (byte_received>31) &&(byte_received<127) ){

              data[cont1]=byte_received;
              cont1=cont1+1;
              delay(1);
              if (cont1==20)  break;
            }
          }  
          lcd.setCursor(0,2);
          for (int i=0;i<cont1;i++)    lcd.print(data[i]);
          for (int i=cont1;i<20;i++)   lcd.print(" ");
          break;
        }

        case '3':
        {
          byte cont1=0;
          byte data[20];
          while (Serial.available()>0){
            byte_received=Serial.read();      
            if ( (byte_received>31) &&(byte_received<127) ){

              data[cont1]=byte_received;
              cont1=cont1+1;
              delay(1);
              if (cont1==20)  break;
            }
          }  
          lcd.setCursor(0,3);
          for (int i=0;i<cont1;i++)    lcd.print(data[i]);
          for (int i=cont1;i<20;i++)   lcd.print(" ");
          break;
        }            
      }

    }
  }
}


 



El programa es sencillo,utiliza la libreria LiquidCrsytal para el control del lcd basado en HD44780 y se debe recibir las siguientes "tramas" para escribir en cada línea:
L0lo_que_quiero_escribir_en_la_primera_linea
L1lo_que_quiero_escribir_en_la_segunda_linea
L2lo_que_quiero_escribir_en_la_tercera_linea
L3lo_que_quiero_escribir_en_la_cuarta_linea

El conexionado de mi LCD (comprado en Sure Electronics por ebay) ha sido:
  • pin 1 Vss     => Unido a masa
  • pin 2 Vdd    => Unido a +5 voltios
  • pin 3 Vo      => Poti de 10 Kohm (los otros dos extremos del poti a +5V y GND respectivamente)
  • pin 4 RS      => Unido a pin 8 Arduino
  • pin 5 R/W   => Unido a masa (no uso la opción de crear carácter)
  • pin 6  E       => Unido a pin 9 Arduino
  • pin 7   DB0 => No conectado (control 4 bits)
  • pin 8   DB1 => No conectado (control 4 bits)
  • pin 9   DB2 => No conectado (control 4 bits)
  • pin 10 DB3 => No conectado (control 4 bits) 
  • pin 11 DB4 => Unido a pin 10 Arduino
  • pin 12 DB5 => Unido a pin 11 Arduino
  • pin 13 DB6 => Unido a pin 12 Arduino
  • pin 14 DB7 => Unido a pin 13 Arduino
  • pin 15 A      => Unido +5V a través de R=120 ohm
  • pin 16 K      => Unido GND




Lo mejor es ver un video de funcionamiento:









Con este ejemplo, se ha visto cómo funcionan los formularios y cómo tratar los datos recibidos mediante POST al script para su posterior tratamiento. En html, los formularios disponen de diversos tipos de controles: text, radio, textarea, select , ...  En este ejemplo, para no introducir demasiados conceptos, se han usado los controles de tipo texto, pero el funcionamiento es similar para el resto.
Gracias al programa de Arduino, ahora es sencillo pasar al display información de Twitter, páginas web,...








 












  

2 comentarios:

  1. Buenas noches Amigo
    Tengo una duda sobre tu proyecto. yo he utilizado el modulo ethernet pero nunca he logrado trabajarlo por fuera de una red local, tu sabes como hacerlo ?????

    ResponderEliminar
    Respuestas
    1. Yo tenia el mismo problema hasta que me di a la tarea de investigar y encontré la solución, es simple, solo tienes que abrir los puertos de tu Router (Yo uso Telmex)

      Eliminar