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}

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 = "";
  }
}

Controlando led RGB al ritmo de la música

Posted in Arduino, Prácticas by admin on the March 19th, 2009

La idea principal del proyecto es armar una lámpara usando un led RGB. El color de la lámpara varía (verde, azul, rojo) dependiendo de la forma de la onda del sonido al reproducir un archivo mp3.

Por lo que dividimos el proyecto en 2 fases:

  • La primera fase consiste en cargar el archivo mp3, reproducirlo, obtener los valores de la onda y por último enviar el color en hexadecimal de forma serial al arduino.
  • En la segunda fase se trabaja sobre el arduino, se descompone el color (en R, G y B) se envían los valores a las salidas PWM (pines 9, 10 y 11).

Para más detalles de la segunda fase, consulten el capítulo 6 del siguiente libro, en la página 73:

ver capítulo 6. talking to the cloud, pág. 73

ver capítulo 6. talking to the cloud, pág. 73

Para la primera fase utilice la librería de audio Minim, consulten este ejemplo antes para comprender el funcionamiento: Examples->Library->Minim->LoadFile.

Motivación

Código aplicación en Processing

/*Dennys Regalado Díaz
  19/03/09
  Mapea onda de sonido a un color RGB y
  se lo envía por serial al Arduino Duemilanove
  Utiliza libreria Minim y parte del código de los ejemplos.
*/

import processing.serial.*;
import ddf.minim.*;

AudioPlayer player;
Minim minim;

Serial port;
int r,g,b,c,last_color=-1;
String cs;

void setup()
{
  size(512, 200,P3D);
  background(0);
  stroke(255);
  minim = new Minim(this);
  player = minim.loadFile("/home/dennys/Music/slipknot 2008/04. Psychosocial.mp3", 2048);
  player.play();
  //configura puerto serial
  println(Serial.list());
  port = new Serial(this, Serial.list()[0], 9600);
}

void draw()
{
  int sum=0;
  //Dibuja ondas de audio, tomado del ejemplo Libraries->Minim(Sound)->Load File
  for(int i = 0; i < player.left.size()-1; i++)
  {
    line(i, 50 + player.left.get(i)*50, i+1, 50 + player.left.get(i+1)*50);
    line(i, 150 + player.right.get(i)*50, i+1, 150 + player.right.get(i+1)*50);
    sum+=player.left.get(i)+player.right.get(i);
  }
  if(sum>10){
    r=255;
    g=b=0;
  }else if(sum>0){
    b=255;
    r=g=0;
  }
  else{
    g=255;
    r=b=0;
  }
  c = color(r,g,b);
 
  if(c!=last_color){
    cs = "#" + hex(c,6);
    port.write(cs);
    last_color=c;
  }
}


void stop()
{
  player.close();
  minim.stop()
  super.stop();
}

Código para el Arduino

/*Extracto del Ejemplo 6-1 Getting Started with Arduino,
http://www.makezine.com/getstartedarduino
Arduino networked lamp parts of the code
are inspired by a blog post by Tod E. Kurt (todbot.com)
*/

//puertos: 9,10,11 son por default salidas
#define R_LED 9
#define G_LED 10
#define B_LED 11
char buffer[7] ;
int pointer = 0;
byte inByte = 0;
byte r = 0;
byte g = 0;
byte b = 0;
void setup() {
  Serial.begin(9600); // open the serial port   
}
void loop() {
  // the serial port
  if (Serial.available() >0) {
    // read the incoming byte:
    inByte = Serial.read();
    // If the marker's found, next 6 characters are the colour
    if (inByte == '#') {
      while (pointer < 6) { // accumulate 6 chars
        buffer[pointer] = Serial.read(); // store in the buffer
        pointer++; // move the pointer forward by 1
      }
      // now we have the 3 numbers stored as hex numbers
      // we need to decode them into 3 bytes r, g and b
      r = hex2dec(buffer[1]) + hex2dec(buffer[0]) * 16;
      g = hex2dec(buffer[3]) + hex2dec(buffer[2]) * 16;
      b = hex2dec(buffer[5]) + hex2dec(buffer[4]) * 16;
      pointer = 0; // reset the pointer so we can reuse the buffer
    }
  }
  analogWrite(R_LED, r); // turn the leds on
  analogWrite(G_LED, g); // at the colour
  analogWrite(B_LED, b); // sent by the computer
  delay(10);              // wait 100ms between each send
}
int hex2dec(byte c) { // converts one HEX character into a number
  if (c >= '0' && c <= '9') {
    return c - '0';
  }
  else if (c >= 'A' && c <= 'F') {
    return c - 'A' + 10;
  }
}

Probando el servo motor

Posted in Arduino, Prácticas by admin on the March 15th, 2009

