logoTh!nk Again


Marquesina basada en Arduino

Posted in Arduino, Prácticas, proyectos by admin on the November 22nd, 2009

Después del sketch del Knight Rider, fue imposible evitar la tentación de escribir otro sketch para el Arduino, que transformará la matriz de leds de 8×8 en una mini-banner. Solo bastaron un pocos cambios en el contador 4017 para ¡tener el hardware listo! (eliminar el reset autómatico al llegar al Output 8).

banner

banner

La mayor parte del código está basado en el instructivo de Syst3mX.

///Dennys Regalado Díaz
//22 Noviembre de 2009
int col[] = {0,1, 2, 3, 4, 5, 6, 7};

int clock = 9;// goes to the clock pin on the 4017 IC
int reset = 8;//goes to the reset pin on the 4017 IC
const int numPatterns = 18 ;
byte patterns[numPatterns][8]={space,M,lit_a,lit_k,lit_e,dos_pts,space,lit_e,lit_n,space,E,lit_s,lit_p,lit_a,lit_nh,lit_o,lit_l,space};

void setup(){
    //simple stuff here
  pinMode(clock,OUTPUT);
  pinMode(reset,OUTPUT);
    //simple stuff here
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins for matrix 1:
    pinMode(col[thisPin], OUTPUT);
  }
 
    //reseting the 4017 IC, you have to do this
  digitalWrite(reset,HIGH);
  delayMicroseconds(5);
  digitalWrite(reset,LOW);

 
}

void display_pattern(int loops)
{
  //for each pattern
  for(int x=0; x<numPatterns-1; x++){

    for (int z=0;z<8;z++){
    //scrolls one bite at a time
   
      // the delay we get with loops
      for(int t=0;t<loops;t++){
        //reseting the 4017 IC, you have to do this
        digitalWrite(reset,HIGH);
        delayMicroseconds(5);
        digitalWrite(reset,LOW);

        for(int y=0; y<8; y++){         
          byte temp = patterns[x][y];
          byte temp_2=patterns[x+1][y];
         
         //writes digital outputs, Z is for how much bites it need to scroll
          PORTD = B11111111 - ((temp<<z) + (temp_2>>7-z));
          delayMicroseconds(400);// the time every row is one
          PORTD= B11111111;// all pins are low, fixes the ghosting effect
         
          digitalWrite(clock,HIGH);
          delayMicroseconds(50);                   
          digitalWrite(clock,LOW);         
         
        }
      }
    }
  }
}

void loop(){
  display_pattern(50); // int loop = 15(if you do more loop the pattern whould scrrol slower).
}

Aquí esta la representación de los caracteres para la matriz de 8×8

