Skocz do zawartości
crbjsfso

Monitor warunków atmosferycznych i jakości powietrza obszaru roboczego.

Pomocna odpowiedź

1. Wprowadzenie

Podczas hobbystycznego majsterkowania może zdarzyć się, że zajdzie potrzeba zmierzenia, jakie dokładnie warunki atmosferyczne, czy jakość powietrza panuje w pomieszczeniu lub obszarze roboczym. Może być to na przykład "pojemnik" na drukarkę 3D, jak coś w stylu: Original Prusa i3 MK3 ENCLOSURE -Ikea Lack table - Prusa ResearchIKEA Lack Enclosure Creality Ender 3 CompilationIKEA LACK ENCLOSURE V1. Gdy chcemy sprawdzić jak bardzo nasza drukarka 3D nas truje, mimo, że możemy korzystać z pozornie bezpiecznego i biodegradowalnego PLA. Lub sprawdzić jaką temperaturę osiąga otoczenie podczas wielogodzinnej pracy i czy może to zagrażać elementom z tworzywa i konieczna jest dodatkowa wentylacja. Taki monitor może przydać się również do testów wydajności wyciągu lutowniczego, czyli urządzenia które powinno w sposób najlepiej całkowity odprowadzać z obszaru pracy szkodliwe opary.

Zaprezentowany układ będzie oparty na czujnikach BME280 i MQ-135, a nie jak można było się spodziewać na GP2Y1010AU0F, czy też HM3301, lub czymś z rodziny PMS, jak PMS7003, PMS5003ST czy PMS3003.

2. Projekt i schemat

Projekt będzie bazował na płytce deweloperskie ESP32, co zapewni dostęp do danych przez interfejs sieciowy, ale zostanie również wyposażony w wyświetlacz OLED. Za pomiary warunków odpowiadają wcześniej wspomniane BME280 i MQ-135. Całości dopełnia dzielnik napięcia dla wejścia analogowego MQ-135. Producent układu deklaruje, iż układ można zasilać w przedziale od 2.5V do 5V, to w dokumentacji  widnieje jedynie wartość 5V jeśli chodzi o zasilanie czujnika i tego będziemy się trzymać. Komunikacja odbywa się po magistrali I2C. Całość zasilana jest napięciem 5V przy użyciu ładowarki impulsowej jakich pełno w naszych domach. Zasilanie można doprowadzić poprzez podwójny przewód microUSB lub pojedynczy i moduł z gniazdem microUSB. W drugim przypadku należy podać zasilanie na pin VIN o wartości od 7-12V poprzez przetwornicę Step-Up.

schemat.thumb.jpg.148880f8571af08baf1c1c25a6c75584.jpg

2.1. Schemat połączeń elektrycznych projektu.

3. Części i narzędzia

Aby wykonać projekt będą nam potrzebne następujące elementy:

4. Oprogramowanie

Do ESP32 należy załadować kod z niewielką modyfikacją. Mianowicie w linii 17 i 18 należy wpisać nazwę swojej sieci i hasło:

const char *ssid = "nazwa_sieci_wifi";
const char *password = "haslo_sieci_wifi";

Zapewni on możliwość korzystania z interfejsu sieciowego w sieci lokalnej pod adresem 192.168.0.150. Oczywiście wszelkie informacje zostaną również wyświetlone na ekranie OLED.

KOD:

#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define mq135analogpin (4)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_BME280 bme;

int h1, p1, jp1;
float jp1v;
const char *ssid = "nazwa_sieci_wifi";
const char *password = "haslo_sieci_wifi";
String header;

WiFiServer server(80);

