For a coming project I'll need to know if a room has the lights on or off.
That's when a Light Dependent Resistor (LDR), or photocell comes in handy.
As usual, Ladyada provides an excellent tutorial on understanding and using electronics: Ladyada's 101 on LDR
I also found useful info here.
For the LDR that I have, I'm using this Datasheet. I'm not sure if this is the correct datasheet, but for this component I think it should be close enough.
The quantity of light can be measured in Lux, Lumen or Candela depending on several factors.
Here's some more info.
In this case, here's a table of some real world approximate Lux values, in order to understand the values we need to read:
Light source LUX
---------------------------
Moonlight 0.1
60W Bulb at 1m 50
1W Bulb at 0.1m 100
Fluorescent Lighting 500
Bright Sunlight 30,000
The resistance of a LDR can vary from +/-400 Ohm (for Bright Sunlight) to +/- 2 MOhm (in the Dark), depending also on the make of the component.
Here are some of the values I measured (from bright to dark):
Showing posts with label Arduino. Show all posts
Showing posts with label Arduino. Show all posts
Monday, July 9, 2012
Monday, January 23, 2012
Understanding Servo Motors
"Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the Arduino board. The signal pin is typically yellow, orange or white and should be connected to a digital pin on the Arduino board. Note servos draw considerable power, so if you need to drive more than one or two, you'll probably need to power them from a separate supply (i.e. not the +5V pin on your Arduino). Be sure to connect the grounds of the Arduino and external power supply together."
I bought my Servo motors from InMotion who imported them from SparkFun.
It's easy to control a Servo with Arduino using the libraries distributed with the Arduino IDE, but with only three wires, how is that controlled?
A servo motor expects a PWM signal with a very specific period and duty time.
Usually a 20ms period and a 1ms to 2ms as duty time.
On a regular servo the minimal duty cycle means a 0º position, the maximum corresponds to 180º and half way equals 90º.
On a full rotation servo, each period to motor rotates acording to the duty cycle.
Under 1,5ms rotates counter-clockwise and above 1,5ms rotates clockwise.
Controlling a servo from Arduino:
To test the theoretical knowledge I tried to run this simple sketch:
Worked fine!
But for the best control, why not use a tested and proven library?
So I used Arduino's IDE Sweep example that rotates the Servo from side to side (0 to 180 degrees and back) using a class designed for that purpose.
The Sweep example seems simple and self-explanatory for me to give more detail about it.
In my full rotation servo I noticed that it rotated more going counter-clockwise than when moving clockwise.
I don't know why does it happen...
I bought my Servo motors from InMotion who imported them from SparkFun.
It's easy to control a Servo with Arduino using the libraries distributed with the Arduino IDE, but with only three wires, how is that controlled?
A servo motor expects a PWM signal with a very specific period and duty time.
Usually a 20ms period and a 1ms to 2ms as duty time.
On a regular servo the minimal duty cycle means a 0º position, the maximum corresponds to 180º and half way equals 90º.
On a full rotation servo, each period to motor rotates acording to the duty cycle.
Under 1,5ms rotates counter-clockwise and above 1,5ms rotates clockwise.
Controlling a servo from Arduino:
To test the theoretical knowledge I tried to run this simple sketch:
void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(9, HIGH);
delay(2);
digitalWrite(9, LOW);
delay(18);
}
Worked fine!
But for the best control, why not use a tested and proven library?
So I used Arduino's IDE Sweep example that rotates the Servo from side to side (0 to 180 degrees and back) using a class designed for that purpose.
The Sweep example seems simple and self-explanatory for me to give more detail about it.
In my full rotation servo I noticed that it rotated more going counter-clockwise than when moving clockwise.
I don't know why does it happen...
Thursday, January 19, 2012
Nokia 5110 LCD
I bought a SparkFun Nokia 5110 LCD through InMotion. Both sites have the datasheet and example documentation for how to use it.
Adafruit also sells this and documents its use with another excellent Ladyada tutorial.
Here it is with connectors already soldered:
The soldering is pretty bad. Maybe I should buy a new tip for my soldering iron...
This screen supports direct connection to an Arduino (5V), but in doing so we push it to the datasheet defined limits, so to it is best to reduce all signals to a confortable 3.3V.
My Arduino Duomilanove only outputs 5V signals, so in order to translate those signals to 3.3V, the simplest way is to use a Voltage Divider.
I used this site to calculate the best resistor values to use for this case (10kOhm and ~5kOhm).
Adafruit offers a free level shifter with the LCD that can be used as a more efficient Voltage Divider.
Also to light up the 4 leds used as backlight I used a 22Ohm resistor, so that I could connect to a 5V signal on the Arduino in order to control them with PWM.
And here it is using the Arduino example code 2:
Adafruit also sells this and documents its use with another excellent Ladyada tutorial.
Here it is with connectors already soldered:
![]() | ![]() |
The soldering is pretty bad. Maybe I should buy a new tip for my soldering iron...
This screen supports direct connection to an Arduino (5V), but in doing so we push it to the datasheet defined limits, so to it is best to reduce all signals to a confortable 3.3V.
My Arduino Duomilanove only outputs 5V signals, so in order to translate those signals to 3.3V, the simplest way is to use a Voltage Divider.
I used this site to calculate the best resistor values to use for this case (10kOhm and ~5kOhm).
Adafruit offers a free level shifter with the LCD that can be used as a more efficient Voltage Divider.
Also to light up the 4 leds used as backlight I used a 22Ohm resistor, so that I could connect to a 5V signal on the Arduino in order to control them with PWM.
![]() | ![]() |
And here it is using the Arduino example code 2:
![]() | ![]() |
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)!
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:
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!
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!
Monday, April 25, 2011
Arduino Standalone
After setting a Arduino on a Breadboard I also needed to be able to make work without a computer or an Arduino Board to provide power.
The ATMega needs a 5V power source, and I want to be able to power it on any regular wall wart. How can this be done?
Small electronics need some kind of rectifier to take the Alternate Current (AC) you get in your house outlets (220V in most of europe) to something as small as 5-12V of Direct current (DC) (if you want to know more about AC and DC you can read the 'War of Currents' article on Wikipedia).
To be able to ensure a smooth 5V DC to the circuit, I used a 7805 rectifier. In order to use it correctly you need a diode and two capacitors. Here's the schematic I used.
This rectifier has an input limit of 40V DC (but it is recommended to use from 7 to 12V), so we still need an AC-DC adapter capable of providing the recommended input to the 7805.
To test it all, I connected a LED to the Arduino running a Blink example:
The ATMega needs a 5V power source, and I want to be able to power it on any regular wall wart. How can this be done?
Small electronics need some kind of rectifier to take the Alternate Current (AC) you get in your house outlets (220V in most of europe) to something as small as 5-12V of Direct current (DC) (if you want to know more about AC and DC you can read the 'War of Currents' article on Wikipedia).
To be able to ensure a smooth 5V DC to the circuit, I used a 7805 rectifier. In order to use it correctly you need a diode and two capacitors. Here's the schematic I used.
This rectifier has an input limit of 40V DC (but it is recommended to use from 7 to 12V), so we still need an AC-DC adapter capable of providing the recommended input to the 7805.
To test it all, I connected a LED to the Arduino running a Blink example:
Sunday, April 17, 2011
Breaduino
In order to use the Arduino IC on a real board, we need to learn how to use it.
There's a common type of Arduino configuration for this called Breaduino (derived for Arduino on a Breadboard).
What I want to use is the minimal configuration, in order to avoid buying an external crystal oscillator, knowing that it is possible to use the IC's internal oscillator.
These oscillators are what sets the pace for a circuit. The faster the oscillator can go, the faster can the IC make calculations.
My Arduino is a Duemilanove an has an ATMega328p IC. In the datasheet it is stated that we can use an external oscillator up to 20 MHz (for Arduino we should use one at 16 MHz). The internal oscillator runs at 8 Mhz, but these frequencies can be divided by 8 using configuration (I'll write more about it in the end).
Once again the Arduino site has very good references and tutorials:
- Arduino To Breadboard
- Standalone
- Disabling Auto Reset (You'll need this one, even not being mentioned on the above tutorials)
If you look for the 'Minimal Circuit (Eliminating the External Clock)' sections you'll find an illustrated guide on how to configure the Arduino IDE and to connect the IC to the breadboard for both burning the bootloader and programming the IC.
After reading all of these and much more, I still couldn't burn a bootloader for using the internal oscillator on the ATMega328. Because of that I read and learned about understanding the configurations of the IDE, programming the ATMega by command line using AVRdude, and setting the fuses (configuration of the IC) in order to configure its behavior.
So why couldn't I burn the bootloader using the Minimal Circuit?
All my ATMega came preloaded with the regular Arduino Bootloader for use with the Arduino Board. That way they are configured to work with an external 16 MHz crystal.
So, because of that, the ATMega that I was trying to burn a bootloader into wasn't working. It needed the external crystal as configured for me to be able to burn a different bootloader.
Some of the errors I've seen because of this (both on Arduino IDE and running avrdude by command line):
- avrdude: Yikes! Invalid device signature;
- avrdude: Device signature = 0x00000000;
- avrdude: Expected signature for ATMEGA328P is 1E 95 0F;
- avrdude: stk500_getsync(): not in sync: resp=0x00;
- avrdude: stk500_getsync(): not in sync: resp=0x15;
Well, I had to buy a 16 MHz crystal after all.
To sum it up, what I had to do was:
1) In the \hardware\arduino\boards.txt add the breadboard settings below
2) On Arduino IDE, load the ArduinoISP sketch of the Examples tab to the Arduino Board;
3) Set the hardware as in the images on the ArduinoToBreadboard tutorial (with the external crystal). Also you will need to disable the Auto-Reset feature if your board has it (and Duemilanove does have it);
4) (Optional) I read the comments on the ArduinoISP sketch and it talks about some pins you can use to light up some status LEDs. I used them to help me understand what was happening;
5) Upload the ArduinoISP sketch (confirm that you have the correct board configured in the IDE - in my case 'Arduino Duemilanove or Nano w/ ATMega328');
6) Make sure once again that all hardware is well connected.
7) Select the ATMega328 on a breadboard (8MHz internal clock) and burn the bootloader 'w/ Arduino as ISP'. It will take a while.
8) Now that the bootloader is set, you can upload a sketch. Don't forget to remove the ATMega from the Arduino Board, so that the ATMega on the breadboard is the one used. Also, don't forget to connect only the VCC, GND, RX and TX pins (one of my mistakes was to leave the crystal connected and because of that I couldn't upload sketches);
[edit]
A tip about setting extended_fuses (efuse):
This fuse controls the brown out detector and it can influence the correct working of the controller if you use less than 5V to power it.
There are only 4 possible values for this fuse so the controller might only read those 2 bits in the full 2 bytes reserved for the fuse.
If you can't burn a bootloader because the efuse doesn't match the expected efuse (like 0xFF != 0x07) it means that that kind of controller expects that bits 2 to 7 are the opposite of what you set (remember that they won't be really needed), so you might need to adjust the value for the fuse accordingly.
So here are the values you need with bits 2 to 7 ON and OFF:
OFF(1) ON(0) Meaning
0xFF <-> 0x07 = Brown-out detection disabled->
0xFE <-> 0x06 = Brown-out detection at VCC=1.8V->
0xFD <-> 0x05 = Brown-out detection at VCC=2.7V (Arduino 5V default)->
0xFC <-> 0x04 = Brown-out detection at VCC=4.3V->
There's a common type of Arduino configuration for this called Breaduino (derived for Arduino on a Breadboard).
What I want to use is the minimal configuration, in order to avoid buying an external crystal oscillator, knowing that it is possible to use the IC's internal oscillator.
These oscillators are what sets the pace for a circuit. The faster the oscillator can go, the faster can the IC make calculations.
My Arduino is a Duemilanove an has an ATMega328p IC. In the datasheet it is stated that we can use an external oscillator up to 20 MHz (for Arduino we should use one at 16 MHz). The internal oscillator runs at 8 Mhz, but these frequencies can be divided by 8 using configuration (I'll write more about it in the end).
Once again the Arduino site has very good references and tutorials:
- Arduino To Breadboard
- Standalone
- Disabling Auto Reset (You'll need this one, even not being mentioned on the above tutorials)
If you look for the 'Minimal Circuit (Eliminating the External Clock)' sections you'll find an illustrated guide on how to configure the Arduino IDE and to connect the IC to the breadboard for both burning the bootloader and programming the IC.
After reading all of these and much more, I still couldn't burn a bootloader for using the internal oscillator on the ATMega328. Because of that I read and learned about understanding the configurations of the IDE, programming the ATMega by command line using AVRdude, and setting the fuses (configuration of the IC) in order to configure its behavior.
So why couldn't I burn the bootloader using the Minimal Circuit?
All my ATMega came preloaded with the regular Arduino Bootloader for use with the Arduino Board. That way they are configured to work with an external 16 MHz crystal.
So, because of that, the ATMega that I was trying to burn a bootloader into wasn't working. It needed the external crystal as configured for me to be able to burn a different bootloader.
Some of the errors I've seen because of this (both on Arduino IDE and running avrdude by command line):
- avrdude: Yikes! Invalid device signature;
- avrdude: Device signature = 0x00000000;
- avrdude: Expected signature for ATMEGA328P is 1E 95 0F;
- avrdude: stk500_getsync(): not in sync: resp=0x00;
- avrdude: stk500_getsync(): not in sync: resp=0x15;
Well, I had to buy a 16 MHz crystal after all.
To sum it up, what I had to do was:
1) In the \hardware\arduino\boards.txt add the breadboard settings below
##############################################################Note that these settings are not the same as downloaded with breadboard.zip from the Arduino site;
atmega328bb.name=ATmega328 on a breadboard (8 MHz internal clock)
atmega328bb.upload.protocol=stk500
atmega328bb.upload.maximum_size=30720
atmega328bb.upload.speed=57600
atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xD8
atmega328bb.bootloader.extended_fuses=0x07
atmega328bb.bootloader.path=atmega
atmega328bb.bootloader.file=ATmegaBOOT_168_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F
atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino
2) On Arduino IDE, load the ArduinoISP sketch of the Examples tab to the Arduino Board;
3) Set the hardware as in the images on the ArduinoToBreadboard tutorial (with the external crystal). Also you will need to disable the Auto-Reset feature if your board has it (and Duemilanove does have it);
4) (Optional) I read the comments on the ArduinoISP sketch and it talks about some pins you can use to light up some status LEDs. I used them to help me understand what was happening;
5) Upload the ArduinoISP sketch (confirm that you have the correct board configured in the IDE - in my case 'Arduino Duemilanove or Nano w/ ATMega328');
6) Make sure once again that all hardware is well connected.
7) Select the ATMega328 on a breadboard (8MHz internal clock) and burn the bootloader 'w/ Arduino as ISP'. It will take a while.
8) Now that the bootloader is set, you can upload a sketch. Don't forget to remove the ATMega from the Arduino Board, so that the ATMega on the breadboard is the one used. Also, don't forget to connect only the VCC, GND, RX and TX pins (one of my mistakes was to leave the crystal connected and because of that I couldn't upload sketches);
[edit]
A tip about setting extended_fuses (efuse):
This fuse controls the brown out detector and it can influence the correct working of the controller if you use less than 5V to power it.
There are only 4 possible values for this fuse so the controller might only read those 2 bits in the full 2 bytes reserved for the fuse.
If you can't burn a bootloader because the efuse doesn't match the expected efuse (like 0xFF != 0x07) it means that that kind of controller expects that bits 2 to 7 are the opposite of what you set (remember that they won't be really needed), so you might need to adjust the value for the fuse accordingly.
So here are the values you need with bits 2 to 7 ON and OFF:
OFF(1) ON(0) Meaning
0xFF <-> 0x07 = Brown-out detection disabled->
0xFE <-> 0x06 = Brown-out detection at VCC=1.8V->
0xFD <-> 0x05 = Brown-out detection at VCC=2.7V (Arduino 5V default)->
0xFC <-> 0x04 = Brown-out detection at VCC=4.3V->
Tuesday, March 29, 2011
What is PWM?
Here is a nice article on what is Pulse Width Modulation: PWM
Basically, with PWM you can simulate a voltage by turning the pin on and off (HIGH and LOW, 5V and 0V) according to a certain frequency.
The amount of time in a cycle that the pin is on and off (duty cycle) determines the resulting voltage between the pin and the component.
On Arduino, PWM values are output with analogWrite() using values between 0 and 255.
P.S.: Here's another great article about PWM that you should read.
Basically, with PWM you can simulate a voltage by turning the pin on and off (HIGH and LOW, 5V and 0V) according to a certain frequency.
The amount of time in a cycle that the pin is on and off (duty cycle) determines the resulting voltage between the pin and the component.
On Arduino, PWM values are output with analogWrite() using values between 0 and 255.
P.S.: Here's another great article about PWM that you should read.
Thursday, March 17, 2011
The Curious Case of Pull-Up / Push-Down Resistors
What are pull-up resistors? And push-down resistors?
While trying to find answers to these questions on-line, I could only find sources too advanced for me to understand (I'm still a newbie after all).
But only after coming across some phenomena while playing with my RGB LEDs, did I understand what's the idea.
You see, one might think that if a circuit is open (like a switch) that the potential (voltage) is 0V, but actually because of the static electricity in the environment, that isn't entirely true.
There are components that need so little energy to work, that they might be influenced by that electricity.
What happened to me was that while having a LED connected only to GND, when I touched the other lead, it would light up a little.
When I tried to use a push button in a circuit connecting only one end to an output pin and the other end to an input pin of the Arduino, the Arduino would read strange values either I did or didn't press the push button.
So, these pull-up / push-down resistors are to compensate for this extra energy, forcing the circuit to a stable state.
In the push button case, I had to use a resistor in parallel with the input pin of the Arduino, so that when the button isn't pressed, it would always read 0V (LOW).
The difference between pull-up and push-down is where you use that resistor, either connecting the component to GND or to the source.
I hope to have simplified it enough. What do you think?
While trying to find answers to these questions on-line, I could only find sources too advanced for me to understand (I'm still a newbie after all).
But only after coming across some phenomena while playing with my RGB LEDs, did I understand what's the idea.
You see, one might think that if a circuit is open (like a switch) that the potential (voltage) is 0V, but actually because of the static electricity in the environment, that isn't entirely true.
There are components that need so little energy to work, that they might be influenced by that electricity.
What happened to me was that while having a LED connected only to GND, when I touched the other lead, it would light up a little.
When I tried to use a push button in a circuit connecting only one end to an output pin and the other end to an input pin of the Arduino, the Arduino would read strange values either I did or didn't press the push button.
So, these pull-up / push-down resistors are to compensate for this extra energy, forcing the circuit to a stable state.
In the push button case, I had to use a resistor in parallel with the input pin of the Arduino, so that when the button isn't pressed, it would always read 0V (LOW).
The difference between pull-up and push-down is where you use that resistor, either connecting the component to GND or to the source.
I hope to have simplified it enough. What do you think?
RGB LED Part II
After some absence, I finally got some weekend time to play with my electronics.
Now that I have 100 new RGB LEDs, it’s time for some experiments.
I wanted to know how to control the colors emitted by this LEDs so here’s how I did it.
First I searched for a datasheet and found this one on Sparkfun.
According to it, the recommended current is 20mA, and the voltages are 2.0V, 3.2V and 3.2V for red, green and blue. As I wrote on my last post, each color has a different lead, and there is another for Ground (GND). These are common cathode LEDs, as it receives energy on the leads for the colors and all that energy is returned to the circuit on a single lead.
As I source all my projects with the Arduino connected to the laptop (as it already is a regulated power source), I calculated the resistors for a 5V source power.

Connecting all wires, we can see that 3 different tiny LEDs lit up inside our 5mm RGB LED as you can see below.
Also we can see that we can’t count on a mixed color far from the LED, as the three parts point to different directions, although there might be some ways to try to improve that situation.

So the LED lights up. Big deal! Let’s play some more...
The next step is to be able to combine the three colors into making new colors.
First I tried to make a simple program on the Arduino using a (very, very poor) simulated PWM. Basically I would light up only one color at a time and tried different delay() times, to control the ‘quantity of color embedded’ in the final result. That idea came from the LED matrix project, as some kind of multiplexing.
Please, don’t waste your time on something like this.
After some online searching, I saw that the best way is to use ‘real’ PWM, as in using the PWM pins in the Arduino and analogWrite() the value (0-255) for each color. This controls the voltage at the pin, altering the luminosity of the LED. It is best to keep all color lit at the same time (not using delay()).
So now we can programmatically define the color we want to obtain, in theory. Again, with clear LEDs, it is kind of hard to observe a good mix of the light emitted by the three ‘sub-LEDs’.
But isn’t it cooler to be able to mess with those values by hand? So enter the potentiometers (pots).
My first try was to use 3 pots, to control each color. As two of them aren’t ‘breadboard friendly’, you can see below what a mess it is to connect it all.
But then I thought: “What a good opportunity to try to use push buttons.”
So I replaced the 3 potentiometers by 3 push buttons, and altered the Arduino program to cycle through the values for each color.
A simple control to avoid altering the values too much in one push was to have a small delay() after the digitalRead() of each button.



You might notice some resistors connected from each button to GND in parallel with the reader pins of the Arduino.
Those are push-down resistors.
And here is the code:
So to end it, I wanted to create a demo to cycle to all colors as simply as possible. I found ‘Hue-controllable RGB LED lamp‘ that shows how to cycle through the colors using only a Hue value.
I tried to use the conversion code directly from http://www.easyrgb.com/math.php?MATH=M21#text21, but all the values were quite wrong, so I lazily used the code akgraphics provided on the first post.
As the code was kind of slow because of lots of (unnecessary) math, I reduced it to:
Now that I have 100 new RGB LEDs, it’s time for some experiments.
I wanted to know how to control the colors emitted by this LEDs so here’s how I did it.
First I searched for a datasheet and found this one on Sparkfun.
According to it, the recommended current is 20mA, and the voltages are 2.0V, 3.2V and 3.2V for red, green and blue. As I wrote on my last post, each color has a different lead, and there is another for Ground (GND). These are common cathode LEDs, as it receives energy on the leads for the colors and all that energy is returned to the circuit on a single lead.
As I source all my projects with the Arduino connected to the laptop (as it already is a regulated power source), I calculated the resistors for a 5V source power.
V=R.I
Red --> (5 – 2.0) / 0.20 = 150 Ohm
Green / Blue --> (5 – 3.2) / 0.20 = 90 Ohm (The closest I have is 100 Ohm)

Connecting all wires, we can see that 3 different tiny LEDs lit up inside our 5mm RGB LED as you can see below.
Also we can see that we can’t count on a mixed color far from the LED, as the three parts point to different directions, although there might be some ways to try to improve that situation.

So the LED lights up. Big deal! Let’s play some more...
The next step is to be able to combine the three colors into making new colors.
First I tried to make a simple program on the Arduino using a (very, very poor) simulated PWM. Basically I would light up only one color at a time and tried different delay() times, to control the ‘quantity of color embedded’ in the final result. That idea came from the LED matrix project, as some kind of multiplexing.
Please, don’t waste your time on something like this.
After some online searching, I saw that the best way is to use ‘real’ PWM, as in using the PWM pins in the Arduino and analogWrite() the value (0-255) for each color. This controls the voltage at the pin, altering the luminosity of the LED. It is best to keep all color lit at the same time (not using delay()).
So now we can programmatically define the color we want to obtain, in theory. Again, with clear LEDs, it is kind of hard to observe a good mix of the light emitted by the three ‘sub-LEDs’.
But isn’t it cooler to be able to mess with those values by hand? So enter the potentiometers (pots).
My first try was to use 3 pots, to control each color. As two of them aren’t ‘breadboard friendly’, you can see below what a mess it is to connect it all.
![]() | ![]() | ![]() |
![]() | ||
But then I thought: “What a good opportunity to try to use push buttons.”
So I replaced the 3 potentiometers by 3 push buttons, and altered the Arduino program to cycle through the values for each color.
A simple control to avoid altering the values too much in one push was to have a small delay() after the digitalRead() of each button.



You might notice some resistors connected from each button to GND in parallel with the reader pins of the Arduino.
Those are push-down resistors.
And here is the code:
int R = 9;
int G = 10;
int B = 11;
int vR = 0;
int vG = 0;
int vB = 0;
int T = 200;
int d = 15;
void setup() {
pinMode(R, OUTPUT);
pinMode(G, OUTPUT);
pinMode(B, OUTPUT);
pinMode(7, OUTPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
digitalWrite(7, HIGH);
}
void loop() {
if(digitalRead(2) == HIGH)
{
vR+=d;
if(vR>l)
vR=0;
delay(T);
}
if(digitalRead(3) == HIGH)
{
vG+=d;
if(vG>l)
vG=0;
delay(T);
}
if(digitalRead(4) == HIGH)
{
vB+=d;
if(vB>l)
vB=0;
delay(T);
}
analogWrite(R, vR);
analogWrite(G, vG);
analogWrite(B, vB);
}
So to end it, I wanted to create a demo to cycle to all colors as simply as possible. I found ‘Hue-controllable RGB LED lamp‘ that shows how to cycle through the colors using only a Hue value.
I tried to use the conversion code directly from http://www.easyrgb.com/math.php?MATH=M21#text21, but all the values were quite wrong, so I lazily used the code akgraphics provided on the first post.
As the code was kind of slow because of lots of (unnecessary) math, I reduced it to:
void setup() // run once, when the sketch starts
{
//Serial.begin(9600); // set up Serial library at 9600 bps
}
void h2rgb(float H, int& R, int& G, int& B) {
int var_i;
float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;
var_h = H * 6;
if ( var_h == 6 ) var_h = 0; //H must be < 1
var_i = int( var_h ) ; //Or ... var_i = floor( var_h )
//var_1 = V * ( 1 - S );
var_1 = 0;
//var_2 = V * ( 1 - S * ( var_h - var_i ) );
var_2 = ( 1 - ( var_h - var_i ) );
//var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );
var_3 = ( var_h - var_i );
if ( var_i == 0 ) {
var_r = V ;
var_g = var_3 ;
var_b = var_1 ;
}
else if ( var_i == 1 ) {
var_r = var_2 ;
var_g = V ;
var_b = var_1 ;
}
else if ( var_i == 2 ) {
var_r = var_1 ;
var_g = V ;
var_b = var_3 ;
}
else if ( var_i == 3 ) {
var_r = var_1 ;
var_g = var_2 ;
var_b = V ;
}
else if ( var_i == 4 ) {
var_r = var_3 ;
var_g = var_1 ;
var_b = V ;
}
else {
var_r = V ;
var_g = var_1 ;
var_b = var_2 ;
}
R = (1-var_r) * 255; //RGB results = 0 ÷ 255
G = (1-var_g) * 255;
B = (1-var_b) * 255;
}
void loop() // run over and over again
{
for(int val=0;val<1024;val++)
{
//Serial.println(val);
float h = ((float)val)/1024;
int h_int = (int) 360*h;
int r, g, b;
h2rgb(h,r,g,b);
analogWrite(9, r);
analogWrite(10, g);
analogWrite(11, b);
delay(10);
}
}
Saturday, January 8, 2011
Piezo 101
To learn how to use a Piezo Buzzer I followed this tutorial.
They say that piezos have polarity, but the one I have doesn't show what it is, or if it has any.
What is polarity?
It is best explained on Wikipedia, but basically it defines a single right way to connect a component to the circuit, depending on the direction of the current flow. Components like resistances don't have polarity, so they can be connected either way. Polarity matters for most electrical objects like diodes (LEDs are diodes) or speakers.

I couldn't find a datasheet to the exact name (PKM22EPP-40) and neither on the manufacturer (muRata) datasheets for similar components.
But after reading this I found the explanation for the reference name (not helpful...).
So I tried the program supplied using a 330K resistance so that I could test for polarity reducing the risk of burning the piezo.
It generated a very low sound either way I connected it.
With a 10K resistance, the sound is louder, but still kind of weird.
Then I tried 470 Ohm and 47 Ohm with the same results.
So I dropped the resistances, and the sound isn't much louder, but still as annoying.
And this piezo has no polarity after all.
(Something wrong with the processing of the video from Blogger that makes the sound out of sync...)
---------------------------------------
So for the next test I tried this example from Adafruit, and got better results. The sound is clearer, and not as annoying.
The basic difference from the previous example is the use of digitalWrite instead of analogWrite to the piezo.
But what difference does it make? Well that is [TO BE SEARCHED].
They say that piezos have polarity, but the one I have doesn't show what it is, or if it has any.
What is polarity?
It is best explained on Wikipedia, but basically it defines a single right way to connect a component to the circuit, depending on the direction of the current flow. Components like resistances don't have polarity, so they can be connected either way. Polarity matters for most electrical objects like diodes (LEDs are diodes) or speakers.

I couldn't find a datasheet to the exact name (PKM22EPP-40) and neither on the manufacturer (muRata) datasheets for similar components.
But after reading this I found the explanation for the reference name (not helpful...).
So I tried the program supplied using a 330K resistance so that I could test for polarity reducing the risk of burning the piezo.
It generated a very low sound either way I connected it.
With a 10K resistance, the sound is louder, but still kind of weird.
Then I tried 470 Ohm and 47 Ohm with the same results.
So I dropped the resistances, and the sound isn't much louder, but still as annoying.
And this piezo has no polarity after all.
(Something wrong with the processing of the video from Blogger that makes the sound out of sync...)
---------------------------------------
So for the next test I tried this example from Adafruit, and got better results. The sound is clearer, and not as annoying.
The basic difference from the previous example is the use of digitalWrite instead of analogWrite to the piezo.
But what difference does it make? Well that is [TO BE SEARCHED].
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.
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...
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.

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.
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:
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).
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!
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!
Subscribe to:
Posts (Atom)
























