Friday, November 26, 2010

LED Matrix

After a very frail Pringles Led Matrix that kept falling apart, I turned myself to a perforated board.
Better restart on the basics...

So I built a new 5x7 LED Matrix:

(Yes, this newbie is soldering on the wrong side of the board...
For all the other newbies that might let this one pass, those circles around the holes are to help soldering the components and should be on the lower side.)

I chose to use 7 anode rows and 5 cathode columns, for no particular reason.

To test the connections I used a 9V battery and a 220 Ohm resistor. That creates a current of 27mA during the test. My Leds support 30mA max, so it's fine for testing purposes.


As this matrix will be controlled by an Arduino, the circuit voltage will be 5V. So I soldered 100 Ohm resistors to the columns, so that at any given time the lit LED closing the circuit receives the datasheet recommended 20mA at 5V. I chose to connect the resistors with the columns because that way I would only need 5 resistors. I could connect them to the rows, as they would have the same effect on the circuit.


In order to connect the rows without touching the columns, I use a screwdriver to help me bend the ends.


This circuit has 12 ends, and all must connect to the Arduino. The simplest form to connect them is by linking each end to an Arduino pin. As the resulting circuit is still very frail and hard to manage, and I didn't have enough parts to make a better solution, I connected the Arduino to a breadboard so I could test the circuit.
You will notice a potentiometer also connected to the Arduino. I used it to control the refresh rate of the matrix, by defining the value passed to the delay function between each pass.


The hardest part was to connect the circuit to the breadboard, because I had very little space to maneuver the LEDs ends below the board. Also I only had some already cut wires (in groups of 5 for each length) for use with a breadboard, that are not fit for this kind of connections. As you can see I had to use two wires with claw ends for the two remaining pins. Connected to those claws are ends I had to cut of broken LEDs, in order to connect to the breadboard below.



Well now to program the Arduino:
//
// Controlo de uma matriz de LEDs 5x7
// thylux
//

void setup() 
{
// Positivos
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
// Negativos
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

//Serial.begin(9600);
}

int freq = 1000 / 600; // Hz
int b[5][7];
int pot = 0;

//   2   3   4   5   6   7   8 
// -----------------------------
// |7 1|6 1|5 1|4 1|3 1|2 1|1 1| 9
// ----------------------------- 
// |7 2|6 2|5 2|4 2|3 2|2 2|1 2| 10
// -----------------------------
// |7 3|6 3|5 3|4 3|3 3|2 3|1 3| 11
// -----------------------------
// |7 4|6 4|5 4|4 4|3 4|2 4|1 4| 12
// -----------------------------
// |7 5|6 5|5 5|4 5|3 5|2 5|1 5| 13
// -----------------------------

void loop() 
{
//char debug[10];

// Demo
for(int i = 1; i <= 5; i++)
{
for(int j = 1; j <= 7; j++)
{
light(i, j);
pot = map(analogRead(A0), 0, 1023, 0, 500);
delay(pot);

/*sprintf(debug, "i:%d j:%d", i, j);
debug[9]='\0';
Serial.println(debug);*/
}
}

int i=0;
while(i<1000)
{
write('a');
i++;
}
}

void write(char chr)
{ 
switch(chr)
{
case 'a':
case 'A':
b[0][0]=1; b[1][0]=1; b[2][0]=1; b[3][0]=1; b[4][0]=1;
b[0][1]=1; b[1][1]=0; b[2][1]=0; b[3][1]=0; b[4][1]=1;
b[0][2]=1; b[1][2]=0; b[2][2]=0; b[3][2]=0; b[4][2]=1;
b[0][3]=1; b[1][3]=1; b[2][3]=1; b[3][3]=1; b[4][3]=1;
b[0][4]=1; b[1][4]=0; b[2][4]=0; b[3][4]=0; b[4][4]=1;
b[0][5]=1; b[1][5]=0; b[2][5]=0; b[3][5]=0; b[4][5]=1;
b[0][6]=1; b[1][6]=0; b[2][6]=0; b[3][6]=0; b[4][6]=1;

}

for(int i = 1; i <= 5; i++)
{
for(int j = 1; j <= 7; j++)
{
if(b[i-1][j-1] == 1)
light(i, j);
}
}
}

