Skocz do zawartości

Pomocna odpowiedź

Napisano (edytowany)

Witam wszystkich. Udostępniam swój projekt nie tylko żeby się pochwalić ale też żeby zobaczyć czy może coś przeoczyłem i ktoś byłby w stanie doradzić, zwłaszcza w kwestiach bezpieczeństwa pożarowego - jako, że jestem logistykiem a nie elektronikiem i moja wiedza to głównie Forbot + Claude to chętnie posłucham porad i krytyki.

 

IMG_20260614_183137.thumb.jpg.0f9520187ab9dae8108f1871f4b1d069.jpg

 

Projekt podlewaczki powstał z dwóch powodów - potrzeby bo zapominam podlać kwiatka i braku pomysłu na coś bardziej ambitnego. 

Lista części które użyłem:

  • Klon Arduino Nano (na zdjęciach Uno bo nano było dopiero w dostawie od Pana chińczyka)
  • Czujnik wilgotności gleby analogowy
  • Przekaźnik dwukanałowy 5V/230V
  • Dioda 1N4007
  • Kondensator elektrolityczny 220µF 35V
  • Pompa perstaltyczna Kamoer NKP-DC-S08D 12V (wężyk w głowicy o średnicy 2,5mm połączony ze standardowym akwarystycznym 4mm)
  • Płytka uniwersalna 40×60mm
  • Zasilacz 12V DC
  • 4x Palma Chamedora

Dodatkowo jako, że mam drukarkę 3d to wydrukowałem sobie łączniki na wężyk silikonowy bo nie udało się kupić stacjonarnie nietypowego łącznika 2,5mm, niestety nie przemyślałem kolorystyki i promocyjna czerwona mata silikonowa zaburza czytelność zdjęć, za co przepraszam.

Jak wspominałem, zaczynam dopiero zabawę i nie wstydzę się przyznać, że kod wygenerowałem przy użyciu Claude, działa zaskakująco dobrze, nie wierzyłem, że to działa tak sprawnie na poziomie darmowego użytkownika. Poniżej finalny kod z rozpiską podłączeń:

// ============================================================
//  Automatyczny podlewacz chamedory – Arduino Uno
//  Pompa: Kamoer NKP-DC-S08D (75ml/min realnie)
//  Przekaźnik: Songle SRD-05VDC-SL-C (logika odwrócona!)
//  Czujnik: między rośliną 2 i 3
//  Kroplowniki: między rośliną 1-2 oraz 3-4
//  Doniczka: 60cm balkonowa ~13L ziemi
//  Dawka: ~200ml na sesję podlewania
// ============================================================

// ----- PINY -----
const int PIN_PRZEKAZNIK    = 2;   // D2 → przekaźnik IN1
const int PIN_CZUJNIK_VCC   = 6;   // D6 → zasilanie czujnika (chroni przed korozją)
const int PIN_CZUJNIK_AO    = A0;  // A0 ← sygnał czujnika
const int PIN_LED           = 13;  // wbudowana LED statusu

// ----- KALIBRACJA CZUJNIKA -----
const int WILGOTNOSC_MOKRO  = 325; // wartość gdy ziemia mokra (świeżo podlana)
const int WILGOTNOSC_SUCHO  = 400; // wartość gdy czas podlewać

// ----- USTAWIENIA PODLEWANIA -----
// 75ml/min → 160 sekund = dokładnie ~200ml
const unsigned long CZAS_POMPOWANIA     = 160000UL; // 160 sekund w ms

// Przerwa po podlaniu zanim znów zmierzymy (45 minut na wsiąknięcie)
const unsigned long PRZERWA_PO_PODLANIU = 2700000UL; // 45 minut w ms

// Pomiar co godzinę
const unsigned long INTERWAL_POMIARU    = 3600000UL; // 60 minut w ms

// ----- ZMIENNE WEWNĘTRZNE -----
unsigned long czasOstatniPomiar = 0;
int licznikPodlewan = 0;

