"Народный" инкубатор

lean_74
Offline
Зарегистрирован: 22.12.2015

Почему "народный"? Потому что почитал я форум, взял за основу инкубатор от Umka, ПИД от  yul-i-an, часики от dimax , температуру с Далласа от Pyotr и слепил, что получилось. Главной целью было упростить по максимуму и использовать то что уже было куплено, LCD16x2, Даллас , но без даллосовской библиотеки, DHT11 или si7021, ардуино Нано с прошивкой оптибут. В первом моем инкубаторе я wdt не использовал, в итоге 150 перепелиных яиц испортил. Теперь сделал инкубатор поменьше из пенопластовой коробки. фотки позже выложу, если  кого заинтересует.

#include <avr/wdt.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
//#include "DHT.h"
#include <Si7021.h> //мой датчик влажности
#include <OneWire.h>
#include <Wire.h>
OneWire ds(7); 
#define START_CONVERT 0
#define READ_TEMP 1



//#define DHTPIN 11     // what digital pin we're connected to
//#define DHTTYPE DHT11   // DHT 11, DHT 22
//DHT dht(DHTPIN, DHTTYPE);
SI7021 si7021; //раскоментировать, если используем датчик si7021. 

LiquidCrystal_I2C lcd(0x27, 16, 2);  // инициализация библиотеки дисплея

//номера выводов кнопок
//#define EXT_HEATING                  // ИСПОЛЬЗУЕМ ДОП.НАГРЕВАТЕЛЬ ВМЕСТО УВЛАЖНИТЕЛЯ. Если нужен увлажнитель, просто закомментируйте эту строку.
#define heater_pin 6                  // нагреватель
#define humidifer_pin 12               // увлажнитель
#define fan_pin 13                     // вентилятор
#define alarm_pin 10                   // пин аварии
#define beeper_pin 14                   //пищалка по аварии

#define turn_pin 8                     // управление поворотом вперед
//#define turn_pin2 6                    // управление поворотом назад
//#define extend_heater_pin 8         // дополнительный нагреватель
#define button_minus_pin 3            //пин кнопки "минус"
#define button_plus_pin 4             //пин кнопки "плюс"
#define button_enter_pin 5           //пин кнопки "enter"
#define DS18B20_Pin 7                 //пин термометра
//Пин 2 Вход обработки прерывания для детектора нуля и управления семистором
#define voltmeter_pin 15               //вход А1 через делитель (22к/10к) подключен к питанию модуля. Измеряет до 16В.


boolean button_minus;                // статус нажатия кнопок
boolean button_plus;
boolean button_enter;

unsigned long currentTime;            // задаем переменные для тайминга поворота
unsigned long loopTime;
unsigned long serialTime; //this will help us know when to talk with processing

boolean hotFlag1 = 0;              // флаг включения обогревателя основного   1-ошибка, включать нельзя 
boolean fanFlag = 0;        // флаг включения вентилятора проветривания 1-включено проветривание
unsigned long trhMillis = 0;

boolean flag = 0;
int clockTime = 0; // флаг того что выводим температуру или влажность
unsigned long lastMillis = millis();
int TimeTemp = 4;  //время следующего измерения температуры в секундах
int TimeTurn = 20;  //время поворота в десятых долях секунды

const unsigned long TRHSTEP   = 300UL;  // Период опроса датчиков

//int counter=0;//для проверки вачдога

volatile uint8_t minut=0;
//volatile uint8_t chas=0;
int chas=0;
volatile uint8_t sec=0;
int den=0;
int oldden=0;
int oldchas=0;

int temp=0; // температура Далласа
float temp1=0; // температура Далласа с десятыми
float temp2=0; // температура DHT, si7021
float hum=0;

int del = 80;                     // переменная ожидания между выборами меню
unsigned int interval = 200;      // интервал сколько будет длиться цикл while, после чего перейдёт к следующему меню.(кол-во итераций)

boolean out=0;//управление симистором yul-i-an
int reg,er,zad;//    yul-i-an
double I,Kp=3,Ki=0.45,Kd=0.6,pre_err,err; //    yul-i-an

unsigned long alarmDelay;

float needTemp = 37.6;                  // нужная для текущего дня температура инкубации (по умолчанию)
float needHum = 60.5;                   // ---- влажность
int ventTime = 2;                       // длительность проветривания
boolean needTurn = false;               // нужен ли поворот яиц?
int bird=0;

// make some custom characters:
byte znak_g[8] = {//г
  0b11111,
  0b10001,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b00000
};
byte znak_b[8] = {//Б
  0b11111,
  0b10001,
  0b10000,
  0b11110,
  0b10001,
  0b10001,
  0b11110,
  0b00000
};

byte znak_p[8] = {
  0b11111,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b00000
};
byte znak_i[8] = {
  0b10001,
  0b10001,
  0b10011,
  0b10101,
  0b11001,
  0b10001,
  0b10001,
  0b00000
};

byte znak_l[8] = {
  0b00111,
  0b01001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b00000
};

byte light_znak[8] = {
  0b10000,
  0b10000,
  0b10000,
  0b11110,
  0b10001,
  0b10001,
  0b01110,
  0b00000
};

byte znak_u[8] = {
  0b10001,
  0b10001,
  0b10001,
  0b01111,
  0b00001,
  0b10001,
  0b01110,
  0b00000
};


byte znak_ia[8] = {
  0b01111,
  0b10001,
  0b10001,
  0b01111,
  0b00101,
  0b01001,
  0b10001,
  0b00000
};
byte znak_d[8] = {
  0b01110,
  0b01010,
  0b01010,
  0b01010,
  0b01010,
  0b11111,
  0b10001,
  0b00000
};
byte znak_ch[8] = {
  0b10001,
  0b10001,
  0b10001,
  0b01111,
  0b00001,
  0b00001,
  0b00001,
  0b00000
};
byte znak_c[8] = {
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b11111,
  0b00001
};



void readSet(){
 den=EEPROM_int_read(100);
 chas=EEPROM_int_read(102);
  int bird;                  // выбор птицы
  int r_array[6][4][5] = {
  {{2, 382, 600, 0, 1}, {12, 376, 600, 3, 1}, {15, 374, 480, 10, 1}, {18, 370, 855, 10, 0}},
  {{2, 378, 550, 0, 1}, {7, 378, 500, 3, 1}, {14, 378, 500, 10, 1}, {16, 375, 700, 0, 0}},
  {{7, 382, 700, 0, 1}, {14, 378, 600, 0, 1}, {25, 378, 600, 10, 1}, {28, 375, 855, 0, 0}},
  {{2, 380, 600, 0, 1}, {7, 378, 550, 0, 1}, {29, 375, 450, 10, 1}, {30, 370, 750, 0, 0}},
  {{7, 378, 700, 0, 1}, {14, 378, 600, 0, 1}, {27, 378, 600, 15, 1}, {30, 375, 855, 0, 0}},
  {{8, 377, 650, 0, 1}, {14, 377, 500, 0, 1}, {25, 375, 650, 10, 1}, {28, 375, 655, 10, 0}},
  }; 
//Serial.println("readset=");

bird=  EEPROM_int_read(110);
  for (int d=4; d>=0; d--){
  if(den <= r_array[bird][d][0]){
  needTemp = float(r_array[bird][d][1])/10;//
  needHum = float(r_array[bird][d][2])/10; //
  ventTime = r_array[bird][d][3];
  needTurn = r_array[bird][d][4];
  }
  }

  if (den>36 || den<0){
    den=0; // 
  } 
  if (chas>24){
    chas=0; // 
  } 
  if (minut>60){
    minut=0; // 
  } 
  
}
  
void setup(){
   wdt_disable(); // запретили как можно скорее собаку, что-бы не уйти в бесконечный ребут
//   Serial.begin(9600);
//   readSet();
    lcd.begin();
    lcd.backlight();     // Включаем подсветку дисплея
    lcd.clear();
    
  // create a new character
//  lcd.createChar(5, znak_g);//г
  lcd.createChar(5, znak_b);//Б
  lcd.createChar(1, znak_i);//И
  lcd.createChar(2, znak_p);//П
  lcd.createChar(3, znak_l);//Л  
  lcd.createChar(4, light_znak);  // мягкий хнак
  lcd.createChar(7, znak_d);  //Д
  lcd.createChar(8, znak_c); //Ц 
  lcd.createChar(6, znak_u);//У
   
  lcd.setCursor(0, 0);

  lcd.print("   HAPO"); 
  lcd.write(7);
  lcd.print("H");
  lcd.write(4);
  lcd.print("|");
  lcd.write(1);
  lcd.setCursor(0, 1);
  lcd.print("   ");
  lcd.write(1);
  lcd.print("HK");
  lcd.write(6);
  lcd.write(5);
  lcd.print("ATOP");


  
  Wire.begin();        // старт I2C
 
//   dht.begin();
  si7021.begin(); // Runs : Wire.begin() + reset() // старт датчика влажности
  delay(3000);// подождем пока датчик запуститься, и завтавка погорит
  si7021.setHumidityRes(12); // Humidity = 12-bit / Temperature = 14-bit //максимальное разрешение
   

lcd.createChar(5, znak_g);//г
  readSet();  // читаем настройки из еепром 
  


// настройкa часов
TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание

  tempProcess(START_CONVERT);//конвентируем dallas

  attachInterrupt(0, zero_crosss_int, RISING);//внешнее прерывание на D2
 
  //pinMode(extend_heater_pin, OUTPUT);      //пин дополнительного нагревателя. Переводим в 1 чтобы не включать реле.
  //digitalWrite(extend_heater_pin, HIGH);
  pinMode(heater_pin, OUTPUT);
  pinMode(turn_pin, OUTPUT);      // устанавливаем выводы
  //pinMode(turn_pin2, OUTPUT);      // устанавливаем выводы
  digitalWrite(turn_pin, HIGH);
  //digitalWrite(turn_pin2, HIGH);
  pinMode(humidifer_pin, OUTPUT);
  pinMode(fan_pin, OUTPUT);
  digitalWrite(fan_pin, HIGH);
  pinMode(alarm_pin, OUTPUT);
  digitalWrite(alarm_pin, HIGH);
  pinMode(button_minus_pin, INPUT_PULLUP); //подтягиваем входы кнопок к плюсу встроенными резисторами
  pinMode(button_plus_pin, INPUT_PULLUP);
  pinMode(button_enter_pin, INPUT_PULLUP);
  alarmDelay = millis();

  wdt_enable(WDTO_8S); // активировали таймер, каждые 8 секунд его нужно сбрасывать

}

ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду 
if (sec>59){sec=0; minut++;} 
if (minut>59){minut=0; chas++;} // при записи каждый час хватит памяти на 11 лет
if (chas>23){chas=0;den++;}//readSet(); но нам главное знать день инкубации
if (den>36){den=0; } // частный случай для нас не принципиальный, у нас день инкубации
}

