Ejemplo rápido y simple de AJAX con PHP y PrototypeJS

Introducción.

Intentando recuperar mis neuronas que saben de Prototype para continuar por fin con uno de los proyectos que se encontraba en pausa permanente, el día de hoy me día a la breve tarea de recordar un poco la invocación asíncrona y la manipulación del DOM utilizando esta librería.  Para hacer una pequeña práctica decidí modificar el ejemplo de la calculadora que se basaba en jQuery y PHP para migrar su código de acuerdo con la especificación de Prototype.

Las modificaciones necesarias se centraron en la inclusión de la librería javascript en la página web (frontend) y en reescribir la invocación asíncrona de la aplicación web en PHP (backend).

Procedimiento.

Reemplazar la inclusión de la librería de jQuery por la de Prototype.  Para este caso se continúo utilizando el API de Google AJAX.

<script src="http://www.google.com/jsapi"></script>
<script>google.load("prototype", "1.6");</script>

Posteriormente se asoció el manejo del evento de presión del botón igual a la invocación de la función procesar, esto se realiza tan pronto como la estructura de la página (código HTML) se encuentra cargada completamente por el navegador.

/* Código a ejecutarse tan pronto como la
   página ha sido cargada por el navegador */

document.observe('dom:loaded', function()
{
    /* Asociar el evento de clic del botón 'igual'
       con la lógica del negocio de la aplicación */

    Event.observe('igual', 'click', procesar);
});

Finalmente se implementa la función procesar que realizará la invocación asíncrona del cálculo matemático.  Esta función consta de las siguientes partes.

  1. Información básica del requerimiento.
  2. Que hacer en caso de éxito.
  3. Que hacer en caso de fracaso.

El requerimiento incluye la siguiente información básica de conexión.

  • El URL de la aplicación remota a invocar (backend).
  • El método HTTP a utilizar.
  • Los parámetros de la página web a enviarse.
function procesar()
{
    new Ajax.Request('calcular.php',                                         /* URL a invocar asíncronamente */
    {
        method:       'post',                                                /* Método utilizado para el requerimiento */
        parameters:   $('formulario').serialize(true),                       /* Información local a enviarse con el requerimiento */

En caso de que la invocación asíncrona tenga un resultado exitoso se deberán realizar los siguientes pasos.

  • Mostrar un mensaje de éxito en color verde.
  • Desplegar el valor del resultado obtenido en el campo definido para tal fin.
        /* Que hacer en caso de ser exitoso el requerimiento */

        onSuccess: function(transport)
        {
            /* Cambiar el color del texto a verde */

            $('mensaje').setStyle('color: #0ab53a');

            /* Mostrar un mensaje informando el éxito sucedido */

            $('mensaje').update("Operación realizada exitosamente");

            /* Mostrar el resultado obtenido del cálculo solicitado */

            $('resultado').update(transport.responseText);
        },

En caso de que fracase el proceso de invocación asíncrona se deberán realizar los siguientes pasos análogos.

  • Mostrar el mensaje de error proveniente del servidor, en color rojo.
  • Limpiar cualquier resultado previo para evitar confusiones con la operación.
        /* Que hacer en caso de que sea fallido el requerimiento */

        onFailure: function(transport)
        {
            /* Cambiar el color del texto a rojo */

            $('mensaje').setStyle('color: #ff0e0e');

            /* Mostrar el mensaje de error */

            $('mensaje').update('Error: ' + transport.responseText);

            /* Limpiar cualquier resultado anterior */

            $('resultado').update('Error');
        }
    });
}

Enlaces.

Comunicación de la tarjeta Arduino con el computador

Introducción.

La tarjeta Arduino incluye un puerto serial que puede accederse a través de los pines digitales 0 (RX) y 1 (TX) o desde el computador a través del puerto USB.  Esto se realiza a través del objeto Serial con el que es posible realizar las siguientes acciones.

Descripción general de las funciones de E/S.

Establecer tasa de transmisión de datos.

void Serial.begin(int velocidad);
  • Debe realizarse como paso previo a la emisión/recepción de información a través del puerto serial.
  • La tasa puede ser una de las estándar: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 y 115200, o cualquiera personalizada.
  • La velocidad utilizada para realizar la conexión con el computador es de 9600.

Verificar bytes pendientes por lectura.

int Serial.available();
  • Como su nombre lo indica, la transmisión de información a través del puerto serial se realiza de manera serial, es decir un byte a la vez.
  • Este método permite verificar si hay bytes pendientes de lectura retornando el número de bytes disponibles en el buffer del puerto serial.
  • El buffer del puerto serial puede retener hasta 128 bytes.
  • Retorna 0 si no hay bytes pendientes de lectura en el puerto.

