Автоматика для курятника. Проблемы с прерыванием.
- Войдите на сайт для отправки комментариев
Чт, 20/12/2018 - 20:04
Приветствую всех форумчан!
Собираю автоматику для курятника. Комплектация6 Ардуино Про мини, ЕСП-12 (для передачи данных на смартфон), ДХТ22 - конроль температуры и влажности, TM1637 - отображение температуры и влажности в самом помещении, 2-х канальный (самодельный) семисторный диммер с отслеживанием ноля, по классической схеме. Один канал (без диммирования) на включение вентилятора, второй(с диммированием) - для плавного включения красной обогревательной лампы.
Для диммирования был взят, доработан под себя и отдельно обкатан такой код:
[code]
#include <CyberLib.h> //Библиотека от Cyber-Place.ru
volatile uint8_t tic, Dimmer1, Dimmer2, Dimmer3;
uint8_t data;
int DimRandom=10; //Переменная для хранения максимального значения яркости Диммера (0 макс/200-мин, 255-выключено)
int DimRandomOld = 255; //Переменная для хранения минимального значения яркости Диммера
void setup()
{
D11_Out; //Настраиваем порты на выход
D11_Low; //установить на выходах низкий уровень сигнала
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
StartTimer1(halfcycle, 40); //время для одного разряда ШИМ
StopTimer1(); //остановить таймер
UART_Init(115200); //инициализация порта
}
//********************обработчики прерываний*******************************
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if(Dimmer1 < tic ) D11_High; //управляем выходом
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic=0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
D11_Low; //логический ноль на выходы
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
//*************************************************************************
void loop()
{ Start
//DimRandom = random(15, 200);
//if (DimRandom > DimRandomOld)
//{
//for (int i = DimRandomOld; i < DimRandom+1; i++)
//{
//Dimmer1 = i;
//delay (10);
//}
//}
if (DimRandom < DimRandomOld)
{
for (int i = DimRandomOld; i > DimRandom-1; i--)
{
Dimmer1 = i;
//delay (10);
}
}
//DimRandomOld = DimRandom;
End
}
[/code]
Здесь все работает. я даже смирился с функцией delay в обработчике увеличения яркости.
У attachInterrupt уровень может быть не только LOW/HIGH , но и CHANGE.
И?
Потом я разместил этот код в уже рабочую, отлаженную программу автоматики (вместо симисторов раньше я использовал реле).
Скетч компилируется без ошибок, но устройство не работает. Даже индикатор ТМ1637 не загорается. Но если закоментировать эту строчку
// attachInterrupt(0, detect_up, FALLING); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
то устройство запускается и работает. Естественно плавного пуска подогрева не происходит. Помогите разобраться в чем дело. Уже пять вечеров и ночей пытаюсь разобраться - не получается. Вот сам код:
не успел дописать пост
У attachInterrupt уровень может быть не только LOW/HIGH , но и CHANGE.
Я брал готовый код, переделал под себя, обкатал на готовом устройстве с подключенными нагрузками и датчиками. Все работало.
Я вам просто сообщаю. А то вы в обработчике начинаете вытворять странные вещи. К добру такой подход не приводит.
Я вам просто сообщаю. А то вы в обработчике начинаете вытворять странные вещи. К добру такой подход не приводит.
Какие именно вещи? Ткните носом.
Переназначать прерывания, например.
Ткните носом.
Тыкаю. Ошибки в строках №№ ХЗ, ХЗ и ХЗ.
А теперь сходите в песочницу, научитеь нормально вставлять код и тогда только возвращайтесь.
Вот, блин, ведь в окне сообщения есть красная иконка с надписью code. Неужели она ни о чём не говорит?
Переназначать прерывания, например.
Подскажите, что именно и где сделать. В программировании не силен. Нахожу похожие коды под свои задачи и переделываю под себя. Переделываю интуитивно, методом проб и ошибок.
Ткните носом.
Тыкаю. Ошибки в строках №№ ХЗ, ХЗ и ХЗ.
А теперь сходите в песочницу, научитеь нормально вставлять код и тогда только возвращайтесь.
Вот, блин, ведь в окне сообщения есть красная иконка с надписью code. Неужели она ни о чём не говорит?
Извините, не разобрался с интерфейсом.
Переназначать прерывания, например.
Подскажите, что именно и где сделать. В программировании не силен. Нахожу похожие коды под свои задачи и переделываю под себя. Переделываю интуитивно, методом проб и ошибок.
Вы меня уж извинте, но курятники - не мой конек. Тем более под Новый Год. И в таких объемах кода. Просто можно два обработчика в одном сделать, а не ставить себе ловушки. Вот и все, что я хотел написать.
Ну, вот, теперь хоть обсуждать можно, а то ведь без номеров строк как разговаривать-то
Манипулровать векторами прерывания из прерываний, конечно, можно, но надо очень хорошо понимать что именно происходит.
чтобв не усложнять себе жизнь, обычно это делается один раз в начале, а потом их не трогаюи.
И перезалейте ваш код согласно правилам форума. Если вы хотите что бы вам помогли - не усложняйте задачу помогающим.
курятник это хорошо, пожалуй подскажу что знаю:
1. научитесь вставлять код правильно, так читать его никто не будет (в верхнейчати окошка есть две скобки красные , жмем туда и вставляем код)
2. я тоже пользуюсь библиотекой киберлиб, меня она устраивает. но у нее есть свои недостатки
- при работе с димером она ачень сильно грузит контроллер это представьте себе за одну секунду период полуволны =100 прерываний ,и между каждым прерыванием вызывается еще 256 прерываний от внутреннего таймера. и того получается что на остальную работу не так уж и много времени остается., а еще если в прерывание запихнуть код подлиннее (что тоже нельзя) то все встает колом. Проверино на практике (собрал уравление электро двигателем с поддержанием оборотов-не работает).
поэтому я понял что эту кучу прерываний я вывел в отдельный микроконтроллер, я использую мини на 168 меге тоит 90 рублей + готовый Wire протокол для связи. но можно любой другой контроллер и соединить хоть по сериалу хоть по любому другому протоколу. так что не мучайте код толком он не заработает. могу выложить код для диммера, если нужен на 168мегу
Так основной код программы я перезалил. Или опять что-то не правильно?
так правильно, я пока писал меня опередили))
курятник это хорошо, пожалуй подскажу что знаю:
1. научитесь вставлять код правильно, так читать его никто не будет (в верхнейчати окошка есть две скобки красные , жмем туда и вставляем код)
2. я тоже пользуюсь библиотекой киберлиб, меня она устраивает. но у нее есть свои недостатки
- при работе с димером она ачень сильно грузит контроллер это представьте себе за одну секунду период полуволны =100 прерываний ,и между каждым прерыванием вызывается еще 256 прерываний от внутреннего таймера. и того получается что на остальную работу не так уж и много времени остается., а еще если в прерывание запихнуть код подлиннее (что тоже нельзя) то все встает колом. Проверино на практике (собрал уравление электро двигателем с поддержанием оборотов-не работает).
поэтому я понял что эту кучу прерываний я вывел в отдельный микроконтроллер, я использую мини на 168 меге тоит 90 рублей + готовый Wire протокол для связи. но можно любой другой контроллер и соединить хоть по сериалу хоть по любому другому протоколу. так что не мучайте код толком он не заработает. могу выложить код для диммера, если нужен на 168мегу
Для управления вентилятором, у меня в канале управления тиристором стоит птрон МОС3041, со встроенным детектором ноля. Ина нем прерывания не нужны. Такой же оптрон я могу поставить на нагревательную лампу - это обеспечит минимальную защиту нити накала и продлит срок службы. Я только по этой причине и хочу сделать плавный пуск лампы, потому, что когда она управлялась реле -за сезон вышли из строя 2 лампы.
За код - буду благодарен. Может когда пригодится.
Тогда поставим вопрос так - если в канале диммера использовать оптрон МОС3041( со встроенным детектором ноля), избавить код от прерываний - пусть этим занимается оптрон. Можно будет реализовать подобие плавного пуска?
С зависшей программой, при включении прерывания, проблема была. Вытащил из setup (109 строка) и перенес в конец loop, запускается ессно один раз через флаг. Все работает. Почему помогло, не знаю, чессно, может старшие товарищи объяснят.
Интересные эффекты бывают если не сделать INPUT_PULLUP и забыть подтянуть штаны.
код для двух димеров
один можно выбросить или просто игнорить
Интересные эффекты бывают если не сделать INPUT_PULLUP и забыть подтянуть штаны.
2 пин подтянут к +5В резистором на плате с диммером
С зависшей программой, при включении прерывания, проблема была. Вытащил из setup (109 строка) и перенес в конец loop, запускается ессно один раз через флаг. Все работает. Почему помогло, не знаю, чессно, может старшие товарищи объяснят.
Перенес строку 109 на 245. Залил скетч. Схема запустилась - лампа зажглась без диммирования, Индикатор завис на показаниях влажности, точка вай фай поднялась, но приложение на смартфоне подключиться не может.
Вы ее от повторных обращений заблокировали?
Вы ее от повторных обращений заблокировали?
Как это сделать?
Примерно так:
я не понял что и куда вы перенесли в коде, но похоже что не заработает диммер и какая разница где прервание будет задаваться
Примерно так:
Сделал так ( это стоит в конце loop)
Не помогло. Все как в предыдущий раз.
Значит не судьба.((((
Спасибо.
тут незнаю что вы ходели но похоже на бред
тут незнаю что вы ходели но похоже на бред
Почему бред?
При наступлении события ( средняя вычисленная температура ниже установленного значения), запускается плавный пуск (диммирование).
Вэтом коде все работало как надо.
апотом что тут происходит?
DimMin = DimMax;
и что произойдет при второс заходе в эту функцию?
апотом что тут происходит?
DimMin = DimMax;
и что произойдет при второс заходе в эту функцию?
если не будет этой строчки, лампа циклично плавно зажигается и резко гаснет. А с этой строчкой - просто продолжает светиться.
Тогда поставим вопрос так - если в канале диммера использовать оптрон МОС3041( со встроенным детектором ноля), избавить код от прерываний - пусть этим занимается оптрон. Можно будет реализовать подобие плавного пуска?
можно вот так сделать, добавить флаг, в верху обьявить как boolean flag = true;
можно вот так сделать, добавить флаг, в верху обьявить как boolean flag = true;
это с учетом установки оптрона МОС3041?
Тогда поставим вопрос так - если в канале диммера использовать оптрон МОС3041( со встроенным детектором ноля), избавить код от прерываний - пусть этим занимается оптрон. Можно будет реализовать подобие плавного пуска?
Каким образом это сделать?
нет в схеме ничего не меняйте, только код, и закоментируйте это странное присвоение минимума к максимуму
в верху обьявить как boolean flag = true;
нет в схеме ничего не меняйте, только код, и закоментируйте это странное присвоение минимума к максимуму
в верху обьявить как boolean flag = true;
Происходит следующее:
Сначала лампа включается резко, горит секунд 5, потом гаснет. Потом плавно зажигается, секунды 3 и гаснет на это же время. Индикатор висит на показаниях влажности.
Делать диммер по такому алгоритму как у вас это изваращение. Вот нормальная реализация - https://playground.arduino.cc/Main/ACPhaseControl
Для линейной регулировки мощности обогрева в OCR1A надо заносить не напрямую, а использую заранее рассчтанную таблицу. Но можно и без этого обойтись
Делать диммер по такому алгоритму как у вас это изваращение. Вот нормальная реализация - https://playground.arduino.cc/Main/ACPhaseControl
Для линейной регулировки мощности обогрева в OCR1A надо заносить не напрямую, а использую заранее рассчтанную таблицу. Но можно и без этого обойтись
Я попробую использовать код из вашего примера у себя в программе. но он очень похож на код из первого поста. И схема диммера такая-же. Суть в том (повторю), что скетч только диммера (из первого поста) работает без замечаний. Но стоит его внедрить в программу автоматики, и эта программа зависает.
пробуем так, должно работать
я ошибся в условии должно быть так else if (ave_t.mean()> hotTemp +1)
уже исправил. так что перезалейте. а по поводу моего кода да он похож, но я понял что контроллер не успевает все делать поэтому и разделил задачи один контролирует диммерну или сразу несколько димеров а второй все остальное и в том чесле говорит как работать диммеру
Без изменений.
На сегодня эксперементов хватит. Всем спаибо! До завтра.
Отладка методом тыканья палкой в сено. Интересно даже - как долго продолжится и чем закончится.