Skocz do zawartości

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


crbjsfso

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
Link do komentarza
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.

@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
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@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
Link do komentarza
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
Link do komentarza
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
Link do komentarza
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.

Link do komentarza
Share on other sites

@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
Link do komentarza
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
Link do komentarza
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!

Anonim
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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.