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}
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 = "";
}
}
Cómo leer píxeles de una imagen y mostrarlos con un LED RGB
La idea de escribir este sketch surgió por un comentario de Pedro que recibí hace una semana. Después de ver unos ejemplos (Examples->Topics->Image Processing->PixelArray) me dí cuenta que el programa era muy sencillo de escribir.
El objetivo cargar una imagen en Processing y de acuerdo a la posición del cursor del mouse, leer ese pixel y enviarlo al Arduino para que éste lo muestre usando un LED RGB.
El código para el Arduino es el mismo que usé en el post Controlando led RGB al ritmo de la música, solo se encarga de descomponer el color (enviado en hexadecimal) y luego escribir los valores Red, Green, Blue a las salidas PWM 9, 10, 11.
Este es un extracto del código en el que se asignan los pines de salida al LED RGB:
#define G_LED 9
#define B_LED 10
El código en Processing es el siguiente:
* PixelArray
* por Dennys Regalado Díaz
*
* Posiciona el cursor del raton sobre la imagen, obtiene el color del pixel,
* lo envía al Arduino y lo muestra con un LED RGB
* 2 de Mayo del 2009
*/
import processing.serial.*;
PImage a;
int[] aPixels;
float signal;
String cs;
int last_color = -1;
Serial port;
void setup()
{
a = loadImage("test.jpg");
size(a.width, a.height);
aPixels = new int[a.width*a.height];
noFill();
stroke(255);
frameRate(10);
//configura puerto serial
println(Serial.list());
port = new Serial(this, Serial.list()[0], 9600);
}
void draw()
{
image(a,0,0);
if(mouseY > height-1)
mouseY = height-1;
if(mouseY < 0)
mouseY = 0;
signal = mouseY*a.width + mouseX;
rect(signal%a.width-5, int(signal/a.width)-5, 10, 10);
point(signal%a.width, int(signal/a.width));
color c = a.pixels[int(signal)];
// println(red(c)+","+green(c)+","+blue(c));
//Envia datos al arduino
if(c!=last_color){
cs = "#" + hex(c,6); // Prepare a string to be sent to Arduino
port.write(cs);
last_color=c;
}
fill(c);
rect(width-20,height-20,20,20);
noFill();
}
Controlando led RGB al ritmo de la música
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:
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
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
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
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
Este es el código de ejemplo que viene con el IDE, Examples->Library-servo->Knob
// 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
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

tarjeta arduino
Desarrollo
Lo dividí en dos fases:
- Interfaz en processing que permite establecer el estado de los segmentos (on/off) a través de un click, funciona como un toggle button.
- 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.
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
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 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++;
}
}

