Inkubatorius paukščiams perėti 2

Inkubatoriumi pasinaudojau jau kelis mėnesius. Per tą laiką išsiperėjo virš 150 viščiukų.

   Veikia pakankamai neblogai, tik perdegant lempai nugaišta ir SSR relė, iš keturių perdegusių lempų taip buvo vienai, o nugaišusi ji lieka atsidariusi ir likusi lempa šildo toliau. Parinkus per galingas lempas kiaušiniai gali ir iškepti. Gaminant galutinę inkubatoriaus elektronikos versiją tai reikia numatyti ir kiekvienai lempai naudoti atskiras reles, jos taip pat turėtų būti lengvai keičiamos. Taip pat tikslesniam temperatūros bei drėgmės palaikymui reiktų naudoti PID algoritmą, nes dabar naudojamas BitBang temperatūrą pakelia pakelia daugiau nei vienu laipsniu virš pageidaujamos temperatūros, po to kai buvo atidarytas dangtis ir inkubatorius daugiau atvėsta. Po dešimties minučių temperatūros svyravimai sumažėja iki plius/minus vienos dešimtosios laipsnio dalies. Panaši situacija ir su drėgme, nukėlus dangtį ji krinta iki patalpos drėgmės, o po kurio laiko uždėjus inkubatoriaus dangtį drėgmė pakyla tiek, kad viršija pageidaujamą iki 15%, po kokios valandos svyravimai sumažėja iki ±3%. PID algoritmas leistų išvengti staigių šuolių po inkubatoriaus uždarymo, bet tai nėra labai didelė problema, kiaušinis per tą laiką vistiek nespėja perkaisti, o lempų junginėjimas dabar yra gerokai retesnis nei būtų su PID, manau tai teigiamai atsiliepia lempos ilgaamžiškumui. Nors galima padaryti lempų galios reguliavimą, mažinant jų švietimo intensyvumą, bet tada reikia keisti elektrinę valdiklio schemą ir programos darbą derinti prie tinklo dažnio ir fazės.

Drėgmės palaikymui naudotas pigus kiniškas ultragarsinis oro drėkiklis savo darbą atlieka puikiai, kol neužsikemša kalkėmis. 

Per naudojimo laiką jis išgarino gal kokius du kibirus šulinio vandens ir po truputį nustojo veikti. Bandžiau acte mirkyti piezo elementą, bet be teigiamų rezultatų. Reikia naudoti distiliuotą vandenį, bet kažin ar verta, kai pats drėkintuvas kainuoja mažiau negu kainuos distiliuotas vanduo tam pačiam darbo laikui.

Iš pradžių naudotas drėgmės/temperatūros daviklis DHT21 nepasiteisino, labai grybauja jo parodymai, kelių laipsnių svyravimai tokiam prietaisui nėra priimtini. Vietoje jo panaudotas AM2320 daviklis, su juo jokių nusiskundimų dėl tikslumo ir parodymo šokinėjimų nėra. Bet jis neveikia kartu su oled ekrano SSD1306 I2C versija, todėl ekranas pakeistas į to paties tipo SPI variantą. Prireikė daugiau valdiklio kojų ekrano pajungimui, bet tai nėra didelė problema, kojų užtenka.

Į pasirinktą dėžutę netilpo norima maketinė plokštė, teko imti mažesnę, kartu Arduino Nano pakeisti į Arduino Pro Micro, kitaip netelpa norimi komponentai.

   Ventiliatoriaus greičiui reguliuoti panaudotas mosfet tranzistorius. Kol kas vis neprisiruošiu padaryti automatinio kiaušinių vartymo, taip pat būtų gerai ir automatinis vandens papildymas, tam jau turiu peristaltinį siurblį. Gal dar būtų neblogai, kad kur į internetą keltų daviklių parodymus ir perspėtų apie nukrypimus nuo normos žinute.

Pajungimo schemos nepateiksiu, ji labai aiškiai suprantama iš Arduino programos:

#include <Arduino.h>
#include <string.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <EEPROMex.h>
#include <AM2320.h>
#define plus 9
#define minus 8
#define rezimas 7
#define ventiliatorius 6
#define dregme 5
#define temperatura 4
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 14, /* cs=*/ A2, /* dc=*/ A1, /* reset=*/ A0);
AM2320 th;
char buffer[10];
byte mode;
boolean keitimai = false, paspausta = false, jungta=false;
float h, t, hs, ts, reikia[3], skaitiklis;
unsigned long laikas, laikas2, laikas3;

void softReset() {
  asm volatile ("jmp 0");
}

void setup(void) {
  u8g2.begin();
  pinMode(plus, INPUT_PULLUP);
  pinMode(minus, INPUT_PULLUP);
  pinMode(rezimas, INPUT_PULLUP);
  pinMode(plus, INPUT_PULLUP);
  pinMode(minus, INPUT_PULLUP);
  pinMode(rezimas, INPUT_PULLUP);
  pinMode(ventiliatorius, OUTPUT);
  pinMode(dregme, OUTPUT);
  pinMode(temperatura, OUTPUT);
  digitalWrite(ventiliatorius, LOW);
  digitalWrite(dregme, LOW);
  digitalWrite(temperatura, LOW);
  EEPROM.setMemPool(0, 30);
  EEPROM.setMaxAllowedWrites(100);
  delay(100);
  reikia[0] = EEPROM.readFloat(0);
  reikia[1] = EEPROM.readFloat(10);
  reikia[2] = EEPROM.readFloat(20);
  if (isnan(reikia[0]) || reikia[0] > 50 || reikia[0] < 10) reikia[0] = 37;
  if (isnan(reikia[1]) || reikia[1] > 99 || reikia[1] < 10) reikia[1] = 75;
  if (isnan(reikia[2]) || reikia[2] > 9 || reikia[2] < 0) reikia[2] = 6;
  switch (th.Read()) {
    case 2:
      u8g2.clearBuffer();
      u8g2.firstPage();
      do {
        u8g2.setFont(u8g2_font_ncenB18_tr);
        u8g2.drawStr(10, 40, "CRC Klaida");
      } while (u8g2.nextPage());
      u8g2.sendBuffer();
      break;
    case 1:
      u8g2.clearBuffer();
      u8g2.firstPage();
      do {
        u8g2.setFont(u8g2_font_ncenB18_tr);
        u8g2.drawStr(10, 40, "Klaida");
      } while (u8g2.nextPage());
      u8g2.sendBuffer();
      delay(1000);
      softReset();
      break;
    case 0:
      h = th.h;
      t = th.t;
      break;
  }
  skaitiklis = millis();
  u8g2.clearBuffer();
  u8g2.sendBuffer();
}

void isvedimas() {
  u8g2.clearBuffer();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    if (isnan(h) || isnan(t)) {
      u8g2.drawStr(0, 20, "neapib");
      return;
    }
    u8g2.drawStr(0, 12, "Temp Dreg Vent");
    u8g2.setFont(u8g2_font_ncenB14_tr);
    dtostrf(t, 4, 1, buffer);
    u8g2.drawStr(1, 35, buffer);
    dtostrf(h, 4, 1, buffer);
    u8g2.drawStr(52, 35, buffer);
    dtostrf(reikia[2], 2, 0, buffer);
    u8g2.drawStr(105, 35, buffer);
    u8g2.drawLine(45 * mode + 10, 62, 45 * mode + 30, 62);
    u8g2.drawLine(45 * mode + 10, 63, 45 * mode + 30, 63);
    u8g2.setFont(u8g2_font_ncenB12_tr);
    for (int i = 0; i < 2; i++) {
      dtostrf(reikia[i], 4, 1, buffer);
      //Serial.println(reikia[i]);
      u8g2.drawStr(48 * i + 4, 55, buffer);
    }
  } while (u8g2.nextPage());
  u8g2.sendBuffer();
  hs = h;
  ts = t;
}

