Led Bar
A Led Bar utilizada é de 10 leds, 7 são verdes e os últimos 3 são vermelhos.
Primeiro temos que identificar quais são os pinos positivos, para isso recorremos à datasheet:
"o lado marcado pela 'Anode Mark' é o lado dos pinos +"
A 1ª parte deste projecto é simples, ligar tudo ao Arduino com resistências seguindo o esquema da página oficial: http://www.arduino.cc/en/Tutorial/BarGraph
(Resistências de 220 ohm)
Aspecto do circuito:
Código de teste:
/*
LED bar graph
Turns on a series of LEDs based on the value of an analog sensor.
This is a simple way to make a bar graph display. Though this graph
uses 10 LEDs, you can use any number by changing the LED count
and the pins in the array.
This method can be used to control any series of digital outputs that
depends on an analog input.
The circuit:
* LEDs from pins 2 through 11 to ground
created 4 Sep 2010
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/BarGraph
*/
// these constants won't change:
const int analogPin = A0; // the pin that the potentiometer is attached to
const int ledCount = 10; // the number of LEDs in the bar graph
int ledPins[] = {
2, 3, 4, 5, 6, 7,8,9,10,11 }; // an array of pin numbers to which LEDs are attached
void setup() {
// loop over the pin array and set them all to output:
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
pinMode(ledPins[thisLed], OUTPUT);
}
}
void loop() {
// read the potentiometer:
int sensorReading = analogRead(analogPin);
// map the result to a range from 0 to the number of LEDs:
int ledLevel = map(sensorReading, 0, 1020, 0, ledCount);
/*
// loop over the LED array:
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
// if the array element's index is less than ledLevel,
// turn the pin for this element on:
if (thisLed < ledLevel) {
digitalWrite(ledPins[thisLed], LOW);
}
// turn off all pins higher than the ledLevel:
else {
digitalWrite(ledPins[thisLed], HIGH);
}
}
*/
// loop over the LED array:
for (int i = 0; i < ledCount; i++){
if (i < ledCount) {
digitalWrite(ledPins[i], HIGH);
delay(100);
}
if (i >= ledCount) {
for (int i = 10; i > ledCount; i--){
if (i > ledCount) {
digitalWrite(ledPins[i], LOW);
delay(100);
}
}
}
}
}
Código que acende automaticamente todos os leds, de forma sequencial e com velocidade controlada pelo potenciómetro:
// these constants won't change:
const int analogPin = A0; // the pin that the potentiometer is attached to
const int ledCount = 10; // the number of LEDs in the bar graph
int ledPins[] = {
2, 3, 4, 5, 6, 7,8,9,10,11 }; // an array of pin numbers to which LEDs are attached
int Estado=0;
void setup() {
// loop over the pin array and set them all to output:
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
pinMode(ledPins[thisLed], OUTPUT);
}
}
void loop() {
// read the potentiometer:
int sensorReading = analogRead(analogPin);
// map the result to a range from 0 to the number of LEDs:
int ledLevel = map(sensorReading, 0, 1020, 0, 500);
/*
// loop over the LED array:
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
// if the array element's index is less than ledLevel,
// turn the pin for this element on:
if (thisLed < ledLevel) {
digitalWrite(ledPins[thisLed], LOW);
}
// turn off all pins higher than the ledLevel:
else {
digitalWrite(ledPins[thisLed], HIGH);
}
}
*/
// loop over the LED array:
for (int i = 0; i < ledCount+1; i++){
digitalWrite(ledPins[i], LOW);
delay(ledLevel);
}
delay(10);
for (int i = 10; i >= 0; i--){
digitalWrite(ledPins[i], HIGH);
delay(ledLevel);
}
}
Por forma a gastar menos pinos do arduino utilizei 2 Shift Register 74HC595, este esquema está disponível no site http://arduino.cc/en/Tutorial/ShiftOut e temos apenas de seguir o tutorial.
Os pinos do 74HC595:
Ambos os Shift Register têm de estar ligados da seguinte forma à fonte de alimentação:
GND (pin 8) to ground,
Vcc (pin 16) to 5V
OE (pin 13) to ground
MR (pin 10) to 5V
O 1º Shift Register liga desta forma ao Arduino (verificar imagens na página do esquema acima referida):
DS (pin 14) to Ardunio DigitalPin 11 (blue wire)
SH_CP (pin 11) to to Ardunio DigitalPin 12 (yellow wire)
ST_CP (pin 12) to Ardunio DigitalPin 8 (green wire)
Para ligar os dois Shift Register um ao outro basta efectuar estas ligações:
Partilhar a mesma ligação "clock pin" e "latch pin" (amarelo e verde na imagem) e ligar o pino 9 do 1º Shift Register (Serial Out) ao pino 14 (Serial data input) do 2º Shift Register:
Do pino Q0 ao Q7 de ambos os Shift Registers podemos ligar as resistências que por sua vez ligam aos Leds, neste caso usei as 8 saídas do 1º SR e apenas 2 saídas do 2º SR, pois a Led Bar usada tem apenas 10 Leds (8+2):
Usando depois um dos códigos disponibilizados para testarmos o esquema, por exemplo:
//**************************************************************//
// Name : shiftOutCode, Predefined Dual Array Style //
// Author : Carlyn Maw, Tom Igoe //
// Date : 25 Oct, 2006 //
// Version : 1.0 //
// Notes : Code for using a 74HC595 Shift Register //
// : to count from 0 to 255 //
//****************************************************************
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
//holders for infromation you're going to pass to shifting function
byte dataRED;
byte dataGREEN;
byte dataArrayRED[10];
byte dataArrayGREEN[10];
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
Serial.begin(9600);
//Arduino doesn't seem to have a way to write binary straight into the code
//so these values are in HEX. Decimal would have been fine, too.
dataArrayRED[0] = 0xFF; //11111111
dataArrayRED[1] = 0xFE; //11111110
dataArrayRED[2] = 0xFC; //11111100
dataArrayRED[3] = 0xF8; //11111000
dataArrayRED[4] = 0xF0; //11110000
dataArrayRED[5] = 0xE0; //11100000
dataArrayRED[6] = 0xC0; //11000000
dataArrayRED[7] = 0x80; //10000000
dataArrayRED[8] = 0x00; //00000000
dataArrayRED[9] = 0xE0; //11100000
//Arduino doesn't seem to have a way to write binary straight into the code
//so these values are in HEX. Decimal would have been fine, too.
dataArrayGREEN[0] = 0xFF; //11111111
dataArrayGREEN[1] = 0x7F; //01111111
dataArrayGREEN[2] = 0x3F; //00111111
dataArrayGREEN[3] = 0x1F; //00011111
dataArrayGREEN[4] = 0x0F; //00001111
dataArrayGREEN[5] = 0x07; //00000111
dataArrayGREEN[6] = 0x03; //00000011
dataArrayGREEN[7] = 0x01; //00000001
dataArrayGREEN[8] = 0x00; //00000000
dataArrayGREEN[9] = 0x07; //00000111
//function that blinks all the LEDs
//gets passed the number of blinks and the pause time
blinkAll_2Bytes(2,500);
}
void loop() {
for (int j = 0; j < 10; j++) {
//load the light sequence you want from array
dataRED = dataArrayRED[j];
dataGREEN = dataArrayGREEN[j];
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, 0);
//move 'em out
shiftOut(dataPin, clockPin, dataGREEN);
shiftOut(dataPin, clockPin, dataRED);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
delay(300);
}
}
// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut�
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
//blinks the whole register based on the number of times you want to
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(200);
for (int x = 0; x < n; x++) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);
delay(d);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(d);
}
}}
Obtemos o seguinte resultado: