lunes, 27 de agosto de 2012

Configurar D-Link DIR-600 para Telefónica

El problema de la sincronización en los routers D-Link DIR-600 de los MODEM ADSL se trata de un error de la configuración de la velocidad de comunicación por cable desde el Router con el Mode. Para solucionarlo solo debemos seguir los siguientes pasos:

d-link dir-600
Fig. Autenticación en un router D-Link DIR-600
d-link dir-600
Fig. Entramos en la opción AVANZADA
d-link dir-600
Fig. Seleccionamos la velocidad del puerto LAN
d-link dir-600
Fig. Guardamos los cambios

Capturar audio de línea de entrada con Java

Hace poco publiqué un artículo en donde muestro la manera de cómo graficar archivos de audio. En este post voy a mostrarles la manera de cómo graficar audio capturado desde un micrófono. La aplicación que usaré será la misma que está posteada en el artículo anterior, con una ligera modificación. Aunque pueda parecer un proceso tedioso, el capturar y graficar audio en tiempo real es una tarea relativamente sencilla. Lo primero que debemos hacer es capturar la entrada de audio de nuestra computadora indicándole un formato determinado.

private void capturarAudio() {
    try {
        final AudioFormat format = getFormat();
        DataLine.Info info = new DataLine.Info(
                TargetDataLine.class, format);
        final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
        line.open(format);
        line.start();
        Runnable runner = new Runnable() {

            int bufferSize = (int) format.getSampleRate()
                    * format.getFrameSize();
            byte buffer[] = new byte[bufferSize];

            public void run() {
                out = new ByteArrayOutputStream();
                running = true;
                try {
                    while (running) {
                        int count =
                                line.read(buffer, 0, buffer.length);
                        if (count > 0) {
                            out.write(buffer, 0, count);
                        }
                        graficarBytes(buffer);
                    }
                    out.close();
                } catch (IOException e) {
                    System.err.println("I/O problems: " + e);
                    System.exit(-1);
                }
            }
        };
        Thread captureThread = new Thread(runner);
        captureThread.start();
    } catch (LineUnavailableException e) {
        System.err.println("Line unavailable: " + e);
        System.exit(-2);
    }
}

Ahora debemos determinar el formato de la captura de audio. Lo podemos hacer mediante el siguiente método:

private AudioFormat getFormat() {
    float sampleRate = 8000;
    int sampleSizeInBits = 8;
    int channels = 1;
    boolean signed = true;
    boolean bigEndian = true;
    return new AudioFormat(sampleRate,
            sampleSizeInBits, channels, signed, bigEndian);
}

Hecho esto ya podemos acceder al arreglo de bytes que componen los frames de audio que han sido capturados. Para realizar la graficación del espectro podemos utilizar la aplicación  que de la que comenté al incio de este post. Aquí les comparto un video que muestra el funcionamiento del software grabando voces en una casa en la que según me dijeron habitan fantasmas y cuya historia compartiré en otro post.


También les dejo el archivo del proyecto desarrollado en netbeans para que puedan tener una idea más clara de este proceso y lo puedan aplicar en otras situaciones.

 

domingo, 26 de agosto de 2012

Cómo realizar una placa de circuito impreso de dos caras

Regresando después de algún tiempo al mundo de la electrónica quiero mostrarles la manera de cómo se debe desarrollar una placa de circuito impreso utilizando materiales disponibles en casa. El proyecto que realizaremos en esta oportunidad será un módulo receptor de GPS Rockwell Jupiter.
1.- Para empezar a desarrollar el proyecto necesitamos en primer lugar de los esquemas del circuito (todos los archivos necesarios están disponibles al final del post). Las imágenes que muestro a continuación pertenecen a ambas caras de la placa tal como detalle la descripción de cada imágen.

Bottom Layer
Fig. Bottom Layer
Top Layer
Fig. Top Layer 
2.- Una vez que se tienen los diagramas de las pistas de nuestro lo circuito debemos imprimirlos utilizando una impresora láser. Usar este tipo de impresora es realmente importante puesto que si utiliza otro tipo de impresora no será posible pasar el dibujo del papel a la baquelita. El tipo de papel puede variar, sin embargo yo recomiendo fuertemente el papel couché pues me ha dado muy buenos resultados además de ser bastante cómodo y presentar una alta disponibilidad.

pcb
Fig. Diseño del circuito impreso en papel couché utilizando impresora láser
3.- Es altamente recomendable también tener un esquema de la disposición de los componentes a la mano de forma impresa para poder realizar el  montaje de manera adecuada.