Leer información.

int Serial.read();
  • Obtiene el siguiente byte disponible en el buffer del puerto serial.
  • Retorna -1 si no hay información disponible.

Limpiar el buffer de entrada.

void Serial.flush();
  • Limpia el buffer de entrada del puerto serial, descartando cualquier contenido que se encuentre allí.

Enviar información.

void Serial.print(datos);
void Serial.print(datos, tipo);
void Serial.println(datos);
void Serial.println(datos, tipo);
  • Envían la información (datos) en el formato especificado (tipo) a través del puerto serial.
  • El formato (tipo) puede ser uno de los siguientes.
    • DEC: representación en cadena de un número decimal (79).
    • HEX: representación en cadena de un número hexadecimal (4F).
    • OCT: representación en cadena de un número octal (117).
    • BIN: representación en cadena de un número binario (1001111).
    • BYTE: un único byte.
  • Si no se especifica un formato (tipo), se utiliza por defecto a DEC.
  • La diferencia entre print y println es que el segundo agrega un retorno de carro (ASCII 13 o ‘r‘) y un salto de línea (ASCII 10 o ‘n‘) al final de de la información enviada.

Enviar información binaria.

void Serial.write(datos);
void Serial.write(buffer, longitud);
  • Envía información binaria: un byte o una secuencia de bytes, al puerto serial.
  • Los datos a enviarse pueden ser un número o una cadena.
  • Si se desea enviar un arreglo (buffer) es necesario especificar su longitud.

Depurando la transmisión de datos.

Es posible revisar fácilmente con el IDE de Arduino lo que la tarjeta está transmitiendo al computador a través del puerto USB mediante el Monitor Serial.  Esto es muy útil también para la depuración rápida de los sketches.

Para activar el Monitor Serial se debe presionar el ícono serial_monitor y utilizar las funciones de envío de información mencionadas anteriormente, de esta manera aparecerá en la sección inferior del IDE una consola donde se podrán apreciar los mensajes enviados por la Arduino.

void Serial.print(datos, tipo);

El cuarto sketch: The LED with fotoresistor

Sketch 'The LED with fotoresistor'.
Sketch 'The LED with fotoresistor'.

Descripción.

Este sketch utiliza una fotoresistencia como sensor, es decir, la cantidad de luz recibida por el componente determina la cantidad de voltaje que es permitido pasar a través de él.  Como actuador se utiliza el mismo LED de siempre que nos mostrará de manera visual cuanto voltaje atravieza por el sistema.

A mayor cantidad de luz percibida el LED tendrá un mayor brillo.

Implementación.

Hardware.

En términos de la implementación del hardware suceden dos cosas interesantes.

  1. Como ya se había hecho en el sketch anterior, The LED with button and fade, para provocar el efecto de intensidad de luz del LED es necesario conectarlo a uno de los pines con soporte para modulación por ancho de pulsos (PWM), es decir, a los pines 9, 10 y 11, y enviarle la inforamción correspondiente con la instrucción analogWrite.
  2. La foto resistencia, a diferencia del botón que tiene sólo dos estados: presionado o no presionado, es capaz de producir un rango de valores según la cantidad de luz que recibe en un momento específico del tiempo.  Para leer su información es necesario utilizar las entradas (pines) análogos ubicados en la parte inferior derecha de la tarjeta Arduino y leer su información con la instrucción analogRead.

Software.

En términos de software el sketch es muy sencillo, sólo debe realizar los siguientes pasos.

  1. Leer estado del sensor.
  2. Modificar la intensidad del LED de acuerdo a lo leído del sensor.
  3. Esperar un momento para reinciar la iteración.

Es muy importante tener en cuenta que la instrucción analogRead retornará un número entre 0 y 1023 mientras que la instrucción analogWrite espera un valor numérico como parámetro entre 0 y 255, por esto será necesario dividir entre 4 el valor de la lectura hacia la escritura si se va a utilizar directamente.

#define SENSOR 0                    // Analog pin for the fotoresistor
#define LED    9                    // Digital pin (PWM) for the LED

void setup()
{
  pinMode(LED, OUTPUT);            // LED pin is output

  // Analog pins are always INPUT.
}

