ПОДСКАЖИТЕ В КОДЕ
- Войдите на сайт для отправки комментариев
Чт, 03/03/2016 - 23:52
#include <PID_v1.h> #include <Wire.h> #include "RTClib.h" #include <LiquidCrystal_I2C.h> #include <EEPROM2.h> #include <DallasTemperature.h> #include <OneWire.h> #include <SimpleTimer.h> #include <avr/wdt.h> #include "DHT.h" int del = 80; // переменная ожидания между выборами меню unsigned int interval = 300; // интервал сколько будет длиться цикл while, после чего перейдёт к следующему меню.(кол-во итераций) //#define EXT_HEATING // ИСПОЛЬЗУЕМ ДОП.НАГРЕВАТЕЛЬ ВМЕСТО УВЛАЖНИТЕЛЯ. Если нужен увлажнитель, просто закомментируйте эту строку. #define heater_pin 13 // нагреватель #define humidifer_pin 12 // увлажнитель #define fan_pin 11 // вентилятор #define alarm_pin 14 // пин аварии #define beeper_pin 9 //пищалка по аварии #define turn_pin 10 // управление поворотом #define extend_heater_pin 8 // дополнительный нагреватель #define button_minus_pin 2 //пин кнопки "минус" #define button_plus_pin 3 //пин кнопки "плюс" #define button_enter_pin 4 //пин кнопки "enter" #define DS18B20_Pin 7 //пин термометра #define setSampleTime 1000 //время цикла ПИД #define voltmeter_pin 1 //вход А1 через делитель (22к/10к) подключен к питанию модуля. Измеряет до 16В. #define T_correction -0.0 // коррекция температуры SHT10 #define h_histeresis 5.0 // гистерезис влажности #define DHTPIN 5 // what pin we're connected to #define DHTTYPE DHT22 // DHT 22 (AM2302) boolean button_minus; boolean button_plus; boolean button_enter; boolean bottomView = 0; // флаг индикации нижней строки float humidity; // Влажность float temp1Ink; // Температура DS18B20 float temp2Ink; // Температура SHT10 float dewpoint; // Точка росы unsigned int rawData; unsigned long currentTime; // задаем переменные для тайминга поворота unsigned long serialTime; //this will help us know when to talk with processing unsigned long now; unsigned long trhMillis = 0; // период опроса датчиков const unsigned long TRHSTEP = 300UL; // Период опроса датчиков LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display RTC_DS1307 rtc; OneWire oneWire(DS18B20_Pin); DallasTemperature sensors(&oneWire); DHT dht(DHTPIN, DHTTYPE); double Setpoint, Input, Output; //объявляем переменные для ПИД PID myPID(&Input, &Output, &Setpoint, 10000.0, 0.5, 10.5, DIRECT); //Инициализируем ПИД-библиотеку и коэффициенты int WindowSize = setSampleTime; // ширина окна терморегулятора 1 секунда. unsigned long windowStartTime; unsigned long alarmDelay; //SimpleTimer timer; /* EEPROM1 - tempInk (float) EEPROM(13) - set_humidity (float) EEPROM5 - +-alarmTemp (float) EEPROM9 - fanTemp (int) EEPROM11 - turnPeriod (int) */ //////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { Serial.begin(9600); lcd.init(); // Старт дисплея lcd.backlight(); // Включаем подсветку дисплея windowStartTime = millis(); byte stat; byte error = 0; float tempInk; float set_humidity; float alarmTemp; rtc.begin(); // Старт часов //int fanTemp; //int turnPeriod; rtc.adjust(DateTime(__DATE__, __TIME__)); // EEPROM_read(1, tempInk); // tempInk = constrain(tempInk, 36.7, 38.7); // EEPROM_write(1, tempInk); // EEPROM_read(13, set_humidity); // set_humidity = constrain(set_humidity, 40.0, 90.0); // EEPROM_write(13, set_humidity); // EEPROM_read(9, fanTemp); // fanTemp = constrain(fanTemp, 38, 39); // EEPROM_write(9, fanTemp); // EEPROM_read(5, alarmTemp); // alarmTemp = constrain(alarmTemp, 1.0, 4.0); // EEPROM_write(5, alarmTemp); // EEPROM_read(11, turnPeriod); // alarmTemp = constrain(turnPeriod, 0, 13); // EEPROM_write(11, turnPeriod); delay(15); wdt_enable (WDTO_8S); //взводим сторожевой таймер на 8 секунд. myPID.SetOutputLimits(0, WindowSize); //задаем лимиты ширины ПИД-импульса от 0 до 1 секунды. myPID.SetMode(AUTOMATIC); //включаем ПИД-регулирование myPID.SetSampleTime(setSampleTime); pinMode(extend_heater_pin, OUTPUT); //пин дополнительного нагревателя. Переводим в 1 чтобы не включать реле. digitalWrite(extend_heater_pin, LOW); pinMode(heater_pin, OUTPUT); pinMode(turn_pin, OUTPUT); // устанавливаем выводы digitalWrite(turn_pin, LOW); pinMode(humidifer_pin, OUTPUT); pinMode(fan_pin, OUTPUT); digitalWrite(fan_pin, LOW); 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(); dht.begin(); sensors.begin(); sensors.setResolution(12); // установить разрешение (точность) sensors.setWaitForConversion(false); // отключить ожидание //timer.setInterval(3000, getSensors); windowStartTime = millis(); } //////////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { // Input = getTemp(); unsigned long now = millis(); { DateTime now = rtc.now(); lcd.setCursor(11, 0); lcd.print(now.hour(), DEC); lcd.print(':'); lcd.print(now.minute(), DEC); } //timer.run(); 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)); // включаем/выключаем реле поворота по кнопке Плюс } if (!button_plus && !button_plus) { delay(del); lcd.clear(); // bottomView = !bottomView; // переключаем режим показа нижней строки. } //send-receive with processing if it's time if (millis() > serialTime) { SerialReceive(); SerialSend(); serialTime += 500; } getSensors(); thermostat(); //#ifdef EXT_HEATING extend_heater(); //#else humidifer(); //#endif turn(); fan(); alarm(); //outpuPower(); wdt_reset(); //unsigned long now1 = millis(); //Serial.println(now1-now); } /////////////////////////////////////////////////////////////////////////////////////////////// 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() { temp_setup(); hum_setup(); turn_setup(); alarm_setup(); vent_setup(); //data_time_setup(); } //устанавливаем температуру в меню/////////////////////////////////////////////////////////// void temp_setup() { float tempInk; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("TEMP.INK SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); //EEPROM_write(1, 37.7); EEPROM_read(1, tempInk); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(1, tempInk + 0.1); if (tempInk > 40) { //проверяем, если выше 40, EEPROM_write(1, 40); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(1, tempInk - 0.1); if (tempInk < 30.0) { //проверяем, если выше 30, EEPROM_write(1, 30.0); //пишем в память 30 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("TEMP.INK = "); lcd.print(tempInk, 1); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем влажность//////////////////////////////////////////////////////////////////////// void hum_setup() { float set_humidity; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("HUMIDITY SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); //EEPROM_write(13, 65.0); //EEPROM_read_mem(13, &set_humidity, sizeof(set_humidity)); EEPROM_read(13, set_humidity); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(13, set_humidity + 0.5); if (set_humidity > 100) { //проверяем, если выше 40, EEPROM_write(13, 100.0); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(13, set_humidity - 0.5); if (set_humidity < 20) { //проверяем, если выше 40, EEPROM_write(13, 20.0); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("Humidity = "); lcd.print(set_humidity, 1); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем поворот///////////////////////////////////////////////////////////////////////// void turn_setup() { int turnPeriod; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("TURN SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(11, turnPeriod); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(11, turnPeriod + 1); if (turnPeriod > 13) { //проверяем, если выше 40, EEPROM_write(11, 13); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(11, turnPeriod - 1); if (turnPeriod < 0) { //проверяем, если выше 40, EEPROM_write(11, 0); //пишем в память 40 } lcd.clear(); } EEPROM_read(11, turnPeriod); lcd.setCursor(0, 0); lcd.print("PERIOD = "); lcd.print(turnPeriod); lcd.print(" Hour"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем сигнализацию///////////////////////////////////////////////////////////////////// void alarm_setup() { float alarmTemp; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("ALARM SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); //EEPROM_write(5, 2.5); EEPROM_read(5, alarmTemp); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(5, alarmTemp + 0.1); if (alarmTemp > 10.0) { //проверяем, если ниже 10, EEPROM_write(5, 10.0); //пишем в память 10 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(5, alarmTemp - 0.1); if (alarmTemp < 1.0) { //проверяем, если выше 40, EEPROM_write(5, 1.0); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("T.Alarm + - "); lcd.print(alarmTemp, 1); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } //устанавливаем вентиляцию///////////////////////////////////////////////////////////////// void vent_setup() { int fanTemp; lcd.clear(); delay(del); button_read(); lcd.setCursor(0, 0); lcd.print("FAN SETUP"); delay(1000); int x = 0; while (1) { x++; if (x > interval) { break; } button_read(); EEPROM_read(9, fanTemp); if (!button_enter) { delay(del); lcd.clear(); //очищаем экран break; } if (!button_minus) { x = 0; EEPROM_write(9, fanTemp + 1); if (fanTemp > 40) { //проверяем, если выше 40, EEPROM_write(9, 40); //пишем в память 40 } lcd.clear(); } if (!button_plus) { x = 0; EEPROM_write(9, fanTemp - 1); if (fanTemp < 20) { //проверяем, если выше 40, EEPROM_write(9, 20); //пишем в память 40 } lcd.clear(); } lcd.setCursor(0, 0); lcd.print("T.Fan = "); lcd.print(fanTemp); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("minus NEXT plus"); delay(del); } } ///////////////////////////////////////////////////////////////////////////////////////////////// void getSensors() { unsigned long curMillis = millis(); // Получаем текущее время работы if (curMillis - trhMillis >= TRHSTEP) { // время для нового измерения? sensors.requestTemperatures(); temp1Ink = sensors.getTempCByIndex(0); } if (curMillis - trhMillis >= TRHSTEP * 4) { // время для нового измерения? temp2Ink = dht.readTemperature(); temp2Ink = (temp2Ink + (T_correction)); // Корректируем показания текрмометра humidity = dht.readHumidity(); trhMillis = curMillis; } // logData(); } ////////////////////////////////////////////////////////////////////////////////////////////////// //void logData() { // Serial.print("temp1Ink = "); // Serial.print(temp1Ink); // Serial.print("temp2Ink = "); // Serial.print(temp2Ink); // Serial.print(" C, Humidity = "); // Serial.print(humidity); // Serial.print(" %, Dewpoint = "); // Serial.print(dewpoint); // Serial.println(" C"); //} //используем терморегулятор void thermostat() { now = millis(); float tempPoint; float set_humidity; EEPROM_read_mem(1, &tempPoint, sizeof(tempPoint)); EEPROM_read(1, tempPoint); EEPROM_read_mem(13, &set_humidity, sizeof(set_humidity)); EEPROM_read(13, set_humidity); Setpoint = tempPoint; myPID.Compute(); if (now - windowStartTime > WindowSize) { //время для перещелкивания периода окна windowStartTime = windowStartTime + WindowSize; voltmeter(); //запускаем функцию измерения напряжения Input = temp1Ink; lcd.setCursor(0, 0); // устанавливаем курсор в 0-ом столбце, 0 строка (начинается с 0) lcd.print("T"); lcd.print(temp1Ink, 1); // печать температуры на дисплей //lcd.print((char)223); //lcd.print(" ("); //lcd.print(Setpoint, 1); //lcd.print(")"); lcd.setCursor(5, 0); lcd.print("T"); lcd.print(temp2Ink, 1); // печать температуры на дисплей //lcd.print((char)223); //lcd.setCursor(12, 0); //lcd.print(" "); //lcd.print(temp1Ink - temp2Ink, 1); //lcd.print(" "); //lcd.print((char)223); //lcd.print(" ("); //lcd.print(Setpoint, 1); //lcd.print(")"); lcd.setCursor(0, 1); // устанавливаем курсор в 2-ом столбце, 3 строка (начинается с 0) lcd.print("H"); lcd.print(humidity, 1); // печать влажности на дисплей } if (Output > (now - windowStartTime)) digitalWrite(heater_pin, HIGH); else digitalWrite(heater_pin, LOW); } //управляем влажностью///////////////////////////////////////////////////////////////////////// void humidifer() { //float humidity; float set_humidity; // if (curMillis - humMillis >= humStep) { // humMillis = curMillis; // //humidity = sht1x.readHumidity(); // } //EEPROM_read_mem(13, &set_humidity, sizeof(set_humidity)); EEPROM_read(13, set_humidity); if (set_humidity > humidity) digitalWrite(humidifer_pin, HIGH); //сравниваем измеренную влажность с заданной lcd.setCursor(5, 1); lcd.print("#");//вывод инфо состояния на LCD if (set_humidity < humidity + h_histeresis) digitalWrite(humidifer_pin, LOW); lcd.setCursor(5, 1); lcd.print("-");//вывод инфо состояния } //управляем поворотом////////////////////////////////////////////////////////////////////////// void turn() { int turnPeriod; //период поворота лотков в часах int turnCommand; boolean turnFlag = 0; // флаг поворота для случайного периода static unsigned long loopTime; EEPROM_read(11, turnPeriod); if (turnPeriod == 0) return; //если нулевой период поворота, то не поворачиваем яйца. if (turnPeriod < 13) turnCommand = turnPeriod; else if (turnPeriod > 12 && turnFlag == 0) { //если произошел поворот (сброшен флаг) и значение в памяти 13, то turnCommand = random(1, 6); //берем случайное значение часов 1-6 turnFlag = 1; //защелкиваем флаг вычисления случайных значений до следующего поворота } currentTime = millis()/1000; //lcd.setCursor(6, 1); //lcd.print("P"); Serial.println(currentTime); Serial.println(loopTime + turnCommand * 3600UL); if (currentTime > (loopTime + turnCommand * 3600UL)) { // 3600000 сравниваем текущий таймер с переменной loopTime + период поворота в часах. digitalWrite(turn_pin, !digitalRead(turn_pin)); // включаем/выключаем реле поворота loopTime = currentTime; // в loopTime записываем новое значение turnFlag = 0; //сбрасываем флаг поворота } //lcd.print((loopTime - currentTime + turnCommand * 3600UL) / 60UL); //lcd.print(" "); } //управляем авариями///////////////////////////////////////////////////////////////////////////// void alarm() { float tempInk = sensors.getTempCByIndex(0); float alarmTemp; float setTemp; EEPROM_read(5, alarmTemp); EEPROM_read_mem(1, &setTemp, sizeof(setTemp)); EEPROM_read(1, setTemp); //lcd.setCursor(0, 3); //lcd.print("A"); //lcd.print(setTemp + alarmTemp, 1); if ((millis() - alarmDelay) > 1800000) { if (tempInk > (setTemp + alarmTemp) || tempInk < (setTemp - alarmTemp)) { beeper(10); digitalWrite(alarm_pin, LOW); //если измеренная температура выше заданной на величину аварии } else digitalWrite(alarm_pin, HIGH); //то включаем аварийный сигнал. } } //////////////////////////////////////////////////////////////////////////////////////////////////// void beeper(int duration) { tone(beeper_pin, 2000, duration); } //управляем вентиляторами//////////////////////////////////////////////////////////////////////////// void fan() { //float tempInk = sht1x.readTemperatureC(); int fanTemp; EEPROM_read(9, fanTemp); //lcd.setCursor(6, 3); //lcd.print("F"); //lcd.print(fanTemp); if (temp1Ink > fanTemp) digitalWrite(fan_pin, HIGH); //если измеренная температура выше заданной на величину аварии else digitalWrite(fan_pin, LOW); //то включаем аварийный сигнал. } // вольтметр///////////////////////////////////////////////////////////////////////////////////////// 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(6, 1); lcd.print("V"); lcd.print(outputValue, 1); } // Печать мощности нагрвателя/////////////////////////////////////////////////////////////////////// void outpuPower() { //lcd.setCursor(15, 3); //lcd.print("W"); //lcd.print(Output, 0); //lcd.print(" "); } void extend_heater() { // управление допnnnnnnnnnnm,.kkkолнительным нагревателем на 8 ножке через блок реле./////////// float tempInk = sensors.getTempCByIndex(0); float setTemp; EEPROM_read_mem(1, &setTemp, sizeof(setTemp)); EEPROM_read(1, setTemp); if (tempInk < (setTemp - 3)) //{ digitalWrite(extend_heater_pin, HIGH); //#ifdef EXT_HEATING //digitalWrite(humidifer_pin, LOW); //#endif //} else digitalWrite(extend_heater_pin, LOW); //#ifdef EXT_HEATING //digitalWrite(humidifer_pin, HIGH); //#endif } /******************************************** * Serial Communication functions / helpers ********************************************/ union { // This Data structure lets byte asBytes[24]; // us take the byte array float asFloat[6]; // sent from processing and } // easily convert it to a foo; // float array // getting float values from processing into the arduino // was no small task. the way this program does it is // as follows: // * a float takes up 4 bytes. in processing, convert // the array of floats we want to send, into an array // of bytes. // * send the bytes to the arduino // * use a data structure known as a union to convert // the array of bytes back into an array of floats // the bytes coming from the arduino follow the following // format: // 0: 0=Manual, 1=Auto, else = ? error ? // 1: 0=Direct, 1=Reverse, else = ? error ? // 2-5: float setpoint // 6-9: float input // 10-13: float output // 14-17: float P_Param // 18-21: float I_Param // 22-245: float D_Param /////////////////////////////////////////////////////////////////////////////////////////////////// void SerialReceive(){ // read the bytes sent from Processing int index = 0; byte Auto_Man = -1; byte Direct_Reverse = -1; while (Serial.available() && index < 26){ if (index == 0) Auto_Man = Serial.read(); else if (index == 1) Direct_Reverse = Serial.read(); else foo.asBytes[index - 2] = Serial.read(); index++; } // if the information we got was in the correct format, // read it into the system if (index == 26 && (Auto_Man == 0 || Auto_Man == 1) && (Direct_Reverse == 0 || Direct_Reverse == 1)) { Setpoint = double(foo.asFloat[0]); //Input=double(foo.asFloat[1]); // * the user has the ability to send the // value of "Input" in most cases (as // in this one) this is not needed. if (Auto_Man == 0) // * only change the output if we are in { // manual mode. otherwise we'll get an Output = double(foo.asFloat[2]); // output blip, then the controller will } // overwrite. double p, i, d; // * read in and set the controller tunings p = double(foo.asFloat[3]); // i = double(foo.asFloat[4]); // d = double(foo.asFloat[5]); // myPID.SetTunings(p, i, d); // if (Auto_Man == 0) myPID.SetMode(MANUAL); // * set the controller mode else myPID.SetMode(AUTOMATIC); // if (Direct_Reverse == 0) myPID.SetControllerDirection(DIRECT); // * set the controller Direction else myPID.SetControllerDirection(REVERSE); // } Serial.flush(); // * clear any random data from the serial buffer } /////////////////////////////////////////////////////////////////////////////////////////////// void SerialSend(){ Serial.print(millis() / 1000); Serial.print("PID "); Serial.print(Setpoint); Serial.print(" "); Serial.print(Input); Serial.print(" "); Serial.print(Output); Serial.print(" "); Serial.print(myPID.GetKp()); Serial.print(" "); Serial.print(myPID.GetKi()); Serial.print(" "); Serial.print(myPID.GetKd()); Serial.print(" "); if (myPID.GetMode() == AUTOMATIC) Serial.print("Automatic"); else Serial.print("Manual"); Serial.print(" "); if (myPID.GetDirection() == DIRECT) Serial.println("Direct"); else Serial.println("Reverse"); }
нужно изменить датчик SHT10
на
DHT11
нужна помощь
в этом деле
а что, трудно заменить в 33 строке DHT22 на DHT11?
а почему только в одной строке
читайте что такое объявление переменых, и что может библиотека dht