componentes del pcb
Fig. Diagrama impreso de los componentes de la placa de circuito impreso
4.- Ahora debemos preparar la baquelita. En primer lugar debemos cortarla a la medida y lijar los bordes para eliminar la escoria (es siempre bueno manipular la placa con guantes para no impregnarla de grasa o sudor). Luego debemos frotarla suavemente con una esponja metálica, utilizada para la limpieza de ollas, de forma circular por ambas caras hasta tener el cobre reluciente.

limpieza de la baquelita
Fig. Limpieza de la baquelita
5.- Ahora debemos pasar el diseño a nuestra placa. Para eso debemos recortar el impreso dejando unos márgenes a modo de alas que servirán para fijar el papel a la placa haciendo un doblez en cada ala. En el caso de las placas de dos caras no es recomendable utilizar cinta adhesiva pues la goma que contiene deja manchas que luego resultan en una mala transmisión de nuestro esquema a la pcb.

placa de circuito impreso recortada
Fig. Forma en la que se debe recortar un diseño antes de ser transferido a la pcb
6.- Es hora de transferir el esquema a nuestra placa. El método más común es la plancha. Decir que se necesita determinado tiempo a modo de ley es incorrecto pues dependerá muchas veces de la plancha, de la presión que uno le aplique o de otros factores. La mejor manera de saber el tiempo es practicando. Sin embargo 2 a 3 minutos utilizando una plancha muy caliente y deslizándola uniformemente sobre la placa es un tiempo adecuado. Hay que resaltar que no se debe arrastrar la plancha haciendo presión pues hará que el toner se deslize haciendo que las pistas se unan unas con otras.

usar plancha para pcb
Fig. Utilización de una plancha para transferencia térmica
El mismo procedimiento debe ser utilizado para ambas caras. Antes de realizar la transferencia de la segunda cara debemos esperar cierto tiempo para que la cara anterior pueda fijarse correctamente. También es imporante imprimir ambas caras en modo espejo para no obtener un esquema al revés.

7.- Cuando se han transferido ambas caras debemos esperar 1 minuto y luego sumergir la pcb en agua muy caliente y mover constantemente. No nos preocupemos si el papel no se retira por sí solo pero si esto llegase a pasar sería genial. De cualquier forma debemos frotar suavemente la placa para retirar toda la escoria y solo quedarnos con las pistas de nuestro circuito. Si hay pistas muy juntas podemos ayudarnos con una aguja para retirar el papel sobrante.

8.- Luego de habernos asegurado de retirar todo el papel debemos colocar nuestra placa en el ácido férrico. Esta es otra razón por la que debemos utilizar guantes pues este ácido es muy corrosivo y altamente tóxico.

ácido ferrico aplicado a una pcb
Fig. Aplicación de ácido férrico sobre una pcb

9.- Ahora es momento de lavar la placa y retirar el toner utilizando la misma esponja metálica. Como se indicó anteriormente, debemos tener cuidado con la manipulación del ácido. Una vez que tenemos la placa lista debemos taladrarla para poder realizar el montaje. Es importante utilizar un tipo de punta o clavo para poder realizar una pequeña marca en el centro de cada agujero de la placa. Esto con el fin de que al momento de realizar la perforación la broca del taladro no patine arruinando nuestras pistas.

placa de circuito impreso
Fig. Placa de circuito impreso lista para el montaje de componentes
10.- Al momento de realizar el montaje hay un problema con el que muchos nos hemos topado: Cuando una pista finaliza en una cara y su continuación se encuentra en la otra. La solución es muy práctica. Simplemente debemos hacer pasar un alambre de cobre muy fino de tal forma que el pin que será insertado en esa posición no tenga ningún problema. Fijamos dicho alambre con un poco de soldadura y tenemos el problema solucionado.

soldar placa a dos caras
Fig. Solución del inconveniente de las placas de dos caras
11.- Luego de soldados los componentes debemos tener algo como esto:

Módulo GPS finalizado
Fig. Módulo GPS finalizado
Y ahora para comprobar el correcto funcionamiento de nuestra placa  les dejo un video.



Aquí les dejo los archivos para la realización de este proyecto.

 

Pronto publicaré un post relacionado al uso de este interesante dispositivo, por eso no dejes de seguirnos a través de nuestra página de Facebook.

miércoles, 8 de agosto de 2012