void loop()
{
  int fr = analogRead(SENSOR);      // Read the status of the fotoresistor

  analogWrite(LED, fr/4);           // Change the brightness of the LED
                                    // acording the fotoresistor's value
  delay(10);                        // Wait a moment fot next iteration
}

El tercer sketch: The LED with button and fade

Sketch 'The LED with button and fade'
Sketch 'The LED with button and fade'

Descripción.

Este sketch es la continuación del anterior, The LED with button and state, agregándole el efecto de desvanecimiento mientras se modifica la intensidad del LED.

Si se mantiene presionado el botón (mas de 500 ms.) la intensidad del LED aumenta hasta llegar a su máximo, momento en el cual se apaga por completo y vuelve a iniciar el proceso.  Si se presiona el botón por un momento corto (menos de 500 ms.) la luz del LED se desvanece hasta llegar a cero brillo.

El proceso aparente de desvanecimiento se logra con la combinación de pulsos cada vez mas largos (o mas cortos) que se traducen longitudes de tiempo en que el LED permanece encendido, esto unido al efecto de persistencia del ojo humano (lentitud en el refrescamiento de la imagen de la retina).

Implementación.

Hardware.

Para hacer esto se utilizan los pines digitales 9, 10 u 11 que soportan Modulación por ancho de pulsos (PWM) y permiten manipular la longitud de los pulsos, por esto se movió el LED del pin 13 que había sido habitual hasta ahora, al 9.  Probablemente habría sido precavido agregar una resistencia entre el LED y la tierra (cable azul).

La magia del desvanecimiento se observa en el software.

Software.

En términos generales el sketch realiza lo siguiente.

  • Si se presionó el botón:
    • Cambia el estado a encendido (HIGH).
    • Almacena el momento en que fue presionado.
  • Si se presionó el botón y se mantiene presionado (mas de 500 ms.):
    • Aumenta el brillo.
    • Reinicia el brillo (0) si este excede el máximo (255).
  • Si se presionó el botón corto tiempo (menos de 500 ms.):
    • Cambia el estado a apagado (LOW).
  • Almacena el estado actual del botón como último estado para la siguiente iteración.
  • Si el estado es encendido aumenta el brillo con la instrucción: analogWrite(LED, brightness).
  • Si el estado es apagado disminuye gradualmente el brillo del LED hasta llegar a cero.

Se debe tener siempre en cuenta que la función analogRead retorna un entero entre 0 y 1023 mientras que analogWrite recibe un entero entre 0 y 255, un cuarto del rango del valor retornado por la lectura.

#define LED 9              // Digital PIN for the LED
#define BUTTON 7           // Digital PIN for the Button

int brightness          = 0;      // Amount of light of LED
int lastValue           = LOW;    // Last button status
int state               = LOW;    // Current button status
unsigned long startTime = 0;      // Time of last button pressed

/**
 * Executes only once when the sketch starts, sets initial values
 */

void setup ()
{
  pinMode(LED, OUTPUT);      // LED pin is output
  pinMode(BUTTON, INPUT);    // Button pin is input
}

/**
 * Executes continuously and infinitely
 */

void loop()
{
  int button = digitalRead(BUTTON);         // Reads the button status

  if(button == HIGH && lastValue == LOW)    // The button is pressed
  {
    state = HIGH;                           // The state is ON now

    startTime = millis();                   // Gets the current time

    delay(10);                              // Waits 10 ms.
  }

  if(button == HIGH && lastValue == HIGH)   // The button keeps beign pressed
  {
    if(millis() - startTime >= 500)         // Checks if the button is pressed by
    {                                       // more than 500 ms.
      brightness ++;                        // Amounts the brightness of the LED
      delay(15);                            // Waits for 15 ms.

      if(brightness > 255)                  // If the brightness exceeds 255
        brightness = 0;                     // backs to 0, its a byte
    }
  }

  if(button == LOW && lastValue == HIGH)    // The button is released
  {
    if(millis() - startTime < 500)          // and was pressed less than 500 ms.
      state = LOW;                          // The state is OFF now
  }

  lastValue = button;                       // Sets the current button status as
                                            // last value for the next iteration

  if(state == HIGH)                         // If the state is ON ...
    analogWrite(LED, brightness);           // Make the LED shine with its new brightness
  else                                      // Else, because its OFF ...
    fadeOut();                              // Turn it off gracefully
}

/**
 * Turns off the LED by reducing its brightness until total darkness
 */

void fadeOut()
{
  for(int i=brightness; i>=0; i--)          // Begins with the current level of brightness
  {                                         // decreasing by units until complete off
    analogWrite(LED, i);                    // Sends the reduced brightness to the LED
    delay(10);                              // Waits for 10 ms.
  }

  brightness = 0;                           // Resets the brightness reference to zero
}