#define A     {B00111100,B01000010,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010}
#define B     {B01111100,B01000010,B01000010,B01111100,B01000010,B01000010,B01000010,B01111100}
#define C     {B00111110,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B00111110}
#define D     {B01111100,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B01111100}
#define E     {B01111110,B01000000,B01000000,B01111100,B01000000,B01000000,B01000000,B01111110}
#define F     {B01111110,B01000000,B01000000,B01111100,B01000000,B01000000,B01000000,B01000000}
#define G     {B00111100,B01000010,B01000010,B01000000,B01000111,B01000010,B01000010,B00111100}
#define H     {B01000010,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B01000010}
#define I     {B00111000,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000,B00111000}
#define J     {B00011100,B00001000,B00001000,B00001000,B00001000,B01001000,B01001000,B00110000}
#define K     {B01000100,B01001000,B01010000,B01100000,B01010000,B01001000,B01000100,B01000010}
#define L     {B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01111110}
#define M     {B10000010,B11000110,B10101010,B10010010,B10000010,B10000010,B10000010,B10000010}
#define N     {B01000010,B01100010,B01010010,B01001010,B01001010,B01001010,B01000110,B01000010}
#define O     {B00111100,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B00111100}
#define P     {B01111100,B01000010,B01000010,B01000010,B01111100,B01000000,B01000000,B01000000}
#define Q     {B00111100,B01000010,B01000010,B01000010,B01000010,B01000110,B00111110,B00000001}
#define R     {B01111100,B01000010,B01000010,B01000010,B01111100,B01000100,B01000010,B01000010}
#define S     {B00111100,B01000010,B01000000,B01000000,B00111100,B00000010,B01000010,B00111100}
#define T     {B11111110,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000,B00010000}
#define U     {B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B00111100}
#define V     {B01000010,B01000010,B01000010,B01000010,B01000010,B01000010,B00100100,B00011000}
#define W     {B10000010,B10000010,B10000010,B10000010,B10010010,B10010010,B10101010,B01000100}
#define X     {B01000010,B01000010,B00100100,B00011000,B00011000,B00100100,B01000010,B01000010}
#define Y     {B10000010,B01000100,B00101000,B00010000,B00010000,B00010000,B00010000,B00010000}
#define Z     {B01111110,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B01111110}
#define lit_a {B00000000,B00110000,B01001000,B00001000,B00111000,B01001000,B01001000,B00110100}
#define lit_b {B00000000,B00100000,B00100000,B00100000,B00111100,B00100010,B00100010,B00111100}
#define lit_c {B00000000,B00000000,B00000000,B00111100,B01000000,B01000000,B01000000,B00111100}
#define lit_d {B00000000,B00000100,B00000100,B00000100,B00111100,B01000100,B01000100,B00111100}
#define lit_e {B00000000,B00111000,B01000100,B01000100,B01111100,B01000000,B01000100,B00111000}
#define lit_f {B00011000,B00100100,B00100000,B00100000,B01110000,B00100000,B00100000,B00100000}
#define lit_g {B00011100,B00100010,B00100010,B00011100,B00001000,B00001100,B00100010,B00011100}
#define lit_h {B01000000,B01000000,B01000000,B01000000,B01111000,B01000100,B01000100,B01000100}
#define lit_i {B00000000,B00010000,B00000000,B00010000,B00010000,B00010000,B00010000,B00010000}
#define lit_j {B00000000,B00010000,B00000000,B00010000,B00010000,B00010000,B01010000,B00100000}
#define lit_k {B00000000,B01000000,B01001000,B01010000,B01100000,B01100000,B01010000,B01001000}
#define lit_l {B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000,B01000000}
#define lit_m {B00000000,B00000000,B10110110,B01001001,B01001001,B01001001,B01001001,B01001001}
#define lit_n {B00000000,B00000000,B10111000,B01000100,B01000100,B01000100,B01000100,B01000100}
#define lit_nh {B01111100,B00000000,B10111000,B01000100,B01000100,B01000100,B01000100,B01000100}
#define lit_o {B00000000,B00000000,B00000000,B00011100,B00100010,B00100010,B00100010,B00011100}
#define lit_p {B00000000,B00011100,B00100010,B00100010,B00111100,B00100000,B00100000,B00100000}
#define lit_q {B00000000,B00000000,B00111000,B01000100,B01000100,B00111100,B00000100,B00000100}
#define lit_r {B00000000,B00000000,B00111000,B01000000,B01000000,B01000000,B01000000,B01000000}
#define lit_s {B00000000,B00111000,B01000100,B01000000,B00111000,B00000100,B01000100,B00111000}
#define lit_t {B00100000,B00100000,B00100000,B01111100,B00100000,B00100000,B00100100,B00011000}
#define lit_u {B00000000,B00000000,B00000000,B01000100,B01000100,B01000100,B01000100,B00111000}
#define lit_v {B00000000,B00000000,B01000100,B01000100,B01000100,B01000100,B00101000,B00010000}
#define lit_w {B00000000,B00000000,B00000000,B01000100,B01000100,B01010100,B01010100,B00101000}
#define lit_x {B00000000,B00000000,B00000000,B00000000,B00100100,B00011000,B00011000,B00100100}
#define lit_y {B00000000,B01000100,B01000100,B00111100,B00000100,B00000100,B01000100,B00111000}
#define lit_z {B00000000,B00000000,B00000000,B01111100,B00001000,B00010000,B00100000,B01111100}
#define space {B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000}
#define num_0 {B00111100,B01000110,B01001010,B01001010,B01001010,B01010010,B01100010,B00111100}
#define num_1 {B00001000,B00011000,B00001000,B00001000,B00001000,B00001000,B00001000,B00011100}
#define num_2 {B00111100,B01000010,B00000100,B00001000,B00010000,B00100000,B01000000,B01111110}
#define num_3 {B01111110,B00000010,B00000010,B00011100,B00000010,B00000010,B01000010,B00111100}
#define num_4 {B00000100,B00001100,B00010100,B00100100,B01000100,B01111110,B00000100,B00000100}
#define num_5 {B01111110,B01000000,B01000000,B00111100,B00000010,B00000010,B00000010,B01111100}
#define num_6 {B00111100,B01000000,B01000000,B01111100,B01000010,B01000010,B01000010,B00111100}
#define num_7 {B01111110,B00000010,B00000100,B00001000,B00010000,B00010000,B00010000,B00010000}
#define num_8 {B00111100,B01000010,B01000010,B00111100,B01000010,B01000010,B01000010,B00111100}
#define num_9 {B00111100,B01000010,B01000010,B01000010,B00111110,B00000010,B00000010,B00111100}
#define times {B00000000,B01000010,B00100100,B00011000,B00011000,B00100100,B01000010,B00000000}
#define dos_pts{B00000000,B00000000,B00110000,B00110000,B00000000,B00110000,B00110000,B00000000}