Graficar espectros de audio en tiempo real

Buen día a todos, en esta oportunidad les quiero presentar un artículo dedicado al procesamiento de audio en tiempo real. A raíz de este post y con la finalidad  de responder a las preguntas que me llegan de los lectores de este blog es que escribo este artículo en el cual les muestro la manera de graficar archivos mp3 en tiempo real, con la posibilidad de poder cambiar la forma mediante la cual se renderiza el espectro tanto en su forma como en su color. Mediante la biblioteca kj_dsp1.1.jar y algunas otras adicionales (que se encuentran agregadas en el proyecto adjunto) podemos graficar espectros de audio como lo hacen reproductores de música como Amarok o Winamp. Las dos imagenes siguientes muestran la manera en que se grafica el espectro de un archivo de música mientras ésta es reproducida. Lograr algo como esto parece ser una tarea tediosa pero gracias al proyecto que les presento en este post, obtener una interfaz como la mostrada es relativamente sencillo.



En primer lugar necesitamos tener una clase que se encargue de manejar todo lo relacionado con los controles de nuestro pequeño reproductor. Dicha clase sería similar a la siguiente:

package com.blogspot.rolandopalermo.gui;

import java.util.Map;
import javazoom.jlgui.basicplayer.BasicController;
import javazoom.jlgui.basicplayer.BasicPlayerEvent;
import javazoom.jlgui.basicplayer.BasicPlayerListener;

/**
 *
 * @author Rolando
 */
public class Reproductor implements BasicPlayerListener {

    @Override
    public void opened(Object o, Map map) {
    }

    @Override
    public void progress(int i, long l, byte[] bytes, Map map) {
    }

    @Override
    public void stateUpdated(BasicPlayerEvent bpe) {
    }

    @Override
    public void setController(BasicController bc) {
    }
    
}

Hecho esto ahora necesitamos tener un componente el cuál se encargará de capturar los frames de nuestro audio y a continuación graficarlo. Para esto necesitamos un objeto de la clase  SpectrumTimeAnalyzer, la cual se encuentra en el proyecto que adjunto. Con eso bastaría para poder gestionar un pequeño reproductor y visualizar la gráfica del archivo. Cabe resaltar que para poder editar los colores de las barras necesitamos de un editor de viscolor similar al usado por el winamp. En el proyecto adjunto un archivo viscolor.txt el cual contiene los colores y su degradado. En un próximo post hablaré de cómo realizar un pequeño editor de archivos de viscolor para reproductores de música.

Les adjunto el archivo del proyecto para Netbeans esperando que sea de utilidad para sus proyectos.

Photobucket

lunes, 6 de agosto de 2012

SQLite con Java en Eclipse

SQLite es un ligero sistema de gestión de base de datos que soporta la mayor parte del estándar SQL-92. En este post voy a mostrar la forma de cómo integrar esta biblioteca con una aplicación desarrollada en Java. Muchas son las aplicaciones que hacen uso de SQLite, como por ejemplo: Firefox, Skype, OpenOffice, etc. Y es que la relación entre la cantidad de recursos que demanda y su rendimiento lo hacen idóneo para aplicaciones en las cuales no se va a manejar grandes cantidades de datos ni múltiples transacciones. Otro factor importante es la distribución de las aplicaciones. Supongamos que hemos desarrollado una versátil aplicación para mensajería instantánea y necesitamos manejar las agendas de los usuarios. Pensar en distribuir scripts de base de datos junto al instalador o pedirle al usuario que como requisito deba tener instalado algún motor de base de datos es algo inconcebible. Obviamente existen otras opciones, sin embargo para este post nos centraremos en el uso de SQLite.
La aplicación que les muestro es un sencillo mantenimiento a una tabla de productos que será representado por la clase producto.

package com.blogspot.rolandopalermo.bean;

public class Producto {

    private long id;
    private String nombre;
    private double precioUnitario;
    private int stock;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public double getPrecioUnitario() {
        return precioUnitario;
    }

    public void setPrecioUnitario(double precioUnitario) {
        this.precioUnitario = precioUnitario;
    }

    public int getStock() {
        return stock;
    }

    public void setStock(int stock) {
        this.stock = stock;
    }

    @Override
    public String toString() {
        return nombre;
    }
}

La clase encargada de ejecutar las sentencias Sql es la siguiente:

package com.blogspot.rolandopalermo.sql;