Modificación del segundo sketch: The LED with button and state

Descripción.

Este sketch se encuentra completamente basado en el anterior al cual se le modifica su funcionalidad permitiendo manipular un estado para el LED, es decir, cuando se presiona el botón el LED se enciende, aún sin necesidad de que el usuario final continúe presionandolo; este comportamiento se mantendrá hasta que el usuario presione nuevamente el botón para apagar el LED.

Ya que los cambios introducidos desde el sketch anterior corresponden a su funcionalidad, el hardware permanece sin variaciones y estas son introducidas en el software.

Implementación.

Software.

#define LED 13              // Digital PIN for the LED
#define BUTTON 7            // Digital PIN for the Button

int state = 0;              // The current state of the LED
int lastState = 0;          // The past state of the button

void setup ()
{
  pinMode(LED, OUTPUT);      // LED pin is output: turn it on/off
  pinMode(BUTTON, INPUT);    // Button pin is input: read it
}

void loop()
{
  int currentState = digitalRead(BUTTON);

  // Consider a button's change of state only when is pressed
  if (lastState == LOW && currentState == HIGH)
  {
    state = !state;

    delay(10);
  }

  lastState = currentState;

  digitalWrite(LED, state);
}

El segundo sketch: The LED with button

Sketch 'The LED with a button'
Sketch 'The LED with a button'

Descripción.

Este sketch incluye el uso de un sensor (botón de pulsación) y un actuador (LED) nos permite manipular el ambiente de acuerdo a lo percibido.

La tarjeta Arduino es capaz de notar que ha sido presionado el botón (debajo del dedo en la imagen) y esta responde encendiendo el LED.  De manera antagónica, cuando el botón es liberado, la tarjeta Arduino apaga el LED.

Implementación.

Hardware.

  • En el pin digital 13 se inserta nuevamente el LED.
  • El botón se inserta en la protoboard.
  • Una de las patas del botón va a Power-5v.
  • La otra pata va al pin 7 (entrada – lectura de datos).
  • Una resistencia une la segunda pata del botón con la tierra.

Software.

#define LED 13              // Digital PIN for the LED
#define BUTTON 7            // Digital PIN for the Button

void setup ()
{
  pinMode(LED, OUTPUT);      // LED pin is output: turn it on/off
  pinMode(BUTTON, INPUT);    // Button pin is input: read it
}

void loop()
{
  if (digitalRead(BUTTON) == HIGH)    // Button is pressed
    digitalWrite(LED, HIGH);          // Turn the LED on
  else                                // Button is NOT pressed
    digitalWrite(LED, LOW);           // Turn the LED off
}

Mi primer sketch con Arduino: The blinking LED

The blinking LED
The blinking LED

Descripción.

Este es tal vez el programa mas sencillo que se puede hacer con Arduino, lo utilizo para verificar el éxito del proceso de instalación recién realizado.

Este sketch enciende y apaga un led con la frecuencia proporcional a los tiempos de retardo que se especifiquen.  Estos son los pasos que realiza el algoritmo.

  1. Define al pin digital 13 como la constante LED.
  2. Convierte al pin LED como salida (escribir información).
  3. Realiza infinitamente la siguiente subrutina.
    1. Enciende el LED.
    2. Espera un segundo.
    3. Apaga el LED.
    4. Espera dos tercios de segundo.

Implementación.

Hardware.

  • Tome un LED e inserte su pata positiva (mas larga) en el pin digital número 13 y su pata negativa (mas corta) en el pin digital de tierra (GND) ubicado al lado izquierdo del pin 13.

Este paso es opcional, si no se utiliza un LED “externo”, el software utilizará el LED que incluye la tarjeta Arduino para propósitos de experimentación.

Software.

#define LED 13              // The LED is on 13th digital pin

void setup()
{
  pinMode(LED, OUTPUT);    // The LED digital pin is an output
}

void loop()
{
  digitalWrite(LED, HIGH);  // Turns the LED on
  delay(1000);              // Waits for a second

  digitalWrite(LED, LOW);   // Turns the LED off
  delay(666);               // Waits for 2/3 of second
}

