sobota, 25 lipca 2015

[2] Arduino - Obsługa diod zewnętrznych


Dioda świecąca (LED)

Dioda elektroluminescencyjna (ang. Light-Emitted Diode) jest ona zaliczana do półprzewodnikowych przyrządów optoelektronicznych. 

Działanie oparte jest na zasadzie rekombinacji nośników ładunków. Występuje gdy elektrony przechodzą z poziomu elektrycznego wyższego na niższy. 

Dioda świecąca zawiera dwa wyprowadzenia anodę i katodę. Aby odpowiednio odróżnić jedno od drugiego należy zwrócić uwagę na wielkość płytki wewnętrznej (katoda będzie zawsze większa). Ta metoda daje 100% pewność na odróżnienie wyprowadzeń. Druga metoda opiera się o długości wyprowadzeń. Przeważnie nóżka krótsza jest katodą, natomiast dłuższa, jest to anoda.

PRZYKŁAD 1

Pierwszy program przedstawiony poniżej pozwala na odpalenie wszystkich diod z opóźnieniem 100 ms. Program w części setup odwołuje się do zewnętrznej funkcji, której zadaniem jest odpalenie diod.

Rys. 1.1. Widok podłączonego układu.


//Diody podłączone są do pinów od 2 do 11
int DiodePin1 = 2;
int DiodePin2 = 3;
int DiodePin3 = 4;
int DiodePin4 = 5;
int DiodePin5 = 6;
int DiodePin6 = 7;
int DiodePin7 = 8;
int DiodePin8 = 9;
int DiodePin9 = 10;
int DiodePin10 = 11;
int DiodePin11 = 12;
int DiodePin13 = 13;
 
void TurnLeds(void);           //Wstępna deklaracja funkcji
 
void setup() 
{
  pinMode(DiodePin1, OUTPUT);  //Ustawienie pinu jako wyjście
  pinMode(DiodePin2, OUTPUT);
  pinMode(DiodePin3, OUTPUT);
  pinMode(DiodePin4, OUTPUT);
  pinMode(DiodePin5, OUTPUT);
  pinMode(DiodePin6, OUTPUT);
  pinMode(DiodePin7, OUTPUT);
  pinMode(DiodePin8, OUTPUT);
  pinMode(DiodePin9, OUTPUT);
  pinMode(DiodePin10, OUTPUT);
  pinMode(DiodePin11, OUTPUT);
 
  TurnLeds();
}
 
void loop() 
{
  //Nic nie robi
}
 
void TurnLeds()
{
   digitalWrite(DiodePin1, HIGH); //Ustawienie stanu wysokiego, odpalenie diod
   delay(100);                    //Opóźnienie 100ms 
   digitalWrite(DiodePin2, HIGH);
   delay(100);           
   digitalWrite(DiodePin3, HIGH);
   delay(100);           
   digitalWrite(DiodePin4, HIGH);
   delay(100);           
   digitalWrite(DiodePin5, HIGH);
   delay(100);           
   digitalWrite(DiodePin6, HIGH);
   delay(100);           
   digitalWrite(DiodePin7, HIGH);
   delay(100);           
   digitalWrite(DiodePin8, HIGH);
   delay(100);
   digitalWrite(DiodePin9, HIGH);
   delay(100);           
   digitalWrite(DiodePin10, HIGH);
   delay(100);           
   digitalWrite(DiodePin11, HIGH);
   delay(100);             
}

Dobrą praktyką jest oddzielanie funkcji wykonujących większą ilość operacji jak np. TurnLeds() od głównej części programu przy pomocy wywołania jej jako funkcji zewnętrznej. Pozwala to na zwiększenie przejrzystości całego kodu.


Przykład 2 - przyciski


Działanie programu pozostaje bez zmian, natomiast w tym momencie wykorzystałem trzy przyciski. Pierwszy zapala diody, drugi je gasi w odwrotnej kolejności, trzeci natomiast odpala pojedynczo każdą z zaprogramowanych diod.

Dla przycisku zapalającego kolejną diodę należy wykorzystać program, który pozwoli na eliminację jego drgań. Jeśli to nie zostałoby włączone, wtedy zapalały by się diody w losowej ilości.


Rys. 2.1. Schemat podłączenia


Rys. 2.2. Widok podłączonego układu


//Diody podłączone są do pinów od 2 do 11
const int DiodePin1 = 2;
const int DiodePin2 = 3;
const int DiodePin3 = 4;
const int DiodePin4 = 5;
const int DiodePin5 = 6;
const int DiodePin6 = 7;
const int DiodePin7 = 8;
const int DiodePin8 = 9;
const int DiodePin9 = 10;
const int DiodePin10 = 11;
const int DiodePin11 = 12;
const int DiodePin13 = 13;
 
//Deklaracja pinów od przycisków
const int ButtonOff = 13;
const int ButtonOn = 12;
const int ButtonUp = 1;
 
int Pin = 2;    //Deklaracja zmiennej Pin
 
boolean ButtonUpLast = LOW;  //Zmiena przechowująca wcześniejszy przycisku
boolean ButtonUpCurrent = LOW;  //Zmienna przechowująca aktualny stan przycisku
 
