Jeśli spędzamy dużo czasu w zamkniętych pomieszczeniach, to z pewnością znamy uczucie zmęczenia, powodowane przez podwyższony poziom dwutlenku węgla. Zwłaszcza obecnie, gdy wiele osób pracuje w domu, jest to częsta sytuacja. Wystarczy tylko otworzyć okno albo po prostu przejść się po mieszkaniu czy wyjść na chwilę na dwór i objawy zmęczenia ustępują. Kiedy jednak wstać od pracy, aby odetchnąć świeżym powietrzem? Istnieje wiele metod – można robić to regularnie, np. co 45...60 minut wstawać od komputera i wietrzyć pokój, można też czekać na pierwsze objawy zmęczenia…
Jednak zdecydowanie najlepszą metodą określania momentu, w którym warto przewietrzyć pomieszczenie, jest zastosowanie sensora dwutlenku węgla. Ten relatywnie nieskomplikowany element mierzy poziom CO2 w naszym otoczeniu i informuje, gdy przekroczy on ustalony limit, co oznacza konieczność otwarcia okna itp. Autor opisanego projektu doszedł do podobnych wniosków, dlatego postanowił samodzielnie zbudować taki system. Prace rozpoczął od wyszukania odpowiedniego sensora dwutlenku węgla.
Pierwszy wybór padł na sensor Sensirion SCD-41. Jest to bardzo kompaktowy sensor, który realizuje nową metodę pomiaru poziomu CO2 – z zastosowaniem sensora fotoakustycznego. Na bazie sensora SCD-41 autor skonstruował kompaktowy układ monitorujący poziom dwutlenku węgla. Został on ponadto wyposażony w mały brzęczyk ostrzegający otoczenie, że poziom dwutlenku węgla przekroczył założony próg. Do konfiguracji służy aplikacja mobilna, która pozwala łączyć się z urządzeniem z poziomu telefonu, wyświetlać wykresy poziomu CO2 w funkcji czasu i przechowywać dane.
Potrzebne elementy
Układ składa się z zaledwie trzech elementów. Całkowity koszt budowy tego systemu to około 50 dolarów. Potrzebne są następujące moduły:
- płytka deweloperska TTGO T-Display z ESP32 i CP2104 z wyświetlaczem LCD 1,14”,
- moduł z sensorem SCD-41 lub sam układ, jeśli damy radę wlutować go metodą „na pająka”,
- buzzer 3 V, CMI-1295IC-0385 T.
Oprócz samych modułów potrzebne będą przewody, aby je ze sobą połączyć, oraz obudowa. Dodatkowo, potrzebny jest także zasilacz dla gotowego urządzenia. Autor zastosował zasilacz USB i przygotował obudowę specjalnie tak, aby pozwalała na wetknięcie bezpośrednio do gniazda USB w zasilaczu gniazdkowym.
Obudowa
Obudowa składa się z trzech elementów – jej projekt został pokazany na rysunku 1. Należy je wykonać za pomocą drukarki 3D. Elementy są przeznaczone do druku z PLA i są przygotowane tak, aby dało się je wydrukować bez suportów. Pliki do druku 3D dostępne są na stronie z projektem (link na końcu artykułu).
Schemat elektryczny
Schemat połączenia poszczególnych modułów pokazano na rysunku 2. Wszystkie połączenia pomiędzy modułami wykonywane są za pomocą cienkiego drutu, lutowanego do poszczególnych pól. Zdecydowano się na takie podejście, aby zminimalizować objętość układu i umożliwić umieszczenie go w niewielkiej obudowie.
Jedyną trudną częścią budowy układu jest przylutowanie przewodów do małego sensora SCD-41 (fotografia 1).
Można to zrobić zwykłą lutownicą, bez pomocy mikroskopu – tak jak wykonał to autor (fotografia 2). Aby ułatwić sobie zadanie, należy użyć możliwie cienkiego drutu. Element mocujemy w stabilny sposób i zabieramy się do lutowania, mając już pod ręką przygotowane odizolowane kable. Zaczynamy od ustawienia układu w taki sposób, aby wiedzieć, gdzie znajduje się wyprowadzenie numer 1 – jeden z padów ma niewielkie ścięcie, które pozwala to rozpoznać.
Pięć połączeń sygnałowych obejmuje linie VDD, GND, SDA i SCL (wszystkie z jednej strony) oraz DDH naprzeciwko VDD. Wyprowadzenie DDH podciągane jest do zasilania, więc można podłączyć go bezpośrednio do pinu VDD naprzeciwko lub przylutować osobny przewód i podłączyć niezależnie z TTGO.
Lutując należy użyć dużej ilości topnika na padach i umieścić na każdym z nich małą kulkę lutowia przed przymocowaniem przewodów. Należy również umieścić małą kulkę lutowia na końcach każdego przewodu, aby umożliwić łatwe połączenie przy minimalnym nagrzaniu. Należy lutować ostrożnie, aby nie uszkodzić delikatnych pól lutowniczych. Po przylutowaniu wszystkich przewodów można zabezpieczyć je np. odrobiną kleju na ciepło. Pozwoli to zapobiec przypadkowemu oderwaniu przewodów czy też uszkodzeniu pól lutowniczych.
Interfejs I2C dołączany jest do GPIO 21 i 22. Zasilanie i masa są dostarczane przez złącze 3 V na płytce z mikrokontrolerem. Buzzer jest podłączony do GPIO 13 i do masy (GND). Zasilanie płytki jest podłączone do tylnego złącza USB do linii 5 V i GND na płycie. Mała kolorowa dioda LED jest dołączona w złączu zasilania czujnika.
Budowa
Zasilanie urządzenia doprowadzone jest modułu w postaci wtyku USB znajdującego się z tyłu, wydrukowanego w 3D. To bardzo minimalistyczna opcja zasilania, która jest zintegrowana z obudową urządzenia. Pozwala podłączyć układ do portu USB np. w komputerze czy ładowarce w gniazdku.
Drukowany element USB ma dwa cienkie wcięcia, które mieszczą dwa małe paski folii miedzianej. Należy ostrożnie przyciąć miedź, aby dopasować ją do tych wcięć i wkleić je na miejsce. Przewody łączące zasilanie i masę przechodzą z tyłu urządzenia. Używając dużej ilości topnika, aby ułatwić lutowanie, należy podłączyć je do miedzianych pasków. Lutując przewody do taśmy miedzianej, należy zrobić to tak, aby lutowie nie rozciągało się na otwarte obszary, w których łączy się USB. Można teraz złożyć ten element w całość i przykleić złącze USB z tyłu urządzenia po przeprowadzeniu przewodów przez otwory.
Moduł TTGO wsuwa się w szczeliny w uchwycie. Zespół czujnika CO2 i buzzera z przewodami mieszczą się w malutkiej komorze w górnej części urządzenia (fotografia 3). Dioda LED znajduje się w pobliżu otworów umożliwiających ruch powietrza.
Finalnie należy upewnić się, że połączenie USB-C dla TTGO jest dostępne do programowania przez otwarte gniazdo. Można sprawdzić, czy urządzenie działa poprawnie, a na koniec przykleić płytę czołową na miejsce. Układ jest teraz gotowy do wgrania oprogramowania układowego.
Oprogramowanie
Oprogramowanie, potrzebne do działania układu, składa się z dwóch elementów – programu dla modułu TTGO oraz aplikacji na telefon, która umożliwia zdalny odczyt i konfigurację systemu.
Programu dla modułu
Większa część skryptu, pokazanego na listingu 1, pochodzi bezpośrednio z gotowego oprogramowania Sensiriona, przeznaczonego do obsługi układu SCD-30. Zmieniono delikatnie obsługę sensora, aby działał on z SCD-41. Ponadto autor dodał kilka dodatkowych czcionek. Program nawiązuje łączność poprzez Bluetooth z telefonem i komunikuje się z aplikacją Sensiriona na telefon, która pozwala na sczytywanie danych dotyczących wilgotności, temperatury oraz oczywiście stężenia dwutlenku węgla. Aplikacja na telefonie zajmuje się pozostałymi funkcjonalnościami, takimi jak zapisywanie danych itp.
#include "esp_timer.h"
#include <Wire.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include "Sensirion_GadgetBle_Lib.h"
const int16_t SCD_ADDRESS = 0x62;
static int64_t lastMmntTime = 0;
static int startCheckingAfterUs = 1900000;
GadgetBle gadgetBle = GadgetBle(GadgetBle::DataType::T_RH_CO2_ALT);
#define SENSIRION_GREEN 0x6E66
#define sw_version "v1.0"
#define GFXFF 1
#define FF99 &SensirionSimple25pt7b
#define FF90 &ArchivoNarrow_Regular10pt7b
#define FF95 &ArchivoNarrow_Regular50pt7b
bool tell = 0;
// Wywołuje bibliotekę wyświetlacza, piny zdefiniowane są w User_Setup.h
TFT_eSPI tft = TFT_eSPI(135, 240);
//-------------------------------------------------
void displayInit() {
tft.init();
tft.setRotation(1);
}
//-------------------------------------------------
void displayCo2(uint16_t co2) {
if (co2 > 9999) {
co2 = 9999;
}
tft.fillScreen(TFT_BLACK);
uint8_t defaultDatum = tft.getTextDatum();
tft.setTextSize(1);
tft.setFreeFont(FF90);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextDatum(6); // na dole po lewej
tft.drawString("CO2", 10, 125);
tft.setTextDatum(8); // na dole po prawej
tft.drawString(gadgetBle.getDeviceIdString(), 230, 125);
// Wypisuje zawartość CO2
if (co2 >= 1600 ) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tell = 1;
} else if (co2 >= 1000 ) {
tft.setTextColor(TFT_ORANGE, TFT_BLACK);
tell = 0;
} else {
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tell = 0;
}
tft.setTextDatum(8); // na dole po prawej
tft.setTextSize(1);
tft.setFreeFont(FF95);
tft.drawString(String(co2), 195, 105);
// dodaje jednostki do stężenia CO2
tft.setTextSize(1);
tft.setFreeFont(FF90);
tft.drawString("ppm", 230, 90);
tft.setTextDatum(defaultDatum);
}
//-------------------------------------------------
void setup() {
Serial.begin(115200);
delay(100);
while(!Serial);
// formatowanie wyjści
Serial.println("CO2(ppm)\tTemperature(degC)\tRelativeHumidity(percent)");
// Inicjalizacja biblioteki GadgetBle
gadgetBle.begin();
Serial.print("Sensirion GadgetBle Lib initialized with deviceId = ");
Serial.println(gadgetBle.getDeviceIdString());
// Inicjalizacja sterownika SCD30
Wire.begin();
displayInit();
Wire.beginTransmission(SCD_ADDRESS);
Wire.write(0x21);
Wire.write(0xb1);
Wire.endTransmission();
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
// Ekran powitalny
delay(500);
gadgetBle.writeCO2(55);
gadgetBle.writeTemperature(55);
gadgetBle.writeHumidity(55);
gadgetBle.commit();
}
//-------------------------------------------------
void loop() {
if (esp_timer_get_time() – lastMmntTime >= startCheckingAfterUs) {
float co2, temperature, humidity;
uint8_t data[12], counter;
// Wysyłanie komendy do odczytu danych z SCD41
Wire.beginTransmission(SCD_ADDRESS);
Wire.write(0xec);
Wire.write(0x05);
Wire.endTransmission();Wire.requestFrom(SCD_ADDRESS, 12);
counter = 0;
while (Wire.available()) {
data[counter++] = Wire.read();
}
// konwersja na wartość zmiennoprzecinkową
co2 = (float)((uint16_t)data[0] << 8 | data[1]);
// konwersja temperatury do stopni Celsjusza
temperature = -45 + 175 * (float)((uint16_t)data[3] << 8 | data[4]) / 65536;
// konwersja wilgotności do wartości procentowej
humidity = 100 * (float)((uint16_t)data[6] << 8 | data[7]) / 65536;
Serial.print(co2);
Serial.print("\t");
Serial.print(temperature);
Serial.print("\t");
Serial.print(humidity);
Serial.println();
if(co2 < 400){
co2=55;
temperature = 55;
humidity = 55;
}
gadgetBle.writeCO2(co2);
gadgetBle.writeTemperature(temperature);
gadgetBle.writeHumidity(humidity);
gadgetBle.commit();
lastMmntTime = esp_timer_get_time();
displayCo2((uint16_t) std::round(co2));
if (tell){
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
}
gadgetBle.handleEvents();
delay(3);
}
Pierwsza z funkcji w kodzie – displayCo2() – ustawia ekran i czcionki na ekranie oraz wyświetla na nim powitalną wiadomość. W zależności od poziomu CO2 zmienia się kolor wyświetlanej czcionki. Funkcja setup() uruchamia komunikację przez interfejs I2C i inicjalizuje układ SCD-41. Konfigurowane jest także wyjście cyfrowe do kontroli buzzera, obsługiwane przez funkcję digitalWrite.
Funkcja loop() cyklicznie odpytuje czujnik o dane, przesyła je do łącza bluetooth, wyświetla je na ekranie TFT i jeśli poziom CO2 jest wyższy niż 1600, ustawia wyjście w stan wysoki, aby aktywować buzzer podłączony do GPIO 13. Interwał czasowy dla próbkowania można ustawić w oprogramowaniu.
Oprogramowanie na telefonie
Urządzenie jest bardzo łatwe w użyciu. Wystarczy podłączyć je do dowolnego gniazdka USB, a zacznie monitorować pomieszczenie pod kątem nadmiaru CO2. Aby zbierać dane na temat wilgotności, temperatury lub poziomu dwutlenku węgla, wystarczy otworzyć aplikację Sensirion na telefonie, która natychmiast połączy się z systemem i zapisze punkty danych w pamięci telefonu.
Nie ma konieczności korzystania z połączenia z Internetem. Dane będą przechowywane tak długo, jak to potrzebne w telefonie i można je przesłać jako plik txt lub e-mailem w dowolne miejsce. Plik ma nietypowy format, który można konwertować na .CSV, aby działał na komputerze. Sama aplikacja może łatwo wykreślić dane.
Czcionka, którą opisano poziom CO2, zmienia kolor w zależności od stężenia tego gazu. Poziom alarmu jest ustawiony domyślnie na 1600, ale można to łatwo zmienić w oprogramowaniu.
Podsumowanie
Pokazany w artykule kompaktowy sensor pozwala na monitorowanie w czasie rzeczywistym stężenia dwutlenku węgla w otaczającym nas powietrzu. Można ustawić konfigurowalny alarm, który uruchomi się, gdy stężenie przekroczy zadany próg. Daje to użytkownikowi informacje, że należy przewietrzyć pomieszczenie, w którym przebywa.
Stosowanie tego rodzaj systemów, podobnie jak np. układów do analizy zawartości pyłów zawieszonych (PM 2,5 itp.) oraz lotnych związków organicznych (VOC), to kluczowe czynniki, pozwalające na monitorowanie jakości powietrza w naszym otoczeniu, dzięki któremu możemy reagować i częściej wietrzyć pomieszczenia, a czym lepsze jest powietrze, którym oddychamy, tym wyższy komfort i samopoczucie. Szczególnie teraz, gdy sporo osób pracuje w swoich domach, ważne jest dbanie o jakość powietrza w nim. Wszak jest to miejsce, gdzie spędzamy większość czasu.
Nikodem Czechowski, EP
Źródło: https://bit.ly/35aRxFv