Despliegue.

  1. Digite el código anterior en el IDE de Arduino.
  2. Presione save para almacenar el código.  Este paso es importante, de lo contrario recibirá mensajes de error del siguiente estilo.Couldn’t determine program size: NullPointerException
  3. Presione play para verificar el código y de ser posible, si no hay errores, compilarlo.
  4. Presione export para enviar el software binario al microcontrolador de la tarjeta Arduino.
  5. Observe la tarjeta Arduino, el LED deberá estar titilando según las instrucciones del código.

Instalación de la plataforma Arduino 0016 en Linux Ubuntu 9.04

Procedimiento.

Instalar Java.

$ sudo aptitude install sun-java6-jre

$ sudo update-alternatives –config java

Instalar otras dependencias requeridas.

$ sudo aptitude install gcc-avr avr-libc

Descargar la última versión de Arduino disponible en http://arduino.cc/en/Main/Software.

$ cd ~/ & mkdir Arduino & cd Arduino

$ wget http://arduino.googlecode.com/files/arduino-0016-linux.tgz

$ tar zxvf arduino-0016-linux.tgz

Conectar la tarjeta al computador a través del cable USB.

$ cd arduino-0016/

$ ./arduino

Seleccionar el puerto serial (emulado) en el cual se encuentra la tarjeta.

Elija el menú Tools > Serial Port.

Seleccione el puerto USB disponible, probablemente sea /dev/ttyUSB0.

Enlaces.

Una primera mirada a Arduino

Introducción.

  • Es una plataforma de hardware y software de código abierto.
  • Por este motivo, es posible obtener los planos del circuito, adquirir los componentes y ensamblar las tarjetas sin pagar ningún tipo de licenciamiento o de regalías.  De igual manera, también es posible adquirir la tarjeta ya ensamblada.
  • Su costo es bajo con respecto a soluciones análogas.
  • Fue diseñada pensando en los artistas, diseñadores, entusiastas y en cualquiera interesado en crear objetos y ambientes interactivos.
  • Su principal virtud es la de permitir crear prototipos de manera rápida y flexible, evitando la necesidad de desarrollar todo desde cero.
  • Permite percibir el ambiente mediante gran cantidad de sensores e interactuar con él mediante la manipulación de distintos actuadores.
  • El microcontrolador se programa en el lenguaje de Arduino el cual se basa en Wiring y que a su vez es similar en su sintáxis al lenguaje C.
  • Los proyectos desarrollados con esta plataforma pueden actuar de manera independiente o hacerlo directamente con el software en un computador.
  • Su ambiente de desarrollo es multiplataforma, se ejecuta en Windows, Macintosh OS X y Linux.
  • Su conexión se realiza vía USB en lugar de Serial.
  • Su comunidad de usuarios es muy activa y la liberación de mejoras es frecuente.

La plataforma.

  • Se encuentra formada por dos partes fundamentales.
    • El hardware: la tarjeta Arduino.
    • El software: el Arduino IDE (Integrated Development Enviroment).
  • Al ser una solución de alto nivel que combina el hardware con el software permite la modificación ágil y flexible de los prototipos elaborados.

El hardware.

  • La tarjeta Arduino se basa en el microcontrolador ATmega168.
  • Su conexión con el computador es a través del puerto USB.
  • Existen varias versiones de la tarjeta.
  • Cuenta con pines análogos y digitales de entrada y de salida.
  • Su alimentación se puede proveer a tarvés del puerto USB, de cargadores USB y de adaptadores AC de 9v.

El software.

  • Permite el desarrollo de los sketch (programas).
    • Escritura.
    • Verificación (verify).
    • Conversión a lenguaje C.
    • Compilación.
    • Carga en la tarjeta (upload).

Enlaces.

Desempacando mi primer Arduino

Por fin este fin de semana tuve tiempo de desempacar mi primer Arduino.  Esta es, según su propio sitio web, una plataforma opensource para la elaboración de prototipos basados en hardware y software flexible y fácil de utilizar, desarrollado para artistas, diseñadores, entusiastas y cualquiera interesado en crear objetos o ambientes interactivos.

En palabras [muy] informales, una tarjetica que sirve para hacer proyectos interactivos basados en software y hardware, muy interesante sobre todo para ingenieros que ya se nos olvidó la electrónica y que preferimos el desarrollo de software a la manipulación del hardware de bajo nivel.  Todo un mundo por descubrir.

Freeduino v1.20
Freeduino v1.20

El kit incluye los siguientes elementos.

Este paquete y otro hardware similar (Freeduino, iDuino, LilyPads, etc.) se pueden adquirir facilmente en Colombia a través de la Tienda de Marlonj que tiene estos productos para la venta o el alquiler a precios bastante econónicos.

Enlaces.