Miesięczne archiwum: Kwiecień 2010

Czujnik nachylenia

W ofercie Nettigo znajdują się czujniki nachylenia o zakresie pracy 30°  oraz 60°  (dokładniej od -30°  do +30°  od poziomu). Czujnik nachylenia to rodzaj przełącznika. Urządzenie to różni się od normalnych włączników tym, że zaczyna przewodzić prąd po przechyleniu. Skierowany wyprowadzeniami w górę nie przewodzi, natomiast skierowany wyprowadzeniem w dół przewodzi. Sensory takie najczęściej stosuje się w alarmach, gdzie badają położenie samochodu i włączają alarm podczas wciągania pojazdu na lawetę.

Sprzęt

Wykorzystanie czujnika nie jest trudne. Używa się go jak każdego włącznika. Potrzebny tylko wolny PIN cyfrowy w Arduino. Gdy PIN Arduino ustawiony jest na wejście, jego stan jest nieustalony (losowy) do chwili przyłączenia do niego jakiegoś napięcia. Przyłączenie „GND” wyzwala w nim stan „LOW”, natomiast podłączenie 5V wyzwala stan „HIGH”.

Gdy mamy podłączony czujnik do PINu cyfrowego jedną nogą i do „GND” drugą, wiemy że gdy zacznie przewodzić uaktywni się stan „LOW”. Gdy nie przewodzi oczekujemy, że będzie stan przeciwny czyli „HIGH”. W obecnej sytuacji jest to stan nieustalony. Dlatego aby ustalić stan podczas nieprzewodzenia czujnika zastosujemy wbudowany w procesor Arduino rezystor „Pull Up”. Powoduje on, że gdy nie doprowadzamy do PINu żadnego napięcia, automatycznie ustawia się on w stan „HIGH”.

Oprogramowanie

Korzystamy z sensora odczytując stan wybranego PINu cyfrowego. Najpierw w funkcji „setup” należy ustawić kierunek działania PINu na „INPUT” (wejście).

pinMode(numer_pinu, INPUT);

Oraz uaktywnić wbudowany rezystor „Pull Up”.

digitalWrite(numer_pinu, HIGH);

Następnie w funkcji „loop” możesz odczytywać stan PINu, a co za tym idzie położenie czujnika funkcją „digitalRead”.

zmienna = digitalRead(numer_pinu);

Przykładowy program użycia, świecący diodą „L” podczas przechyłu.

// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13


