Bogusław Kempny

Zwarcie/rozwarcie

×
Autor English
Początek HC-SR04 LCD Kamera fork() sms strfry() GPIO impulsy Klawiatura Brama GPIO PWM SG90 RFID Grafolog RCP Shutdown Temperatura ....












W praktyce często spotkać się możemy z sygnałami typu zwarty - rozwarty.

Może to być prosty mechaniczny wyłącznik wykrywający otwarcie drzwi, wyłącznik zmierzchowy, klawisz klawiatury, sygnał z bardziej skomplikowanego urządzenia, na przykład z centralki alarmowej lub przeciwpożarowej.

Sygnał może pochodzić ze styków zwykłego mechanicznego wyłącznika, styków przekaźnika, może też być sygnałem typu open collector.

Obsługa takiego sygnału przez Raspberry Pi jest trywialna. Używaliśmy jej już do obsługi klawiatury czy przy zliczaniu impulsów. Było to jednak zrobione przy okazji omawiania innych problemów, może nie przyciągnęło należycie uwagi, omówimy więc ten problem oddzielnie.

Żeby za bardzo nie teoretyzować, opiszemy prosty układ do sygnalizowania otwartej bramy.

Czy może się przydać? Może.

Przykład z życia:
Młody piesek wybiegł w nocy na drogę, co skończyło się dla niego tragicznie. Prawdopodobnie ktoś z domowników zapomniał wieczorem zamknąć bramę posesji.

Wyposażymy więc naszą bramę w prosty mechaniczny wyłącznik rozwierający styki po jej otwarciu, a nasz Raspberry, jeśli nie zostanie ponownie zamknieta po ustalonym czasie, na przykład dwu minutach, zareaguje na ten fakt włączając sygnalizacje świetlną, dźwiękową, wyśle sms albo uruchomi mechanizm zamykania bramy, jeśli jest w takowy wyposażona.

Piny GPIO wyposażone są w rezystory (umówmy się, że 50kΩ, choć różne źródła podają zakres 40 - 100 kΩ - nie jest to szczególnie istotne), którymi możemy je połączyć z masą lub zasilaniem (3,3V). Rezystory te są częścią układu BCM2xxx (x - różne dla różnych wersji Raspberry), można je włączać i wyłączać programowo. Niestety nie można programowo odczytać które z nich aktualnie są aktywne.

Pewnym wyjątkiem są piny 8 i 9 WiringPi (2 i 3 według BCM w Raspberry rev.2), które mają dodatkowe zewnętrzne rezystory 1,8 kΩ przyłączone na stałe do napięcia zasilania. Są one używane do sterowania magistralą I2C. Pinów tych nie możemy programowo zewrzeć do masy.

Jeśli więc pin GPIO zaprogramujemy na wejście i włączymy rezystor zwierający go do napięcia zasilania, odczytamy na nim jedynkę logiczną, jeśli nie wymusimy zewnętrznym sygnałem innego stanu. Analogicznie, jeśli włączymy rezystor zwierający do masy, odczytamy zero logiczne).

Takie to proste. Wybieramy sobie jakiś wolny pin, włączamy nasz wyłącznik (styki przekaźnika) do tego pinu oraz masy i hardware gotowy.

Teraz software.

Jak w innych przykładach, użyjemy biblioteki wiringPi. Jeśli jej nie masz i nie wiesz jak zainstalować, zerknij na tę stronę.

Korzystając z tej biblioteki możemy zaprogramować pin na wejście lub wyjście:

void pinMode (int pin, int mode) ;

pin to oczywiście numer pinu GPIO, jako mode użyć możemy INPUT, OUTPUT lub PWM_OUTPUT.

Dwa pierwsze parametry są pewnie zrozumiałe, trzeci to modulacja szerokości impulsu (Pulse Width Modulation).

Druga funkcja która nas zainteresuje to

void pullUpDnControl (int pin, int pud) ;