Knight Rider effect based on Arduino

Posted in Uncategorized by admin on the November 22nd, 2009

I confess that I liked so much the TV show “Knight Rider” (”Kit, el auto increíble” in Mexico) of eighties. I have seen the new version, the effects are cool but not so much the story. Here is an sketch that looks like the ancient panel of Kit. Take a look and leave me your comments!

matrix 8x8

matrix 8x8


Here is the Arduino sketch, it’s a mod of Tom Igoe’s code that reduce the number of ports that we need to control the matrix adding an 4017 counter.

// Kinght Rider
// by Dennys Regalado Díaz <http://challenges.qumax.org>
int clock = 9;// goes to the clock pin on the 4017 IC
int reset = 8;//goes to the reset pin on the 4017 IC
int row[]={0,1,2,3,4,5,6,7}; //PORTD(0-7)
void setup(){
  //simple stuff here
  pinMode(clock,OUTPUT);
  pinMode(reset,OUTPUT);

   for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins for matrix 1:
    pinMode(row[thisPin], OUTPUT);
    // take the row pins (i.e. the cathodes) low to
    // the LEDS are off:
    digitalWrite(row[thisPin], HIGH);
  }
 
  //reseting the 4017 IC, you have to do this
  digitalWrite(reset,HIGH);
  delayMicroseconds(5);
  digitalWrite(reset,LOW);
}

void display_pattern(int loops)
{
  for (int thisrow = 0; thisrow < 8; thisrow++) {
    // take the row pin (cathodes) high:
    digitalWrite(row[thisrow], LOW);
    // iterate over the cols (anodes):
    for (int thiscol = 0; thiscol < 8; thiscol++) {
      // when the row is low and the col is high,
      // the LED where they meet turns on:
      //send a clock signal to the counter 4017
      digitalWrite(clock, LOW);
      delay(50);
      digitalWrite(clock, HIGH);
    }
    // take the row pin high to turn off the whole row
    digitalWrite(row[thisrow], HIGH);
  }
}

void loop(){
  display_pattern(100);// calls for the display_pattern function and says that int loop = 15(if you do more loop the pattern whould scrrol slower).
}

Reciclando casetes

Posted in Hazlo-Tú-Mismo by admin on the October 12th, 2009

Lámpara DIY con 30 casetes y unas cintas para mantenerlos unidos. ¿Alguna idea para reutilizar esos casetes viejos que tienes en casa? Admito que me costó un poco convencerme de armar el cubo de casetes, pero ¡al final lo logré!. Quizá realizarlo en dos sesiones es la mejor idea, empezar formando las 5 caras y unirlas al final.

El resultado fue esa lámpara de arriba que luce poco ordinaria sobre mi mesa de trabajo.

[vía ooomydesign]

Editors Day 2009

Posted in Futuro by admin on the October 9th, 2009


Conferencias de Intel LABS en Ixtapan de la Sal.

[vía bytepodcast]

Concepto Nokia Morph

Posted in Futuro by admin on the October 5th, 2009


Hoy por la mañana me tocó ver este video en una presentación relacionada con gadgets y me quedé con la interrogante: ¿hoy en día qué tan avanzada está la nanotecnología?¿en verdad se puede construir?¿ustedes qué opinan?

Cambia tu aburrido mouse por este joystick sacado de la basura

Posted in Arduino, Prácticas by admin on the September 23rd, 2009