void loop(){
 wdt_reset(); // говорим собаке что "В Багдаде все спокойно", начинается очередной отсчет 8-х секунд.
 
 if (oldchas!=chas){ // раз в час сохраняем время
 EEPROM_int_write(102, chas);
 oldchas=chas;
 }
 if (oldden!=den){ // раз в день читаем настройки заново
 EEPROM_int_write(100, den); 
 readSet();
 oldden=den;
 }
   button_read();
  if (!button_enter) {
    delay(del); // 
    lcd.clear();
    menu();
  }
  if (!button_minus) {
    delay(del);
    lcd.clear();
    alarmDelay = millis();    // задержка аварии по нажатии кнопки Минус
  }
  if (!button_plus) {
    delay(del);
    lcd.clear();
    digitalWrite(turn_pin, !digitalRead(turn_pin));       // включаем/выключаем реле поворота по кнопке Плюс
  }

  lcd.setCursor(0, 0);
  if (millis() > serialTime)
  {
    PID();//расчитываем ПИД yul-i-an
    serialTime += 1200;
   
  }

    if (flag == 0)
  {
     lastMillis = millis();
    clockTime=!clockTime; 
    flag = 1;
  }

  if (millis() - lastMillis >=TimeTemp*1000) {
    flag = 0;
}
  if (clockTime == 1){
  lcd.setCursor(0, 0); // выводим часы и день инкубации
  if (chas < 10) lcd.print(" ");
  lcd.print(chas, DEC);
  lcd.print(":");
  if (minut < 10)lcd.print(0);
  lcd.print(minut, DEC);
  lcd.print(" ");
   lcd.write(7);
    lcd.print("EH");
   lcd.write(4);   
  lcd.print(" ");
  lcd.print(den, DEC);
  lcd.print("     ");
    lcd.setCursor(0, 1);
//    lcd.print("      ");
   lcd.print(temp2, 1);              // печать температуры на дисплей temp%10
   lcd.print((char)223);
   lcd.print(" ");
    printbird(bird);
  }
  else {
    lcd.setCursor(0, 0);                 // устанавливаем курсор в 0-ом столбце, 0 строка (начинается с 0)
    lcd.print("T1=");
    lcd.print(temp/10, 1);              // печать температуры на дисплей temp
    lcd.print(".");
    lcd.print(temp%10, 1);              // печать температуры на дисплей temp%10
    
    lcd.print((char)223);
    lcd.print(" (");
    lcd.print(needTemp, 1);
    lcd.print((char)223);
    lcd.print(")   ");
    lcd.setCursor(0, 1);                 
    lcd.print("H =");
    lcd.print(hum, 1);           // печать влажности на дисплей
    lcd.print("%");
    lcd.print(" (");
    lcd.print(needHum, 1);
    lcd.print("%) ");
  //  lcd.setCursor(15, 3);
  //  lcd.print("   ");

    }

  getSensors(); // получаем данные с датчиков
  humidifer(needHum);
  turn(needTurn);
  fan(ventTime);
  alarm(needTemp);
}


//регулятор ПИД
 void PID(){
   err=needTemp-temp1;
    if (hotFlag1 ==0) I=I+err;//если проветривание или авария не включаем
 
   zad=Kp*err+(Ki*I*0.25)+(Kd*(err-pre_err)/0.25);
   pre_err=err; 
   if (temp1>=39.5) //это при перегреве
   {
   zad=0;
    I=0;
   }
  if (zad<0){ zad=0;I=0;}
  if (zad>100){zad=100;}
 }
 //Внешнее прерывание детектора нуля
//управление симистором
void zero_crosss_int(){
  delayMicroseconds(1230);//для попадания в ноль
  reg = zad + er;
  if (reg < 50){
    out=0;
    er = reg ;
 
  }
  else {
    out=1;

    er=reg-100;
    }
 if (hotFlag1 ==0){
 digitalWrite(heater_pin,out); //если проветривание или авария не включаем
 }
 else {
 digitalWrite(heater_pin,LOW);
   
  }
 }
 
 //Авто настройка коэффициентов ПИД
void AutoPIDSet(){
  //тут будет автонастройка
}


void button_read() {//функция проверки нажатия кнопки
  button_minus = digitalRead(button_minus_pin); //запоминаем значение кнопки
  button_plus = digitalRead(button_plus_pin); //запоминаем значение кнопки
  button_enter = digitalRead(button_enter_pin); //запоминаем значение кнопки
  if (!button_minus || !button_plus || !button_enter) beeper(50);
  wdt_reset();
}


//меню
void menu() {
  startInk();
  time_setup_chas();
  time_setup_minut();
  bird_setup();  
  turn_setup();
  alarm_setup();
  vent_setup();
}