void TurnLeds(void);   //Wstępna deklaracja funkcji zapalenie diod
void LedsOff(void);    //Wstępna deklaracja funkcji zgaszenie diod
void LedsUp(void);     //Wstępna deklaracja funckji zapalającej kolejne diody
boolean debounce(boolean last); //Wstępna deklaracja funkcji odczytującej stan przycisku
 
void setup() 
{
  pinMode(DiodePin1, OUTPUT);  //Ustawienie pinu jako wyjście
  pinMode(DiodePin2, OUTPUT);
  pinMode(DiodePin3, OUTPUT);
  pinMode(DiodePin4, OUTPUT);
  pinMode(DiodePin5, OUTPUT);
  pinMode(DiodePin6, OUTPUT);
  pinMode(DiodePin7, OUTPUT);
  pinMode(DiodePin8, OUTPUT);
  pinMode(DiodePin9, OUTPUT);
  pinMode(DiodePin10, OUTPUT);
  pinMode(DiodePin11, OUTPUT);
 
  pinMode(ButtonOff, INPUT);  //Ustawienie pinów jako wejście
  pinMode(ButtonOn, INPUT);
  pinMode(ButtonUp, INPUT);
}
 
void loop() 
{
  ButtonUpCurrent = debounce(ButtonUpLast);  //Odczytanie stanu funkcji debounce
 
  if(digitalRead(ButtonOn) == 1) //Sprawdzenie czy przycisk został wciśnięty
  {
    TurnLeds();                  //Jeśli tak to wywołuje funkcję
  }
 
  if(digitalRead(ButtonOff) == 1)
  {
    LedsOff();
  }
 
  //Jesli poprzedni stan przycisku był niski
  //oraz aktualny stan jest wysoki wtedy wykonanie się funkcji
  if(ButtonUpLast == LOW && ButtonUpCurrent == HIGH)
  {
    LedsUp();    //Wejscie do zewnętrznej funckji
  }
  ButtonUpLast = ButtonUpCurrent;  //Reset stanu przycisku
}
 
boolean debounce(boolean last)      //Funckja sprawdzająca stan przycisku
{
  boolean current = digitalRead(ButtonUp);
  if(last != current)
  {
    delay(5);     //opóźnienie 5ms 
    //Przypisanie zmiennej current aktualnego stanu przycisku
    current = digitalRead(ButtonUp);
  }
  return current;  //Zwrócenie stanu przycisku
}
 
void TurnLeds()
{
   digitalWrite(DiodePin1, HIGH); //Ustawienie stanu wysokiego, odpalenie diod
   delay(100);                    //Opóźnienie 100ms 
   digitalWrite(DiodePin2, HIGH);
   delay(100);           
   digitalWrite(DiodePin3, HIGH);
   delay(100);           
   digitalWrite(DiodePin4, HIGH);
   delay(100);           
   digitalWrite(DiodePin5, HIGH);
   delay(100);           
   digitalWrite(DiodePin6, HIGH);
   delay(100);           
   digitalWrite(DiodePin7, HIGH);
   delay(100);           
   digitalWrite(DiodePin8, HIGH);
   delay(100);
   digitalWrite(DiodePin9, HIGH);
   delay(100);           
   digitalWrite(DiodePin10, HIGH);
   delay(100);           
   digitalWrite(DiodePin11, HIGH);
   delay(100);             
}
void LedsOff()
{
   digitalWrite(DiodePin11, LOW); //Ustawienie stanu wysokiego, odpalenie diod
   delay(100);                    //Opóźnienie 100ms 
   digitalWrite(DiodePin10, LOW);
   delay(100);           
   digitalWrite(DiodePin9, LOW);
   delay(100);           
   digitalWrite(DiodePin8, LOW);
   delay(100);           
   digitalWrite(DiodePin7, LOW);
   delay(100);          
   digitalWrite(DiodePin6, LOW);
   delay(100);           
   digitalWrite(DiodePin5, LOW);
   delay(100);           
   digitalWrite(DiodePin4, LOW);
   delay(100);
   digitalWrite(DiodePin3, LOW);
   delay(100);           
   digitalWrite(DiodePin2, LOW);
   delay(100);           
   digitalWrite(DiodePin1, LOW);
   delay(100);             
}
void LedsUp()
{
  digitalWrite(Pin, HIGH);  //Zapalenie diody podłączonej do portu Pin
 
  Pin++;         //Zwiększenie wartości zmiennej
 
  if(Pin == 13)  //Jeśli Pin wynosi 12 czyli ostatnia podłączona dioda
  {
    LedsOff();   //Wyłączenie wszystkich diod
    Pin = 2;     //Ustawienie stanu początkowego
  }
}

Funkcja TurnsLed() oraz LedsOff() mogły zostać także wykonane za pomocą pętli for.
W tej pętli najpierw podawany jest warunek początkowy, następnie granica do jakiej ma się ona wykonywać. Ostatnim elementem jest krok o jaki ma nastąpić zmiana co każde jej przejście.

void TurnLeds()
{
   for(Pin=2;Pin<=12;Pin++)
   {
     digitalWrite(Pin, HIGH);
     delay(100);
   }
 
   if(Pin == 13)  //Jeśli Pin wynosi 12 czyli ostatnia podłączona dioda
   {
     Pin = 2;     //Ustawienie stanu początkowego
   }           
}
void LedsOff()
{
   for(Pin=11;Pin>=2;Pin--)
   {
     digitalWrite(Pin, LOW);
     delay(100);
   }      
}