Vous êtes sur la page 1sur 11

Observe que los datos son pasados a un 74LS125 o similar, esto es para

ajustar los niveles lógicos de 3v a 5V. En rigor de verdad el sistema


funciona sin este adaptador sin embargo se ha visto que su implementación
mejora mucho la estabilidad.

Ejemplo de una página web embebida.


La idea es lograr programar una web como la que se aprecia en la imagen
dentro de la memoria 25LC256.

El objeto de este trabajo es controlar dos LED que se encuentran conectados


a los pines 5 y 8 del microcontrolador PIC.

Nota:
Descarge desde la web del autor el material complementario a este libro,
descomprima el archivo Ejemplo_1.zip, el proyecto está ya listo para ser
compilado y programar elmicrocontrolador, también encontrará web.b y
todas las fuentes para reformar la web. No altere el proyecto hasta estar
seguro que sabe lo que hace.

Para lograr embeber un sitio web dentro de la memoria 25LC256 y poder


accederla desde un navegador web, necesitamos seguir varios pasos,
primero la construcción de la propia pagina web que se puede realizar con
cualquier herramienta web de diseño (teniendo siempre en cuenta el espacio
con que contamos, no es lo mismo meter un sitio web en un servidor PC que
un PIC).
Nosotros para simplificar las cosas trabajaremos con una pagina ya
construida la cual modificaremos con PageBreeze Luego que tenemos
nuestra pagina creada debemos compilarla con la herramienta de Microchip
MPFS.EXE. Esta herramienta formatea nuestra pagina web y todos los
archivos vinculados a ella en un formato comprensible para el STACK y el
pequeño sistema operativo que lo hace funcionar. Es decir entonces que para
hacer funcionar todo necesitamos dos tipos de compilación, la del propio
MPLAB que genera el archivo .hex que enviamos a la FLASH del PIC con
el programador de PIC que estemos usando. Y por otro lado la compilación
con MPFS del sitio web que programaremos en la memoria SPI 25LC256.
Esta programación la haremos mediante el servidor FTP que esta dentro del
propio STACK y al cual nos conectaremos mediante una sesión clásica FTP
con cualquier cliente FTP desde el lado de la computadora.
Está claro entonces que para poder programar nuestro sitio dentro de la
memoria 25LC256 tenemos que tener ya funcionando el STACK puesto que
nos conectaremos a la memoria con el servidor FTP que esta en el propio
STACK, en otras palabras, el propio micro es quien programa la memoria
25LC256 a través de una conexión remota mediante FTP tal cual lo
haríamos en un servidor web informático. El circuito completo del lado del
PIC es como sigue.
Puede ver aquí un video de como funciona la carga de la web de manera
remota mediante FTP.
Dentro del archivo congif.h entre otras cosas usted encontrará las
siguientes configuraciones resaltadas en color rojo que son de absoluta
utilidad para el control del FTP.