Hoy encontré un stick de un viejo control de playstation 1, que hace tiempo había rescatado de la basura con la esperanza de reutilizarlo alguna vez. Así que sin pensarlo dos veces me dí a la tarea de soldar unos pines a los potenciometros, conectar algunos cables, escribir algo de código para mi Arduino Duemilanove y reciclar código de un sketch de Processing.

El funcionamiento del joystick es sencillo, son dos potenciometros de los que se leen los valores x y y; sólo hay conectarlos a las entradas análogas del Arduino y enviar los valores a la computadora.

Este es el sketch para el Arduino

int  ledPin = 13;
int  joyPin1 = 0;          // variable x conectado al  pin análogo 0
int  joyPin2 = 1;          // variable y conectado al  pin análogo 1
int  value1 = 0;           // valor digitalizado del pin 0
int  value2 = 0;           // valor digitalizado del pin 1
void setup() {
  beginSerial(9600);
}
//convierte un numero a su valor ascii
int tochar(int data) {
  return (data + 48);
}
void loop() {
  // lee los valores de los potenciometros
  value1 = analogRead(joyPin1);
  //pequeña pausa entre las lecturas
  delay(100);
 //lee el segundo potenciometro
  value2 = analogRead(joyPin2);

  //envia el valor de x
  serialWrite('X');
 //envia el valor numerico digito por digito, solo 8 bits a la vez
  if(value1>0){
    while(value1){
      serialWrite(treatValue(value1%10));
      value1 = value1/10;
    }
  }else serialWrite('0')
  serialWrite(10);
  //envia el valor de y
  serialWrite('Y');
  if (value2>0){
    while(value2){
      serialWrite(treatValue(value2%10));
      value2 = value2/10;
    }
  }else serialWrite('0');
  serialWrite(10); //el fin de linea marca el final de la lectura
}
joystick+arduino+processing

joystick+arduino+processing

y este el sketch de Processing

// Joystick
// por Dennys Regalado Díaz
//
// Creado el 11 de septiembre de 2009
////////////
int num = 60;
float mx[] = new float[num];
float my[] = new float[num];

import processing.serial.*;

String buff = "";
int x_val=0,y_val=0;
int NEWLINE = 10;

Serial port;

void setup(){
  size(400,400);
  smooth();
  noStroke();
  fill(255, 153);
  // Print a list in case COM1 doesn't work out
  println("Available serial ports:");
  println(Serial.list());

  //port = new Serial(this, "COM1", 9600);
  // Uses the first available port
  port = new Serial(this, Serial.list()[0], 9600);
}

void draw()
{
   background(41);
  while (port.available() > 0) {
    serialEvent(port.read());
  }
 

 
  // Reads throught the entire array
  // and shifts the values to the left
  for(int i=1; i<num; i++) {
    mx[i-1] = mx[i];
    my[i-1] = my[i];
  }
 
  int xx = (int) map(constrain(x_val,10,1024),0,1024,10,width-10);
  int yy = (int) map(constrain(y_val,10,1024),0,1024,10,height-10);
  mx[num-1] = xx;
  my[num-1] = yy;
  float r = random(125,205);
  float g = random(100,205);
  float b = random(150,200);

  for(int i=0; i<num; i++) {
    fill(r,g,b,153);
    ellipse(mx[i], my[i], i/2, i/2);
  }
  println("x:"+xx+", y:" + yy);
}

void serialEvent(int serial)
{
  if(serial != NEWLINE) {     
    buff += char(serial);   
  } else if(buff.length()> 0) {
    char c = buff.charAt(0);
    buff = buff.substring(1);
    if (c == 'X')
      x_val = Integer.parseInt(buff);
    else if (c == 'Y')
      y_val = Integer.parseInt(buff);
    buff = "";
  }
}

Python: Hallar el punto de intersección entre dos segmentos

Posted in Algoritmos, Ejemplos, Python by admin on the September 11th, 2009

Este segmento de código devuelve el punto de intersección entre dos rectas, no se consideran el caso de que no exista o exista más de uno (lineas paralelas). Depende del valor de la variable det, si es igual a cero, es necesario verificar que las lineas sean paralelas, si no lo son, entonces nunca se tocan.

#/usr/bin/env python
#interseccion EN UN UNICO PUNTO entre segmentos
class punto:
  def __init__(self,x,y):
    self.x = x
    self.y = y
  def __str__(self):
    return "("+str(self.x)+","+str(self.y)+")"
