lunes, 5 de mayo de 2014

Menu horizontal solo con CSS

Una de las cosas que mas a menudo agrego a un sitio son los menús, estos son simples fáciles de implementar y ayudan a conservar mucho espacio en las paginas.

Este tutorial asume que ya se tiene conocimientos de CSS por lo cual no dará grandes explicaciones del código.

Bueno, básicamente nuestro menú se debe de ver de la siguiente manera cuando este finalizado.



De tal modo que cuando el ratón pase por el menú principal este despliegue un sub-menú, todo usando solamente CSS.

En la siguiente imagen se puede ver como es la estructura del menú cuando no se le ha aplicado el CSS que es lo que le da formato.


Junto con el HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Simple menu</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="CSS/menu.css" rel="stylesheet" type="text/javascript">
    </head>
    <body>
        <div>
            <ul class="menu">
                <li><a href="#">Menu 1</a></li>
                <li><a href="#">Menu 2</a></li>
                <li><a href="#">Menu 3</a>
                    <ul>
                        <li><a href="#">Sub Menu 1</a></li>
                        <li><a href="#">Sub Menu 2</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </body>
</html>


Como se puede observar es muy sencillo y fácil, no tiene mayor complicación.

Ahora el CSS:

html, body{
    margin: 0;
    padding: 0;
}
div{
    padding: 50px;
}
ul{
    list-style: none;
    margin: 0;
    padding: 0;
}
a{
    color: #FFF;
}
ul.menu{
    position: relative;
}
ul.menu > li{
    float: left;
    position: relative;
    padding: 5px;
    background: #09F;
}
ul.menu > li:hover{
    background: #396eb6;
}
ul.menu > li:hover > ul{
    display: block;
}
ul.menu > li > ul{
    position: absolute;
    display: none;
}
ul.menu > li > ul > li{
    white-space: nowrap;
    padding: 5px;
    background: #0000ff;
}
ul.menu > li > ul > li:hover{
    background: #396eb6;
}


Para este código se esta usando ul.menu como la clase que le dará formato a todo el menú, es de fácil implementación y puede ser adaptado de forma muy fácil pueden agregarle border, colores especificos y mas.

Bueno pues copy paste y adaptenlo a sus necesidades.

lunes, 17 de febrero de 2014

Reloj usando PMW e Interrupts en Arduino

Reloj con Arduino

Creo que uno de los proyectos más comunes con Arduino es crear un reloj el cual sea muy exacto.

Pero siempre necesitas piezas externas para poder lograr este propósito ya que de lo contrario el reloj no será lo suficientemente exacto y perdería varios segundos de forma diaria o posiblemente mas lo cual no es de beneficio para nuestro proyecto.

Hay varios componentes externos que nos permiten tener un RTC (Real time clock) como por ejemplo el Adafruit DS1307, este componente es un reloj externo con batería de respaldo lo cual le permite mantener la hora en todo momento, el problema es si no tenemos uno disponible o queremos ahorrarnos el dinero del componente (exactamente $9.00 USD es el precio de este pequeño componente).

Esta entrada intentara dar una solución, a este problema aun cuando nos queda el problema del respaldo por batería ya que siempre que se reprograme o bien cuando la tarjeta Arduino pierda energía la configuración del reloj se reiniciara y por lo tanto el reloj se reiniciara en ceros, pero esto es tema de otra entrada.

Lista de materiales

Los componentes que se necesitan son los siguientes:
  1. Tarjeta Arduino - En mi caso casi siempre uso el modelo MEGA2560
  2. 3 botones pushup
  3. Pantalla LCD HD44780 o similar.
  4. Placa de pruebas - Breadboard.
  5. Cables de conexión

Armado

Ahora bien, que si no queremos gastar esos $9.00 USD y nos gustan los soluciones alternativas siempre se puede comprar un DS1307 por $3.00 USD en las paginas "wholesale" de China, y con esto tenemos la solución a la perdida de energía en nuestra placa.

Ahora que si nos gusta indagar y aprender como funcionan las cosas, la solución propuesta es el camino a tomar, ya que usaremos uno de los elementos que ya existen en la propia placa de Arduino como son los Interrupts, en este momento les recomiendo una lectura ligera de lo que son los interrupts y para que sirven.