Sólo usé el código de ejemplo que incluye el IDE del arduino y listo!
Motivación

Materiales

Desarrollo
Así me quedó el circuito

Diagrama del circuito

Diagrama del circuito

Este es el código de ejemplo que viene con el IDE, Examples->Library-servo->Knob

// Controlling a servo position using a potentiometer (variable resistor)
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

#include <Servo.h>
 
Servo myservo;  // create servo object to control a servo
 
int potpin = 0// analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
 
void setup()
{
  myservo.attach(9)// attaches the servo on pin 9 to the servo object
}
 
void loop()
{
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  delay(15);                           // waits for the servo to get there
}

Processing + Arduino

Posted in Arduino, Processing, Prácticas by admin on the March 15th, 2009

Introducción

Después de una semana de tener el Arduino Duemilinove, por fin me decidí a realizar una pequeña aplicación, la cuál consiste en interfazar el Arduino con un sketch de Processing.

Objetivos

Encender y apagar los segmentos de un display de ánodo común mediante una interfaz construida en Processing
Motivación

Materiales

DA05

DA05

tarjeta arduino

tarjeta arduino

Desarrollo

Lo dividí en dos fases:

  1. Interfaz en processing que permite establecer el estado de los segmentos (on/off) a través de un click, funciona como un toggle button.
  2. Programa para el arduino que recibe la configuración y actualiza el estado del display.

Este es el código en processing, creé una clase segmento para hacerlo más fácil.

class Segmento{
  float x,y,alto,ancho;
  int color_current;
  boolean over= false;
  boolean presionado = false;
  final int color_on=#FF0000,
            color_off=#999999,
            color_over=color(102,255,0,246);
  Segmento(float x, float y, float w, float h){
    this.x = x;
    this.y = y;
    alto = h;
    ancho = w;
    color_current = color_off;
  }
  void display(){
    stroke(color_current);
/*    if(presionado)
      fill(color_on);
    else
      fill(color_off);*/

    fill(color_current);
    rect(x,y,ancho,alto);
  }
  void update(){
    if(isOver()){
      color_current= color_over;
    }
    else if(presionado)
      color_current = color_on;
    else
      color_current= color_off;       
     
    if(mousePressed && isOver() && !locked){     
      presionado = !presionado;     
    }   

  }
  boolean encendido(){
    return presionado;
  }
  boolean pressed()
  {
    locked = over;
    return locked;
  }
 
  boolean isOver(){
    over = (mouseX>=x && mouseX<=x+ancho && mouseY>=y && mouseY<=y+alto);
    return over;
  }
}

y esté es el código del sketch principal

/*Test display DA05 usando Arduino Duemilanove
  por Dennys Regalado Díaz
  10/03/09
*/


import processing.serial.*;
 
Serial port;
boolean locked=false;
Segmento dis7seg[];
void setup(){
  size(200,250);
  smooth();
  background(0);
  dis7seg = new Segmento[7];
  dis7seg[0] = new Segmento(55,13.620,90,13); //a
  dis7seg[1]=new Segmento(145.036,26.659,13,90); //b
  dis7seg[2]=new Segmento(145,129.961,13,90); //c
  dis7seg[3]=new Segmento(55,220,90,13); //d
  dis7seg[4]=new Segmento(42.253,129.961,13,90); //e 
  dis7seg[5]=new Segmento(42.253,26.659,13,90);//f
  dis7seg[6]=new Segmento(55,116.712,90,13); //g

  println(Serial.list());
  port = new Serial(this, Serial.list()[0], 9600);


}
//escribe un número de segmento al puerto, si está encendido
void draw(){
  update();

  for(int i=0; i<7; i++){
    dis7seg[i].display();
    if(dis7seg[i].encendido()){
      port.write('L');
    }else
      port.write('H');
  }
 
}

void update(){
  int i;
  if(locked == false) {
    for(i=0; i< 7; i++){
      dis7seg[i].update();   
    }
  }
  else {
    locked = false;
  }

  if(mousePressed) {
    //raliza el bloqueo si se esta presionando un segmento
    for(i=0; i<7; i++){
      if(dis7seg[i].pressed()){
        break;
      }
    }
 
  }
}

Por último, el código para el arduino

int pins[] = { 2, 3, 4, 5, 6, 7, 8 }; // an array of pin numbers
int num_pins = 7;
int val,i;
void setup()
{
  Serial.begin(9600);
  for(i=0; i<num_pins; i++)
    pinMode(pins[i], OUTPUT);
}

void loop()
{
  while(Serial.available() ){
    i%=7;
      val = Serial.read();
      if(val=='L')
        digitalWrite(pins[i],LOW);
      else if(val=='H')
        digitalWrite(pins[i],HIGH);
      i++;   
  }
}