Ви не увійшли.
Данный код вставить не получится, так как это часть другой программы, его надо адаптировать для вашей программы - изменить или добавить переменные и функции.
Second, Minute, Hour ... - переменные в них хранятся соответствующие значения.
bcd2dec - функция преобразования формата чисел.
Print_Digits - функция преобразования числа в строку.
а можно пример
а то я совсем туго
Надо писать свой обработчик или спросить у гугла.
Когда то давно я писал свой, не помню рабочий ли он на 100%. Вот код, это кусок из программы, но смысл понятен. Поправиш его под свои нужды.Loop: //блок считывания текущего времени и даты Wire.beginTransmission(0x68); Wire.write((byte)0); Wire.endTransmission(); Wire.requestFrom(0x68, 7); // if (Wire.available() < 7) return; Second = bcd2dec(Wire.read() & 0x7f); Minute = bcd2dec(Wire.read() ); Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock Wday = Wire.read(); Day = bcd2dec(Wire.read() ); Month = bcd2dec(Wire.read() ); Year = bcd2dec(Wire.read() ); //отсчет с 2000 года //блок подготовки строк для вывода на дисплей Print_Digits(output_string_1, 4, 2, ' ', Hour); //4,0 output_string_1[6] = ':'; Print_Digits(output_string_1, 7, 2, '0', Minute); //7,0 output_string_1[9] = ':'; Print_Digits(output_string_1, 10, 2, '0', Second); //10,0 Print_Digits(output_string_2, 3, 2, ' ', Day); //3,1 output_string_2[5] = '/'; Print_Digits(output_string_2, 6, 2, '0', Month); //6,1 output_string_2[8] = '/'; Print_Digits(output_string_2, 9, 4, '0', Year + 2000); //9,1 //вывод на дисплей lcd.clear(); lcd.print(output_string_1); lcd.setCursor(0, 1); lcd.print(output_string_2); //считываем нажатия кнопок key = 0; if (!digitalRead(GasButonPin)) key = 2; if (!digitalRead(BenzButonPin)) key = 3; if (analogRead(ButonsPin) < 100) key = 1; if (key) delay(500); else delay(100); //корректируем время/дату switch (Cursor) { case 0: //часы switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Hour > 0) Hour--; break; case 3: // + if (Hour < 23) Hour++; break; } lcd.setCursor(4, 0); break; case 1: //минуты switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Minute > 0) Minute--; break; case 3: // + if (Minute < 60) Minute++; break; } lcd.setCursor(7, 0); break; case 2: //секунды switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Second > 0) Second--; break; case 3: // + if (Second < 60) Second++; break; } lcd.setCursor(10, 0); break; case 3: //день switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Day > 1) Day--; break; case 3: // + if (Day < 31) Day++; break; } lcd.setCursor(3, 1); break; case 4: //месяц switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Month > 1) Month--; break; case 3: // + if (Month < 12) Month++; break; } lcd.setCursor(6, 1); break; case 5: //год switch (key) { case 1: //следующая Cursor++; if (Cursor > 5) Cursor = 0; break; case 2: // - if (Year > 16) Year--; break; case 3: // + if (Year < 250) Year++; break; } lcd.setCursor(9, 1); break; } //записываем время если были нажаты клавиши + или - if (key > 1) { Second |= 0x80; // stop the clock Wire.beginTransmission(0x68); Wire.write((uint8_t)0x00); // reset register pointer Wire.write(dec2bcd(Second)) ; Wire.write(dec2bcd(Minute)); Wire.write(dec2bcd(Hour)); // sets 24 hour format Wire.write(Wday); Wire.write(dec2bcd(Day)); Wire.write(dec2bcd(Month)); Wire.write(dec2bcd(Year)); Wire.endTransmission(); Second &= 0x7f; // start the clock Wire.beginTransmission(0x68); Wire.write((uint8_t)0x00); // reset register pointer Wire.write(dec2bcd(Second)) ; Wire.endTransmission(); //!!!!!!!!!!!!!!!!!!!!!!!!!! проверить или будет работать с неполной передачей данных!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } goto Loop; //зацикливаем настройку, выход из настройки - выключением }
извините за глупый вопрос но где его правильно вставить?
подскажите как сделать чтоб
время выставлять с помощью кнопок
а не через пк
усилия хватает а вот как
замутить переворот на нем
он делает один оборот за 5-ть
минут мотор на 220в
Dima, если Вы думаете что главное это управление двигателем то очень сильно заблуждаетесь. Сделайте пожалуйста механику, поставьте двигатель и по управляйте двигателем в ручном режиме поворотом и сразу все поймете . Вы не внимательно читали пост #37. Ручная дрель метал сверлит и имеет не хилое усилие на валу но вы можете без особых усилий рукой провернуть патрон . Вот когда у Вас будет в "железе" работающая механика, тогда и будем править скетч под нее. Не помню который раз но еще раз повторю, главное это работающий инкубатор с поворотом, нагревателем и увлажнителем (реально работающий а не где то "представлении"). Я тоже когда то был таким же самоуверенным, что конструкция будет работать . Как потом оказалось программа это может 5% задачи.
понятно значит буду без шаговика городить
и дальше голову ломать о перевороте
у меня нет возможности в ручную поворачивать
а яйца спалить жалко да и смысл их класть в духовый шкаф
Dima пише:Так как Вы собрались делать поворот? Если кривошип то двигатель может вращаться в одну сторону.
да хочу кривошип но ничего не выходит как в этот скеч,
заделать скеч шаговика и соединить вместеТак Вы определитесь чем вращаете. То сервой то шаговиком Вас не поймешь
да шаговик из принтера на 4 тыре вывода
Так как Вы собрались делать поворот? Если кривошип то двигатель может вращаться в одну сторону.
да хочу кривошип но ничего не выходит как в этот скеч,
заделать скеч шаговика и соединить вместе
да вот еще забыл почему постоянно горит светодиод на пин а0 авария
ну откЕдова мне знать как он сделал? )
могу только сказать что при переднем или заднем фронте на 10 ноге он крутит лоток
у Nefreemen спросите
да на 10 ногу у меня реле подключено и после его с работки
нужно в ручную нажимать на кнопку +
чтоб оно отключилось
а мне нужно автоматически
а также чтоб двигатель знал когда и в какую сторону крутить
я придумал что можно впихнуть в корпсус с индикатором от терминала ), там даже модем есть что б слать смс или звонить при аварии )
у меня скоро будет своя ардуино! во ))))
мне не нужны навороты
как Вы не поймете у меня проблема с авто поворотом лотка
в данном скече раъзясните плиз как его организовать на пальцах
а как фото загрузить на этот форум?
с своего пк
в данный момент у меня проблема с поворотом лотка
Дима, Вы не обижайтесь. Я хочу что бы Вы понимали что находится за "углом" и были к этому готовы. Поймите правильно, хороший инкубатор будет тогда когда у Вас будет хорошая, продуманная и надежная конструкция а не программа на 5+. Программу можно написать за день, на конструкцию в лучшем случае уйдет неделя. Сделаете что то не так будете делать новый, потому что процесс инкубации не остановить для устранения ошибок.
А программу править по ходу будете в любом случае, ранее я Вам объяснял почему.
я понимаю Вас но и Вы поймите меня
для человека который расбираеться в таких вещах как тот скетч
сделать 1- р плюнуть
Вы мне подскажите как там организовать
поворот лотка а то я скоро совсем седой буду но
я думаю надо параллельно кнопке+
прицепить 2-а геркона и 2-а магнита
поскольку скеч работает не пойми как
то есть после с работки времени на двигатель идет постоянно питание
когда нажимаешь кнопку +
все сбрасывается
вот поэтому я и решил применять геркон и магнит
ведь концевик не сработает
извините за грамматику
Дима, у Вас есть только один выход - полностью повторить тот пример который вы взяли за основу.
включая железо и механизмы, даже если он Вам не очень нравится (
свои пожелания сможете реализовать уже в следующей редакции.
я с радостью но не могли б Вы немного разяснить а особенно по повороту лотков
я попытался весь скетче расс комментировать а там куча ошибок после компиляции
и раз ясните мне как в этом сктче правильно организовать поворот лотков
Да к стати о весе лотка а Вы прикиньте и прозреете
я сервой пробовал кран водопроводный открывать справилась
а уж лоток отцентрованный тем более повернет
я не хочу быть настойчивым но можно ближе к практике
а то и запускать уже пора инкубатор а электроники нет
NoName пише:"но и так затраты большие а окупаемость "0"" - категорически не согласен,
на себе любимом нельзя экономить, особенно если дело идет о таких цяцьках )Угу. А Вы посчитайте стоимость цыпы и ее падеж и успокойтесь по поводу окупаемости. Согласен с NoName, можете сэкономить 50 грн. а убытка иметь на пару сотен.
Так я понял у Вас есть часики, вот и переворот привязать нужно к ним. Способов масса начиная от привязки к hours так и к min.
я не знаю как это вам легко говорить
мы с вами говорим как учитель который спец с учеником первого класса
А с какого форума вы взяли данный материал?
Я не помню
где-то тут http://arduino.ru/forum/
"но и так затраты большие а окупаемость "0"" - категорически не согласен,
на себе любимом нельзя экономить, особенно если дело идет о таких цяцьках )
если не ошибаюсь Вы говорили о помощи с кодом
как и че делать в нем особенно с переворотом лотков я в смятении
я имею ввиду этот код:
#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");
}
Есть несколько способов. Весь лоток поворачивается на 40-43 градуса в одну сторону (от горизонтали) потом в другую (у меня так, поскольку "этажерка"
у меня один лоток прямоугольный и я тоже думаю поворот от горизонтали на 45 градуса и через 2-3 часа на исходную
Я применил двигатель РД-09 ( прибл. 2 об/мин.)
у меня имеется:HP LaserJet 4ml 4L 4P Main DC Printer Motor RG5 0765 MSCM048A50 4 Pin
и серва а также небольшой вес лотка и усилие нет смысла в актуаторе
Очень настоятельно не рекомендую расположение яйца на "носик"
полностью с Вами согласен
Для такого объема идеальный вариант два тепловых шнура по 30 Вт цена вопроса в районе 120 грн.:
согласен но и так затраты большие а окупаемость "0"
так как пару раз за сезон пополнить хозяйство курами для себя не для продажи
хочу 25ть бролеров и20ть обычных цыплят
вентилятор я думаю поставить от пк
на всякий пожарный
Что касается аварии то это выход режимов инкубации за пределы (каких Вам решать) и подача сигнала :
тогда авария температуры; Влажности; и сбоя
Ну если простой инкубатор, то вам вполне подойдет мой скетч. Делался на быструю руку для пластмассовой коробки объемом 125 л. Все работает - проверенно. Что непонятно спрашивайте.
heater_hi в 2 раза мощнее heater_low, итого получаем 4-х ступенчатую регулировку, в результате максимальное отклонение от заданной температуры у меня не превышало 0,125 С. Увлажнитель - вентилятор дующий на емкость с водой. Автоматического переворота нет, может быть допишу на досуге. Все настройки задаются в скетче.
З.Ы. Насчет watchdogа - я не знаю будет ли ваша плата корректно обрабатывать срабатывание watchdogа, это зависит от используемого проца и бутлоадера. Я не использую бутлоадер - делаю экспорт бинарного файла, затем заливаю программатором через ISP, старт без бутлоадера. Если будете использовать бутлоадер почитайте это, если не боитесь зависания - просто закоментируйте строки касающиеся watchdogа.#include <avr/wdt.h> #include <LiquidCrystal.h> #include <OneWire.h> #include <SimpleDHT.h> //если много ошибок датчика DHT: //SimpleDHT.h -> строка 98 -> delayMicroseconds(10); уменьшить значение до 9 или 8, результат delayMicroseconds(9);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define heater_pin_low 0 //пин нагревателя малой мощности #define heater_pin_hi 1 //пин нагревателя большой мощности #define DS18B20_Pin 2 //пин термометра #define DHT11_pin 3 //пин влажности и температуры #define beeper_pin 10 //пин подключения пищалки #define humidity_pin 11 //пин подключения увлажнителя #define opros 5000 //интервал опроса датчиков, 2*5=10 сек #define set_temperature 37.53 //заданая температура в инкубаторе, C #define set_humidity 60 //заданая влажность в инкубаторе, % #define max_humidity 80 #define min_humidity 50 #define max_temperature 38.5 #define min_temterature 36.5 #define max_delta_temp 3 //максимальная разница между показаниями датчиков, C float DS1820_temp; //температурв измереная с датчика DS18B20, C float DS1820_temp_old; //температура предыдущего измерения с датчика DS18B20, C byte DHT11_temp; //температура измеренная с датчика DHT11, C byte DHT11_hum; //влажность измеренная с датчика DHT11, % byte DHT11_Error = 0; //счетчик ошибок датчика DHT11 byte DS1820_Error = 0; //счетчик ошибок датчика DS1820 boolean Sensor_Error = false; //флаг ошибки датчиков boolean StartFlag = true; //флаг начального запуска, сбрасывается когда контролируемые параметры достигнут нужных значений byte Heater = 2; //индекс мощности нагревателя, 0-3 //для DS1820 byte addr[8]; byte data[12]; LiquidCrystal lcd(9, 8, 7, 6, 5, 4); //Создаём объект LCD-дисплея, указываем, к каким пинам Arduino подключены выводы дисплея: RS, E, DB4, DB5, DB6, DB7 OneWire ds(DS18B20_Pin); SimpleDHT11 dht11; void setup() { wdt_disable(); //выключаем watchdog (на случай перезагрузки по watchdog) wdt_enable(WDTO_8S); //включаем на 8 секунд pinMode(heater_pin_low, OUTPUT); pinMode(heater_pin_hi, OUTPUT); pinMode(humidity_pin, OUTPUT); digitalWrite(heater_pin_low, LOW); digitalWrite(heater_pin_hi, LOW); digitalWrite(humidity_pin, LOW); if ( !ds.search(addr)) Sensor_Error = true; //датчик не найден if (OneWire::crc8(addr, 7) != addr[7]) Sensor_Error = true; //ошибка crc lcd.begin(24, 2); lcd.print("DS t="); lcd.setCursor(11, 0); lcd.print(">"); lcd.print(set_temperature, 2); lcd.print("< H="); lcd.setCursor(0, 1); lcd.print("DHTt="); lcd.setCursor(8, 1); lcd.print("h="); lcd.setCursor(13, 1); lcd.print(">"); lcd.print(set_humidity); lcd.print("< Err="); } void loop() //------------------------------------------------------------------------------------------ { wdt_reset(); //сбрасываем watchdog GetSensors(); //получаем значения с датчиков Thermostat(); //корректируем мощность нагревателя Alarm(); //проверка корректности параметров Display(); //отображение данных на дисплее delay(opros); //задержка 5 сек wdt_reset(); //сбрасываем watchdog if (StartFlag) tone(beeper_pin, 4000, 200); //звук раз в 10 сек пока контролируемые параметры не придут в норму delay(opros); //задержка 5 сек wdt_reset(); //сбрасываем watchdog } // Процедура считывания температуры и влажности с датчиков---------------------------------------------- void GetSensors() { ds.reset(); ds.select(addr); ds.write(0x44, 1); //запуск конвертации delay(1000); // maybe 750ms is enough, maybe not ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( byte i = 0; i < 9; i++) data[i] = ds.read(); DS1820_temp_old = DS1820_temp; //запоминаем предыдущую температуру DS1820_temp = ((data[1] << 8) | data[0]) / 16.0; //температура, С if (dht11.read(DHT11_pin, &DHT11_temp, &DHT11_hum, NULL)) { DHT11_Error++; if (DHT11_Error > 5) Sensor_Error = true; } else DHT11_Error = 0; } //Процедура регулирования температуры и влажности------------------------------------------------------- void Thermostat() { //прогноз нужен потому что система обладает инерцией DS1820_temp_old = DS1820_temp + DS1820_temp - DS1820_temp_old; //вычисляем прогноз температуры для следующего измерения if (DS1820_temp_old > set_temperature) { if (Heater > 0) Heater--;//если прогноз больше установленной температуры - уменьшаем мощность нагревателя } else { if (Heater < 3) Heater++; } DS1820_temp_old = DS1820_temp - set_temperature; if (DS1820_temp_old > 0.14) Heater = 0; //1 шаг измерения = 0,0625: (2 шага=0,125 < 0,14 < 3 шага=0,1875), если температура больше заданной на 2 шага - выключаем нагреватель if (DS1820_temp_old < -0.14) Heater = 3; //1 шаг измерения = 0,0625: (2 шага=0,125 < 0,14 < 3 шага=0,1875), если температура меньше заданной на 2 шага - включаем нагреватель switch (Heater) { case 0: digitalWrite(heater_pin_low, LOW); digitalWrite(heater_pin_hi, LOW); break; case 1: digitalWrite(heater_pin_low, HIGH); digitalWrite(heater_pin_hi, LOW); break; case 2: digitalWrite(heater_pin_low, LOW); digitalWrite(heater_pin_hi, HIGH); break; case 3: digitalWrite(heater_pin_low, HIGH); digitalWrite(heater_pin_hi, HIGH); break; } if (DHT11_hum > set_humidity) digitalWrite(humidity_pin, LOW); else digitalWrite(humidity_pin, HIGH); } //управляем авариями------------------------------------------------------------------------------------ void Alarm() { boolean alarm_flag = false; //флаг выхода контролируемых параметров за допустимые пределы word delta; noTone(beeper_pin); //выключаем сигнал об аварии delta = abs(DS1820_temp - DHT11_temp); //вычисляем разницу показаний температуры с датчиков if ( delta > max_delta_temp ) Sensor_Error = true; //проверяем разницу между показаниями температуры с датчиков if (DHT11_hum > max_humidity) alarm_flag = true; //проверяем выход контролируемых параметров за допустимые пределы if (DHT11_hum < min_humidity) alarm_flag = true; if (DS1820_temp > max_temperature) alarm_flag = true; if (DS1820_temp < min_temterature) alarm_flag = true; if (alarm_flag && StartFlag) { alarm_flag = false; //если был старт и параметры еще не вошли в норму сбрасываем флаг выхода контролируемых параметров за допустимые пределы Sensor_Error = false; } else StartFlag = false; // иначе сбрасываем флаг старта if (alarm_flag || Sensor_Error) tone(beeper_pin, 4000); } //Процедура вывода информации на дисплей---------------------------------------------------------------- void Display() { lcd.setCursor(5, 0); lcd.print(DS1820_temp, 2); lcd.setCursor(21, 0); lcd.print(Heater); lcd.setCursor(5, 1); lcd.print(DHT11_temp); lcd.setCursor(10, 1); lcd.print(DHT11_hum); lcd.setCursor(22, 1); lcd.print(DHT11_Error); }
ваш код не компилируется по ходу на библиотеку жалуется
у меня версия иде 1.6.6
искал в сети не нашел точно такой библиотеки #include <SimpleDHT.h>
у меня просто #include <DHT.h>
https://arduino-ua.com/prod406-Draiver_ … i_na_L298N
+
HP LaserJet 4ml 4L 4P Main DC Printer Motor RG5 0765 MSCM048A50 4 Pin
+
https://arduino-ua.com/prod166-Arduino_Nano_ATmega328
+
https://arduino-ua.com/prod22-Real_Time … dyl_DS1307
+
https://arduino-ua.com/prod201-2h_kanalnoe_rele_5V_10A
+
дшт11+ds18b20+дисплей 20*16 и есть 2004
вот эти вещи у меня имеются в наличии
по в части механики (переворот) и влажности у меня вопрос как Вы это видите?
с помощью шаговика или сервы переворот каждые 2-3 часа
влажность как-то не думал об этом
вопрос по нагревателю, что Вы хотите использовать лампы
да для начала лампы накал. если все получится попробую сделать тен на 12в
если что неправильно написал поправьте пожалуйста
а вот про аварию я не совсем понимаю так как с такими вещами столкнулся в первые
Проще всего использовать функцию millis() и по прошествии n-го числа миллисекунд дергать каким-то пином.
у меня не получилось я использовал функцию millis()
для сервопривода он срабатывал когда ему хотелось
а,как переворот лотков сделать
в вашем скетче
#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 DHT11 // 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"); }
вот нашел новый код только не пойму почему
горит постоянно #define alarm_pin 14 // пин аварии
и подскажите правильно ли я понял что он находится на пин А0
и вольтметр показывает ерунду почему то от пк 3,3 вольта