// записываем в память день начала инкубации 
void startInk() {
String str_menu= "START INK";
int perem_menu=den;
int adress_errom=100;
int perem_max=30;
String str_perem="Day";
den= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}
//устанавливаем часы
void time_setup_chas() {
String str_menu= "SETUP HOUR";
int perem_menu=chas;
int adress_errom=102;
int perem_max=23;
String str_perem="Hour";
chas= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}
//устанавливаем минуты
void time_setup_minut() {
String str_menu= "SETUP minute";
int perem_menu=minut;
int adress_errom=0;
int perem_max=59;
String str_perem="minute";
minut= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

//выбираем птицу /////////////////////////////////////////////////////////

void bird_setup() {
String str_menu= "SETUP bird";
int perem_menu=bird;
int adress_errom=110;
int perem_max=5;
String str_perem="bird";
bird= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}


//устанавливаем поворот
void turn_setup() {
int turnPeriod=EEPROM_int_read(104);                //период поворота лотков в часах
  
String str_menu= "TURN SETUP";
int perem_menu=turnPeriod;
int adress_errom=104;
int perem_max=12;
String str_perem="TURN Hour";
turnPeriod= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}


//устанавливаем сигнализацию
void alarm_setup() {
 int  alarmTemp=EEPROM_int_read(106);
String str_menu= "ALARM SETUP";
int perem_menu=alarmTemp;
int adress_errom=106;
int perem_max=10;
String str_perem="T.Alarm +- C";
alarmTemp= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

//устанавливаем вентиляцию
void vent_setup() {
int fanTemp=EEPROM_int_read(108);
String str_menu= "A.FAN SETUP";
int perem_menu=fanTemp;
int adress_errom=108;
int perem_max=40;
String str_perem="T.Fan C";
fanTemp= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

int setup_menu(String str_menu,int perem_menu,int adress_errom,int perem_max,String str_perem) {
  lcd.clear();
  delay(del);
  button_read();
  lcd.setCursor(0, 0);
  lcd.print(str_menu);
  lcd.print("         ");
  delay(1000);
  int x = 0;
  while (1) {
    x++;
    if (x > interval) break;
    button_read();
     if (adress_errom!=0) perem_menu=EEPROM_int_read(adress_errom); 
    if (!button_enter) {
      delay(del);
      lcd.clear(); //очищаем экран
      break;
    }
    if (!button_minus) {
      perem_menu--;
  if (perem_menu<0) perem_menu=perem_max;
      if (adress_errom!=0) EEPROM_int_write(adress_errom, perem_menu);
      lcd.clear();
      readSet();
    }

    if (!button_plus) {
      perem_menu++;
      if (perem_menu>perem_max) perem_menu=0;
      if (adress_errom!=0) EEPROM_int_write(adress_errom, perem_menu);
      lcd.clear();
      readSet();
    }
    if (adress_errom!=0) perem_menu= EEPROM_int_read(adress_errom);
    
    lcd.setCursor(0, 0);
    if (str_perem=="bird"){
    lcd.print("BIRD ");
    printbird(perem_menu);
 
    lcd.print("           ");
    
      }else{
    lcd.print(str_perem);
    lcd.print("= ");
    lcd.print(perem_menu);
    lcd.print("           ");
      }
    lcd.setCursor(0, 1);
    lcd.print("START NEXT +1");
    delay(del);
  }
 return perem_menu;
}

void printbird(int nbird){
    switch (nbird) {
      case 0:
        lcd.print("K");  // курица
        lcd.write(6);
        lcd.print("P");  // курица
        lcd.write(1);
        lcd.write(8);
        lcd.print("A    ");  // курица
        break;
      case 1:
        lcd.write(2);
        lcd.print("EPE");  // перепелка
        lcd.write(2);
        lcd.print("E");  // перепелка
        lcd.write(3);
        lcd.print("KA ");  // перепелка
        break;
      case 2:
        lcd.write(6);
        lcd.print("TKA      ");   // утка
        break;
      case 3:
        lcd.write(1);
        lcd.print("H");  // индоутка
        lcd.write(7);
        lcd.print("O");  // индоутка
        lcd.write(6);
        lcd.print("TKA  ");   // утка
        break;
      case 4:
         lcd.write(5);
         lcd.write(6);
         lcd.print("C");  // гусь
         lcd.write(4);
         lcd.print("      ");  // гусь
        break;
      case 5:
        lcd.write(1);
        lcd.print("H"); // индюк
        lcd.write(7);
        lcd.print("|OK    "); // индюк
        
        break;
    }

}


void getSensors() {
  unsigned long curMillis = millis();          // Получаем текущее время работы
  if (curMillis - trhMillis >= TRHSTEP) {    // время для нового измерения?
  temp= tempProcess(READ_TEMP);//читаем темпратуру с далласа 
  temp1=float(temp)/10;
  tempProcess(START_CONVERT); // сразу запрос на конвертацию
  }

  // Demonstrate non-blocking calls
  if (curMillis - trhMillis >= TRHSTEP * 4) {    // время для нового измерения?
    
//    hum = dht.readHumidity(); //получение темпрературы и влажности с DHT11
//    temp2 = dht.readTemperature();
    temp2=si7021.readTemp(); //получение темпрературы и влажности с si7021
    hum = si7021.readHumidity();
    
    trhMillis = curMillis;
  }

}

//управляем влажностью
void humidifer(float set_humidity) {
  //float humidity;
  unsigned long humMillis = 0;
  unsigned long curMillis = millis();
   if (set_humidity > hum) digitalWrite(humidifer_pin, HIGH); //сравниваем измеренную влажность с заданной
  else if (set_humidity -5 < hum) digitalWrite(humidifer_pin, LOW); //если влажность низкая, включаем увлажнитель

}

//управляем поворотом
void turn(boolean needTurn) {
  int turnPeriod=EEPROM_int_read(104);                //период поворота лотков в часах
  int turnCommand;
  if (turnPeriod == 0) return;           //если нулевой период поворота, то не поворачиваем яйца.
    turnCommand = turnPeriod;
  currentTime = millis();
  if (needTurn == true) {
    if (currentTime >= (loopTime + turnCommand * 3600000)) {  // 3600000 сравниваем текущий таймер с переменной loopTime + период поворота в часах.
 //     if (turnFlagUp){
       digitalWrite(turn_pin,LOW);
       delay(TimeTurn*100); //время поворота
       digitalWrite(turn_pin,HIGH);
      loopTime = currentTime;    // в loopTime записываем новое значение
    }
  }
}

//управляем авариями
void alarm(float needTemp) {
  int alarmTemp=EEPROM_int_read(106);
    if (temp1> (needTemp + alarmTemp) || temp1 < (needTemp - alarmTemp)) {
      beeper(10);
      digitalWrite(alarm_pin, LOW); //если измеренная температура выше заданной на величину аварии
    }
    else digitalWrite(alarm_pin, HIGH); //то включаем аварийный сигнал.

}

void beeper(int duration) {
  tone(beeper_pin, 2000, duration);
}


//управляем вентиляторами
void fan(int fanTime) {
   int fanTemp=EEPROM_int_read(108);
  if ((chas == 7 && minut < fanTime) || (chas == 19 && minut < fanTime) || (temp1 > fanTemp)) {
   // digitalWrite( fan_pin, LOW);
    fanFlag=1;
  
    //если наступило время проветривания или измеренная температура выше заданной на величину авариито включаем продувку.
//    digitalWrite(extend_heater_pin, HIGH);  // при этом отключаем обогрев
//    digitalWrite(heater_pin, LOW);
    hotFlag1 = 1;
 //   hotFlag2 = 1; 
  }
  else {
    fanFlag=0;
    hotFlag1 = 0;
  }
  
  //digitalWrite(fan_pin, HIGH); //иначе выключаем.
    
//    hotFlag1 = 1;
//    hotFlag2 = 1; 
//

}

// вольтметр
//void voltmeter() {
//  float outputValue = 0;
//  outputValue = float(analogRead(voltmeter_pin)) / 63, 9;
//  //if(outputValue < 4.5) beeper(50);
//  //Serial.print("Voltage = " );
//  //Serial.println(outputValue);
//  lcd.setCursor(14, 3);
//  lcd.print("V");
//  lcd.print(outputValue, 1);
//}
//
//// Печать мощности нагрвателя
//void outpuPower() {
//  lcd.setCursor(14, 3);
//  lcd.print("W");
//  lcd.print(Output, 0);
//  lcd.print(" ");
//}


//============================== 
int tempProcess(boolean ch){
  int t=0; 
  if(!ch){
    ds.reset(); 
    ds.write(0xCC);
    ds.write(0x44);
  }
  else{
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    t= ds.read(); 
    t = t | (ds.read()<<8); 
    //return  t>>4;//целые *C, десятые отброшены
    //return  (t+8)>>4;//целые *С с округлением
    return  (t*10)>>4;//целое в десятых *C (214=>21,4*C)
  }
}
// чтение
int EEPROM_int_read(int addr) {    
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}

// запись
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
//пример int
//// запись
//EEPROM_int_write(12, 1000); // адрес 12 (+2 байта)
//EEPROM_int_write(14, 2000); // адрес 14 (+2 байта)
//EEPROM_int_write(16, 3000); // адрес 16 (+2 байта)
//// чтение
//int d = EEPROM_int_read(12);
//int e = EEPROM_int_read(14);
//int f = EEPROM_int_read(16);

  

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean_74 меня интересует. Пока начинаю с нуля, но есть большое желание сделать такой девайс. Раньше делал инкубатор на плате W1209. Хочу автоматизировать. Поэтому для начала интересует список оборудования и схема соединений, буду очень признателен.

 

lean_74
Offline
Зарегистрирован: 22.12.2015

Оборудование : 1. Ардуино Нано(у ней надо перешить загрузчик на optiboot чтобы нормально работал wdt -"вачдог"). https://ru.aliexpress.com/item/Freeshipping-Nano-3-0-controller-compatible-for-arduino-nano-CH340-USB-driver-NO-CABLE/32242032996.html?spm=2114.13010608.0.0.dAXz9E

2. DS18b20- датчик температуры (вывод D7 Нано ) . https://ru.aliexpress.com/item/Free-shipping-DS18B20-Stainless-steel1-meters-waterproof-temperature-probe-temperature-sensor/1885949662.html?spm=2114.13010608.0.0.qYVKGw

3. si7021 - датчик температуры и влажностиподключенный по I2C: A4 (SDA) и A5 (SCL) .https://ru.aliexpress.com/item/J34-Free-Shipping-Industrial-High-Precision-Si7021-Humidity-Sensor-with-I2C-Interface/32581660471.html?

4. LCD16x2 подключенная по I2C: A4 (SDA) и A5 (SCL) .https://ru.aliexpress.com/item/15959-Free-Shipping-1602-2004-LCD-Adapter-Plate-IIC-I2C-Interface-i2c-lcd-adapter-for-arduino/32358255501.html?spm=2114.13010608.0.0.Wozd7H

https://ru.aliexpress.com/item/Free-Shipping-LCD1602-1602-module-Blue-screen-16x2-Character-LCD-Display-Module-HD44780-Controller-blue-blacklight/32357804531.html?spm=2114.13010608.0.0.Wozd7H

5. схема подключения двух подключенных паралельно 40-ватных лампочек в качестве нагревателей,  взята отсюда http://cxem.net/arduino/arduino71.php, 

6.увлажнитель.https://ru.aliexpress.com/item/New-Ultrasonic-Mist-Maker-Fogger-Water-Fountain-Pond-Atomizer-Air-Humidifier-free-shipping/32317739179.html?spm=2114.13010608.0.0.dAXz9E

7.переворот яиц https://ru.aliexpress.com/item/Quail-Incubator-16-eggs-64-birds-eggs-AutomaticTurn-eggs-tray-Hand-Incubator-Accessories-Laboratory-incubators/32436706594.html?spm=2114.13010608.0.0.Wozd7H

Схему соединений видна из скетча, я распаял пока на макетке, как все отлажу буду плату разводить, по отдельности все работало нормально, когда все в кучу соединил,  перестала работать схема с ПИД регулированием - сейчас с ней разбираюсь.

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean_74 спасибо за ответ. Начинаю заказывать оборудование, кое-что заказал ранее, правда еще не получил.

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean_74 есть вопрос. На сколько вольт двигатель в поворотных лотках, по ссылке не понятно.

lean_74
Offline
Зарегистрирован: 22.12.2015

у меня на 220в, но следующий раз я бы 12в заказал, на случай пропадания 220в в сети и переключения на резервное питание от 12в

MVN123P
Offline
Зарегистрирован: 29.07.2016

Если возможно, снимите небольшое видео экрана инкубатора (меню, настройки и.т.д).

lean_74
Offline
Зарегистрирован: 22.12.2015

MVN123P пишет:

Если возможно, снимите небольшое видео экрана инкубатора (меню, настройки и.т.д).

Снимал телефоном, так что качество так себе https://youtu.be/LEt51o0bDeY

MVN123P
Offline
Зарегистрирован: 29.07.2016

Спасибо.

lean_74
Offline
Зарегистрирован: 22.12.2015

Добавил автоподстройку вых мощности от yul-i-an

#include <avr/wdt.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
//#include "DHT.h"
#include <Si7021.h> //мой датчик влажности
#include <OneWire.h>
#include <Wire.h>
OneWire ds(7); 
#define START_CONVERT 0
#define READ_TEMP 1



//#define DHTPIN 11     // what digital pin we're connected to
//#define DHTTYPE DHT11   // DHT 11, DHT 22
//DHT dht(DHTPIN, DHTTYPE);
SI7021 si7021; //раскоментировать, если используем датчик si7021. 

LiquidCrystal_I2C lcd(0x27, 16, 2);  // инициализация библиотеки дисплея

//номера выводов кнопок
//#define EXT_HEATING                  // ИСПОЛЬЗУЕМ ДОП.НАГРЕВАТЕЛЬ ВМЕСТО УВЛАЖНИТЕЛЯ. Если нужен увлажнитель, просто закомментируйте эту строку.
#define heater_pin 6                  // нагреватель
#define humidifer_pin 12               // увлажнитель
#define fan_pin 13                     // вентилятор
#define alarm_pin 10                   // пин аварии
#define beeper_pin 14                   //пищалка по аварии

#define turn_pin 8                     // управление поворотом вперед
//#define pin9 9                    // проверка
//#define extend_heater_pin 8         // дополнительный нагреватель
#define button_minus_pin 3            //пин кнопки "минус"
#define button_plus_pin 4             //пин кнопки "плюс"
#define button_enter_pin 5           //пин кнопки "enter"
#define DS18B20_Pin 7                 //пин термометра
//Пин 2 Вход обработки прерывания для детектора нуля и управления семистором
#define voltmeter_pin 15               //вход А1 через делитель (22к/10к) подключен к питанию модуля. Измеряет до 16В.


boolean button_minus;                // статус нажатия кнопок
boolean button_plus;
boolean button_enter;

unsigned long currentTime;            // задаем переменные для тайминга поворота
unsigned long loopTime;
unsigned long serialTime; //this will help us know when to talk with processing

boolean hotFlag1 = 0;              // флаг включения обогревателя основного   1-ошибка, включать нельзя 
boolean fanFlag = 0;        // флаг включения вентилятора проветривания 1-включено проветривание
unsigned long trhMillis = 0;

boolean flag = 0;
int clockTime = 0; // флаг того что выводим температуру или влажность
unsigned long lastMillis = millis();
int TimeTemp = 4;  //время следующего измерения температуры в секундах
int TimeTurn = 20;  //время поворота в десятых долях секунды

const unsigned long TRHSTEP   = 300UL;  // Период опроса датчиков

//int counter=0;//для проверки вачдога

volatile uint8_t minut=0;
//volatile uint8_t chas=0;
int chas=0;
volatile uint8_t sec=0;
int den=0;
int oldden=0;
int oldchas=0;

int temp=0; // температура Далласа
float temp1=0; // температура Далласа с десятыми
float temp2=0; // температура DHT, si7021
float hum=0;

int del = 80;                     // переменная ожидания между выборами меню
unsigned int interval = 200;      // интервал сколько будет длиться цикл while, после чего перейдёт к следующему меню.(кол-во итераций)

boolean out=0;//управление симистором yul-i-an
int reg,er,zad;//    yul-i-an
double I,Kp=3,Ki=0.45,Kd=0.6,pre_err,err; //    yul-i-an

unsigned long alarmDelay;

float needTemp = 37.6;                  // нужная для текущего дня температура инкубации (по умолчанию)
float needHum = 60.5;                   // ---- влажность
int ventTime = 2;                       // длительность проветривания
boolean needTurn = false;               // нужен ли поворот яиц?
int bird=0;

// make some custom characters:
byte znak_g[8] = {//г
  0b11111,
  0b10001,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b00000
};
byte znak_b[8] = {//Б
  0b11111,
  0b10001,
  0b10000,
  0b11110,
  0b10001,
  0b10001,
  0b11110,
  0b00000
};

byte znak_p[8] = {
  0b11111,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b00000
};
byte znak_i[8] = {
  0b10001,
  0b10001,
  0b10011,
  0b10101,
  0b11001,
  0b10001,
  0b10001,
  0b00000
};

byte znak_l[8] = {
  0b00111,
  0b01001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b00000
};

byte light_znak[8] = {
  0b10000,
  0b10000,
  0b10000,
  0b11110,
  0b10001,
  0b10001,
  0b01110,
  0b00000
};

byte znak_u[8] = {
  0b10001,
  0b10001,
  0b10001,
  0b01111,
  0b00001,
  0b10001,
  0b01110,
  0b00000
};


byte znak_ia[8] = {
  0b01111,
  0b10001,
  0b10001,
  0b01111,
  0b00101,
  0b01001,
  0b10001,
  0b00000
};
byte znak_d[8] = {
  0b01110,
  0b01010,
  0b01010,
  0b01010,
  0b01010,
  0b11111,
  0b10001,
  0b00000
};
byte znak_ch[8] = {
  0b10001,
  0b10001,
  0b10001,
  0b01111,
  0b00001,
  0b00001,
  0b00001,
  0b00000
};
byte znak_c[8] = {
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b10010,
  0b11111,
  0b00001
};

//расчет мощности по ПИД закону регулирования
//_------------------------------------------------------------
#define kP 6//коэффициент пропорциональности 6
#define p_min 0.0//минимум П составляющей - не < 0
#define p_max 100.0//максимум П составляющей - не > 100 
#define kI 0.100//коэффициент интегрирования 0.025
#define i_min 0.0//минимум И составляющей
#define i_max 30.0//максимум И составляющей
#define kd 0//коэффициент диференциирования
#define d_ctl 7.0//зона пропорциональности ust-d_ctl
#define out_min 0//минимальный выходной %
#define out_max 100//максимальный выходной % 
//возвращает необходимую мощность
uint8_t PIctl(float temp, float ust) { 

  uint8_t out = 0; //uint8_t
  static float i = 0;
  static float ed=0;///
  float e, p;
  float d;///
  e = (ust - temp); //ошибка регулирования
  p=(temp<ust-d_ctl)?p_max:(temp>ust)?p_min:(kP*e);//П составляющая
  i=(i<i_min)?i_min:(i>i_max)?i_max:i+(kI*e);//И составляющая
  d=kd*(e-ed);//Д составляющая
  ed=e;///
  out=(p+i+d<out_min)?out_min:(p+i+d>out_max)?out_max:p+i+d;
  //вывод для настройки
     Serial.print(" e  ");
      Serial.print(e);
      Serial.print("  p ");
      Serial.print(p);
      Serial.print("  i ");
      Serial.print(i);
      Serial.print("  out ");
      Serial.println(out);
  return out;
}
//---------------------------------------------------------------



void readSet(){
 den=EEPROM_int_read(100);
 chas=EEPROM_int_read(102);
  int bird;                  // выбор птицы
  int r_array[6][4][5] = {
  {{2, 382, 600, 0, 1}, {12, 376, 600, 3, 1}, {15, 374, 480, 10, 1}, {18, 370, 855, 10, 0}},
  {{2, 378, 550, 0, 1}, {7, 378, 500, 3, 1}, {14, 378, 500, 10, 1}, {16, 375, 700, 0, 0}},
  {{7, 382, 700, 0, 1}, {14, 378, 600, 0, 1}, {25, 378, 600, 10, 1}, {28, 375, 855, 0, 0}},
  {{2, 380, 600, 0, 1}, {7, 378, 550, 0, 1}, {29, 375, 450, 10, 1}, {30, 370, 750, 0, 0}},
  {{7, 378, 700, 0, 1}, {14, 378, 600, 0, 1}, {27, 378, 600, 15, 1}, {30, 375, 855, 0, 0}},
  {{8, 377, 650, 0, 1}, {14, 377, 500, 0, 1}, {25, 375, 650, 10, 1}, {28, 375, 655, 10, 0}},
  }; 
//Serial.println("readset=");

bird=  EEPROM_int_read(110);
  for (int d=4; d>=0; d--){
  if(den <= r_array[bird][d][0]){
  needTemp = float(r_array[bird][d][1])/10;//
  needHum = float(r_array[bird][d][2])/10; //
  ventTime = r_array[bird][d][3];
  needTurn = r_array[bird][d][4];
  }
  }

  if (den>36 || den<0){
    den=0; // 
  } 
  if (chas>24){
    chas=0; // 
  } 
  if (minut>60){
    minut=0; // 
  } 
  
}
  
void setup(){
   wdt_disable(); // запретили как можно скорее собаку, что-бы не уйти в бесконечный ребут
   Serial.begin(9600);
//   readSet();
    lcd.begin();
    lcd.backlight();     // Включаем подсветку дисплея
    lcd.clear();
    
  // create a new character
//  lcd.createChar(5, znak_g);//г
  lcd.createChar(5, znak_b);//Б
  lcd.createChar(1, znak_i);//И
  lcd.createChar(2, znak_p);//П
  lcd.createChar(3, znak_l);//Л  
  lcd.createChar(4, light_znak);  // мягкий хнак
  lcd.createChar(7, znak_d);  //Д
  lcd.createChar(8, znak_c); //Ц 
  lcd.createChar(6, znak_u);//У
   
  lcd.setCursor(0, 0);

  lcd.print("   HAPO"); 
  lcd.write(7);
  lcd.print("H");
  lcd.write(4);
  lcd.print("|");
  lcd.write(1);
  lcd.setCursor(0, 1);
  lcd.print("   ");
  lcd.write(1);
  lcd.print("HK");
  lcd.write(6);
  lcd.write(5);
  lcd.print("ATOP");


  
  Wire.begin();        // старт I2C
 
//   dht.begin();
  si7021.begin(); // Runs : Wire.begin() + reset() // старт датчика влажности
  delay(3000);// подождем пока датчик запуститься, и завтавка погорит
  si7021.setHumidityRes(12); // Humidity = 12-bit / Temperature = 14-bit //максимальное разрешение
   

lcd.createChar(5, znak_g);//г
  readSet();  // читаем настройки из еепром 
  


// настройкa часов
TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание

  tempProcess(START_CONVERT);//конвентируем dallas

  attachInterrupt(0, zero_crosss_int, RISING);//внешнее прерывание на D2
 
  //pinMode(extend_heater_pin, OUTPUT);      //пин дополнительного нагревателя. Переводим в 1 чтобы не включать реле.
  //digitalWrite(extend_heater_pin, HIGH);
  pinMode(heater_pin, OUTPUT);
  pinMode(turn_pin, OUTPUT);      // устанавливаем выводы
//  pinMode(pin9, INPUT);      // устанавливаем выводы
  digitalWrite(turn_pin, HIGH);
  //digitalWrite(turn_pin2, HIGH);
  pinMode(humidifer_pin, OUTPUT);
  pinMode(fan_pin, OUTPUT);
  digitalWrite(fan_pin, HIGH);
  pinMode(alarm_pin, OUTPUT);
  digitalWrite(alarm_pin, HIGH);
  pinMode(button_minus_pin, INPUT_PULLUP); //подтягиваем входы кнопок к плюсу встроенными резисторами
  pinMode(button_plus_pin, INPUT_PULLUP);
  pinMode(button_enter_pin, INPUT_PULLUP);
  alarmDelay = millis();

  wdt_enable(WDTO_8S); // активировали таймер, каждые 8 секунд его нужно сбрасывать

}

ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду 
if (sec>59){sec=0; minut++;} 
if (minut>59){minut=0; chas++;} // при записи каждый час хватит памяти на 11 лет
if (chas>23){chas=0;den++;}//readSet(); но нам главное знать день инкубации
if (den>36){den=0; } // частный случай для нас не принципиальный, у нас день инкубации
}

void loop(){
 wdt_reset(); // говорим собаке что "В Багдаде все спокойно", начинается очередной отсчет 8-х секунд.
// Serial.print("pin9=");
// Serial.println(digitalRead(pin9));
// Serial.println("   ");

 if (oldchas!=chas){ // раз в час сохраняем время
 EEPROM_int_write(102, chas);
 oldchas=chas;
 }
 if (oldden!=den){ // раз в день читаем настройки заново
 EEPROM_int_write(100, den); 
 readSet();
 oldden=den;
 }
   button_read();
  if (!button_enter) {
    delay(del); // 
    lcd.clear();
    menu();
  }
  if (!button_minus) {
    delay(del);
    lcd.clear();
    alarmDelay = millis();    // задержка аварии по нажатии кнопки Минус
  }
  if (!button_plus) {
    delay(del);
    lcd.clear();
    digitalWrite(turn_pin, !digitalRead(turn_pin));       // включаем/выключаем реле поворота по кнопке Плюс
  }

  lcd.setCursor(0, 0);
  if (millis() > serialTime)
  {
    PID();//расчитываем ПИД yul-i-an
    serialTime += 1200;
 // err=needTemp-temp1 
 Serial.print("needTemp=");
 Serial.println(needTemp);
 Serial.print("temp1=");
 Serial.println(temp1);
 Serial.print("err=");
 Serial.println(err);
 Serial.print("zad=");
 Serial.println(zad);
// Serial.print("serialTime=");
// Serial.println(serialTime);
// Serial.print("hotFlag1=");
// Serial.println(hotFlag1);
  }

    if (flag == 0)
  {
     lastMillis = millis();
    clockTime=!clockTime; 
    flag = 1;
  }

  if (millis() - lastMillis >=TimeTemp*1000) {
    flag = 0;
}
  if (clockTime == 1){
  lcd.setCursor(0, 0); // выводим часы и день инкубации
  if (chas < 10) lcd.print(" ");
  lcd.print(chas, DEC);
  lcd.print(":");
  if (minut < 10)lcd.print(0);
  lcd.print(minut, DEC);
  lcd.print(" ");
   lcd.write(7);
    lcd.print("EH");
   lcd.write(4);   
  lcd.print(" ");
  lcd.print(den, DEC);
  lcd.print("     ");
    lcd.setCursor(0, 1);
//    lcd.print("      ");
   lcd.print(temp2, 1);              // печать температуры на дисплей temp%10
   lcd.print((char)223);
   lcd.print(" ");
    printbird(bird);
  }
  else {
    lcd.setCursor(0, 0);                 // устанавливаем курсор в 0-ом столбце, 0 строка (начинается с 0)
    lcd.print("T1=");
    lcd.print(temp/10, 1);              // печать температуры на дисплей temp
    lcd.print(".");
    lcd.print(temp%10, 1);              // печать температуры на дисплей temp%10
    
    lcd.print((char)223);
    lcd.print(" (");
    lcd.print(needTemp, 1);
    lcd.print((char)223);
    lcd.print(")   ");
    lcd.setCursor(0, 1);                 
    lcd.print("H =");
    lcd.print(hum, 1);           // печать влажности на дисплей
    lcd.print("%");
    lcd.print(" (");
    lcd.print(needHum, 1);
    lcd.print("%) ");
  //  lcd.setCursor(15, 3);
  //  lcd.print("   ");

    }

  getSensors(); // получаем данные с датчиков
  humidifer(needHum);
  turn(needTurn);
  fan(ventTime);
  alarm(needTemp);
}


//регулятор ПИД
 void PID(){
   err=needTemp-temp1;
    if (hotFlag1 ==0) I=I+err;//если проветривание или авария не включаем
 
//   zad=Kp*err+(Ki*I*0.25)+(Kd*(err-pre_err)/0.25);
   zad = PIctl(temp1, needTemp); //расчет мощности
   pre_err=err; 
   if (temp1>=39.5) //это при перегреве
   {
   zad=0;
    I=0;
   }
  if (zad<0){ zad=0;I=0;}
  if (zad>100){zad=100;}
//   Serial.print("reg=");
//   Serial.println(reg);

 }
 //Внешнее прерывание детектора нуля
 void zero_crosss_int()
{
      ResOut();//Вызов функции управления симистором по алгоритму Брезенхема
}

//управление симистором
void ResOut(){
  delayMicroseconds(1230);//для попадания в ноль
  reg = zad + er;
  if (reg < 50){
    out=0;
    er = reg ;
 
  }
  else {
    out=1;

    er=reg-100;
    }
 if (hotFlag1 ==0){
 digitalWrite(heater_pin,out); //если проветривание или авария не включаем
 }
 else {
 digitalWrite(heater_pin,LOW);
   
  }
 }
 
 //Авто настройка коэффициентов ПИД
void AutoPIDSet(){
  //тут будет автонастройка
}


void button_read() {//функция проверки нажатия кнопки
  button_minus = digitalRead(button_minus_pin); //запоминаем значение кнопки
  button_plus = digitalRead(button_plus_pin); //запоминаем значение кнопки
  button_enter = digitalRead(button_enter_pin); //запоминаем значение кнопки
  if (!button_minus || !button_plus || !button_enter) beeper(50);
  wdt_reset();
}


//меню
void menu() {
  startInk();
  time_setup_chas();
  time_setup_minut();
  bird_setup();  
  turn_setup();
  alarm_setup();
  vent_setup();
}

// записываем в память день начала инкубации 
void startInk() {
String str_menu= "START INK";
int perem_menu=den;
int adress_errom=100;
int perem_max=36;
String str_perem="Day";
den= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}
//устанавливаем часы
void time_setup_chas() {
String str_menu= "SETUP HOUR";
int perem_menu=chas;
int adress_errom=102;
int perem_max=23;
String str_perem="Hour";
chas= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}
//устанавливаем минуты
void time_setup_minut() {
String str_menu= "SETUP minute";
int perem_menu=minut;
int adress_errom=0;
int perem_max=59;
String str_perem="minute";
minut= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

//выбираем птицу /////////////////////////////////////////////////////////

void bird_setup() {
String str_menu= "SETUP bird";
int perem_menu=bird;
int adress_errom=110;
int perem_max=5;
String str_perem="bird";
bird= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}


//устанавливаем поворот
void turn_setup() {
int turnPeriod=EEPROM_int_read(104);                //период поворота лотков в часах
  
String str_menu= "TURN SETUP";
int perem_menu=turnPeriod;
int adress_errom=104;
int perem_max=12;
String str_perem="TURN Hour";
turnPeriod= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}


//устанавливаем сигнализацию
void alarm_setup() {
 int  alarmTemp=EEPROM_int_read(106);
String str_menu= "ALARM SETUP";
int perem_menu=alarmTemp;
int adress_errom=106;
int perem_max=10;
String str_perem="T.Alarm +- C";
alarmTemp= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

//устанавливаем вентиляцию
void vent_setup() {
int fanTemp=EEPROM_int_read(108);
String str_menu= "A.FAN SETUP";
int perem_menu=fanTemp;
int adress_errom=108;
int perem_max=40;
String str_perem="T.Fan C";
fanTemp= setup_menu(str_menu,perem_menu,adress_errom,perem_max,str_perem);
}

int setup_menu(String str_menu,int perem_menu,int adress_errom,int perem_max,String str_perem) {
  lcd.clear();
  delay(del);
  button_read();
  lcd.setCursor(0, 0);
  lcd.print(str_menu);
  lcd.print("         ");
  delay(1000);
  int x = 0;
  while (1) {
    x++;
    if (x > interval) break;
    button_read();
     if (adress_errom!=0) perem_menu=EEPROM_int_read(adress_errom); 
    if (!button_enter) {
      delay(del);
      lcd.clear(); //очищаем экран
      break;
    }
    if (!button_minus) {
      perem_menu--;
  if (perem_menu<0) perem_menu=perem_max;
      if (adress_errom!=0) EEPROM_int_write(adress_errom, perem_menu);
      lcd.clear();
      readSet();
    }

    if (!button_plus) {
      perem_menu++;
      if (perem_menu>perem_max) perem_menu=0;
      if (adress_errom!=0) EEPROM_int_write(adress_errom, perem_menu);
      lcd.clear();
      readSet();
    }
    if (adress_errom!=0) perem_menu= EEPROM_int_read(adress_errom);
    
    lcd.setCursor(0, 0);
    if (str_perem=="bird"){
    lcd.print("BIRD ");
    printbird(perem_menu);
 
    lcd.print("           ");
    
      }else{
    lcd.print(str_perem);
    lcd.print("= ");
    lcd.print(perem_menu);
    lcd.print("           ");
      }
    lcd.setCursor(0, 1);
    lcd.print("START NEXT +1");
    delay(del);
  }
 return perem_menu;
}

void printbird(int nbird){
    switch (nbird) {
      case 0:
        lcd.print("K");  // курица
        lcd.write(6);
        lcd.print("P");  // курица
        lcd.write(1);
        lcd.write(8);
        lcd.print("A    ");  // курица
        break;
      case 1:
        lcd.write(2);
        lcd.print("EPE");  // перепелка
        lcd.write(2);
        lcd.print("E");  // перепелка
        lcd.write(3);
        lcd.print("KA ");  // перепелка
        break;
      case 2:
        lcd.write(6);
        lcd.print("TKA      ");   // утка
        break;
      case 3:
        lcd.write(1);
        lcd.print("H");  // индоутка
        lcd.write(7);
        lcd.print("O");  // индоутка
        lcd.write(6);
        lcd.print("TKA  ");   // утка
        break;
      case 4:
         lcd.write(5);
         lcd.write(6);
         lcd.print("C");  // гусь
         lcd.write(4);
         lcd.print("      ");  // гусь
        break;
      case 5:
        lcd.write(1);
        lcd.print("H"); // индюк
        lcd.write(7);
        lcd.print("|OK    "); // индюк
        
        break;
    }

}


void getSensors() {
  unsigned long curMillis = millis();          // Получаем текущее время работы
  if (curMillis - trhMillis >= TRHSTEP) {    // время для нового измерения?
  temp= tempProcess(READ_TEMP);//читаем темпратуру с далласа 
  temp1=float(temp)/10;
  tempProcess(START_CONVERT); // сразу запрос на конвертацию
  }

  // Demonstrate non-blocking calls
  if (curMillis - trhMillis >= TRHSTEP * 4) {    // время для нового измерения?
    
//    hum = dht.readHumidity(); //получение темпрературы и влажности с DHT11
//    temp2 = dht.readTemperature();
    temp2=si7021.readTemp(); //получение темпрературы и влажности с si7021
    hum = si7021.readHumidity();
    
    trhMillis = curMillis;
  }

}

//управляем влажностью
void humidifer(float set_humidity) {
  //float humidity;
  unsigned long humMillis = 0;
  unsigned long curMillis = millis();
   if (set_humidity > hum) digitalWrite(humidifer_pin, HIGH); //сравниваем измеренную влажность с заданной
  else if (set_humidity -5 < hum) digitalWrite(humidifer_pin, LOW); //если влажность низкая, включаем увлажнитель

}

//управляем поворотом
void turn(boolean needTurn) {
  int turnPeriod=EEPROM_int_read(104);                //период поворота лотков в часах
  int turnCommand;
  if (turnPeriod == 0) return;           //если нулевой период поворота, то не поворачиваем яйца.
    turnCommand = turnPeriod;
  currentTime = millis();
  if (needTurn == true) {
    if (currentTime >= (loopTime + turnCommand * 3600000)) {  // 3600000 сравниваем текущий таймер с переменной loopTime + период поворота в часах.
 //     if (turnFlagUp){
       digitalWrite(turn_pin,LOW);
       delay(TimeTurn*100); //время поворота
       digitalWrite(turn_pin,HIGH);
      loopTime = currentTime;    // в loopTime записываем новое значение
    }
  }
}

//управляем авариями
void alarm(float needTemp) {
  int alarmTemp=EEPROM_int_read(106);
    if (temp1> (needTemp + alarmTemp) || temp1 < (needTemp - alarmTemp)) {
      beeper(10);
      digitalWrite(alarm_pin, LOW); //если измеренная температура выше заданной на величину аварии
    }
    else digitalWrite(alarm_pin, HIGH); //то включаем аварийный сигнал.

}

void beeper(int duration) {
  tone(beeper_pin, 2000, duration);
}


//управляем вентиляторами
void fan(int fanTime) {
   int fanTemp=EEPROM_int_read(108);
  if ((chas == 7 && minut < fanTime) || (chas == 19 && minut < fanTime) || (temp1 > 39.5)) { //fanTemp=395
   // digitalWrite( fan_pin, LOW);
    fanFlag=1;
  
    //если наступило время проветривания или измеренная температура выше заданной на величину авариито включаем продувку.
//    digitalWrite(extend_heater_pin, HIGH);  // при этом отключаем обогрев
//    digitalWrite(heater_pin, LOW);
    hotFlag1 = 1;
 //   hotFlag2 = 1; 
  }
  else {
    fanFlag=0;
    hotFlag1 = 0;
  }
  
  //digitalWrite(fan_pin, HIGH); //иначе выключаем.
    
//    hotFlag1 = 1;
//    hotFlag2 = 1; 
//

}

// вольтметр
//void voltmeter() {
//  float outputValue = 0;
//  outputValue = float(analogRead(voltmeter_pin)) / 63, 9;
//  //if(outputValue < 4.5) beeper(50);
//  //Serial.print("Voltage = " );
//  //Serial.println(outputValue);
//  lcd.setCursor(14, 3);
//  lcd.print("V");
//  lcd.print(outputValue, 1);
//}
//
//// Печать мощности нагрвателя
//void outpuPower() {
//  lcd.setCursor(14, 3);
//  lcd.print("W");
//  lcd.print(Output, 0);
//  lcd.print(" ");
//}


//============================== 
int tempProcess(boolean ch){
  int t=0; 
  if(!ch){
    ds.reset(); 
    ds.write(0xCC);
    ds.write(0x44);
  }
  else{
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    t= ds.read(); 
    t = t | (ds.read()<<8); 
    //return  t>>4;//целые *C, десятые отброшены
    //return  (t+8)>>4;//целые *С с округлением
    return  (t*10)>>4;//целое в десятых *C (214=>21,4*C)
  }
}
// чтение
int EEPROM_int_read(int addr) {    
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}

// запись
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
//пример int
//// запись
//EEPROM_int_write(12, 1000); // адрес 12 (+2 байта)
//EEPROM_int_write(14, 2000); // адрес 14 (+2 байта)
//EEPROM_int_write(16, 3000); // адрес 16 (+2 байта)
//// чтение
//int d = EEPROM_int_read(12);
//int e = EEPROM_int_read(14);
//int f = EEPROM_int_read(16);

 

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

Lean_74

Какие семисторы использовали в ПИД. Не могу найти TIC206.

Часы такие?

https://www.aliexpress.com/item-img/Free-Shipping-1PCS-DS3231-AT24C32-II...

lean_74
Offline
Зарегистрирован: 22.12.2015

BigVal пишет:

Lean_74

Какие семисторы использовали в ПИД. Не могу найти TIC206.

Часы такие?

https://www.aliexpress.com/item-img/Free-Shipping-1PCS-DS3231-AT24C32-II...

Тиристор у меня BT138-800E(хотя можно любой из серии ВТ с напряжением пробоя более 300В и ток от 0.5 ампера, я просто попросил в магазине самые дешевые) он там кстати без радиатора и вообше не греется.

Аппаратных часов нет, они программные на таймере 1 у dimax-a позаимствовал.

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean_74  пока едет из поднебесной заказанное "железо" а я усиленно штудирую (как у Ардуино Нано надо перешить загрузчик на optiboot чтобы нормально работал wdt -"вачдог"), возникло несколько вопросов. Если в электронике я еще более менее разбираюсь, то в програмировании я "чайник", поэтому простите если, что не так спрошу.

1) Вы писали в последнем посте  "Аппаратных часов нет, они программные на таймере 1 у dimax-a позаимствовал". По возможности дайте ссылку. А то я по форуму полазил но ни чего не нашел. Только то, что  dimax писал про реализацию часов на LCD.

2) По схеме  http://cxem.net/arduino/arduino71.php,  ( По подключению: вход сигнала демирования это с 6 пина МК, это понятно, а выход детектора нуля куда подключается не вижу, в скетче 036 строка закоментирована

//Пин 2 Вход обработки прерывания для детектора нуля и управления семистором

3) По пинам:

а) Что подключаете на пин аварии.