// ============================================================
void setup() {
  Serial.begin(9600);

  pinMode(PIN_PRZEKAZNIK,  OUTPUT);
  pinMode(PIN_CZUJNIK_VCC, OUTPUT);
  pinMode(PIN_LED,         OUTPUT);

  // Bezpieczny stan startowy – przekaźnik wyłączony (logika odwrócona)
  digitalWrite(PIN_PRZEKAZNIK,  HIGH);
  digitalWrite(PIN_CZUJNIK_VCC, LOW);
  digitalWrite(PIN_LED,         LOW);

  Serial.println("===========================================");
  Serial.println("  Podlewacz chamedory – wersja finalna");
  Serial.println("===========================================");
  Serial.print("Prog sucho:        "); Serial.println(WILGOTNOSC_SUCHO);
  Serial.print("Prog mokro:        "); Serial.println(WILGOTNOSC_MOKRO);
  Serial.print("Czas pompowania:   "); Serial.print(CZAS_POMPOWANIA / 1000); Serial.println(" sekund");
  Serial.print("Ilosc wody:        ~200 ml");
  Serial.println();
  Serial.print("Pomiar co:         "); Serial.print(INTERWAL_POMIARU / 60000); Serial.println(" minut");
  Serial.println("===========================================");
  Serial.println("Pierwszy pomiar za 10 sekund...");
  Serial.println();

  // Pierwszy pomiar po 10 sekundach (żeby zdążyć otworzyć monitor)
  czasOstatniPomiar = millis() - INTERWAL_POMIARU + 10000UL;
}

// ============================================================
void loop() {
  unsigned long teraz = millis();

  if (teraz - czasOstatniPomiar >= INTERWAL_POMIARU) {
    czasOstatniPomiar = teraz;
    wykonajPomiar();
  }
}

// ============================================================
void wykonajPomiar() {
  // Włącz czujnik, poczekaj 100ms na stabilizację
  digitalWrite(PIN_CZUJNIK_VCC, HIGH);
  delay(100);
  int wartosc = analogRead(PIN_CZUJNIK_AO);
  digitalWrite(PIN_CZUJNIK_VCC, LOW);

  // Przelicz na procent (325=mokro=100%, 400=sucho=0%)
  int procent = map(wartosc, WILGOTNOSC_SUCHO, WILGOTNOSC_MOKRO, 0, 100);
  procent = constrain(procent, 0, 100);

  // Loguj pomiar
  Serial.print("[Pomiar]  Wartosc: ");
  Serial.print(wartosc);
  Serial.print("  Wilgotnosc: ");
  Serial.print(procent);
  Serial.print("%  --> ");

  if (wartosc >= WILGOTNOSC_SUCHO) {
    Serial.println("SUCHO – startuję podlewanie!");
    podlewaj();
  } else {
    Serial.print("OK (");
    if (procent > 70)      Serial.println("wilgotno)");
    else if (procent > 40) Serial.println("umiarkowanie)");
    else                   Serial.println("lekko sucho, ale jeszcze ok)");
  }
}

// ============================================================
void podlewaj() {
  licznikPodlewan++;

  Serial.print(">>> Podlewanie #");
  Serial.print(licznikPodlewan);
  Serial.println(" – pompa ON przez 160 sekund (~200ml)...");

  // Włącz pompę (LOW = włączone, logika odwrócona)
  digitalWrite(PIN_PRZEKAZNIK, LOW);

  // Czekaj z miganiem LED co pół sekundy
  unsigned long start = millis();
  while (millis() - start < CZAS_POMPOWANIA) {
    digitalWrite(PIN_LED, ((millis() - start) / 500) % 2 == 0 ? HIGH : LOW);
  }

  // Wyłącz pompę
  digitalWrite(PIN_PRZEKAZNIK, HIGH);
  digitalWrite(PIN_LED, LOW);

  Serial.println(">>> Pompa OFF. Podano ~200ml wody.");
  Serial.print(">>> Czekam 45 minut na wsiakniecie, nastepny pomiar za ");
  Serial.print((PRZERWA_PO_PODLANIU + INTERWAL_POMIARU) / 60000);
  Serial.println(" minut.");
  Serial.println();

  // Przesuń timer – następny pomiar po przerwie na wsiąknięcie
  czasOstatniPomiar = millis() + PRZERWA_PO_PODLANIU - INTERWAL_POMIARU;
}

 

