Marquesina basada en Arduino
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

La mayor parte del código está basado en el instructivo de Syst3mX.
//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 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
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
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.
// 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

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
Conferencias de Intel LABS en Ixtapan de la Sal.
[vía bytepodcast]
Concepto Nokia Morph
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
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 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
y este el sketch de Processing
// 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
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.
#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
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.
#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
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.
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
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
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:
- 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 - Instalar las herramientas de consola ffmpeg y convert.
- 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
- 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 - Generamos el video con el comando ffmpeg:
cd frames
ffmpeg -f image2 -i anima-%d.jpg video.mpeg
sudo apt-get install ffmpeg
¡Listo!, ya tenemos una animación de nuestro programa.