б) Вентилятор который сидит на пин 13, он продувочный или он же и тепло гоняет 

На сегодня хватит, заранее благодарен.

 

lean_74
Offline
Зарегистрирован: 22.12.2015

1.http://arduino.ru/forum/proekty/net-sosed-ili-domofon-avtomat#comment-136153

2.ответ в вопросе //Пин 2  http://arduino.ru/Reference/AttachInterrupt

3. Пока ничего не подключал, это осталось от Um-ka, но надо полагать а) светодиод, б) "продувочный"

те что постоянно воздух гоняют у меня напрямую к 12В

MVN123P
Offline
Зарегистрирован: 29.07.2016

lean_74 Скажите пожайлуста, как эти часы будут работать после отключения и включения питания?

lean_74
Offline
Зарегистрирован: 22.12.2015

Нарисовал плату, правда это всего лишь 3-я моя плата в Sprint-Layout, посему сильно просьба не пинать.

https://yadi.sk/d/nCYIDGV73E2aRv

lean_74
Offline
Зарегистрирован: 22.12.2015

MVN123P пишет:

lean_74 Скажите пожайлуста, как эти часы будут работать после отключения и включения питания?

В памяти сохраняется день и час инкубации, я думаю без присмотра все равно инкубатор не оставите, если время не соответствует действительному, то значит были какие-то сбои в работе, главное нам надо знать день инкубации, он в памяти сохраняется.

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

