Отсрочить время выполнения команды
- Войдите на сайт для отправки комментариев
Доброго времени суток, вот получил не так давно посылочку с ebay и начал осваивать Ардуино.
Подключил термодатчик DS18S20, залил скетч, все работает, появилась идея выполнить какое-нибудь действие при определенной температуре(в данном случае светодиод) - тоже получилось... Но вот если скажем собираемся управлять электро котлом с помошью Ардуино, показалось все просто, если температура упала, отправляем 1 на контакт реле и котел заработал, но если вдруг температура упала в следствии мимолетного сквозняка, то нам нужно поидее сделать задержку, скажем в 10 минут, те если температура упала, и она на протяжении 10 минут ниже установленной, то только тогда отправляем 1. попробовал на светодиоде, загорается с установленной задержкой, но и данные не идут во время этой задержки с датчика... Подскажите пжст как это реализовать. Скетч ниже. Заранее благодарен за отклики.
#include <OneWire.h>
/*
* Получаем температуру от датчиков серии DS18x20
*/
// Поддерживаемые датчики
#define DS18S20_ID 0x10
#define DS18B20_ID 0x28
int ledpin = 8;
// Линия 1-Wire будет на pin 2
OneWire ds(10);
void setup(void) {
pinMode(ledpin, OUTPUT);
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte data[12];
byte addr[8];
if (!ds.search(addr)) {
ds.reset_search();
return;
}
if (OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
if (addr[0] != DS18S20_ID && addr[0] != DS18B20_ID) {
Serial.print("Device is not a DS18x20 family device.\n");
return;
}
ds.reset();
ds.select(addr);
// Запускаем конвертацию
ds.write(0x44, 1);
// Подождем...
delay(1000);
present = ds.reset();
ds.select(addr);
// Считываем ОЗУ датчика
ds.write(0xBE);
// Обрабатываем 9 байт
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
// Высчитываем температуру :)
int HighByte, LowByte, TReading, Tc_100, SignBit, Whole, Fract;
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
// Проверяем дубак там или нет
SignBit = TReading & 0x8000;
// Если на улице дубак :)
if (SignBit) {
TReading = (TReading ^ 0xffff) + 1;
}
// Умножаем на (100 * 0.0625) или 6.25
Tc_100 = (6 * TReading) + TReading / 4;
// Отделяем целые от дробных чисел
Whole = Tc_100 / 100;
Fract = Tc_100 % 100;
Serial.print("Temperature: ");
// Если на улице дубак напишем минус перед цифрами :)
if (SignBit) {
Serial.print("-");
}
Serial.print(Whole);
Serial.print(".");
if (Fract < 10) {
Serial.print("0");
}
Serial.print(Fract);
Serial.print("\n");
// Включаем светодиод если температура выше
//30 градусов в течении 20 сек и выключаем, если она ниже
if (Whole > 30)
{
delay (20000);
digitalWrite(ledpin, HIGH);
}
else
{
digitalWrite(ledpin, LOW);
}
}
Сама идея описана в " примерах" в разделе "програмирование" Программирование Ардуино | Аппаратная платформа Arduino
Лень искать, но в разных реинкарнациях типа "включать светодиод через 2 секунды после нажатия на кнопку" обсуждалось не раз. Попробуйте поискать по форуму на слово "задержка" и т.п.
Во вторых - думаю "задержка" в данном случае не то направление поиска (хотя, как "для учебы" - можно с этим разобратся).
В вашей задаче IMHO больше подойдет реализация Гистерезис — Википедия
Слово страшное, а суть простая :)
Включаете и выключаете не по одной и той же температуре, а двум разным.
if(Whole>30) { DigitalWrite(ledpin,HIGH); }; if(Whole<25){ DigitalWrite(ledpin,LOW); }Тогда что-бы светодиод поменял свое состояния - нужно что-бы температура "просела" аж на 5-ть градусов. Думаю "случайный сквозняк" с таким не справится. Только целенаправленный :)
На этом же принципе, кстати, работают и цифровые пины. Имеют две границы "какое напряжение считать нулем, а какое единицей".
Если когда-либо покупали датчик вентялятора радиатора в автомобиле, то скорее всегда видели маркировку типа 82/88 или 92/97 . Вот это оно и есть. На 88 - включить вентилятор, на 82 - выключить.
Сама идея описана в " примерах" в разделе "програмирование" Программирование Ардуино | Аппаратная платформа Arduino
Лень искать, но в разных реинкарнациях типа "включать светодиод через 2 секунды после нажатия на кнопку" обсуждалось не раз. Попробуйте поискать по форуму на слово "задержка" и т.п.
Во вторых - думаю "задержка" в данном случае не то направление поиска (хотя, как "для учебы" - можно с этим разобратся).
В вашей задаче IMHO больше подойдет реализация Гистерезис — Википедия
Слово страшное, а суть простая :)
Включаете и выключаете не по одной и той же температуре, а двум разным.
if(Whole>30) { DigitalWrite(ledpin,HIGH); }; if(Whole<25){ DigitalWrite(ledpin,LOW); }Тогда что-бы светодиод поменял свое состояния - нужно что-бы температура "просела" аж на 5-ть градусов. Думаю "случайный сквозняк" с таким не справится. Только целенаправленный :)
На этом же принципе, кстати, работают и цифровые пины. Имеют две границы "какое напряжение считать нулем, а какое единицей".
Если когда-либо покупали датчик вентялятора радиатора в автомобиле, то скорее всегда видели маркировку типа 82/88 или 92/97 . Вот это оно и есть. На 88 - включить вентилятор, на 82 - выключить.
Спасибо, это мысль! т.к. я потом всеравно хотел устанавливать диапазон температур, это поможет, но всетаки при проживании, не комфортно падение температуры на 5 градусов, она может упасть и в следствии понижения температуры за окном, а в зимнее время, падение с 23 до 18 это критично для человеческого тела мне кажется, тут надо именно временем, у меня стоят термоголовки на радиаторах, можно поставить с шаговым двигателем, не можно а так и будет точнее. суть такова, нормальная для меня температура 23 градуса. при падении в комнате температуры до 21 градуса, серва должна приоткрыть батарею и нагреть помещение до 25, после установки температуры в 25 и выше в течении 10 минут, серва прикрывает батарею. и опять до падения ниже 21 градуса. или обратная ситуация с кухней. допустим активно идет готовка и там стало жарко, батарея перекрывается( возможно не полностью, но это уже второй вопрос)
нет случаем функции типа того: если Whole>30 в течении такого-то времени, то делаем то-то???
если тупо привязать к одной температуре, то эти сервы в ечном движении будут
а может можно задать количество значений больше 30 в моем случае? на практике я не собираюсь считывать значения каждую секунду, мне кажется раз в 1 мин будет достаточно, ну скажем если предидущие 20 значений были больше 30, то... выполняем что-то
нет случаем функции типа того: если Whole>30 в течении такого-то времени, то делаем то-то???
Вы знаете. Я в принципе, до того как увидел этот комент, уже успел накидать примерчик. Хоть уже раз 10-ть только я описывал подход (не считая того что в примерах есть "мигаем без delay()"). Но... судя по всему вы даже не попытались разобраться/поискать/сделать самому. Посмотреть на функцию millis(), как другие делают...
Ну "не получилось бы" - поправили бы, помогли бы... вы же советы "поищите, обсуждалось, посмотрите пример" - тупо проигнорили и просто еще раз задали свой вопрос.
Эх... да ладно... не выкидывать же. Не вам, так кому другому пригодится.
Примерно так это выглядит:
boolean IsHot=false; // тут храним "жарко-ли сейчас" boolean IsCold=true; // Холодно-ли сейчас . можно и без него, использовать !IsHot, но так код читабельней выйдет boolean PrevWasHot=false; // было-ли жарко при прошлом проходе loop() boolean PrevWasCold=true; // то же самое, только для холода unsigned long becameCold=0; // когда стало холодно unsigned long becameHot=0; // когда стало жарко #define HOT_PAUSE 2000 // через какое время нужно включать светик после "стало жарко" #define COLD_PAUSE 3000 // через какое время после "стало холодно" нужно включать датчик void setup(){ } void loop(){ //... тут вычисляемте свое Whole IsHot=Whole>30; // выясняем жарко ли IsCold=!IsHot; // "холодно" это "жарко" наоборот // ===== Ловим события перехода из жары в холод и обратно ===== if(PrevWasCold && IsHot){ // было холодно, а стало жарко becameHot=millis(); // запомнили когда это случилось }; if(PrevWasHot && IsCold){ // было жарко, а стало холодно becameCold=millis(); // запомнили когда это случилось }; // ======== если пришло время и нужно - предпринимаем действия if(becameHot && IsHot && ( (millis()-becameHot )>HOT_PAUSE)){ // "таймер жары" запущен, сейчас жарко, и с момента наступления жары прошло больше чем HOT_PAUSE времени digitalWrite(ledpin,HIGH); // включаем светик becameHot=0; // и вырубаем таймер жары } // аналогичные танцы для холода if(becameCold && IsCold && ( (millis()-becameCold )>COLD_PAUSE)){ digitalWrite(ledpin,LOW); becameCold=0; } // сохраняем IsHot, IsCold для следующего прохода loop(), теперь они становятся "прошлыми" значенями PrevWasHot=IsHot; PrevWasCold=IsCold; }Не проверял, но думаю идею в любом случае можно понять. ну и само собой, для корректной работы этой логики нужно что-бы больше нигде в Loop() небыло использования delay() и проч. блокирующих (управление шаговиками и подобного).
но если вдруг температура упала в следствии мимолетного сквозняка, то нам нужно поидее сделать задержку, скажем в 10 минут, те если температура упала, и она на протяжении 10 минут ниже установленной,
Кто мешает мерять температуру регулярно (ежеминутно, например) в течение 5 или 10 минут, усреднять значение и уже его анализировать на соответствие уставке? :) Каждую секунду - не надо: датчики на 1-wire не справятся.
Для управления котлом надо еще предусмотреть сравнение соседних результатов и ситуацию: датчик врет или вышел из строя.
но если вдруг температура упала в следствии мимолетного сквозняка, то нам нужно поидее сделать задержку, скажем в 10 минут, те если температура упала, и она на протяжении 10 минут ниже установленной,
Кто мешает мерять температуру регулярно (ежеминутно, например) в течение 5 или 10 минут, усреднять значение и уже его анализировать на соответствие уставке? :) Каждую секунду - не надо: датчики на 1-wire не справятся.
Для управления котлом надо еще предусмотреть сравнение соседних результатов и ситуацию: датчик врет или вышел из строя.
на самом деле не котлом а сервой, я написал выше, котел будет контролировать температуру теплоносителя. усреднять можно, надо думать... я в любом случае хочу использовать 2 датчика дома, те их показания надо усреднить и еще и по времени усреднить.
По поводу внезапных сквозняков и прочих незначащих колебаний значений всега - где-то было на форуме, народ вольтметр изобретал.
От себя добавлю, что нужно представить себе и пытаться учитывать такой параметр как "инерционность системы" - т.е. скорость набора температуры рабочего тела котла должна быть равна или больше скорости замера температуры воздуха в помещении.
Как физически реализовать инертность замера температуры воздуха в помещении? - ну, прикрутить датчик температуры к 200 граммовой люминиевой болванке.
Второе - датчиков температуры должно быть более одного.
Вы знаете. Я в принципе, до того как увидел этот комент, уже успел накидать примерчик. Хоть уже раз 10-ть только я описывал подход (не считая того что в примерах есть "мигаем без delay()"). Но... судя по всему вы даже не попытались разобраться/поискать/сделать самому. Посмотреть на функцию millis(), как другие делают...
Ну "не получилось бы" - поправили бы, помогли бы... вы же советы "поищите, обсуждалось, посмотрите пример" - тупо проигнорили и просто еще раз задали свой вопрос.
Не проверял, но думаю идею в любом случае можно понять. ну и само собой, для корректной работы этой логики нужно что-бы больше нигде в Loop() небыло использования delay() и проч. блокирующих (управление шаговиками и подобного).
эту функцию я смотрел, но не понял и/или не подумал как ее применить ко мне, я не програмист просто, учил с++ на 1 и 2 курсе универа, по специальности не работаю, а было это 10 лет назад... конечно я не прав в том плане, что не хочу тратать время на поиск и пробы, но это не так, я не ни хочу, а у меня просто нет времени... Зима впереди, если товарищи с умной головой с этого форума не захотят отвечать, буду сам биться, может что-то и выйдет. мне в доме нужно прокинуть провода сразу, вот я и хочу в течении месяца-полутора хотябы понять, куда их бросить и в каком количестве. извините если что не так
А вообще я писал ТЗ что мне нужно в идеале, в разделе Ищу исполнителя, но так ни кто и не откликнулся:) Система работает просто "как у всех", меня ни кто не гонит, поэтому буду делать сам для души!
уточнение к посту №8:
не дома 2 датчика, а в комнате. у меня в каждой комнате/помещении стоит 1-2 радиатора, у них термоголовки, пока простые, но они меняются на серво. котел следит за температурой теплоносителя, даже если все головки закроются, теплоноситель губо говоря вернется с тойже температурой, что и вышел из котла=> он отключится, если пойдут потери на радиатор в одной из комнат, теплоноситель вернется с меньшим показателем, котел его подогреет. батарея не будет брать больше тепла чем разрешил ей термо регулятор, а терморегулятору отдаст команду контроллер оценив значения датчиков температуры
По поводу внезапных сквозняков и прочих незначащих колебаний значений всега - где-то было на форуме, народ вольтметр изобретал.
От себя добавлю, что нужно представить себе и пытаться учитывать такой параметр как "инерционность системы" - т.е. скорость набора температуры рабочего тела котла должна быть равна или больше скорости замера температуры воздуха в помещении.
Как физически реализовать инертность замера температуры воздуха в помещении? - ну, прикрутить датчик температуры к 200 граммовой люминиевой болванке.
Второе - датчиков температуры должно быть более одного.
за инерционность системы думал, но пока решил хотябы так реализовать... а как можно к примеру DHT22 к аллюминию прикрутить? я читал где-то, что для подобных датчиков надо коробочку делать, около 40*40*40, чтоб она не реагировала на дыхание, мгновенные дуновения и пр. может это лучше чем аллюминевый радиатор?
если товарищи с умной головой с этого форума не захотят отвечать,
ну... так ведь, в итоге, вы же получили ровно то что хотели? В посте #6 разве не пример написанный "ровно под ваши требования"? . Осталось только соеденить только добавить в него чтение датчика температуры.
Кстати с ним (датчиком) можно не напрямую работать (обрабатывать байты, переводить в цельсии). Уже есть готовая библиотечка которая этим занимается Dallas Temperature Control Library - Miles Burton - Innovative engineering for pretty much anything Правда.. точно не помню, но в свое время гугляли по инету ее бажные версии (была там какая-то проблемка на отрицательных температурах), если, опять-таки поискать по форму, то обсуждали это и нашли какую-то "пофиксанную". Возможно, по ссылке выше, это и есть "последняя правильная", можете попробовать. Я просто не помню точно.
По поводу "искал исполнителя и не нашел"... ну да.. мы такие... "еж - птица гордая, пока не пнешь - не полетит" :) Иногда даже деньги не могут победить лень и самомнение:)
Кстати, когда человек сам пытается что-то сделать, то "помочь" иногда более превлекательно чем "заработать денег". Так как в одном случае это "работа", а в другом "хобби".
Перечитал еще раз... видимо нужно мне извинится. немного не адекватно я среагировал. уровень наезда не соотвествовал вашим действиям. Просто часто встречается когда человек ... вообщем скорее я просто "среагировал на собирательный образ". Простите.
Не, коробочки из алюминия - совсем уж непредсказуемый результат будет.
Тогда, если DHT22, то городите программным образом инерционность замера температуры.
Не, коробочки из алюминия - совсем уж непредсказуемый результат будет.
Тогда, если DHT22, то городите программным образом инерционность замера температуры.
DHT22 не обязательно. я купил на пробу DHT22, DHT11(то же самое, но ТИПА похуже), DS18S20, и просто есть LM 35, мб есть что-то привлекательней?
если товарищи с умной головой с этого форума не захотят отвечать,
ну... так ведь, в итоге, вы же получили ровно то что хотели? В посте #6 разве не пример написанный "ровно под ваши требования"? . Осталось только соеденить только добавить в него чтение датчика температуры.
Кстати с ним (датчиком) можно не напрямую работать (обрабатывать байты, переводить в цельсии). Уже есть готовая библиотечка которая этим занимается Dallas Temperature Control Library - Miles Burton - Innovative engineering for pretty much anything Правда.. точно не помню, но в свое время гугляли по инету ее бажные версии (была там какая-то проблемка на отрицательных температурах), если, опять-таки поискать по форму, то обсуждали это и нашли какую-то "пофиксанную". Возможно, по ссылке выше, это и есть "последняя правильная", можете попробовать. Я просто не помню точно.
По поводу "искал исполнителя и не нашел"... ну да.. мы такие... "еж - птица гордая, пока не пнешь - не полетит" :) Иногда даже деньги не могут победить лень и самомнение:)
Кстати, когда человек сам пытается что-то сделать, то "помочь" иногда более превлекательно чем "заработать денег". Так как в одном случае это "работа", а в другом "хобби".
Перечитал еще раз... видимо нужно мне извинится. немного не адекватно я среагировал. уровень наезда не соотвествовал вашим действиям. Просто часто встречается когда человек ... вообщем скорее я просто "среагировал на собирательный образ". Простите.
Да ладно Вам, я наезда и не заметил,просто мб сам не понимаю, я думаю, что форум и есть чтоб обсуждать, помогать, делиться... в конце концов все мы люди и у каждого есть свое мнение, я лично благодарен всем кто ответил, истина рождается в споре, я так думаю
за инерционность системы думал, но пока решил хотябы так реализовать...
Тут в сторону ПИД-регулятор — Википедия можно посмотреть.
Там внизу, в ссылках, есть ссылка на статью "ПИД-регулирование на практических примерах". Там действительно, без "высокой математики", на примере наполнения бака воды разжовано. К сожалению, "ссылка умерла", но возможно сможете гуглом найти эту статью в другом месте.
В принципе, для ардуины уже есть готовая либа-реализация ПИД регулятора для этого
Arduino Playground - PIDLibrary
и либа для подбора коэфициентов (настройки этого ПИД) Arduino Playground - PIDAutotuneLibrary
Но, признаюсь честно, на практике не разбирался с этими либами.
Я бы брал что-то вроде DS18S20 - т.е герметичный, механически прочный(более-менее) тип исполнения.
Сверлим отверстие в подходящем по размеру алюминиевом блоке и помещаем датчик в термопасте.
Да ладно Вам, я наезда и не заметил,просто мб сам не понимаю, я думаю, что форум и есть чтоб обсуждать, помогать, делиться...
Тут я с вами согласен чуть больше чем полностью. Но... когда в 10-ты раз одно и тоже "делится". Просто потому что человеку лень (это я счас не про вас) почитать доку или воспользоватся поиском (а иногда, даже просто опустить глаза на одну тему ниже, которая даже с таким же названием) - это начинает утомлять. В этих бесконечных повторениях теряется то чем делятся :) Убивается мотивация. Когда тратишь час, что-бы "расписать", объяснить именно "идею", и через день, задают тот же вопрос (создают новую тему) просто потому что лень в поиск вбить... а на посылки в поиск начинают "тебе шо трудно сказать...", читать ссылки не хочет... Вы знаете, я тоже годами читал форумы в режиме ReadOnly и не понимал поведения "старожилов" который всех послыют на RTF и гугл :) Зачастую в хамской манере. Но когда сам влез в эту шкуру :)
А признаком-отличием "ленивого", от "не разобрался" как правило является когда человек "вот я там прочитал, попытался вот так... че-то не работает.." Кстати тогда намного легче понять, в чем же человек запутался и ответить осмысленно.
Вообщем вот мне и примерещилось (ошибочно) что опять начинается "ссылок не читаю".
Что-то меня совсем в жесткий offtop унесло. Вечер.
Я бы брал что-то вроде DS18S20 - т.е герметичный, механически прочный(более-менее) тип исполнения.
Вы не поверите, но для замера температуры внутри DHT22 стоит именно DS18B20. Пруф: www.adafruit.com/datasheets/DHT22.pdf
Вот, может пригодится как DS18B20 запихнуть в гильзу
VRTP -> Технология изготовления оболочки для DS18B20 т.п.
Ну, вот - пришёл leshak, и рассказал, как всё на самом деле...
Источником дОбычи DS18S20 является DHT22!
Верю!
Всем большое спасибо, отдельное спасибо leshak, его скетч я и использовал, все работает.
Пробовал ваш пример, не получается управлять реле с задержкой, реле включается при исполнении какого либо условия, но выключаться через положенный интервал не хочет(
С deley все отлично, с millis никак. Скорее всего я чего то не понимаю, хотя принцип работы millis мне ясен.
Помогите разобраться, если это вас не затруднит.
Заранее Благодарен)
Уважаемый Никита!
вы дату последнего поста в ветке видите? :)
Поздновато вы спохватились спрашивать...
Видел, к сожалению именно в это теме я нашел подходящий пример, все остальные завязаны на циклической работе.
Видел, к сожалению именно в это теме я нашел подходящий пример, все остальные завязаны на циклической работе.
На тебе в наследство от Лешака, хоть и давно он не появлялся. Если и здесь не разберешься, не знаю что еще посоветовать.
Другие темы тоже рекомендую почитать.