[Projekt] Detektor gazów palnych i dymu oparty o Arduino i czujnik MQ-2
Sygnalizacja poziomu gazu za pomocą diody WS2812
Kolejnym krokiem będzie dodanie do programu obsługi diod RGB WS2812, o które oparty jest moduł KAmodWS2812-1. Ten typ diody wyróżnia się wbudowanym sterownikiem, dzięki któremu można kontrolować diodę przy użyciu zaledwie jednego portu mikrokontrolera. Diody można łączyć szeregowo, dzięki czemu jedną linią sygnałową można sterować nawet 1024 diodami. W kontekście projektu znacznie ważniejsze jest cyfrowe sterowanie kolorem i jasnością diody, które dzięki ustandaryzowanemu protokołowi oraz odpowiedniej bibliotece jest szybkie i proste.
Jeżeli złącza modułu nie są przylutowane, to należy je teraz przylutować. Podłączenie modułu jest proste i wygląda następująco.
Moduł KAmodWS2812-1 |
Arduino |
+VDD |
5V |
DIn |
6 |
GND |
GND |
Zasilanie wystarczy podłączyć z jednej strony, należy natomiast zwrócić uwagę na linie sygnałową, którą należy podłączyć do linii Din. Przypadkowe podłączenie do DOut, które służy do podłączania kolejnych diod, spowoduje że dioda nie będzie świecić.
Sterowanie WS2812 w Arduino
Następnie należy zmodyfikować program tak, aby potrafił sterować LEDami. W tym celu najlepiej skorzystać z biblioteki EasyNeoPixels od Adafruit, która pozwala znacznie prościej sterować pojedynczą diodą niż popularna biblioteka NeoPixels, tradycyjnie służąca do sterowania taśmami i modułami z wieloma diodami. Jeżeli biblioteka nie jest zainstalowana, to możną ją najprościej zainstalować za pomocą Menedżera bibliotek. W wyszukiwarce menedżera należy wpisać „Easy NeoPixels” i kliknąć Instaluj. Powinien wyświetlić się komunikat z pytaniem czy zainstalować również bibliotekę NeoPixels, która jest niezbędna do poprawnego działania EasyNeoPixels. Oczywiście należy potwierdzić.
Następnie należy dołączyć bibliotekę do programu klikając Szkic → Dołącz bibliotekę → Easy NeoPixels.
Po dołączeniu biblioteki należy zdefiniować stałą LED, zawierającą numer portu, do którego podłączony jest moduł z diodą. W tym przypadku jest to port numer 6.
#define LED 6
W funkcji setup() należy zainicjować działanie biblioteki dodając funkcję setupEasyNeoPixels(), która przyjmuje dwa parametry. Pierwszym parametrem jest port, do którego podłączony jest moduł, czyli stała LED, zaś drugim parametrem jest liczba podłączonych diod czyli 1.
setupEasyNeoPixels(LED, 1);
W funkcji loop() należy dodać funkcję writeEasyNeoPixel() ustawiającą kolor diody na niebieski. Przyjmuje ona cztery parametry. Pierwszym parametrem jest numer diody liczony od zera czyli w tym przypadku 0. Kolejnymi parametrami są wartości kolorów w systemie RGB, które ustalają jasność poszczególnych kolorów w zakresie od 0 do 255. Aby dioda świeciła na niebiesko należy ustawić wartość odpowiadającą kolorowi czerwonemu (R) na 0, wartość odpowiadającą kolorowi zielonemu (G) na 0, natomiast wartość odpowiadającą kolorowi niebieskiemu (B) na np. 50, aby dioda nie świeciła zbyt mocno.
writeEasyNeoPixel(0, 0, 0, 50);
Pełen kod programu powinien wyglądać następująco.
#include <EasyNeoPixels.h> #define Sensor A0 #define LED 6 int sensorValue = 0; void setup() { Serial.begin(9600); setupEasyNeoPixels(LED, 1); } void loop() { sensorValue = analogRead(Sensor); Serial.println(sensorValue); writeEasyNeoPixel(0, 0, 0, 50); delay(100); }
Teraz należy wgrać program na płytkę. Jeżeli wszystko przebiegło pomyślnie dioda zaświeci się na niebiesko.
Sygnalizacja poziomu gazu za pomocą diody WS2812
Pora opracować kod, który uzależni kolor świecenia diody od obecności gazu. W tym celu należy skasować funkcję ustawiającą kolor diody na niebieski i w jej miejsce dodać warunek if. Warunek będzie sprawdzać czy odczyt z czujnika, zapisany w zmiennej sensorValue, jest wyższy niż odpowiednia wartość np. 300. Jeśli wartość z czujnika będzie wyższa, dioda zaświeci się na czerwono, natomiast jeśli będzie niższa – na zielono.
if (sensorValue > 300) { writeEasyNeoPixel(0, 50, 0, 0); } else { writeEasyNeoPixel(0, 0, 50, 0); }
Cały kod będzie wyglądał następująco
#include <EasyNeoPixels.h> #define Sensor A0 #define LED 6 int sensorValue = 0; void setup() { Serial.begin(9600); setupEasyNeoPixels(LED, 1); } void loop() { sensorValue = analogRead(Sensor); Serial.println(sensorValue); if (sensorValue > 300) { writeEasyNeoPixel(0, 50, 0, 0); } else { writeEasyNeoPixel(0, 0, 50, 0); } delay(100);
Bezpośrednio po wgraniu programu dioda powinna świecić na zielono, natomiast po zbliżeniu źródła gazu zmienić kolor na czerwony. Jeżeli dioda zmienia kolor mimo braku źródła gazu lub nie reaguje na gaz, należy zmienić wartość 300 w warunku if na inną wartość. Podczas dobierania odpowiedniej wartości można korzystać z Monitora portu szeregowego, co znacznie ułatwi proces.
Dodanie obsługi buzzera
Ostatnim etapem będzie dodanie obsługi buzzera. Należy upewnić się czy przełącznik buzzera ustawiony jest w pozycji włączonej lub w przypadku korzystania z płytki innej niż Maker Nano należy podłączyć GND buzzera do GND Arduino i + buzzera do portu 8 w Arduino. Następnie należy dodać definicję portu buzzera na początku programu tuż po dołączeniu bibliotek.
#define BUZZER 8
Można w tym momencie wyłączyć obsługę Serial.print() z programu, ponieważ nie będzie już potrzebna. W tym celu najlepiej zamienić odpowiednie linie kodu na komentarz korzystając z skrótu klawiszowego Ctrl + /, dzięki czemu w razie potrzeby będzie można łatwo przywrócić tą funkcjonalność do programu, korzystając z tego samego skrótu.
// Serial.begin(9600); (...) // Serial.println(sensorValue);
Następnie w warunku if należy dodać funkcję tone () przyjmująca trzy parametry. Pierwszy parametr to numer pinu do którego podłączony jest buzzer. W tym miejscu należy wpisać stałą BUZZER. Kolejnymi parametrami są częstotliwość dźwięku i jego długość w milisekundach. Tutaj jest to odpowiednio 1000 i 300.
tone(BUZZER, 1000, 300);
W warunku else należy dopisać funkcję noTone(), która wyłączy buzzer w przypadku nie wykrycia gazu.
Ostatecznie kod powinien wyglądać następująco.
#include <EasyNeoPixels.h> #define Sensor A0 #define LED 6 #define BUZZER 8 int sensorValue = 0; void setup() { // Serial.begin(9600); setupEasyNeoPixels(LED, 1); } void loop() { sensorValue = analogRead(Sensor); // Serial.println(sensorValue); if (sensorValue > 300) { writeEasyNeoPixel(0, 50, 0, 0); tone(BUZZER, 1000, 300); } else { writeEasyNeoPixel(0, 0, 50, 0); noTone; } delay(100); }
Efekt działania detektora po wgraniu ostatecznej wersji programu można zobaczyć poniżej.