Włączy nam rezystor do zasilania (PUD_UP), do masy (PUD_DOWN) lub wyłączy oba (PUD_OFF).

Jeszcze tylko

int digitalRead (int pin) ;

Funkcja ta zwróci nam stan logiczny (0 lub 1) wskazanego pinu. No to teraz oprogramowanie. Jak zwykle przykładowy program i prosty skrypt do jego kompilowania.


#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

Definiujemy czas, przez jaki brama może być otwarta bez podnoszenia alarmu:
#define CZAS 7200  // Czas otwarcia bramy, 2 minuty
Definiujemy piny do których podepniemy czujnik otwarcia bramy i sygnalizator alarmu:
#define PIN_WYL 25  // Pin do ktorego podlaczamy czujnik bramy
#define PIN_ALARM 24  // Pin do ktorego podlaczamy alarm

void alarm();


int main (void)
{
int i;
int czas_otw;
Inicjalizacja struktur biblioteki wiringPi:
  if (wiringPiSetup() == -1)
  {
    printf("wiringPi-Error\n");
    exit(1);
  }
  
Pin czujnika otwarcia programujemy na wejście i włączamy rezystor zwierający do 3,3V:
 pinMode(PIN_WYL, INPUT);
 pullUpDnControl(PIN_WYL, PUD_UP);
Pin sygnału alarmu programujemy na wyjście i ustawiamy go w stanie zera logicznego:
 pinMode(PIN_ALARM, OUTPUT);
 digitalWrite(PIN_ALARM,LOW);
Teraz w nieskończonej pętli sprawdzamy stan czujnika bramy:
for (;;)
 {
  if(digitalRead(PIN_WYL)==0)   //brama zamknieta, styk czujnika zwarty
   czas_otw=CZAS; 
  else 
   czas_otw--; // brama otwarta, odliczamy kolejne sekundy otwarcia
  sleep(1); // sekunda opoznienia do kolejnego testu czujnika
  if (czas_otw==0) // licznik sekund otwarcia sie wyzerowal
   {
    alarm(); // brama za dlugo otwarta, zareaguj
    czas_otw=CZAS; // jesli brama mimo alarmu nie zostanie zamknieta, 
                   // po czasie CZAS ponownie uruchom alarm
   }
 } 
Funkcja alarm. Może robić cokolwiek, uruchomić siłownik zamykający bramę, wysłać sms, w naszym przykładzie uruchomi trzykrotnie sygnalizator dźwiękowy (optyczny) podłączony do pinu PIN_ALARM, na 3 sekundy, z przerwami 1 sekundowymi.

Oczywiście sygnalizatora nie możemy podłączyć bezpośrednio do pinu GPIO. W stanie jedynki logicznej będzie tam napięcie około 3,3V. Maksymalny prąd jaki możemy uzyskać z pojedynczego pinu to około 16 mA, a suma wszystkich prądów wypływających z pinów GPIO powinna być mniejsza niż 50 mA.
To niewiele, w dodatku bezpieczniej jest nie zbliżać się do tych granicznych wartości, więc nasz sygnalizator podłączymy na przykład za pośrednictwem tranzystora:

}
void alarm()
{ 
  digitalWrite(PIN_ALARM,HIGH);
  sleep(3);
  digitalWrite(PIN_ALARM,LOW);
  sleep(1);
  digitalWrite(PIN_ALARM,HIGH);
  sleep(3);
  digitalWrite(PIN_ALARM,LOW);
  sleep(1);
  digitalWrite(PIN_ALARM,HIGH);
  sleep(3);
  digitalWrite(PIN_ALARM,LOW);
  sleep(1);
}
I na koniec pytanie. Wiesz na czym nabazgrałem ten schemacik? To karta do perforowania. Ma już prawie pół wieku. Na takich kartach kodowało się programy i dane. Pojemność? 80 znaków 10 bitowych.