/************************************************************
* Global configuration file for the Microchip TCP/IP Stack
*

*===========================================================*
#ifndef _CONFIG_H
#define _CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define VERSION "1.0" // Firmware versión
#include "include/Hardware.h"
//***********************************************************
// TCP/IP Config
//
// Define the default values for your MAC and IP
configuration.
// Notice that the IP addresses are separated by commas and
not by the
// traditional dot in the decimal dotted notation.
//
#define DEFAULT_MAC_ADDRESS { 0x00, 0x04, 0xa3, 0x00, 0x02,
0x00 }
#define DEFAULT_IP_ADDRESS { 192, 168, 1, 201 }
// IP por defecto
#define DEFAULT_NETMASK { 255, 255, 255, 0 }
#define DEFAULT_GATEWAY { 192, 168, 1, 1 }
#define DEFAULT_NS1 { 192, 168, 1, 1 }
#define DEFAULT_NETBIOS_NAME "Firtec_TCP"
// Nombre por defecto

//***********************************************************
// Stack Modules
#define STACK_USE_ICMP
#define STACK_USE_HTTP_SERVER // HTTP server
//#define STACK_USE_IP_GLEANING
#define STACK_USE_DHCP // DHCP (Necesario con un
Router)
#define STACK_USE_FTP_SERVER
//#define STACK_USE_TCP_EXAMPLE1
#define STACK_USE_ANNOUNCE // Ethernet Device Discoverer
// server/client
//#define STACK_USE_SNTP // SNTP client
#define STACK_USE_DNS // DNS client
#define STACK_USE_NBNS // NetBIOS Name Service Server
//#define STACK_USE_UDPTEST // Enable UDP Test code

//***********************************************************
// Some time related definitions
// Define Ticks per second for the tick manager
//
#define TICKS_PER_SECOND (100) // 10ms
//#define USE_TIME // Include time
routines
#define TIME_SOURCE_TICK // Time source is Timer0
Tick counter
//#define TIME_SOURCE_32KTIMER
#define TZ_OFFSET (-3) // Time Zone offset
(negative west of GMT)
#define SNTP_UPDATE_SECS (43200) // SNTP update interval
in seconds (12hrs)

//***********************************************************
// Miscellaneous Stack Options
#define ENABLE_USER_PROCESS // Esto habilita las funciones
del Usuario!!!!!
// Define Username and Password for the FTP Server

#define FTP_USERNAME "firtec"


// Usuario para el FTP
#define FTP_PASSWORD "microchip"
// Pass para el FTP
#define FTP_USER_NAME_LEN (10)
Observe también que hay una serie de definiciones, algunas de ellas
comentadas y otras no según deseemos incluirlas en la compilación.
Básicamente podemos incluir módulos, funcionalidades dependiendo si
comentamos o no la inclusión de estos módulos.

Funcionamiento Interno del Servidor Web Embebido.


El Stack TCP/IP de Microchip es extenso y complejo como lo es el propio
protocolo TCP/IP para entender como funciona vamos a tratar la interacción
entre algunas funciones de configuración que están disponibles para el
usuario, en definitiva gran parte del propio Stack es transparente al
programador, el truco está en saber que módulos necesitamos para nuestro
trabajo, y como configurar los periféricos que vamos a necesitar. Por
ejemplo hay una sección dentro del main.c donde se colocan las funciones
del usuario como por ejemplo control, medición, etc, en config.h está la
configuración de RED, claves del FTP, dir IP, etc, en hardware.h la
configuración de los pines, botónes, conversores, etc.
En esencia el Stack es un pequeño sistema operativo que se ejecutado a un
cierto ritmo en donde todas las funciones son ejecutadas en secuencia y a
este ritmo.
Dentro del main.c puede ver lo siguiente:
///////////////////////////////////////////////////////
//////////
/////////// TAREAS DEL USUARIO SE DEFINEN EN ESTA
SECCIÓN ///////
///////////////////////////////////////////////////////
//////////
#if defined(ENABLE_USER_PROCESS)
ProcessIO(); // Ejecuta las tareas del usuario.
// LAS TAREAS DEL SISTEMA IRIAN AQUI!!!!!!!!! //
// ...........
// ................
// ..................
#endif

Observe que se pregunta si están definidos los procesos de usuario y de ser


así se ejecutan las funciones que el usuario ha escrito.
Por ejemplo la función ProcessIO() contiene:
static void ProcessIO(void){
float voltaje;
ADCON0bits.GO = 1;
while (BusyADC()==1);
M0 += ReadADC(); // Lee el conversor y acumula las lecturas
if(4==conversiones++){ // Se tomaron 5 muestras?
conversiones = 0;
conversion = M0/5;
voltaje=conversion; // Prepara el dato para escalar
voltaje = (voltaje*5)/1024; // Escala la medición en 10 b
ftoa(voltaje,AN0String,2,'f');
LCDBuffer[1][4] = AN0String[0] ;
LCDBuffer[1][5] = AN0String[1] ;
LCDBuffer[1][6] = AN0String[2] ;
LCDBuffer[1][7] = AN0String[3] ;
M0=0;
LCDRefresh(); // Actualiza el LCD

}
}

Claramente podemos ver aquí que esta función es la encargada de leer el


conversor analógico y luego de tomar 5 muestras promediarlas, escalar de
acuerdo a Vref y mostrar el dato en el LCD.
El sistema operativo ejecuta regularmente esta función al ritmo del propio
sistema y de aquí surge una observación, podemos escribir las funciones que
necesitemos pero ninguna de ellas puede acaparar la atención de la CPU
porque entonces los buffer internos del ENC28J60 colapsaran y con ellos
nuestro sistema de red.
El sistema operativo del Stack es del tipo cooperativo por lo tanto los
tiempos son repartidos entre todas las funciones ya sean las creadas por el
usurario como las del propio sistema.

Dentro del archivo hardware.h podemos ver lo siguiente:

Todo lo referente al Hardware del usuario se define en este archivo.


En este punto debemos empezar a hablar de variables reales y virtuales y
saber diferenciarlas ya que si bien ambas están conectadas de manera directa
existen en espacios distintos, las virtuales existen del lado de la PC y se
conectan con las reales que existen del lado del microcontrolador, por
ejemplo cuando actuamos sobre un botón en la web, estamos actuando sobre
una variable virtual pero que se refleja en una variable real, un LED cambia
de estado!!.
Entonces debe quedar entendido que las variables virtuales se conectan con
variables reales y no con cualquiera sino específicamente con la variable
que actúa con el hardware que nos interesa.

Todo esto puede resultar bastante confuso sobre todo si pensamos que en
realidad la propia pagina que el navegador muestra sale también del
microcontrolador, en definitiva nuestro navegador solo lee lo que el servidor
web de nuestro PIC le envía.
Podemos imagina esto como un dialogo entre capas.

1) El navegador pide la pagina.


2) Se transfiere la pagina desde el PIC a la memoria del navegador
(PC).
3) Se oprime un botón web.
4) Se decodifica el botón y se actúa sobre el hardware.

¿Como se decodifican los mensajes desde la web?


Dentro del Web Server hay don funciones fundamentales para la
comunicación con nuestra pagina, HTTPExecCmd y HTTPGetVar, la
primera es la encargada de detectar cambios en nuestra pagina y transmitir
esto a nuestro micro, esta función interacciona con el hardware de acuerdo a
lo que está sucediendo en la pagina web, cambiar el estado de un pin por
ejemplo.
Su prototipo es el siguiente:
HTTPExecCmd(BYTE** argv, BYTE argc)

Donde **argv es un puntero a un arreglo bidimensional y argc es el número


de parámetros enviados.
Dentro de esta función encontramos por ejemplo:
command = argv[0][0] - '0'; // Primer elemento del primer
vector
// Desde el archivo cgi
interpreto el

switch(command)
{
case CGI_CMD_DIGOUT:
var = argv[1][0] - '0';

switch(var)
{
case Boton_LED1: // Nombre = 0x00
LED1_IO ^= 1; // Cambio estado del LED
break;

case Boton_LED2: // Nombre = 0x01


LED2_IO ^= 1; // Cambio el estado del LED
break;
}
}
}

Primero se decodifica el comando, pueden existir varios comandos


dependiendo del trabajo de nuestra aplicación. Luego que se decodifica el
comando se pasa a la acción de este comando, en el caso que estamos
viendo el comando dice que debe cambiar el estado de un pin, Ok cual pin?
Lo siguiente es decodificar el pin que se debe cambiar para encender o
apagar el correspondiente LED.

Definen el valor de retorno, es decir que cuando llegue el mensaje


Boton_LED1 llegará un Byte conteniendo el valor 0x00.

La función HTTPGetVar es la encargada de actualizar los datos en la


pagina de acuerdo al estado de nuestro hardware. Debe quedar claro que
esta función no cambia nada en el hardware solo lee su estado y lo transmite
a la web para que esta lo muestre de acuerdo a lo que se desee ver.
Su prototipo es como sigue:
WORD HTTPGetVar(BYTE var, WORD ref, BYTE* val)
Donde:
• Byte var es el identificador web %xx . (Variable virtual)
• Word ref es donde se informa si es el primer llamado y se indica
cuando es el último mediante el envío de HTTP_END_OF_VAR.
• Byte val es el byte transmitido, esta función solo transmite bytes es
por esto que es necesario indicar cuando se ha finalizado de trasmitir
datos.

Dentro de esta función encontramos por ejemplo:


.
.
.
switch(var){
case LED_1:
*val = LED1_IO ? '1':'0';
break;

case LED_2:
*val = LED2_IO ? '1':'0';
break;

return HTTP_END_OF_VAR; // Terminó!!


Web embebidas y las paginas CGI.
Las siglas CGI proceden del inglés Common Gateway Interface. Sin
profundizar demasiado en el significado del acrónimo CGI, podemos decir
que se trata de un mecanismo que permite que un servidor web invoque la
ejecución de un programa en el propio servidor, y le pase ciertos parámetros
de entrada obtenidos de una página HTML y contenidos en campos de un
formulario.
Por ejemplo:
• Recoger información en la página y enviarla al servidor: por
ejemplo, espera que el usuario oprima un boton para cambiar el
estado de un LED.
• Presentar el valor de una temperatura de forma dinámica en una
página: almacenar el dato en una base de datos y mostrarlos de
forma dinámica, en función de ciertos datos introducidos por el
visitante en un formulario.
Actualmente, el uso de los CGIs en los entornos informáticos ha decaído
con la llegada de nuevas tecnologías (como el lenguaje Java y los ASPs).
Sin embargo, para determinados propósitos con microcontroladores son
todavía el modo más simple y práctico de trabajar con webs dinámicas.

Dentro del servidor HTTP hay un pequeño módulo CGI con el propósito de
que el servidor entienda estas páginas que intercambian información en
tiempo real con el microcontrolador.
Este pequeño módulo permite tener una gran cantidad de variables que
permiten interactuar con el sistema, si bien es verdad que el
microcontrolador dispone de una pequeña cantidad de memoria RAM esta
cantidad de memoria es suficiente para nuestras aplicaciones. Este módulo
permite interactuar con el usuario mediante la función GET() contenida en
los navegadores.
No vamos a desarrollar aquí como hacer CGI´s (necesitaríamos mucho,
mucho tiempo).
Nuestro propósito es aprender a utilizar los que tenemos a nuestra
disposición.
Tomemos como ejemplo una de las paginas de ejemplo del web server. En la
imagen anterior se aprecia el aspecto de una pagina vista en el navegador y
conectada a nuestro microcontrolador.
Tenemos aquí el despliegue de información proveniente del
microcontrolador, estado de los pulsadores, estado de los LED´s y el
conversor A/D. Pero como llega esta información hasta la pantalla web?
La respuesta viene con el archivo status.cgi que es el encargado de
actualizar en nuestra web la información que viene del hardware.
Las acciones ocurrirán de la siguiente forma, cuando el usurario oprima uno
de los botones en la web, esta informará del cambio a través del archivo
index.htm, el microcontrolador cambiará el estado del pin correspondiente y
le enviará a nuestra página información para que actualice los binarios de
LED´s, esto lo hace con status.cgi.

Todo este gran intercambio de información se realiza de manera dinámica


(no es necesario actualizar la página con F5 para ver los cambios) esto
debido a la tecnología AJAK, sin embargo está claro que debe existir una
correspondencia entre las variables mostradas en la web y las que maneja
nuestro controlador.
Para entender como funciona veamos la siguiente imagen.

Vous aimerez peut-être aussi