Thursday, November 17, 2011

First Hack - The LED Strip

Finally finished my first hack.

I needed a light for my kitchen counter, so I ordered a LED Strip from eBay and hacked an AC adapter to include an ON / OFF button and to connect it to mains without using a power socket.

So here's the theoretical work:

To cover the surface of my counter I used 48 segments of the LED strip (about 2 meters). Each segment has 3 white SMD leds (type 3528) and a 150 Ohm resistor. For it to work it needs a 12V power source with sufficient current output.
After learning from [ladyada] about these strips I figured that the theoretical current each segment needs to function at it's maximum is 16 mA. That is:
12V total - (3 leds * 3.2V) / 150R = 0.016A

For the total 48 segments that's 768 mA, resulting in under 10W lighting!!!
For that I bought a SMPS AC adapter in order to guarantee the regulated 12V while using that much current. An average (unregulated) AC adapter wouldn't provide nor the 12V neither near the maximum 1A stated. [ladyada] also shed me some lights on that matter.

White LED StripSuitable AC AdapterThe best switch button I could find

For the practical work:

As you will see for yourself, the tools weren't exactly the best suited for the job: a kitchen knife to cut, a soldering iron to remove plastic, a hammer and a nail to open holes...

The innards of a power outletMains power derivationAdhesive cable duct

In order to cut the space for the switch button in the AC adapter, my kitchen knife wasn't enough, so I used my soldering iron to heat a metal needle and a kind of a thick clip used by stores to keep shirts folded in it's package. Even so it was a hard work.

Pierced top cover from the AC AdapterCreating the space for the switch buttonThe working conditions

Then I just needed to solder the switch button and the wire to the board and cover it all with electrical tape.

The final cutConnecting the switch buttonThat's a wrap

And there we have it!
Our working LED Strip!


Tuesday, September 6, 2011

Project: NiteLite

Problem: I would like to be able to go to my kitchen at night without having to turn on the fluorescent ceiling lamp for a short stay.

Solution:
I will try to build a night light with a motion sensor to light some leds and a luminosity sensor to turn the device on only in the dark.

For me to understand better about circuitry I will avoid using micro-controllers as well.

More details in a few days...

Thursday, August 18, 2011

Root for HTC Desire

It's been a while since I rooted my HTC Desire and I should have written about it at the time.

HTC smartphones have a security check so that the ROM can't be written called S-ON.
To have a full root, you need to S-OFF, but for most cases that won't be necessary.

It is possible to have regular root and to use custom ROMs when S-ON, using a custom recovery image. The recovery is a command line shell used to control the ROM.

For HTC Desire and some other HTC smartphones, you can use the simple method of unrevoked:
- unrevoked Home Page
- unrevoked Wiki