void setup()
{
  Serial.begin(115200);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
  {
    Serial.println(F("Nie ma OLED!"));
    for (;;);
  }

  bool status = bme.begin(0x76);
  if (!status) {
    Serial.println("Nie ma BME280!");
    while (1);
  }

  Serial.print("Laczenie z siecia: ");
  Serial.println(ssid);

  IPAddress ip(192, 168, 0, 150);
  IPAddress gateway(192, 168, 0, 1);
  IPAddress subnet(255, 255, 255, 0);

  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }

  // Wyświetlanie przydzielonego adresu IP w sieci lokalnej i uruchomienie serwera WWW
  Serial.println("");
  Serial.println("WiFi podlaczone.");
  Serial.println("Adres IP: ");
  Serial.println(WiFi.localIP());
  server.begin();

  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop()
{
  WiFiClient client = server.available();

  if (client)
  {
    Serial.println("Nowy klient.");
    String currentLine = "";
    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();
        Serial.write(c);
        header += c;
        if (c == '\n')
        {
          if (currentLine.length() == 0)
          {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html lang=\"pl\">");
            client.println("<head>");
            client.println("<title>Monitor warunków pomieszczeniowych</title>");
            client.println("<meta charset=\"utf-8\">");
            client.println("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">");
            client.println("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">");
            client.println("<meta name=\"robots\" content=\"none\">");
            client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<style>");
            client.println("body {background: #313236; font: bold 42px Verdana, sans-serif; color: #fff; text-align: center; padding: 0; margin: 60px 0;}");
            client.println("div {margin: 40px 0;}");
            client.println("span {font-size: 24px; color: #999;}");
            client.println("</style>");
            client.println("</head>");
            client.println("<body>");
            
            client.println("<div>");
            client.println("<span>TEMPERATURA</span><br>");
            client.println(bme.readTemperature(), 1);
            client.println(" °C<br><span>± 1 °C</span>");
            client.println("</div>");

            client.println("<div>");
            client.println("<span>WILGOTNOŚĆ</span><br>");
            h1 = round(bme.readHumidity());
            client.println(h1);
            client.println(" %<br><span>± 3 %</span>");
            client.println("</div>");

            client.println("<div>");
            client.println("<span>CIŚNIENIE</span><br>");
            p1 = round(bme.readPressure() / 100.0F);
            client.println(p1);
            client.println(" hPa<br><span>± 1 hPa</span>");
            client.println("</div>");

            client.println("<div>");
            client.println("<span>JAKOŚĆ POWIETRZA</span><br>");
            jp1 = analogRead(mq135analogpin);
            jp1v = (jp1/4095)*3;
            if (jp1v < 0.5)
            {
              client.println("DOBRA");
            } else {
              client.println("ZLA!");
            }
            client.println("</div>");

            client.println("</body>");
            client.println("</html>");
            client.println();
            break;
          }
          else
          {
            currentLine = "";
          }
        }
        else if (c != '\r')
        {
          currentLine += c;
        }
      }
    }
    header = "";
    client.stop();
    Serial.println("Klient rozlaczony.");
    Serial.println("");
  }

  display.clearDisplay();
  display.cp437(true);

  // temperatura
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("TEMPERATURA");

  display.setTextSize(3);
  display.setCursor(0, 24);
  display.print(String(bme.readTemperature(), 1));
  display.print(" ");
  display.setTextSize(2);
  display.write(248);
  display.setTextSize(3);
  display.print("C");

  display.setCursor(0, 50);
  display.setTextSize(1);
  display.write(241);
  display.print("1 ");
  display.write(248);
  display.print("C");

  display.display();
  delay(2000);
  display.clearDisplay();

  // wilgotnosc
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("WILGOTNOSC");

  display.setTextSize(3);
  display.setCursor(0, 24);
  h1 = round(bme.readHumidity());
  display.print(String(h1));
  display.print(" ");
  display.write(37);

  display.setCursor(0, 50);
  display.setTextSize(1);
  display.write(241);
  display.print("3 ");
  display.write(37);

  display.display();
  delay(2000);
  display.clearDisplay();

  // cisnienie
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("CISNIENIE");

  display.setTextSize(3);
  display.setCursor(0, 24);
  p1 = round(bme.readPressure() / 100.0F);
  display.print(String(p1));
  display.print(" ");
  display.setTextSize(2);
  display.print("hPa");

  display.setCursor(0, 50);
  display.setTextSize(1);
  display.write(241);
  display.print("1 ");
  display.print("hPa");

  display.display();
  delay(2000);
  display.clearDisplay();

  // jakosc powietrza
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("JAKOSC POWIETRZA");

  display.setTextSize(3);
  display.setCursor(0, 28);
  jp1 = analogRead(mq135analogpin);
  jp1v = (jp1/4095)*3;
  if (jp1v < 0.5)
  {
    display.print("DOBRA");
  } else {
    display.print("ZLA!");
  }

  display.display();
  delay(2000);
}

5. Efekt końcowy

Tak oto prezentuje się prototyp, efekt końcowy i interfejs sieciowy.

1.thumb.jpg.2af4d23cfe0de9003c9d574e9e16c3d4.jpg2.thumb.jpg.d8abde321dfa202f2f5bf83a1a7a193c.jpg

5.1. Pierwszy prototyp, jeszcze bez dzielnika napięcia i innych mniejszych zmian.

4.thumb.jpg.23042f240965bb3d08f50682ea63b511.jpg5.thumb.jpg.973e5d7b1902fd3a77a6da84855ba762.jpg6.thumb.jpg.deb5ddd9466f710f777c8f2229a6b535.jpg7.thumb.jpg.26cd741fd2b4072515d5d8d7f935a3c9.jpg8.thumb.jpg.83983507b88ca9a05ccfbb552ba5a1b2.jpg

5.2. Gotowe urządzenie, prezentacje wszystkich wyników na ekranie OLED.

3.thumb.jpg.4b2cfb5cbe153dad43cf27e19968e82f.jpg

5.3. Zużycie energii elektrycznej podczas pracy urządzenia.

interfejs_sieciowy.jpg.ef0047612a57c85900ba51cfa123b9d5.jpg

5.4. Interfejs sieciowy dostępny pod adresem 192.168.0.150

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

Podoba Ci się ten projekt? Zostaw pozytywny komentarz i daj znać autorowi, że zbudował coś fajnego!

Masz uwagi? Napisz kulturalnie co warto zmienić. Doceń pracę autora nad konstrukcją oraz opisem.