Plan był prosty, polutować wszystko do odpowiednich pinów ale AI zasugerowało dołożenie kondensatora i diody dla bezpieczeństwa układu co uznałem, za konieczność dlatego postanowiłem polutować to na najmniejszej płytce jaką miałem żeby zmieścić się na szerokość doniczki

IMG_20260609_163507.thumb.jpg.c8ed7c844fff7b37013f50978306d62d.jpg

IMG_20260609_185125.thumb.jpg.da4aa5617be723f5874cc8173c5693ac.jpg

 

Luty oczywiście nie są piękne ale jestem zadowolony z efektów. 

Widoczne linie zasilania celowo przeciągnąłem przez całą długość, w planie było dołożenie czujnika odległości i diód informujących o stanie wody w zbiorniku ale odłożyłem ten pomysł na lepsze czasy, zbyt mocno komplikuje projekt do którego nie podchodziłem z dużym entuzjazmem. Teraz tylko się zastanawiam, czy taki drucik przylutowany tylko w punktach gdzie jest to konieczne nie tworzy ryzyka pożarowego dotykając pól od wibracji pracującej pompy?

 

IMG_20260609_191958.thumb.jpg.55b3bbab04886a45886f9e443d9700f9.jpgIMG_20260609_191951.thumb.jpg.8505e06ec43e5a668f76d7c855b17dae.jpg

 

Uno trochę zakurzone bo rok zbierałem się do pierwszego projektu ale spełniło swoją funkcję. W finalnej formie zastąpiło go Nano. Pierwszy test był obiecujący, pompa zadziałała i reagowała na komendy z monitora. Użyłem kodu testowego również od Claude:

// ============================================================
//  TEST podlewacza – Arduino Nano
//  Monitor Szeregowy: 9600 baud
//  Komendy: p = pompuj 5s, s = odczyt czujnika, a = auto test
// ============================================================

const int PIN_PRZEKAZNIK = 2;   // zmień na 7 jeśli używasz D7
const int PIN_CZUJNIK_VCC = 6;  // zasilanie czujnika
const int PIN_CZUJNIK_AO  = A0; // sygnał czujnika
const int PIN_LED         = 13;

void setup() {
  Serial.begin(9600);
  pinMode(PIN_PRZEKAZNIK, OUTPUT);
  pinMode(PIN_CZUJNIK_VCC, OUTPUT);
  pinMode(PIN_LED, OUTPUT);

  digitalWrite(PIN_PRZEKAZNIK, HIGH); // wyłączona (logika odwrócona)
  digitalWrite(PIN_CZUJNIK_VCC, LOW);
  digitalWrite(PIN_LED, LOW);

  Serial.println("=============================");
  Serial.println("  TEST PODLEWACZA – gotowy");
  Serial.println("=============================");
  Serial.println("Komendy (wpisz i Enter):");
  Serial.println("  p = pompa ON przez 5 sekund");
  Serial.println("  s = jeden odczyt czujnika");
  Serial.println("  a = auto: pomiar co 3s przez 30s");
  Serial.println("  1 = pompa ON");
  Serial.println("  0 = pompa OFF");
  Serial.println("=============================");
}

void loop() {
  if (Serial.available()) {
    char cmd = Serial.read();

    if (cmd == 'p') {
      Serial.println(">> Pompa ON przez 5 sekund...");
      digitalWrite(PIN_PRZEKAZNIK, LOW);
      digitalWrite(PIN_LED, HIGH);
      delay(5000);
      digitalWrite(PIN_PRZEKAZNIK, HIGH);
      digitalWrite(PIN_LED, LOW);
      Serial.println(">> Pompa OFF");
    }

    else if (cmd == 's') {
      zmierzCzujnik();
    }

    else if (cmd == 'a') {
      Serial.println(">> AUTO TEST: pomiar co 3s przez 30s");
      for (int i = 0; i < 10; i++) {
        zmierzCzujnik();
        delay(3000);
      }
      Serial.println(">> AUTO TEST zakończony");
    }

    else if (cmd == '1') {
      Serial.println(">> Pompa ON (ręcznie)");
      digitalWrite(PIN_PRZEKAZNIK, LOW);
      digitalWrite(PIN_LED, HIGH);
    }

    else if (cmd == '0') {
      Serial.println(">> Pompa OFF (ręcznie)");
      digitalWrite(PIN_PRZEKAZNIK, HIGH);
      digitalWrite(PIN_LED, LOW);
    }
  }
}