Плата очень даже нормальная. Марка реле под которые разводил? 

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

Пару вопросов по плате.

1) Что за микросхема на 16 ножек

2) Посмотри по плате 7805 по моему наоборот должен стоять

3) 2 -й семистор под нагреватель увлажнителя

lean_74
Offline
Зарегистрирован: 22.12.2015

https://kealan.ru/catalog/124/913/

1.ULN2003 - появилось попутно желание сменить моторчик на перевороте яиц на лежащий без дела шаговик 28BYJ-48

2. Да я его по мере разводки развернул, 

3.Ну это может и дополнительный нагреватель быть, так с запасом сделал, чтобы все ноги атмеги использовать. у нас в Челябинске можно быстро и недорого заказать платы, чем самому травить www.pcb74.ru . 

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean _74 по поводу платы могу войти в долю, правда мне за доставку придется заплатить но бог с ним

lean_74
Offline
Зарегистрирован: 22.12.2015

BigVal пишет:
lean _74 по поводу платы могу войти в долю, правда мне за доставку придется заплатить но бог с ним

Я четыре штуки уже заказал, могу одной поделиться, как будет готова. пиши на почту МойНик@mail.ru

MVN123P
Offline
Зарегистрирован: 29.07.2016

Решил собрать этот блок управления инкубатором по блочной схеме (в наличии есть все элементы) в корпусе от старого модема. Управление нагревателями - твердотельные реле OMRON (два квадратика рядом с ардуинкой). Остальное управление через блок на 4 реле. Питание ардуинки через DC-DC преобразователь на LM2596S. На данный момент - крепеж и слесарка.