@crbjsfso dzięki za opis kolejnego urządzenia 😉 Co to za finalna obudowa? Czy jest jakiś konkretny powód, dla którego czujniki są od siebie tak oddalone?

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Treker Finalna obudowa została wykonana z arkuszy spienionego PCV w kolorze białym o grubości 3mm, łączenia dokonane klejem - cyjanoakrylem. Niestety nie byłem zadowolony z widocznych łączeń ścianek i na wierzch poszedł warstwa samoprzylepnego białego papieru z której też do końca nie jestem zadowolony ponieważ w niektórych miejscach nieznacznie odstaje. W późniejszym czasie obudowa zostanie prawdopodobnie wycięta z drewna na obrabiarce CNC, którą planuje zbudować.

Czujniki oddalone są od siebie, aby nie zachodziło fałszowanie pomiarów. MQ-135 nagrzewa się podczas pracy, dlatego też postanowiłem go umieścić na samej górze, tak aby ciepłe powietrze mogło swobodnie ulatywać w górę i nie było możliwości wpływu na pomiar BME280.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Chumanista Tak, spokojnie. Po jednym czujniku na raz, zaczynałem od samego pomiaru temperatury, później doszła wilgotność, itd. Właśnie czekam na GP2Y1010AU0F i kilka innych z serii MQ. Następnie planuje zabrać się za serię PMS*, czujniki radonu, dozymetry, ect. Właściwie to wszystkie moje konstrukcje są w ciągłej fazie rozwojowej. Niestety mam dosyć mało czasu na swoje hobby dlatego może się wydawać, że idzie mi to bardzo opornie.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@crbjsfso koniecznie mów jak będą działały bo też planuję coś podobnego i wiedza się przyda!

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites
Dnia 1.11.2019 o 13:07, crbjsfso napisał:

@Chumanista Tak, spokojnie. Po jednym czujniku na raz, zaczynałem od samego pomiaru temperatury, później doszła wilgotność, itd. Właśnie czekam na GP2Y1010AU0F i kilka innych z serii MQ. Następnie planuje zabrać się za serię PMS*, czujniki radonu, dozymetry, ect. Właściwie to wszystkie moje konstrukcje są w ciągłej fazie rozwojowej. Niestety mam dosyć mało czasu na swoje hobby dlatego może się wydawać, że idzie mi to bardzo opornie.

Czujniki MQ to tak z mojego doświadczenia bardziej nadają się jako sygnalizatory występowania gazu (lub gazów bo niektóre reagują na kilka) niż jako mierniki stężenia. Tym bardziej MQ135 jest bardzo zawodny w przypadku określania jakości powietrza, gdyż jego odczyty są bardzo zależne od temperatury, wilgotności i zapylenia, co nie do końca przenosi się to na sama jakość powietrza. Próbowałem na tym zrobić sobie automatyczny sygnalizator tego czy sąsiedzi z dołu palą papierosy (niestety cały dym zaciąga do mojego mieszkania) i nie dało się tego odpowiednio skalibrować. Znalazłem gdzieś w necie pracę naukową gdzie napisali równanie kalibrujące wskazania w zależności od warunków atmosferycznych ale zawierał się chyba w 3 liniach na kartce A4 😉

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

@Kuba_k Tak wszystko się zgadza, moje obserwacje również to potwierdzają. Chciałbym jednak trochę pokombinować z kodem, zanim dołożę/wymienia czujnik GP2Y1010AU0F. Choćby z czystej ciekawości.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
10 minut temu, crbjsfso napisał:

@Kuba_k Tak wszystko się zgadza, moje obserwacje również to potwierdzają. Chciałbym jednak trochę pokombinować z kodem, zanim dołożę/wymienia czujnik GP2Y1010AU0F. Choćby z czystej ciekawości.

Z ciekawości sprawdziłem cenę tego GP2Y1010AU0F. Mogłem od razu go brać. Dzięki za pomysł 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Kuba_k Tutaj jest trochę stary, ale moim zdaniem ciekawy film jeśli chodzi o GP2Y1010AU0F w formie czujnika smogu od razu z opcją podpięcia do systemu inteligentne domu opartego o oprogramowanie Domoticz. Eh, szkoda, że mam za mało czasu na swoje projekty i testowanie wszystkich fajnych rozwiązań. Jak coś zbudujesz to daj znać, chętnie rzucę okiem.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@crbjsfso mam już zrobiony na bazie PMS5003, imo trochę dokładniejszy 😉

 

Edit/ przeczytałem dokumentacje. Ten sharp też działa na analogu więc rzeczywiście jako detektor dymu niż jakieś dokładniejsze pomiary.

Edytowano przez Kuba_k
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Analog nie znaczy jeszcze że nie można zdigitalizować i przeliczyć, ten czujnik daje nawet znośne rezultaty przy małym nakładzie.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
9 godzin temu, Chumanista napisał:

Analog nie znaczy jeszcze że nie można zdigitalizować i przeliczyć, ten czujnik daje nawet znośne rezultaty przy małym nakładzie.

Wszystko można, tylko po co. Nie wiem tylko jak skalibrujesz go żeby dawał rzeczywiste wyniki przy tym małym nakładzie.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...