void zmierzCzujnik() {
  // Włącz czujnik, poczekaj chwilę na stabilizację
  digitalWrite(PIN_CZUJNIK_VCC, HIGH);
  delay(100);

  int val = analogRead(PIN_CZUJNIK_AO);

  // Wyłącz czujnik
  digitalWrite(PIN_CZUJNIK_VCC, LOW);

  int procent = map(val, 1023, 0, 0, 100);

  Serial.print("Czujnik: ");
  Serial.print(val);
  Serial.print(" / 1023   (");
  Serial.print(procent);
  Serial.print("%)   --> ");

  if (val > 800)      Serial.println("BARDZO SUCHO");
  else if (val > 600) Serial.println("SUCHO");
  else if (val > 400) Serial.println("UMIARKOWANIE");
  else if (val > 200) Serial.println("WILGOTNO");
  else                Serial.println("MOKRO / W WODZIE");
}

 

Dzięki temu mogłem sprawdzić swoje lutowanie ale też po przesiadce z Uno na Nano szybka weryfikacja czy zrobiłem wszystko dobrze.

W momencie gdy dotarło Nano, zabrałem się za przygotowanie doniczki i kwiatów. Zdecydowałem się na dwa punkty kropelkujące, musiałem przeprowadzić test czy względnie równo podaje wodę bo AI nastraszyło, że centymetr różnicy wężyka zmieni mocno proporcje wody. Przy docięciu na oko nie widziałem różnicy.

IMG_20260610_134947.thumb.jpg.d76cc19ab84a6eed11d1b113a9ab8192.jpg

Na dno doniczki z wywierconymi otworami drenażowymi wrzuciłem cienką warstwę keramzytu żeby nie tworzyć bagna na dnie. Po wsypaniu części ziemi, wstępnie rozłożyłem wężyki żeby je zasypać co było błędem, w późniejszym etapie je odkopywałem. Silikon jest za miękki a doniczka za mała żeby żaden korzeń nie ścisnął węży dławiąc przepływ.

IMG_20260610_140103.thumb.jpg.c6baf26ec47a153fe53368ab8e647c42.jpg

IMG_20260610_140515.thumb.jpg.a8a76723d5f4c5572655adcb10328b0e.jpgIMG_20260610_142341.thumb.jpg.bce52533cec14426df058f53c9c1d080.jpgIMG_20260610_142348.thumb.jpg.470c84a7e625274478d1c6fca9217e06.jpg

 

Po przesadzeniu roślinek i testach czy podaje odpowiednio wodę, przyszła pora na składanie całości do kupy. Do tego zaprojektowałem i wydrukowałem możliwie najprostszą obudowę z dwóch elementów nasuwanych na siebie, najbliższe pół roku to testy czy to w ogóle ma sens, jeśli palmy nie uschną albo nie zgniją, zostaną przesadzone do ozdobnej doniczki a system podlewania zrobię w kilku sztukach żeby każdy kwiatek w domu był automatycznie podlewany.

image.thumb.png.8e9f3b2e3e08e436c4fbe1d815550f4a.pngIMG_20260614_175946.thumb.jpg.7e86eb850ff2664d7c9dc12ae4a2bd0b.jpg

Arduino i płytka przyklejona klejem na gorąco bo nie chciałem marnować filamentu (PETG) na testowe wersje, jedynie pompa przykręcona do dystansu z drukowanym giwntem.

 

A tak prezentuje się po złożeniu:

IMG_20260614_183119.thumb.jpg.8980d882c62d5d44ffbd97b4e0914e55.jpg

IMG_20260614_183104.thumb.jpg.61ab999afdf0699df69231d63325f26c.jpg

Na dzień dzisiejszy pobiera wodę z buteleczki 250ml ale zamienię to na trochę większą bo obecnie jedno podlanie to około 200ml. Całość nie jest może idealnie ukryta ale stoi za monitorem więc nie rzuca się w oczy i jestem zadowolony z efektu.

 

IMG_20260610_142348.jpg

Edytowano przez sebastianekkk
  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...