Específicamente en la Mega2560 tenemos los siguiente: External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2), esto quiere decir que tenemos 6 pines los cuales nos van a servir para este proposito, en el formato, pin (interrupt #).

Para fines de este pequeño proyecto usaremos el interrupt 4, que es el pin 19. Aqui el comando:

attachInterrupt(4, increment, RISING);

Con esto le estamos indicando que active la interrupción en el pin especificado.

analogWrite(8, 127);

Esta linea estamos usando el PWM en el pin 8 para usarlo como señal es en este momento donde tenemos que conectar directamente el pin 8 con el 19, en nuestra Mega2560.

Le indicamos al PWM que envíe una señal al interrupt 4, el ciclo de trabajo es de 255 por lo que solo estamos trabajando con medio ciclo 127, esto quiere decir que 489 serán contabilizados con un segundo completo. Lectura recomendada.

Cuando declaramos attachInterrupt asignamos una referencia a la función "increment" para que esta fuera realizada cada vez que se activa la interrupción, en nuestro código tenemos la función:

void increment() {
  x++;
  if(x == 489)  { // Contamos 489 que son 1 segundo
    x = 0;
    digitalWrite(ledPin, HIGH);
    seconds++;
    calcTime();

    lcd.clear();
    lcd.print(getsize(hours)+ ":" + getsize(minutes) + ":" + getsize(seconds));
  }
}


Y nuestra función calcTime():

void calcTime() //Simples cálculos de tiempo
{
  if(seconds == 60) {
    seconds = 0;
    minutes++;
  }

  if(minutes == 60) {
    minutes = 0;
    hours++;
  }

  if(hours == 24) {
    hours = 0;
  }
}


Así es como podemos crear un reloj sencillo pero muy preciso usando solamente la tarjeta Arduino sin necesidad de tener componente externo alguno, claro que tiene sus desventajas, pero siempre es entretenido conocer el funcionamiento de las cosas.

Les dejo la liga a github con el código completo para este ejemplo.

Preguntas, dudas, mejoras? Dejen su comentario.

viernes, 11 de octubre de 2013

Como conectar un display LCD 16 x 2 a tu Arduino compatible con Hitachi HD44780

Display LCD 16x2 para tu Arduino

Una de las cosas mas basicas es conectar un display o pantalla LCD de 16 x 2, 16 caracteres y 2 lineas.
El más común de estos es el que tiene el chip compatible con el modelo HD44780 de Hitachi que es lo que mas se utiliza hoy en día.

En esta entrada tambien veremos como controlar la luz de fondo (backlight) con PWM (pulse-width modulation o modulación por ancho de pulsos) que es una de las capacidades de las tarjetas Arduino.

Si no están familiarizados con PWM lean esta entrada en Wikipedia, sera de utilidad. Y revisen la documentación de su placa Arduino.

Lista de Materiales

  1. Tarjeta Arduino - En mi caso Mega2560
  2. LCD 16x2 Hitachi HD44780 compatible
  3. 2 botones pushup
  4. 1 potenciometro 10k 
  5. 2 resistencias 10k

 Las Conexiones

En la imagen se muestra el como conectar la tarjeta Arduino con el display LCD 16x2, en este caso se necesitan seis pines para el LCD ya que estamos conectando el LCD en 4bits lo cual nos ayuda a mantener pines libres para otros usos.

Ahora bien, conectando la luz de fondo directamente a Arduino nos da la oportunidad desde la interfaz programable de controlar su comportamiento sin la necesidad de agregar componentes externos. Pero con la desventaja de ocupar un pin mas.

Explicando el código

#include LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
const int buttonPinDown = 24; // the number of the pushbutton pin
const int buttonPinUp = 25;

const int ledPin = 13; // número del pin para el LED
const int ScreenPin = 8; // Pin para pantalla, en este caso la luz de fondo

int buttonStateUp = 0; // variable para leer el botón UP
int buttonStateDown = 0; // variable para leer el botón DOWN

int contador = 0, backLight = 0, porcentaje = 0, funcion = 0;//Contadores

boolean func = false;
boolean screenon = true;

void setup() {
lcd.begin(16, 2);//Inicializamos la pantalla LCD

pinMode(ledPin, OUTPUT); //Inicializamos el pin del Led
pinMode(buttonPinUp, INPUT); //Inicializamos el pin para el botón UP
pinMode(buttonPinDown, INPUT); //Inicializamos el pin para el botón Down
InitBacklight();//Inicializamos las funciones para imprimir en pantalla
}

void loop() {

Backlight(); //Siempre se esta ejecutando a la espera de comandos
}

void InitBacklight()
{
backLight = 128;
porcentaje = (backLight * 100) / 255;

analogWrite(ScreenPin, backLight);
// Print a message to the LCD.
lcd.print("Welcome! Backlight dim test.");
lcd.setCursor(0,1);
lcd.print("BL: " + String(porcentaje) + "% - " + String(backLight));
delay(2000);
}

void Backlight()
{
buttonStateUp = digitalRead(buttonPinUp);//Leemos el estado del pin UP
buttonStateDown = digitalRead(buttonPinDown);//Leemos el estado del pin DOWN

if(backLight <= 255) { backLight = 255; }

if(buttonStateUp == HIGH)//Si el botón UP fue precionado
{
digitalWrite(ledPin, HIGH);//Flasheo del LED

if(backLight >= 0 && screenon == false)//En caso de que la luz este en 0
{
lcd.display();//Encendemos el LCD
screenon = true;//Modificamos la variable
}

backLight += 10; // Incrementamos en pasos de 10
if(backLight >= 255) { backLight = 255; }//No dejamos que el valor de la luz de fondo supere 255 ya que es el ciclo de trabajo máximo del PWM

func = true;//Para modificar los mensajes en pantalla
}

if (buttonStateDown == HIGH)
{
digitalWrite(ledPin, HIGH);
backLight -= 10;

if(backLight <= 0) { backLight = 0; } // No dejamos que el valor sea menor a 0

if(backLight <= 0 && screenon == true)
{
lcd.noDisplay();//Apagamos el display, esto no borra los datos del cache del display
screenon = false; //Cambiamos la variable a apagado
}

func = true;//Para modificar los mensajes en pantalla
}

if(func)//Si alguno de los dos botones fue presionado
{
lcd.clear();//Limpiamos la pantalla
porcentaje = (backLight * 100) / 255; //Calculamos el porcentaje de luz de fondo
lcd.setCursor(0,0);//Ponemos el cursor en el primer carácter de la pantalla
lcd.print("Luz Modificada.");//Imprimimos un mensaje en la pantalla
lcd.setCursor(0,1);//Movemos el curso a la segunda linea
lcd.print("BL: " + String(porcentaje) + "% - " + String(backLight));//Imprimimos el porcentaje y valor
digitalWrite(ledPin, LOW);//Apagamos el LED
analogWrite(Pantalla, backLight);//Mandamos el nuevo valor de PWM y esto modificara la luz de fondo
func = false;//Cambiamos para no entrar en la sección del codigo
delay(200);//Este delay nos ayuda a manejar los clicks en los botones evitando dar un "doble botonazo"
}
}

Como se puede ver no se necesita mucho código, incluso el que presento es muy rustico pero cumple su cometido, adicionalmente que también fue una de las primeras cosas que aprendí a hacer cuando adquirí mi equipo.

Por ultimo les dejo un video de como se ve en funcionamiento.


Espero que esto les ayude en sus proyectos!

viernes, 4 de octubre de 2013

Fraudes por correo electrónico y como identificarlos


Pues últimamente me han estado llegando muchos correos electrónicos en donde se me indica que mi cuenta de BBVA Bancomer esta suspendida, que por un lado no tengo cuenta en Bancomer, lo cual quiere decir que estos correos van dirigidos aleatoriamente.

Algunas de las características que estos incorporan es que contiene varios números aleatorios en el encabezado y cuerpo del mensaje, nombre incompleto en el cuerpo del correo y el inicio del supuesto número de tarjeta a la cual esta asociada la cuenta bloqueada/inactiva/suspendida.

Afortunadamente muchos de estos correos ya llegan a la bandeja de SPAM, pero muchos otros no. Por lo cual es importante aprender a diferenciar uno del otro.

Uno de los principales puntos es que el banco, cualquiera que este sea, no usara un medio de comunicación como correo electrónico para avisarte que tu cuenta esta suspendida. Por lo regular solo envían promociones y alguna que otra basura mas. Pero nunca mensajes alertando al usuario que su cuenta esta bloqueada o suspendida sin mayor aviso.


En la imagen de arriba pueden ver las los elementos que componen el correo y como identificarlos.
  1. La dirección desde donde envían el correo electrónico, esta es noreply@bbva-bancomer-3484.com; a pesar de que la dirección se ve muy convincente tiene unos números adicionales 3484? que para nada forman parte del nombre de Bancomer.
  2. El medio por el cual se envía el correo, server.witensports.com? no tiene relación alguna con Bancomer, se debe de sospechar.
  3. Incluyen el supuesto número de cuenta, el cual viene enmascarado por razones de seguridad, pero mas de un millón de tarjetas distintas podrían empezar con los números 4152-31, ya que los primero cuatro dígitos corresponden al identificador del banco. Que en este caso corresponde a las tarjetas de débito y cuentas de cheques de Bancomer.
  4. El enlace a la página, donde amablemente te piden que actualices tus datos. En el cuerpo del correo podemos ver que corresponde a un enlace a la pagina de bancomer.com, pero la realidad es que te dirige a una pagina que empieza por una IP (Definición en Wikipedia), y la cual es excesivamente larga con el propósito de ocultar la liga y todos los elementos que la componen.
Definitivamente esto es algo que podemos evitar nosotros, simplemente examinando los elementos de las páginas e identificándolos. Con esto nos podemos ahorrar muchas molestias.

Suerte!

Como conectar el lector de tarjetas SD a tu Arduino Mega 2560


Lector de tarjetas SD

Compre el lector de tarjetas en uno de esos sitios chinos, de donde suelo comprar la mayoría de componentes que utilizo para mis proyectos y a un precio de USD$3.20 (a MXN$13.30 el tipo de cambio son aproximadamente MXN$42.56) es bastante barato.

Obvio tiene sus desventajas el comprar algo desde China y es que el envío puede tardar hasta 60 días, pero la mayoría de las veces solo toma dos semanas y por lo regular el envío es gratuito. En Mercado Libre el precio mas barato que he visto es de alrededor de MXN$60.00 + el envío que no baja de MXN$50.00.

La calidad del articulo es bastante buena el armado también es muy aceptable, no tiene defectos ni soldaduras que se vean mal hechas a simple vista. Por lo que recomiendo mucho este articulo.

Cuando me llego lo primero que quise fue conectarlo, pero oh sorpresa, no tiene manual entonces me puse a investigar, encontré un par de cosas en como conectarlo, no del todo claro. Así que por eso motivo hago esto.

Así que a lo que nos interesa.

Como conectar el lector de tarjeta SD a Arduino Mega 2560

En mi Arduino tengo conectado un shield de expansión es por eso que se ve raro, pero se puede conectar muy facilmente sin el.

La conexión que se ve en la foto de la derecha esta hecha por medio del conector ICSP, que la mayoría de las placas arduino ya tienen incluidas y esto facilita mucho la conexión de este tipo de dispositivos.

Los pines del conector ICSP estan configurados de la siguiente forma:
Por lo cual, conectar el lector de tarjeta SD se da casi de forma natural.

El lector de tarjetas SD viene con conectores de doble pin, por lo cual es un poco confuso, pero cada par esta conectado entre si, por lo cual es indistinto si utilizan uno u otro.

Los pines del conector del lector de tarjetas SD viene de la siguiente manera:

Por lo cual se puede ver a primera vista los pines que hay que conectar en común, quedando solamente el pin "CS" que hay que conectar al pin 53 de nuestro Arduino Mega 2560.

Conexiones 

Lector tarjetas SD Arduino
GND GND
+3.3v ICSP +VCC
+5v NC
CS Pin 53
MOSI ICSP MOSI
SCK ICSP SCK
MISO ICSP MISO
GND NC

*NC = No conectar

Ahora el código para tu proyecto.

Básicamente utilizaremos el mismo código que viene en el IDE de Arduino, que es el ejemplo Cardinfo.

Aquí solamente cambiaremos un parámetro y eso es todo lo necesario para poder inicializar el lector de tarjeta y poder comenzar a trabajar con ella.

#include
#include

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// Pin 53 en mega 2560
const int chipSelect = 53;  

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial.print("\nInitializing SD card...");
  pinMode(53, OUTPUT);// Pin 53 en Arduino mega 2560


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
   Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }


  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
 
  volumesize = volume.blocksPerCluster();   
  volumesize *= volume.clusterCount();      
  volumesize *= 512;

  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

 
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
 
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {



Y con esto esta listo para empezar a utilizar tu lector de tarjetas SD!!

Espero que te sirva de algo y si así fue, pues que bueno!