lean_74
Offline
Зарегистрирован: 22.12.2015

[quote=MVN123P]

Решил собрать этот блок управления инкубатором по блочной схеме (в наличии есть все элементы) в корпусе от старого модема. Управление нагревателями - твердотельные реле OMRON (два квадратика рядом с ардуинкой). Остальное управление через блок на 4 реле. Питание ардуинки через DC-DC преобразователь на LM2596S. На данный момент - крепеж и слесарка.

 

/quote]

Детектор нуля все равно нужен, его пока не вижу, а так зачетно!

BigVal
BigVal аватар
Offline
Зарегистрирован: 10.01.2017

lean_74 посмотрел в нете видео по шаговику 28BYJ-48. Внутренности у него пластиковые. Я так понимаю двигатель будет стоять внутри инкубатора, хоть 38 градусов небольшая температура, не будет ли этот пластик пересыхать. Интересно есть у кого-либо опыт эксплуатации в тааких условиях данного девайса.

Rihos
Offline
Зарегистрирован: 16.02.2017

lean_74 очень интерестная тема .Тут PID плавная регулировка (диммирование)?. Дело в том что у меня на инкубаторе ПИД мигает. Это влияет на освещение в соседней комнате.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Знакомый почерк :)

Вижу в хорошие руки мои труды попали. 

