Wednesday, December 15, 2010

Andruino (Cont.)

I've done some searching about the possibility to being able to compile arduino sources on an Android device and upload it to the Arduino via USB.

Well, I've learned that the stock Android doesn't support the use of the USB port, so it could only be done by rooting your device.

For this to work your device should also be able to use USB OTG, as it would have to be the server in the connection to the Arduino.

Here's the best shot so far to be able to implement this idea.

However it is possible to communicate via bluetooth or WiFi with the stock Android, but for the Arduino that would require an extra shield (XBee) or a specific board (Arduino BT).
There is a project for this, called Amarino. It is designed specifically for communication between Android and Arduino by Bluetooth.

Also I found that the stock Android source for HTC phones is shared here.
This can give people hints on how to circumvent the software limitation.

If rooting your device is an option, Cellbots is the way to go.

Saturday, December 4, 2010

Big LED Matrix

In my last post I built a 5x7 LED matrix. After reading this hackaday article, I decided to expand my LED matrix to the most.


In order to reuse the board I had to grow on the columns, which are 7 leds each.
So I soldered 7 more columns to a total of 12. With the existing 7 rows, I will need now 19 pins of the Arduino, the same as in the Jack-o-lantern (14+5), but my matrix totals 84 leds, against 70 of the mentioned article.


As I'm lighting by column, I can send a current of 20mA for the 7 leds to total the same safe 140mA to the Arduino.

In the previous post I also mentioned the issue when each pin of the Arduino can only support a 40mA current. To solve it we need to connect transistors to the matrix cathodes, for diverting that current to a real GND pin. That way, the Arduino pins that were connected to the cathodes will now connect to the base pin of each transistor, and the other pins will receive the total column current and send it to GND.
Notice that the GND pins can only support up to 200mA.


There are two types of transistors we can use in this case.
Here's the basic lecture I read on their differences.
In this case the difference will be how to program the Arduino. Using NPN transistors means we need to set the pin to HIGH to light a led column, an using PNP transistors the pin has to be LOW.

I wanted to use PNP transistors because that way I could save my NPN for other projects. But after some tests on finding the best resistor to attach to the base, I didn't achieve any satisfactory result, in comparison to the currents I could obtain using NPN transistors.

According to the math, I should be using 100 Ohm resistors for each line, and 2.2k Ohm resistors for the base of each transistor, but after some tests with a multimeter, those numbers were quite different from the reality.
I ended up using 47 Ohm for the lines and 1k Ohm for the transistors.
[WILL TRY TO UNDERSTAND THIS BETTER]

I used a flat ribbon for the wires to the Arduino. The male connector soldered on the board may look as a tidy way to use, but it's a nighmare to solder the wires, so I wouldn't recommend to use it for this kind of amateur project...

To finish the hardware I applied hot glue on the connections for isolation and fixation.


Now it's time for the software...

//
// Controlo de uma matriz de LEDs 12x7
// thylux
//
int L01 = 4;
int L02 = 6;
int L03 = 5;
int L04 = 8;
int L05 = 10;
int L06 = 12;
int L07 = 11;
int C01 = A5;
int C02 = A4;
int C03 = A3;
int C04 = A2;
int C05 = A1;
int C06 = A0;
int C07 = 0;
int C08 = 1;
int C09 = 2;
int C10 = 3;
int C11 = 7;
int C12 = 9;

void setup()
{
  // Positivos
  pinMode(L01, OUTPUT);
  pinMode(L02, OUTPUT);
  pinMode(L03, OUTPUT);
  pinMode(L04, OUTPUT);
  pinMode(L05, OUTPUT);
  pinMode(L06, OUTPUT);
  pinMode(L07, OUTPUT);
  // Negativos
  pinMode(C01, OUTPUT);
  pinMode(C02, OUTPUT);
  pinMode(C03, OUTPUT);
  pinMode(C04, OUTPUT);
  pinMode(C05, OUTPUT);
  pinMode(C06, OUTPUT);
  pinMode(C07, OUTPUT);
  pinMode(C08, OUTPUT);
  pinMode(C09, OUTPUT);
  pinMode(C10, OUTPUT);
  pinMode(C11, OUTPUT);
  pinMode(C12, OUTPUT);

  //Serial.begin(9600);
}

