Sygnalizator czyli jak wykorzystać przycisk

Weekend parę tygodni temu od samego początku zapowiadał się deszczowo. Znaczyło to, że z moją trójką dzieci będziemy cały dzień w domu. Jest to pewnego rodzaju wyzwanie – jak to przeżyć bez nadszarpniętych nerwów :)

Jako że mój syn (3 i pół roku) jest na etapie rozjeżdżania dywanu na wszystkie strony z wykorzystaniem samochodów i pociągów wszelkiego rodzaju, zrodził się na szybko pomysł gnalizatora, jak został w mowie 3 latka ochrzczony…

Sygnalizator w akcji
Sygnalizator w akcji

Pół godziny i udało się zrobić coś takiego. Miałem nadzieję, że będzie wzbudzał zainteresowanie przez kolejne pół godziny, a okazało się, że przez następnych kilka dni stanowił niezbędny element torów przeszkód powstających na dywanie.

Jak to działa?

Najpierw literatura – idea była taka, żeby powstał prosty sygnalizator, zmieniający swój stan przez przyciśnięcie przycisku.

Diodę czerwoną podłączamy do cyfrowego wyjścia nr 3, zieloną do cyfrowego wyjścia 2 a przycisk do cyfrowego wejścia nr 4.

Schemat:

Kod:

int buttonPin = 4;

int LED = HIGH;

int greenPin = 02;                // LED connected to digital pin 13
int redPin = 03;
int infraPin = 0;
int val = LOW;
int prev = LOW;

#define ST_OFF 0
#define ST_ON 1
#define ST_PULSE 2
int status = ST_OFF;

//początkowa konfiguracja
void setup()
{
  pinMode(greenPin, OUTPUT);      // sets the digital pin as output
  pinMode(redPin, OUTPUT);      // sets the digital pin as output
  pinMode(buttonPin, INPUT); // ustawienie pinu jako wejscie
  Serial.begin(57600);
  digitalWrite(redPin,HIGH);
  digitalWrite(greenPin,HIGH);
}

void display_status() {
  int static pulse = LOW;
  int static count = 5;
  switch (status) {
    case ST_OFF:
    off(redPin);
    on(greenPin);
    break;
    case ST_ON:
    on(redPin);
    off(greenPin);
    break;
    case ST_PULSE:
    off(redPin);
    digitalWrite(greenPin, pulse);
    pulse = !pulse;
    delay(400);
    count--;
    if (count==0) {
      status=ST_ON;
      count=5;
    }
  }
}


void next_status() {
  switch (status) {
    case ST_OFF:
    status = ST_PULSE;
    break;
    case ST_ON:
    status = ST_OFF;

    break;
    case ST_PULSE:
    
    break;
  }
}

void on( int pin) {
  digitalWrite(pin,HIGH);
}
void off( int pin) {
  digitalWrite(pin,LOW);
}
void loop()
{
  val = digitalRead(buttonPin);
  if (val == HIGH && prev == LOW) {
    next_status();
  }
  prev = val;
  display_status();
  delay(50);
    
}

Sygnalizator może być w trzech stanach – wyłączony (ST_OFF, świeci zielone), włączony (ST_ON, świeci czerwone) i pulsujący (ST_PULSE, miga zielone).

W głównej pętli sprawdzamy czy nie został wciśnięty przycisk. Jeżeli tak, to przejdź do następnego stanu (next_status) z wyjątkiem ST_PULSE, w którym uparcie pozostaje. Dzięki temu naciśnięcie przycisku podczas migania, nie powoduje przeskoku do następnego stanu.

Następnie wyświetlany jest stan odpowiadający bieżącemu statusowi (display_status). Tutaj jest realizowane miganie, oraz po odbębnieniu odpowiedniej liczby cykli, zmieniany stan na ST_ON, czyli – czerwone.

display_status mogłoby być źródłem problemów, gdyby był to bardziej złożony układ. Dodaje swoje opóźnienie w ST_PULSE (delay(400)), zmienia stan – proszenie się o kłopoty. Ale w tak prostym układzie – może być.

Co nowego?

Nowym elementem, którego nie używaliśmy we wcześniejszych przykładach jest tutaj przełącznik. Prosty przycisk którego naciśnięcie ma wykryć Arduino.

Sygnalizator - prosty ale działa
Sygnalizator - prosty ale działa

Potencjalna pułapka – po co tam jest rezystor? Czemu nie tak:

Nie róbcie tego w domu :)
Nie róbcie tego w domu :)

Otóż, w momencie, w którym przycisk jest wyciśnięty, nie ma problemu, wejście cyfrowe jest zwarte do zasilania i jest w stanie wysokim. Jednak po jego zwarciu z masą wejście napięcie zasilania też zostaje zwarte do masy, co powoduje niekontrolowany przepływ prądu. Może to uszkodzić układ zasilający (tutaj to kawałek Arduino).

Gdyby zrezygnować z napięcia zasilania, trzeba sobie zdawać sprawę, że gdy przycisk nie jest wciśnięty, wówczas wejście cyfrowe zostaje zawieszone w powietrzu i nie mamy najmniejszej gwarancji co zostanie odczytane przez Arduino. Może to być stan niski lub wysoki (i będzie się zmieniać losowo). Podłączenie napięcia +5V (przez rezystor) pozwala na unikniecie takiej niejednoznaczności i mieć pewność, że nie zniszczymy układu.