class linea:
  def __init__(self, p0, p1):
    self.p0 = p0
    self.p1 = p1
    self.A = p1.x - p0.x
    self.B = p1.y - p0.y
    self.C = p1.x*p0.y - p0.x*p1.y
  def intersecta(self, otro):
    det = self.A*otro.B - otro.A*self.B
    x = otro.A*self.C-self.A*otro.C
    y = otro.B*self.C-self.B*otro.C
    return punto(x/det,y/det)
   
  def __str__(self):
    return str(self.p0) + "," + str(self.p1)
   
if __name__=="__main__":
  l1 =linea(punto(0,0),punto(10,10))
  l2 =linea(punto(10,0),punto(0,10)) 
  print l1,l2
  print l1.intersecta(l2)

Python: calcular los n primeros números primos

Posted in Algoritmos, Python by admin on the September 8th, 2009

No conozco otro lenguaje más flexible y fácil que python. Este código te permite obtener los n primos menores que la variable MAX.

#/usr/bin/env python
#calcula los primos menores que 100
MAX = 100
primos = [2]

for k in range(3, MAX):
  for i in range(len(primos)):   
    if k%primos[i]==0: break
 
  if i==len(primos)-1: #solo si no es multimplo de los actuales primos
    primos.append(k)       
print primos

Python: Recorridos en un árbol

Posted in Algoritmos, Python by admin on the September 7th, 2009

Una manera muy fácil de representar un árbol binario es utilizando un vector. A partir de esta representación es fácil ejemplificar los recorridos en un árbol: pre-orden, in-orden y post-orden.

#/usr/bin/env python
arbol = [5,3,7,2,4,6,9]
#como se representa un arbol binario casi-completo con una lista?
#    5      Nos enfocamos en el nodo 7, su indice en la lista es 2,
#   / \     el hijo izquierdo esta en la posicion 2*indice + 1
#  3   7    y el hijo derecho esta en la posicion 2*indice + 2
# / \ / \
#2  4 6  9
def postorden(nodo): #id*
  if nodo >= len(arbol): #nodo sin hijo
    return
  else:  
    postorden(2*nodo+1) #subarbol izquierdo
    postorden(2*nodo+2) #subarbol derecho
    print arbol[nodo],

def preorden(nodo): #*id
  if nodo >= len(arbol): #nodo sin hijo
    return
  else:  
    print arbol[nodo],
    preorden(2*nodo+1) #subarbol izquierdo
    preorden(2*nodo+2) #subarbol derecho

def inorden(nodo): #i*d
  if nodo >= len(arbol): #nodo sin hijo
    return
  else:    
    inorden(2*nodo+1) #subarbol izquierdo
    print arbol[nodo],
    inorden(2*nodo+2) #subarbol derecho

if __name__=="__main__":   
  print "pre-orden:"
  preorden(0)
  print "\nin-orden:"
  inorden(0)
  print "\npost-orden:"
  postorden(0)

Salida desde la terminal

pre-orden:
5 3 2 4 7 6 9
in-orden:
2 3 4 5 6 7 9
post-orden:
2 4 3 6 9 7 5

Animación orgánica con Context Free

Posted in Context Free, Ejemplos, Programming Languages, Tutoriales by admin on the August 20th, 2009

Me quedé con la curiosidad de cómo generar una animación del programa en Context Free sin la interfaz de usuario que existe en otras plataformas como güindous y mac.

Esta es la solución que encontre:

  1. Suponiendo que el código fuente document.cfdg se encuentra en el directorio_actual, y que tenemos la siguiente estructura de directorios:
    directorio_actual
       |
       +----animation
                |
                +-----frames
  2. Instalar las herramientas de consola ffmpeg y convert.
  3. sudo apt-get install convert
    sudo apt-get install ffmpeg
  4. Generar los cuadros de nuestra animación, en mi caso 50, con la siguiente línea:
    cfdg -w 500 -h 500 document.cfdg ./animation/art.png -a 500
  5. Como el cfdg solo genera imágenes png y ffmpeg (que convierte una secuencia de imágenes en video) sólo acepta imágenes jpg, realizamos la conversión de las imágenes con la siguiente línea:
    cd animation
    convert * ./frames/anima.jpg
  6. Generamos el video con el comando ffmpeg:

    cd frames
    ffmpeg -f image2 -i anima-%d.jpg video.mpeg

¡Listo!, ya tenemos una animación de nuestro programa.

Next Page »