import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.blogspot.rolandopalermo.bean.Producto;
import com.blogspot.rolandopalermo.util.ConexionJDBC;
import com.blogspot.rolandopalermo.util.ResultExecuteQuery;

public class SqlProducto {

    public void crearProducto(Producto producto) {
        String mensaje = "";
        boolean fallo = false;
        ConexionJDBC conn = new ConexionJDBC();
        Connection connection = conn.getConnection();
        Statement stmt = null;
        String sql = "INSERT INTO TB_PRODUCTOS (txtNombre, txtPrecioUnitario, txtStock) VALUES ('"
                + producto.getNombre()
                + "',"
                + producto.getPrecioUnitario()
                + "," + producto.getStock() + ");";
        try {
            stmt = connection.createStatement();
            stmt.execute(sql);
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
        } catch (Exception e) {
            mensaje = e.getMessage();
            fallo = true;
        } finally {
            if (!fallo) {
                JOptionPane.showMessageDialog(new JFrame(),
                        "El producto se ha guardado correctamente.", "Éxito",
                        JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(new JFrame(),
                        "No se ha podido completar la operación.n" + mensaje,
                        "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void actualizarProducto(Producto producto) {
        String mensaje = "";
        boolean fallo = false;
        ConexionJDBC conn = new ConexionJDBC();
        Connection connection = conn.getConnection();
        Statement stmt = null;
        String sql = "UPDATE TB_PRODUCTOS SET txtNombre='"
                + producto.getNombre() + "', txtPrecioUnitario="
                + producto.getPrecioUnitario() + ", txtStock="
                + producto.getStock() + " WHERE id=" + producto.getId() + ";";
        try {
            stmt = connection.createStatement();
            stmt.execute(sql);
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
        } catch (Exception e) {
            mensaje = e.getMessage();
            fallo = true;
        } finally {
            if (!fallo) {
                JOptionPane.showMessageDialog(new JFrame(),
                        "El producto se ha actualizado correctamente.",
                        "Éxito", JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(new JFrame(),
                        "No se ha podido completar la operación.n" + mensaje,
                        "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void eliminarProducto(long id) {
        String mensaje = "";
        boolean fallo = false;
        try {
            ConexionJDBC conn = new ConexionJDBC();
            Connection connection = conn.getConnection();
            Statement stmt = null;
            String sql = "DELETE FROM TB_PRODUCTOS WHERE id=" + id + ";";
            stmt = connection.createStatement();
            stmt.execute(sql);
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    mensaje = e.getMessage();
                    fallo = true;
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            mensaje = e.getMessage();
            fallo = true;
        } finally {
            if (!fallo) {
                JOptionPane.showMessageDialog(new JFrame(),
                        "El producto se ha eliminado correctamente.", "Éxito",
                        JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(new JFrame(),
                        "No se ha podido completar la operación.n" + mensaje,
                        "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    @SuppressWarnings({"rawtypes", "unchecked"})
    public List<Producto>;

    buscarProductos() {
        List<Producto> productos = new ArrayList<Producto>();
        HashMap column = new HashMap();
        column.put("String:0", "id");
        column.put("String:1", "txtNombre");
        column.put("String:2", "txtPrecioUnitario");
        column.put("String:3", "txtStock");
        String sql = "SELECT * FROM TB_PRODUCTOS";
        ResultExecuteQuery resultExecuteQuery = new ResultExecuteQuery(sql,
                column);
        HashMap<Integer, HashMa> mapResultado = resultExecuteQuery.getMap();
        HashMap res = null;
        for (int i = 0; i &amp; lt; mapResultado.size();
        i++
        
            ) {
   Producto producto = new Producto();
            res = (HashMap) mapResultado.get(i);
            Long id = Long.parseLong(res.get("id").toString());
            producto.setId(id);
            producto.setNombre(res.get("txtNombre").toString());
            Double precio = Double.parseDouble(res.get("txtPrecioUnitario").toString());
            producto.setPrecioUnitario(precio);
            Integer stock = Integer.parseInt(res.get("txtStock").toString());
            producto.setStock(stock);
            productos.add(producto);
        }
        return productos;
    }
}

Aquí les dejo el código fuente del proyecto que pueden importar a su workspace de Eclipse.


La base de datos pueden descargarla del siguiente enlace: base de datos. Este archivo deberá estar en la raíz del disco C:\.

Aquí algunos pantallazos de la aplicación:




Eso es todo por ahora. Espero les sea de utilidad y no dejen de seguir a este blog a través de facebook para enterarse de muchas novedades.