Ну вот вам тогда плата и большая часть наработок и ветвлений. https://drive.google.com/open?id=0B0vRuSZ7oRUeR2tyeG9pSHZ4R2M

Там энкодер есть, остановка ПИД при открытии дверцы, разные датчики, мостик для передачи метрик через ESP8266 в облака. Кстати, DHT11 крайне не советую. Дрянь влагомер.

Вот вам диммер самостоятельный http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie , я так понимаю что от библиотек ушли чтобы диммировалось ровнее? С этим таких проблем не будет.

Пин аварии ой как нужен. Реле на него нормальнозамкнутое, симисторы иногда пробиваются, особенно с лампами накаливания, и тогда вся мощность жарит яйца. А реле аварии клац - и спасены! Вот знакомый недавно 2 короба (по 360) яиц бройлера выкинул, на 20-й день инкубации твердотельное квакнуло. Ну и (или) вентилятор принудительной продувки.

Симисторы BT и BTB имеют "фазу" на радиаторе, а BTA изолированные. Цена почти одинаковая.

Моторы шаговые лучше с драйверами Step/Dir использовать, там 1 дорожку надо перерезать в моторчике. Тогда 2 пина потребуется вместо 4 и под все драйверы подходит. 

А чего часы то не использовал? МК не точно миллисекунды считает и забывает при выключении.

Ну и хочется посмотреть на результат всей работы. Пока неплохо, но надо все в бою проверять обязательно. Успехов!

ЗЫ: забавная разводка...

lean_74
Offline
Зарегистрирован: 22.12.2015

Umka пишет:

Вижу в хорошие руки мои труды попали. 

Спасибо за поддержку! 

Umka пишет:

Ну вот вам тогда плата и большая часть наработок и ветвлений. https://drive.google.com/open?id=0B0vRuSZ7oRUeR2tyeG9pSHZ4R2M

Тут без пузыря не разобраться, файлик бы с пояснением, где, что и для чего. 

Umka пишет:

Пин аварии ой как нужен. Реле на него нормальнозамкнутое, симисторы иногда пробиваются, особенно с лампами накаливания, и тогда вся мощность жарит яйца. А реле аварии клац - и спасены! Вот знакомый недавно 2 короба (по 360) яиц бройлера выкинул, на 20-й день инкубации твердотельное квакнуло. Ну и (или) вентилятор принудительной продувки.

Симисторы BT и BTB имеют "фазу" на радиаторе, а BTA изолированные. Цена почти одинаковая.

У меня тиристор вообще не греется, надо полагать потому, что переключения происходят при переходе через ноль, и мощьности на нем не рассеивается, почему тогда он может выйти из строя? Понятно, когда ШИМом регулируется и часть мощности рассеивается на самом тиристоре. 

Umka пишет:

Моторы шаговые лучше с драйверами Step/Dir использовать, там 1 дорожку надо перерезать в моторчике. Тогда 2 пина потребуется вместо 4 и под все драйверы подходит. 

ну это пока для меня темный лес, попробовал покрутить шаговиком -получилось, усилие для переворота лотков у него вполне приличное и концевики ставить не надо.

Umka пишет:

А чего часы то не использовал? МК не точно миллисекунды считает и забывает при выключении.

Все же хотелось сделать попроще и легче для повторения. в первой версии часы были, но 150 перепелиных яиц на 15 день все равно выкинул, просто все зависло и поджарило до 52 градусов, а днем на работе, сколько там часов ини жарились ХЗ. С растройства даже отложил на время свои эксперименты, и решил подготовиться более основательно.

Umka пишет:

Ну и хочется посмотреть на результат всей работы. Пока неплохо, но надо все в бою проверять обязательно. Успехов!

Еще раз Спасибо! Результаты будем выкладывать.

Umka пишет:

ЗЫ: забавная разводка...

 

:)) ну не волшебник я - только учусь.

Rihos
Offline
Зарегистрирован: 16.02.2017

А Детектор нуля в заводском исполнение есть у ардуины как модуль?

lean_74
Offline
Зарегистрирован: 22.12.2015

Rihos пишет:
А Детектор нуля в заводском исполнение есть у ардуины как модуль?

вон  же у Umka есть готовые http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie#comment-243118

Rihos
Offline
Зарегистрирован: 16.02.2017

Я с Али заказывал Ардуино думал есть готовый модуль на него чтобы вместе заказать.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

lean_74,