Just need to install the drivers for your smartphone, and run the unrevoked tool (don't forget to backup EVERYTHING, because you never know what can go wrong). It will restart your phone and install a ClockworkMod recovery image and root your phone.

After this process you can install any custom ROM and use apps that require root.

I recommend as a first install Titanium Backup for an easy tool to manage your backups of apps and data.

Titanium Backup QR Code:

Monday, July 25, 2011

PIR Motion Sensor

Finally got some time (and patience) to try out one of the first electronic components I bought. The SparkFun PIR Motion Sensor.

It's use on Arduino is quite simple. When a motion is detected the black (the GND wire is brown on this sensor!) wire carries a LOW state.

I tested it based on what I found on this site .

Providing 5V from the Arduino to the PIR might make it unstable, as the board has a 5V regulator in it. So it is better to connect it to a 12V power source. The signal will come out with a 5V limit, so you don't need to worry about ruining your Arduino.


Anyhow, you'll see it being used in a personal project very soon (I hope)!

Tuesday, June 7, 2011

7 Segment Display

So now it's time to control a 7 Segment Display.

I got mine from Sparkfun.
There you can find the datasheet as well as some examples of how to use.



It has 16 pins and for you to be able to use all digits, it multiplexes the anodes. There's a cathode for each pin and 8 anodes for the digit segments and the following dot.
Because of these common anodes, we can only light up one digit at a time for them to show different results.

To control it I used an Arduino connected to a Shift Register. As its specs are 2.1V on 20mA, for the 5V output from the Arduino we need 150 Ohm resistors.
I only have 3 at the moment, and there are 7 output pins on the display to connect to.

So I used some serial (100 Ohm + 47 Ohm) and parallel (220 Ohm + 470 Ohm).
If you need to refresh your theory on calculating resistors or reading the values, hail to Wikipedia.

This is the simplified circuit, without resistors, so that it is easier to view what the connections are.

The next photos are for the complete setup, but can be somewhat confusing. Sorry about that...





The basic usage of this setup is to control what pins from the shift register sink current from the displays anodes and which digit is lit on a given moment with the Arduino.

And now for some code:
//
// thylux
// 7-Segment 4-digit display control using a 74HC595N shift register
//
// This driver only supports writing the digits for the moment
// As the Shift Register controls the anodes (sink current), we need to set the outputs as LOW to turn a light ON

// Display definitions
//
//  __A__
// |     |          Vcc < 2.1V, 20mA --> R = 150 Ohm
// F     B          
// |__G__|
// |     |
// E     C          DIG1 = 1, DIG2 = 2, DIG3 = 6, DIG4 = 8, COLON_P = 4, APOSTROPHE_P = 10
// |__D__|        A = 14, B = 16, C = 13, D = 3, E = 5, F = 11, G = 15, DP = 7, COLON_N = 12, APOSTROPHE_N = 9
//

// Shift Register definitions
//
//   VCC Q0  DAT ENB LAT CLK RES OVR
// ---+---+---+---+---+---+---+---+---        Vcc < 5V, 70mA --> R = 72 Ohm
// |                                  |        Qn < 20mA
// D             74HC595N              |
// |                                  |
// ---+---+---+---+---+---+---+---+---
//   Q1  Q2  Q3  Q4  Q5  Q6  Q7  GND
//

// Display connection to Shift Register (direct breadboard connections)
// Q1 -> B, Q2 -> G, Q3 -> A, Q4 -> C, Q5 -> D, Q6 -> F, Q7 -> E

// Character mapping
//                 HBGACDFE
byte chars[11] = {B10100000, // 0
          B10110111, // 1 
          B10001010, // 2
          B10000011, // 3
          B10010101, // 4
          B11000001, // 5
          B11000000, // 6
          B10100111, // 7
          B10000000, // 8
          B10000101, // 9
                  B11111111};// blank

// Arduino pin definition
int _LATCH = 12;
int _CLOCK = 11;
int _DATA = 10;
int _DIG1 = 7;
int _DIG2 = 6;
int _DIG3 = 5;
int _DIG4 = 4;

#define _BUFF_SIZE   4
#define _SHOWTIME    50

// initializes the buffer with empty characters
byte buffer[_BUFF_SIZE] = { chars[10], chars[10], chars[10], chars[10] };
int digits[_BUFF_SIZE] = { _DIG1, _DIG2, _DIG3, _DIG4 };

void setup()
{
  pinMode(_LATCH, OUTPUT);
  pinMode(_CLOCK, OUTPUT);
  pinMode(_DATA, OUTPUT);

  // TODO: Can a 555 reduce these 4 pins to 1?
  pinMode(_DIG1, OUTPUT);
  pinMode(_DIG2, OUTPUT);
  pinMode(_DIG3, OUTPUT);
  pinMode(_DIG4, OUTPUT);
    
  Serial.begin(9600);
}

void loop()
{
  for(int i = 0; i < 100; i++)
  {
    fillBuffer(i);
    for(int j = 0; j < _SHOWTIME; j++)
      writeScreen();
  }
  
  // Clean the latch for the next execution
  // TODO : needed???
  digitalWrite(_LATCH, LOW); // Begin Write
  shiftOut(_DATA, _CLOCK, LSBFIRST, chars[10]);
  digitalWrite(_LATCH, HIGH);  // End Write
}

void fillBuffer(int num)
{
  bool cleanChar = false;
  
  if(num==0)
  {
    buffer[_BUFF_SIZE - 1] = chars[0];
    return;
  }
    
  for(int i = _BUFF_SIZE - 1; i >= 0; i--)
  {
    if(num==0 && cleanChar) // We need to make sure that all the unused buffer positions are cleaned
      buffer[i] = chars[10];
    else
    {
      buffer[i] = chars[num > 9 ? num%10 : num];
      num/=10;
      cleanChar = true;
    }
  }
}

void writeScreen()
{
  for(int i = 0; i < _BUFF_SIZE; i++)
  {
    for(int i = 0; i < _BUFF_SIZE; i++)
      // TODO: find if it is possible to turn HIGH and LOW an entire PORT
      digitalWrite(digits[i], LOW);
      
    /*
    shiftOut(dataPin, clockPin, bitOrder, value)

    dataPin:     the pin on which to output each bit (int)
    clockPin:     the pin to toggle once the dataPin has been set to the correct value (int)
    bitOrder:     which order to shift out the bits; either MSBFIRST or LSBFIRST. (Most Significant Bit First, or, Least Significant Bit First)
    value:         the data to shift out. (byte) 
    */
    
    digitalWrite(_LATCH, LOW); // Begin Write
    shiftOut(_DATA, _CLOCK, LSBFIRST, buffer[i]);
    digitalWrite(_LATCH, HIGH);  // End Write
    
    digitalWrite(digits[i], HIGH);
    
    delay(3);
  }
}

I believe that this code could be more efficient (a quick side note - Performant isn't a word), so I'll look up ways to make it better. As a proof of concept, works just fine!

Tuesday, May 31, 2011

Python for fun

Interested in learning Python?
I found this site with several well documented small projects that will make an interesting way to learn this language.