void setup()
{
	// Ustawienie wejścia dla czujnika nachylenia
  pinMode(CZUJNIK_PIN, INPUT);
  // Włączenie wbudowanego rezystora Pull Up.
  digitalWrite(CZUJNIK_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}


void loop()
{
	// Sprawdzanie stanu czujnika
  if (digitalRead(CZUJNIK_PIN) == HIGH)
  {
  	// Zdarzenie jeśli wyłączony
    digitalWrite(LED_PIN, HIGH); // Włączenie LED
  }
  else
  {
  	// Zdarzenie jeśli włączony
    digitalWrite(LED_PIN, LOW); // Wyłączenie LED
  }
}

Zadanie

Jak każdy mężczyzna wie, kobieta przechowuje w swej torebce same skarby. Są to o tyle cenne trofea, że nikt nie ma prawa ich przeglądać. Chcąc ochronić biedne niewiasty, a raczej ich torby przed wścibskimi ludźmi postanowiłem skonstruować alarm torebkowy.

Elementy

Do alarmu potrzebne będą:

  • Czujnik nachylenia do badania pozycji w jakiej znajduje się torebka
  • Głośnik piezo do informowania o naruszaniu torebki

Elementy połączyłem jak na poniższym schemacie. Wykorzystałem PIN 2 jako wejście czujnika, PIN 3 jako wyjście dla głośnika piezo oraz PIN 13 dla diody LED.

Program nie różni się zbytnio od poprzedniego, za wyjątkiem dodatkowych funkcji generujących dźwięk.

Pierwszą jest „tone” – włączająca dźwięk.

tone(nr_pinu_głośnika, częstotliwość);

Drugą jest „noTone” – wyłączająca dźwięk.

noTone(nr_pinu_głośnika);

// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
// Ustalenie pinu głośniczka piezo
#define PIEZO_PIN 3


void setup()
{
  // Ustawienie wejścia dla czujnika nachylenia
  pinMode(CZUJNIK_PIN, INPUT);
  // Włączenie wbudowanego rezystora Pull Up.
  digitalWrite(CZUJNIK_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}


void loop()
{
  // Sprawdzanie stanu czujnika
  if (digitalRead(CZUJNIK_PIN) == HIGH)
  {
    // Zdarzenie jeśli wyłączony
    digitalWrite(LED_PIN, HIGH); // Włączenie LED
    tone(PIEZO_PIN, 600); // Dzwięk alarmu
  }
  else
  {
    // Zdarzenie jeśli włączony
    digitalWrite(LED_PIN, LOW); //Wyłączenie LED
    noTone(PIEZO_PIN); // Wyłączenie dźwięku alarmu
  }
}

Jak daje się zauważyć alarm jest zbyt wrażliwy i każdy wstrząs (nawet tupanie) powoduje "skrzeczenie" głośniczka. To się może właścicielce torby nie spodobać.

Czym się różnią wstrząsy od grzebania w torbie?

Najłatwiej można je odróżnić po tym jak szybko przełącza się sensor. Wstrząsy przełączają go co tysięczne części sekundy, natomiast poruszenie torby, albo grzebanie trwa od dziesiątych części sekundy do kilku sekund (wliczając przestrach i ucieczkę napastnika). Trzeba więc zmierzyć ile trwało włączenie sensora i jeśli trwało dłużej niż 0,1 sekundy (poruszenie torby) - włączyć alarm.

Użyłem do tego funkcji "millis", która podaje ile milisekund (setnych części sekundy) upłynęło od włączenia Arduino. Można użyć tej funkcji do zapamiętania czasu uruchomienia czujnika. Potem gdy upłynie większa ilość czasu niż mają wstrząsy uruchamia się alarm.

// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
// Ustalenie pinu głośniczka piezo
#define PIEZO_PIN 3
// ustalenie czasu czułości czujnika
#define CZUJNIK_TIME 100

// zmienna przechowuje czas przełączenia czujnika
unsigned long sensor_time;


// funkcja uruchamiana, gdy alarm jest włączony
void alarm_on()
{
	digitalWrite(LED_PIN, HIGH); // Włączenie LED
  tone(PIEZO_PIN, 600); // Dzwięk alarmu
}


// funkcja uruchamiana gdy alarm jest wyłączony
void alarm_off()
{
  digitalWrite(LED_PIN, LOW); //Wyłączenie LED
  noTone(PIEZO_PIN); // Wyłączenie dźwięku alarmu
}


// funkcja sprawdzająca stan czujnika
void check_sensor()
{
  // Sprawdzanie stanu czujnika
  if (digitalRead(CZUJNIK_PIN) == HIGH)
  {
    // Zdarzenie jeśli wyłączony
    
    if (sensor_time == 0) // Sprawdzenie czy stan został zmieniony
    {
      sensor_time = millis(); // zapamiętanie czasu uaktywnienia czujnika
    }
    // Warunek czy stan czujnika trwa określony czas
    else if (millis() - sensor_time > CZUJNIK_TIME)
    {
      alarm_on();
    }
  }
  else
  {
    // Zdarzenie jeśli włączony
    sensor_time = 0;
    alarm_off();
  }
}


void setup()
{
  // Ustawienie wejścia dla czujnika nachylenia
  pinMode(CZUJNIK_PIN, INPUT);
  // Włączenie wbudowanego rezystora Pull Up.
  digitalWrite(CZUJNIK_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}


void loop()
{
  check_sensor();
}

Prawdziwy alarm

Nasz torebkowy alarm ma jeszcze jedną wadę. Wyłącza się od razu kiedy tylko torba wróci na swoją pozycję. Tak nie działają prawdziwe alarmy! Prawdziwe alarmy mają też bardziej urozmaicone dźwięki. Tu znowu wykorzystamy funkcję pomiaru czasu "millis". W pierwszej kolejności będziemy mierzyli ile czasu upłynęło od włączenia alarmu. Alarm będzie się wyłączał dopiero, gdy minie ustalona ilość czasu, tak by skutecznie odstraszyć i przyciągnąć uwagę.
W drugiej kolejności wykorzystałem pomiar czasu do sprawdzania długości trwania tonu sygnału dźwiękowego, tak by przełączał się cyklicznie między dwoma (wysokim i niskim). Pozwoli to odróżnić torebkowy alarm od innych hałasów.

// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
// Ustalenie pinu głośniczka piezo
#define PIEZO_PIN 3
// ustalenie czasu czułości czujnika [ms]
#define CZUJNIK_TIME 100
// ustalenie czasu trwania alarmu [ms] (5000 ms = 5 s)
#define ALARM_TIME 5000

// zmienna przechowuje czas przełączenia czujnika
unsigned long sensor_time;
// zmienna przechowuje czas włączenia alarmu
unsigned long alarm_time;
// zmienna przechowuje czas zmiany wysokości syreny
unsigned long signal_time = 0;
// zmienna przechowuje stopień wysokości dzwięku
// 0 - brak dzwięku
// 1 - pierwszy ton
// > 1 - drugi ton
byte sound_tone = 0;

// funkcja syreny alarmowej
void alarm_signal()
{
  if (sound_tone != 0) // sprawdzenie czy właczyć syrene
  {
    if (millis() - signal_time > 750) // sprawdzenie długości trwania tonu
    {
      signal_time = millis(); // zapamiętanie czasu włączenia tonu
      sound_tone = ~sound_tone; // włączenie drugiego tonu
    }
    
    if (sound_tone == 1) // ton pierwszy
    {
      tone(PIEZO_PIN, 600);
    }
    else // ton drugi
    {
      tone(PIEZO_PIN, 1200);
    }
  }
  else
  {
    noTone(PIEZO_PIN); // Wyłączenie dźwięku
  }
}


// funkcja uruchamiana, gdy alarm jest włączony
void alarm_on()
{
  alarm_time = millis(); // zapamiętanie czasu włączenia alarmu
  digitalWrite(LED_PIN, HIGH); // Włączenie LED
  sound_tone = 1; // Włączenie syreny alarmowej
}


// funkcja uruchamiana gdy alarm jest wyłączony
void alarm_off()
{
  if (millis() - alarm_time > ALARM_TIME) // sprawdzenie długości trwania alarmu
  {
    digitalWrite(LED_PIN, LOW); //Wyłączenie LED
    sound_tone = 0; // Wyłączenie syreny alarmowej
  }
}


// funkcja sprawdzająca stan czujnika
void check_sensor()
{
  // Sprawdzanie stanu czujnika
  if (digitalRead(CZUJNIK_PIN) == HIGH)
  {
    // Zdarzenie jeśli wyłączony
    
    if (sensor_time == 0) // Sprawdzenie czy stan został zmieniony
    {
      sensor_time = millis(); // zapamiętanie czasu uaktywnienia czujnika
    }
    // Warunek czy stan czujnika trwa określony czas
    else if (millis() - sensor_time > CZUJNIK_TIME)
    {
      alarm_on();
    }
  }
  else
  {
    // Zdarzenie jeśli włączony
    sensor_time = 0;
    alarm_off();
  }
}


void setup()
{
  // Ustawienie wejścia dla czujnika nachylenia
  pinMode(CZUJNIK_PIN, INPUT);
  // Włączenie wbudowanego rezystora Pull Up.
  digitalWrite(CZUJNIK_PIN, HIGH);
  pinMode(LED_PIN, OUTPUT);
}


void loop()
{
  check_sensor();
  alarm_signal();
}

To tylko jedno z zastosowań czujnika nachylenia. Jeśli macie pomysły na inne zastosowania lub pytania - można zostawić komentarz lub skorzystać z maila.

Kody źródłowe:

Kolorowe jarmarki czyli 3 w 1

Nasz blog dostał wsparcie w postaci nowego autora (kto uważny ten pewnie już wie kto to :) ), także nowe ciekawe wpisy się szykują a ja tymczasem przygotowuję jak zwykle jakieś kolorowe światełka :)

Zacznijmy od końca, czyli krótki filmik. Dzieło nie jest pasjonujące, bo komórkowa kamerka kolorów zbyt dobrze nie oddaje:

Co zrobić… No to może zdjęcie zmontowanego układu:

RGB LED

RGB LED

Teraz już wiadomo co zacz – dioda RGB – czyli tytułowe trzy diody w jednej – Red, Green, Blue. Czerwona, Zielona, Niebieska. Wspólna katoda, czyli z Arduino będzie łatwo taką diodą sterować – wystarczy wyjście cyfrowe podłączyć (przez rezystor 220 ohm) do odpowiedniej nóżki i już można sterować jednym kolorem.

Która nożka jest która? Pomocny będzie ten obrazek:

Wyprowadzenia diody RGB

Wyprowadzenia diody RGB

Licząc od lewej mamy niebieski, zielony, masa, czerwony. Najdłuższa nóżka to właśnie masa i to pozwala się nam zorientować jak podłączyć diodę.

Co nam daje taka dioda? Otóż można nią uzyskać światło innych barw mieszając trzy kolory w różnym stopniu. Dla zilustrowania tego kod programu użytego w pierwszym przykładzie. Idea jest taka, że każdy z kolorów jest zapalany z różną intensywnością (korzystając z PWM) i różną częstotliwością. Uzyskujemy w ten sposób efekt mieszania się kolorów:

int LED1 = 9;
int s1 = 255;
int LED2 = 10;
int s2 = 255;
int LED3 = 11;
int s3 = 255;

unsigned long int tme;

void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
};

void loop() {
  
  analogWrite(LED1, s1);
  s1 = sin(tme*tme/50000.0)*128+128;
  
analogWrite(LED3, s3);
  s3 = sin(tme*tme/100000.0)*128+128;


  analogWrite(LED2, s2);
  s2 = sin(tme*tme/70000.0)*128+128;

  delay(15);
  
  tme++;
};

tme jest zmienną reprezentującą upływ czasu. Dzielimy kwadrat tej zmiennej w loop przez różne wartości i z nich obliczamy sinus. Dzięki temu mamy trzy różne fale (o różnej częstotliwości) każda z nich służy do sterowania jednym kolorem. Ponieważ funkcja kwadrat jest funkcją rosnącą nieliniowo więc przesunięcie w fazie poszczególnych fal powinno się zmieniać z czasem (tak sądzę, choć pewnie sprawdzić by to trzeba dokładniej). Dzięki temu kolory mieszają się różnie a nie w jednym cyklu.

Skutek uboczny jest taki, że z czasem cykle zmiany stają się coraz krótsze i dioda zaczyna migać coraz szybciej…

Jeżeli ktoś potrzebuje takiej diody – od teraz jest dostępna na Nettigo.