int freq = 1000 / 600; // Hz
void loop()
{
  //char debug[10];
  
  // Demo
  for(int i = 1; i <= 12; i++)
  {
      for(int j=0; j<7; j++)
      {
        light(i, (byte) 2^j);
        delay(100);
      }
        
      //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<10000)
  {
      writeSymbol('a');
      i++;
  }
  
  i = 0;
  while(i<10000)
  {
      writeSymbol('b');
      i++;
  }
}

void writeMessage(char* msg)
{
  for(int i = 0; i < sizeof(msg); i++)
    writeSymbol(msg[i]);
}

void writeSymbol(char chr)
{
  switch(chr)
  {
      case 'a':
      case 'A':
        light(1, B1111100);
        light(2, B0010010);
        light(3, B0010001);
        light(4, B0010010);
        light(5, B1111100);
        break;
      case 'b':
      case 'B':
        light(1, B1111111);
        light(2, B1001001);
        light(3, B1001001);
        light(4, B1001001);
        light(5, B0111110);
        break;
  }
}

// Ilumina os LED indicados na coluna
void light(int column, byte data)
{
  reset();
  
  switch(column)
  {
      case 1: digitalWrite(C01, HIGH); break;
      case 2: digitalWrite(C02, HIGH); break;
      case 3: digitalWrite(C03, HIGH); break;
      case 4: digitalWrite(C04, HIGH); break;
      case 5: digitalWrite(C05, HIGH); break;
      case 6: digitalWrite(C06, HIGH); break;
      case 7: digitalWrite(C07, HIGH); break;
      case 8: digitalWrite(C08, HIGH); break;
      case 9: digitalWrite(C09, HIGH); break;
      case 10: digitalWrite(C10, HIGH); break;
      case 11: digitalWrite(C11, HIGH); break;
      case 12: digitalWrite(C12, HIGH); break;
  }
  
  digitalWrite(L01, data & B0000001 ? HIGH : LOW);
  digitalWrite(L02, data & B0000010 ? HIGH : LOW);
  digitalWrite(L03, data & B0000100 ? HIGH : LOW);
  digitalWrite(L04, data & B0001000 ? HIGH : LOW);
  digitalWrite(L05, data & B0010000 ? HIGH : LOW);
  digitalWrite(L06, data & B0100000 ? HIGH : LOW);
  digitalWrite(L07, data & B1000000 ? HIGH : LOW);
  
  delay(freq);
}

void reset()
{
  digitalWrite(L01, LOW);
  digitalWrite(L02, LOW);
  digitalWrite(L03, LOW);
  digitalWrite(L04, LOW);
  digitalWrite(L05, LOW);
  digitalWrite(L06, LOW);
  digitalWrite(L07, LOW);
  
  digitalWrite(C01, LOW);
  digitalWrite(C02, LOW);
  digitalWrite(C03, LOW);
  digitalWrite(C04, LOW);
  digitalWrite(C05, LOW);
  digitalWrite(C06, LOW);
  digitalWrite(C07, LOW);
  digitalWrite(C08, LOW);
  digitalWrite(C09, LOW);
  digitalWrite(C10, LOW);
  digitalWrite(C11, LOW);
  digitalWrite(C12, LOW);
}

Note:
During my initial tests I couldn't understand why the columns connected to pin 0 (RX) and pin 1 (TX) were always HIGH.
I found later that it was caused by turning on Serial communication with Serial.begin().
The Serial was used to send debug information to the computer, so if you try to debug my program don't be alarmed by some row/column of leds not behaving as intended.