void issaugom() {
  u8g2.clearBuffer();
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB18_tr);
    u8g2.drawStr(10, 40, "Issaugom");
  } while (u8g2.nextPage());
  u8g2.sendBuffer();
  keitimai = false;
  EEPROM.writeFloat(0, reikia[0]);
  EEPROM.writeFloat(10, reikia[1]);
  EEPROM.writeFloat(20, reikia[2]);
  delay(5000);
}

void skaitom_davikli() {
  if ((millis() - skaitiklis) < -1)
    skaitiklis = millis();
  if ((millis() - skaitiklis) > 2000) {
    switch (th.Read()) {
      case 2:
        u8g2.clearBuffer();
        u8g2.firstPage();
        do {
          u8g2.setFont(u8g2_font_ncenB18_tr);
          u8g2.drawStr(10, 40, "CRC Klaida");
        } while (u8g2.nextPage());
        u8g2.sendBuffer();
        break;
      case 1:
        u8g2.clearBuffer();
        u8g2.firstPage();
        do {
          u8g2.setFont(u8g2_font_ncenB18_tr);
          u8g2.drawStr(10, 40, "Klaida");
        } while (u8g2.nextPage());
        u8g2.sendBuffer();
        delay(1000);
        softReset();
        break;
      case 0:
        h = th.h;
        t = th.t;
        break;
    }
    skaitiklis = millis();
  }
}

void skaitom_mygtukus() {
  if (!digitalRead(rezimas)) {
    mode++;
    paspausta = true;
    if (mode > 2) mode = 0;
    delay(100);
  }
  if (digitalRead(plus) && digitalRead(minus))
    laikas = millis();
  if (!digitalRead(plus)) {
    if (mode == 2 || (millis() - laikas) > 3000) {
      if ((millis() - laikas) > 8000)
        reikia[mode] = reikia[mode] + 5;
      else
        reikia[mode]++;
    }
    else
      reikia[mode] = reikia[mode] + .1;
    if (mode > 1) {
      if (reikia[mode] > 9) reikia[mode] = 9;
    }
    else {
      if (reikia[mode] > 99) reikia[mode] = 99;
    }
    paspausta = true;
    keitimai = true;
    laikas2 = millis();
    delay(20);
  }
  if (!digitalRead(minus) && (reikia[mode] != 0)) {
    if (mode == 2 || (millis() - laikas) > 3000) {
      if ((millis() - laikas) > 8000)
        reikia[mode] = reikia[mode] - 5;
      else
        reikia[mode]--;
    }
    else
      reikia[mode] = reikia[mode] - .1;
    if (reikia[mode] < 0) reikia[mode] = 0;
    paspausta = true;
    keitimai = true;
    laikas2 = millis();
    delay(20);
  }
  if (paspausta || ts != t || hs != h)
    isvedimas();
  paspausta = false;
}

void junginejam() {
  analogWrite(ventiliatorius, (reikia[2]) * 255 / 9);
  if ((t+.6) < reikia[0]) {
    digitalWrite(temperatura, HIGH);
    laikas3 = millis();
    jungta=true;
  }
  else if (t >= reikia[0]) {
    digitalWrite(temperatura, LOW);
    laikas3 = millis();
    jungta=false;
  }
  else if ((millis()-laikas3) > 7500) {
      laikas3 = millis();
      jungta = !jungta;
      if (jungta)
        digitalWrite(temperatura, HIGH);
      else 
        digitalWrite(temperatura, LOW);
      
    }
      
  if (h < reikia[1])
    digitalWrite(dregme, HIGH);
  else
    digitalWrite(dregme, LOW);
}

void loop(void) {
  skaitom_davikli();
  skaitom_mygtukus();
  junginejam();
  if (keitimai && ((millis() - laikas2) > 30000))
    issaugom();
}

Parašykite komentarą

El. pašto adresas nebus skelbiamas. Būtini laukeliai pažymėti *