// Ilumina apenas o LED indicado de acordo com a posicao na matriz
void light(int line, int column)
{
reset();

switch(column)
{
case 1: digitalWrite(2, HIGH); break;
case 2: digitalWrite(3, HIGH); break;
case 3: digitalWrite(4, HIGH); break;
case 4: digitalWrite(5, HIGH); break;
case 5: digitalWrite(6, HIGH); break;
case 6: digitalWrite(7, HIGH); break;
case 7: digitalWrite(8, HIGH); break;
}

switch(line)
{
case 1: digitalWrite(9, LOW); break;
case 2: digitalWrite(10, LOW); break;
case 3: digitalWrite(11, LOW); break;
case 4: digitalWrite(12, LOW); break;
case 5: digitalWrite(13, LOW); break;
}

pot = analogRead(0);
if(pot <= 0)
pot = 1;

pot = 1000/(600+(400/pot));
Serial.println(pot);

delay(pot);
}

void reset()
{
for(int i = 2; i<=8; i++)
digitalWrite(i, LOW);
for(int i = 9; i<=13; i++)
digitalWrite(i, HIGH);
}


This is just a basic program to try out the matrix. It lights only 1 LED at any given time and defines a very high refresh rate, so that to our eyes it would seem that all LEDs are on at the same time (persistance of vision - POV).
We use digitalWrite() to define if the pin(i) will provide 5V (HIGH) or act as GND - 0V (LOW).
To light a LED we need to HIGH the anode controlling pin and to LOW the cathode controlling pin.
With analogRead() we can read a number between 0 and 1023 from an analog pin, and with a potentiometer connected to it, we can physically control variables, as the delay between the lighting of a LED. For a friendlier range of values there is the map() function.

So after some programming this is the end result:



After some research for other Led Matrices on the web I found an interesting tutorial on hackaday. Now I will try to use more Leds on my matrix to make the best use of Arduino.
But there are some things to take into consideration...

My Led Matrix works because I'm only lighting ONE led a a time. If I tried to light more than two Leds in the same row/column at the same time I would burn my Arduino.
As you can see in the datasheet, each pin can only support 40mA. In lighting 1 Led, in this matrix, it creates a current of 20mA (as defined above). With 2 Leds lid, 40mA will run on the circuit.
As you probably can already tell, this current could be supplied by two different pins, but it would be received on another pin connected as output, or would use same input and different outputs. These pins are not real GND, only regular pins set at 0V to create the electron flow. And they can only support 40mA of it...

So to correct this issue I should be using transistors, but that I'll talk about in the next post (part 2).

Saturday, November 20, 2010

Aula Prática de Reciclagem de Motores

Fui recentemente a uma aula sobre reciclagem de motores na Audiência Zero. Por 10€ passamos 4 horas a aprender como interligar o Arduino a motores eléctricos, para além da teoria básica necessária.
Foi bastante interessante e fiquei bastante surpreendido com o conceito e actividades da associação 'Audiência Zero'.

Usamos um motor do tipo Stepper, que dá pequenos passos precisos de acordo com os comandos programados no Arduino.
Existem motores mais simples, que correm de acordo com a energia fornecida, mas que não conseguimos controlar com precisão quanto este roda durante o tempo que é alimentado.
Existem também motores do tipo Servo que podem fornecer feedback sobre o seu estado e que podem ser controlados em passos precisos.

Para controlar estes motores no Arduino só precisamos basicamente de correr uma sequência de estados, nos quais ligávamos ou desligávamos determinados outputs do Arduino, fazendo o motor rodar numa determinada direcção.
Para controlar a velocidade do motor era usada a função delay() do Arduino que provoca uma pausa na execução de instruções de acordo com o tempo em milisegundos que fornecermos à função.

Eis algumas imagens (um pouco desfocadas) do que aprendemos:

Ligamos um chip próprio para controlo de motores ao Arduino de acordo com a datasheet deste.
4 outputs para o motor (fios vermelhos), 4 inputs do Arduino (fios pretos), 4 ligações a terra/GND (fios verdes), 2 ligações ao +5V (fios azuis) e outras 2 ligações ao +5V com o propósito de activar a lógica do chip (fios azuis escuro).
O Arduino fornece energia à breadboard com um fio vermelho para +5V e um preto para GND.


A bancada de trabalho.


Ligamos um potenciómetro a um input analógico do Arduino para servir como o controlo de velocidade do motor. Este input era lido (como um valor entre 0 e 1024) e fornecido como valor passado à função delay() do Arduino. Quanto maior o tempo entre passos menos força o motor tinha para efectuar um passo.


O resultado final!

Friday, November 19, 2010

Andruino

My two newest hobbies are Android and Arduino.

So I thought of a way to combine them.

Wouldn't it be cool to be able to compile and upload code from an Android phone to an Arduino?

In the next days I'll search about that possibility and related issues.