1. все файлы и папки подписаны. Плату точно найдешь. Мы их, кстати, заводские, по 5 баксов продаем.

2. Симистор. Не греется потому что мощность нагревателя маленькая. Да и не должен он греться, это же ключ. Ноль тут не виноват, это от помех делается.

3. Нормальные шаговики драйверами управляются. Драйверы делают нужный ток, удержание микрошаг... а драйверы рулятся двумя сигналами. Шаг и направление. Стоят не дорого и можно любой Nema17 из старого принтера зацепить. Только вот этот редукторный мотор придется вскрывать, там общая точка у обмоток, ее отрезать надо.

4. Проще с часами. Ни пинов дополнительных не надо, ни коррекции. А так свет мигнул и сбились дни. 

5. Я 7 лет в птицеводстве и инкубации и начинал с перепелок тоже. Они и сейчас есть. Всяко бывало. Ты если что спрашивай. Брудер есть? Вот мой видосик по теме и там на канале еще много по железкам https://www.youtube.com/watch?v=W4xM8h5iBI8

Rihos, если сильно надо, то вот такие платы по 2 бакса есть https://www.youtube.com/watch?v=wXA2jGXWzno

только там надо оптрон паять снизу или лапы выворачивать. Перепутал. Готовый автономный диммер. Новые платы заказаны на завод и будут в виде готовых блоков продаваться.

Вообще не совсем понятно зачем тут детектор ноля, если он не диммирует? В бОльшей части оптосимисторов, например MOC3061 есть встроенный детектор ноля. В твердотельных реле тоже. А диммер не тянет контроллер с таким скетчем, мигают лампы из-за запрета прерываний. Автономный диммер хорошее решение.

 

Rihos
Offline
Зарегистрирован: 16.02.2017

Роман я слежку за вашими разработками здорово...
У меня инкубатор из витринного холодильника. Яйца ложу ступенчато первый выводок был удачным. Второй сварил под утро был 52°. Дело в том терморегулятор был заказан ПИД Rex-c100 потом выяснелось что отправили релейный. Из-за частого срабатовании реле залипло температура поднелась до критической. Потом выпаял электромагнитное реле поставил перемычки и подключил SSR. Но плавного накала ламп там я не смог добиться. В этом году хотел заказать регулятор влажности. Передумал заказал УНО (чтобы инкубатор стал смартом) дисплей 16/2 датчики. Вот думаю может и перевотот нагрев, влажность смогу перевести на ардуино. Если добьюсь плавного накала ламп было бы здорово!

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

У меня тоже есть инкубаторы из витрины. Неплохо выводят. Реле залипло, бывает. А вото тут в комментариях товарищи до усёру спорят что реле это нормально https://www.youtube.com/watch?v=zcLj_6EfYgY 

Вот расскажите им! Я не смог переубедить барыг от птицеводства.

Что значит поворот нагрев и влажность перевести на Ардуино? Все же готово уже. И плавный накал тоже. Я же дал уже все. ПИД считает свою математику и на выходе выплевывает некий коэффициент мощности, которую надо подать в нагреватель. Ну мы этот коэффициент мапим в байт и отсылаем по wire в диммер. И всё. И будет очень плавно. Только... а зачем в витрине лампами греть? Есть же ТЭНы воздушные и керамика. Ладно в пенопластовой коробочке...

Rihos
Offline
Зарегистрирован: 16.02.2017

Umka пишет:

Что значит поворот нагрев и влажность перевести на Ардуино? Все же готово уже. И плавный накал тоже. Я же дал уже все.


Спасибо. Я так понимаю теперь мне нужен ваш автономный диммер либо делитель нуля для того чтобы залить скейтч с этой темы И регулировать плавненько? И ещё у меня стоит мотор от стеклоподьемника. Я пологаю нужно корректировать код чтобы он менял полярность и приходил в горизонтальное положение по кнопке чтобы заложить яйца!?

Umka пишет:

Только... а зачем в витрине лампами греть? Есть же ТЭНы воздушные и керамика. Ладно в пенопластовой коробочке...


Я ставил углеродный кабель 15 метров а лампы на разогрев. Но кабель не справляется весной. Наверное не правильно рассчитал. Сейчас работают вместе.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Вот про скетч из этой темы лучше у его автора спрашивать. Я вижу тут многое из моего инкубатора и многое сделано иначе. Думаете мне охота досконально в нем разбираться и понимать все замыслы его создателя? Я только даю варианты своих наработок, а как и где их использовать сами смотрите. Если Вы не сможете самостоятельно прикрутить диммер к ПИД, то либо вы покупатель, либо просите кого-то это сделать. Объясните, какой смысл греть витрину углеродным кабелем да еще и с ПИД-регулятором? 

MVN123P
Offline
Зарегистрирован: 29.07.2016

lean_74 

Собрал схему - но не пойму как должен работать вентилятор?

lean_74
Offline
Зарегистрирован: 22.12.2015

MVN123P пишет:

lean_74 

Собрал схему - но не пойму как должен работать вентилятор?

Вентилятор пока не тестировал, но по задумке он работает во время плановых проветриваний два раза в день, когла они есть и во время аварии, т.е превышении максимально установленной температуры.

 

lean_74
Offline
Зарегистрирован: 22.12.2015

Rihos пишет:
Я ставил углеродный кабель 15 метров а лампы на разогрев. Но кабель не справляется весной. Наверное не правильно рассчитал. Сейчас работают вместе.

Пид нужен, когда нагреватель инерционный, тены, лампочки т.п., когда эл.энергию отключили, а они продолжают греть,  углеродный кабель практически безинерционный, т.е ему достаточно простого терморегулятора.

По скетчу:  он подмигивает,но не сильно и то, я думаю, потому, что накладываются друг на друга аппаратные прерывания и прерывания по таймеру, я в этом пока не сильно разбираюсь, но думаю со времением эту проблему решу, если производительности микроконтроллера хватит. 

По перевороту с помощью мотора для стеклоподъемника, надо корректировать не только код, но схему подключения, она кстати там у Umka  по его ссылке тоже есть, на двух реле сделана и ручкой соединения дорисованы.

Rihos
Offline
Зарегистрирован: 16.02.2017

lean_74
Спасибо за информацию. Тогда не буду на этом сильно заморачиваться.
По поводу схемы мне едут мосфеты.

lean_74
Offline
Зарегистрирован: 22.12.2015

Rihos пишет:
lean_74 Спасибо за информацию. Тогда не буду на этом сильно заморачиваться. По поводу схемы мне едут мосфеты.

Если на мосфетах то придется что-то типа этого городить: https://yadi.sk/i/gKCXBpA03EEM2N

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Насчет инерции. Не только нагреватель надо учитвыать, надо всю систему брать. https://www.youtube.com/watch?v=leY_ptjJLcE

Насчет поворота двигателя постоянного тока. Код корректировать не надо. 2 НЗ концевика надо и сам мотор. http://u-m.biz/shop/index.php?route=product/product&path=62&product_id=62

Насчет МОСФЕТов http://u-m.biz/shop/index.php?route=product/product&path=62&product_id=60

Схемы не рисовал, в интернетах найдете если что. Там же и автоматическая переключалска на 220/12 есть.

 

 

lean_74
Offline
Зарегистрирован: 22.12.2015

Запуталли меня тут с миганием - не миганием лампочек, так при таком способе регулирования обязательно должно мигать, т.к. мощность мы регулируем не отрезанием части полуволны, а всей полуволны, т.е за секунду у нас 100 полуволн, нужно пропустить 50 процентов мощности - пропускаем 50 полуволн, это все равно что диод последовательно с лампочкой включить, уже заметно что мигает, если только 1% то 1 полуволну в секунду - раз в секунду и будет мигать. вот тут популярно написано: https://habrahabr.ru/post/254719/

и действтвительно схему можно еще более упростить, а управление сделать прерываниями по таймеру.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Сам же и запутал своим детектором, человек теперь ищет у китайцев "делитель на ноль" чтобы плавно светило. А я говорю - вот он готовый плавный самостоятельный диммер. В него надо писать по шине I2C нужный уровень, а можно и читать. Ну или при помощи ШИМ обычного и ничего не мигает. Но меня не слушают. Хотя каждый же сам как хочет...

lean_74
Offline
Зарегистрирован: 22.12.2015

Вот сделал заготовку для автопереворота яиц по принципу китайского, только они даже за одну пластмассу больше тысячи просят, тут себестоимость без учета собственного труда - ноль, все из остатков после ремонта. https://youtu.be/VQ0mPMOu_wo

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Хочешь совет хороший по поводу профиля?

lean_74
Offline
Зарегистрирован: 22.12.2015

Umka пишет:

Хочешь совет хороший по поводу профиля?

От тебя любой совет, я думаю, хороший , думаешь оцинковка будет вредно действовать? тогда покрашу.

lean_74
Offline
Зарегистрирован: 22.12.2015

вот и платки сделали.

плата инкбатора

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Совет - делай лотки из сетки оцинкованной. Профиль нифига не продувается. Тем более корыто такое.

lean_74
Offline
Зарегистрирован: 22.12.2015

В печатной плате незначительная ошибочка, у МОС3021 землю завел на 3-ю ногу, вместо 2-й. т.к 3-я не задействована просто соединяем ее со второй. 

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Лучше бы исходник с Layout дал или в чем ты там рисуешь. По фотке же не видно половину дорожек. Все в тумане. Думаешь кто-то будет по фотке плату повторять и еще потом ошибку исправлять?