II. Таймер позволяет каждую секунду проверять не закончилась ли серия, а также позволяет выдержать задержку в N секунд.
Так я и спрашиваю нахера такие сложности!
Чего Вам так неймётся через жопу-то всё делать? ну, сядьте подумайте. СЛОВАМИ напишите, а не непонятными Вам значками! Оно ж делается тривиально, причём контроллер спит ВСЁ ВРЕМЯ, просыпаясь только для когда приходим импульс на несколько микросекунд. Проснулся, порабоал 2-3 микросекунды и снова спать завалися и делать-то ничего не надо. Там всё как два пальца!
Я могу Вам алгоритм написать, мне не трудно, только Вы ведь не отстанете пока Вам готовую программу не дадут (Вы уже привязались к человеку. чтобы он Вам "вопросики" заменял - а это уже написание готовой программы). А готовые программы здесь не пишут. По крайней мере, лично я писать не хочу, ни за деньги, ни за так. Шли бы Вы в "ищу исполнителя", там кто-нибудь возьмётся.
johnnie пишет:
Меня интересует всё, что заменит вопросительные знаки в коде.
Из заменяют в разделе "Ищу исполнителя", я Вам с самого начала про это талдычу.
С того, что Вы уже требуете Вам "вопросики" заменять.
Я прошу помощи, а не требую, потому что вашу ардуину я второй день "вижу". Вопросики я и сам заменю, там делов то в коде осталось, пшик. Тока не в форме я пока...рождество.
Для начала, давайте определимся. Надо воспользоваться тем фактом, что таймер №2 работает в POWER_SAFE режиме, сделать на нём самогонный миллис и при помощи его считать время. Самый дешёвый (в смысле необходимости просыпаться) способ сделать это – это считать время не в миллисекундах, а в неких попугаях. Попугай равен 16,384 миллисекунды. Надеюсь, что такой точности Вам хватит. Это как раз время переполнения этого таймера при макимальном делителе частоты (256 * 1024 / 16000 = 16,384)
Итак, мы сделали собственную функцию _millis(), которая возвращает количество переполнений таймера №2 (т.е. количество интервалов в 16,384 мс) с момента старта программы.
При этом таймер сконфигурирован так, что он считает количество переполнений. Собственно _millis() именно это посчитанное количество и возвращает. Контроллер просыпается по переполнению, увеличивает счётчик переполнений на 1, и тут же засыпает снова. Получается, что ради подсчёта времени, мы просыпаемся на "менее, чем 1 микросекунду" каждые 16384 микросекунды). Мне кажетсся. приемлемо
Если у нас уже есть такая _millis() , нам осталось описать переменные, сконфигурировать прерывание по поступившему импульсу и заснуть. Вся работа будет делаться в обработчике прерывания по импульсу.
Для сна используем режим POWER_SAVE – это самый экономный режим при котором таймер 2 ещё работает.
Пока всё понятно? Продолжу завтра.
Теперь заводим вде константы и две переменные
//
// время (в попугаях) между импульсами, после которого мы считаем,
// что это уже новая пачка сигналов, если меньше равно, то это новый
// сигнал текущей пачки
static const uint32_t sessionBreak = 1000;
//
// время (в попугаях) на которое нужно задерживать начало сессии
static const uint32_t delayTime = 5000;
//
// время (в попугаях) начала текущей пачки сигналов
static uint32_t startSession = 0;
//
// время (в попугаях) последнего зафиксированного сигнала
static uint32_t lastSignal = 0;
Надеюсь, они понятны.
Сейчас можно сделать важное уточнение. При создании механизма _millis о котором шла речь выше, необходимо начальное значение (которое бы выдавалось точно при старте программы) сделать не 0, а sessionBreak+1 !!! Это позволит понять, что самый первый сигнал, который мы получили - есть начало "пачки сигналов" без дополнительных проверок и бубнов.
Ну, собственно всё. Осталось написать обработчик прерывания по поступившему сигналу. Итак, когда поступил сигнал и мы проснулись, необходимо выполнить несколько простейших действий
if (digitalRead(IN_PIN)) { // если это начало сигнала, то провреям
if (_millis() - lastSignal > sessionBreak) { // если с последнего сигнала прошло много времени (это начало новой пачки)
startSession = _millis(); // фиксируем начало новой сессии
} else if (_millis() - startSession >= delayTime) { // Нет,это сигнал из текущей пачки. (тогда проверяем не истекло ли время задержки)
digitalWrite(OUT_PIN, HIGH); // если истекло, то дублируем сигнал
}
lastSignal = _millis(); // по-любому запоминаем время последнего сигнала
} else { // нет - это конец сигнала
digitalWrite(OUT_PIN, LOW); // тогда тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
}
а потом смело ложиться спать дальше.
надеюсь, комментарии достаточно поясняют суть дела?
Вот и всего делов. Котроллер спит практиески всё время, а не рисует лазером по целой секунде.
Ну, если всю жись - тогда чего у нас спрашиваете... Тут даже можно релюшкой щелкать, которая импульсы напрямую запустит в котел, через секунду после подлова фронта.
я бы так и сдел, там тогда кода на десяток-другой строк, и прерываний не надо
Чего там сложного? Таймер на прерывание по переполнению запустить? Ну, если для Вас это сложно, то сорри, конечно, ... Да, и , ... если Вам не нужно спать целыми секундами, так пожалуйста, я пытаюсь делать как Вы говорили, чтобы спасть всё время, а у Вас каждый раз требования меняются, то на стене рисовать, то ещё чего.
Для начала, давайте определимся. Надо воспользоваться тем фактом, что таймер №2 работает в POWER_SAFE режиме, сделать на нём самогонный миллис и при помощи его считать время. Самый дешёвый (в смысле необходимости просыпаться) способ сделать это – это считать время не в миллисекундах, а в неких попугаях. Попугай равен 16,384 миллисекунды. Надеюсь, что такой точности Вам хватит. Это как раз время переполнения этого таймера при макимальном делителе частоты (256 * 1024 / 16000 = 16,384)
Итак, мы сделали собственную функцию _millis(), которая возвращает количество переполнений таймера №2 (т.е. количество интервалов в 16,384 мс) с момента старта программы.
При этом таймер сконфигурирован так, что он считает количество переполнений. Собственно _millis() именно это посчитанное количество и возвращает. Контроллер просыпается по переполнению, увеличивает счётчик переполнений на 1, и тут же засыпает снова. Получается, что ради подсчёта времени, мы просыпаемся на "менее, чем 1 микросекунду" каждые 16384 микросекунды). Мне кажетсся. приемлемо
Если у нас уже есть такая _millis() , нам осталось описать переменные, сконфигурировать прерывание по поступившему импульсу и заснуть. Вся работа будет делаться в обработчике прерывания по импульсу.
Для сна используем режим POWER_SAVE – это самый экономный режим при котором таймер 2 ещё работает.
Пока всё понятно? Продолжу завтра.
Теперь заводим вде константы и две переменные
01
//
02
// время (в попугаях) между импульсами, после которого мы считаем,
03
// что это уже новая пачка сигналов, если меньше равно, то это новый
04
// сигнал текущей пачки
05
staticconstuint32_t sessionBreak = 1000;
06
//
07
// время (в попугаях) на которое нужно задерживать начало сессии
08
staticconstuint32_t delayTime = 5000;
09
//
10
// время (в попугаях) начала текущей пачки сигналов
11
staticuint32_t startSession = 0;
12
//
13
// время (в попугаях) последнего зафиксированного сигнала
14
staticuint32_t lastSignal = 0;
Надеюсь, они понятны.
Сейчас можно сделать важное уточнение. При создании механизма _millis о котором шла речь выше, необходимо начальное значение (которое бы выдавалось точно при старте программы) сделать не 0, а sessionBreak+1 !!! Это позволит понять, что самый первый сигнал, который мы получили - есть начало "пачки сигналов" без дополнительных проверок и бубнов.
Ну, собственно всё. Осталось написать обработчик прерывания по поступившему сигналу. Итак, когда поступил сигнал и мы проснулись, необходимо выполнить несколько простейших действий
01
if(digitalRead(IN_PIN)) { // если это начало сигнала, то провреям
02
if(_millis() - lastSignal > sessionBreak) { // если с последнего сигнала прошло много времени (это начало новой пачки)
03
startSession = _millis(); // фиксируем начало новой сессии
04
} elseif(_millis() - startSession >= delayTime) { // Нет,это сигнал из текущей пачки. (тогда проверяем не истекло ли время задержки)
05
digitalWrite(OUT_PIN, HIGH); // если истекло, то дублируем сигнал
06
}
07
lastSignal = _millis(); // по-любому запоминаем время последнего сигнала
08
} else{ // нет - это конец сигнала
09
digitalWrite(OUT_PIN, LOW); // тогда тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
10
}
а потом смело ложиться спать дальше.
надеюсь, комментарии достаточно поясняют суть дела?
Вот и всего делов. Котроллер спит практиески всё время, а не рисует лазером по целой секунде.
А что, там не описано чётко и однозначно, словами что и зачем надо делать? Или Вам непоянтно? Больше того, я даже псевдокод программы добавил для однозначности и понятности.
Это и всё, больше ничего не надо. Ваша задача решена полностью. нужно написать свой _millis (строк 10 - не более) и ту программу, что я привёл с подробнейшим описанием. Больше ничего делать не надо. Я же говорил, что там как "два пальца". Читайте комментарии в программе и текст топика - разбирайтесь.
Что Вы, Евгений! Этот вопрос исключительно ТС. Он так настойчиво требует алгоритм, что я начинаю сомневаться, что же это такое в понимании ТС. Особено в свете замены вопросиков строчками кода.
Зачем постоянно просыпаться и засыпать? Надо спать пока юзер не открыл кран, пока кран открыт не спать, когда кран закрыли уснуть.
Чего вы добились своей функцией?
Я добился того, что устройство "не спит" всего две с половиной секунды в сутки + по полмикросекунды на кажды импуьс. А сколько в Вашем варианте, скажем при 10 открытиях крана в сутки (а реально открывают больше)? В среднем кран открывается минут на пять (если зубы чистить или руки мыть, то на две минуты, а если душ принимать или посуду мыть, так и на все десять-двадцать). Т.е. в Вашем варианте устройство не спит примерно час в сутки, а реально больше, если три человека принимаю душ - уже минимум час только на это.
Вот этого я и добился.
johnnie пишет:
Какое максимальное время в секундах поместится в ваш милис?
Такое, как и в штатный. т.е. любое (с переходами). А если без переходов, в 16384 раза больше, чем в штатный.
johnnie пишет:
И что произойдет как он перейдет через ноль?
Ничего, будет работать дальше.
Впрочем, я Вам ничего не навязываю, делайте как хотите.
Ну, во-первых - это копипаста, а не понимание. А во-вторых, Вы за всех-то не расписывайтесь. Специалисты по алгоритмам используют определения Чёрча, Клини и Тьюринга на основе частично-рекурсивных функций. Позже Россер доказал, что все три подхода математически эквиваленты, и потому пофиг, что использовать.
Алгоритм программы в 32-м посте, которая, кстати, почти готова:
Основная программа:
Если МК не передаёт сигналы И не выдерживает паузу перед передачей, то уснуть и ждать изменений на входе.
При изменении на входе:
Если передача разрешена, то передать вход на выход, иначе Если это начало серии импульсов, то обнулить счетчик импульсов и запустить таймер с интервалом в 1 секунду, на изменения на входе не реагировать, только считать.
С интервалом в одну секунду:
Если импульсов за это время не было, то остановить передачу, не выдерживать паузу, остановить таймер и ждать изменений на входе, иначе считать кол-во секунд.
Если кол-во секунд равно заданной юзером паузе, то разрешить передачу и ждать изменений на входе.
Это не алгоритм, ему не хватает ясности и однозначности.
Читаю последние две фразы и сравниваю их с первой фразой "Если МК не занят передачей ..." и никак не могу въехать, когда же ему можно обратно на боковую? Обе последние фразы заканчиваются "начать реалировать ..." ... а спать-то когда? В этих фразах (первой и двух последних) используются разные слова (возможно,для одинаковых понятий), а потому ясности и однозначности у описания нет.
В итоге девайс включается в работу когда нужен, а всё остальное время спит. Его задача либо передавать, либо делать задержку в начала передачи. Во время этих 2-х своих основных задач, ему спать не следует.
Специалисты по алгоритмам используют определения Чёрча, Клини и Тьюринга на основе частично-рекурсивных функций. Позже Россер доказал, что все три подхода математически эквиваленты, и потому пофиг, что использовать.
Можно умничать как угодно, алгоритм - последовательность действий.
if(digitalRead(IN_PIN)) { // если это начало сигнала, то провреям
02
if(_millis() - lastSignal > sessionBreak) { // если с последнего сигнала прошло много времени (это начало новой пачки)
03
startSession = _millis(); // фиксируем начало новой сессии
04
} elseif(_millis() - startSession >= delayTime) { // Нет,это сигнал из текущей пачки. (тогда проверяем не истекло ли время задержки)
05
digitalWrite(OUT_PIN, HIGH); // если истекло, то дублируем сигнал
06
}
07
lastSignal = _millis(); // по-любому запоминаем время последнего сигнала
08
} else{ // нет - это конец сигнала
09
digitalWrite(OUT_PIN, LOW); // тогда тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
10
}
Нигде не уточнялось, что импульсы всегда начинаются с 1. Там датчик Холла, на каком уровне остановится - тот и будет полдня висеть. :))
ну а фраза "тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)" идиотская, как и постоянно выполняющаяся ненужная команда
Можно умничать как угодно, алгоритм - последовательность действий.
Для каждого своё определение. Для Вас одно,для меня - другое, для специалистов по алгоритмам - третье. так же как язык программирования. Уверен. что Вы понимаете под этим свосем не то. что я.
Ну вот, почти мой алгоритм реализован. Еще сравнить с предыдущим уровнем и прерываний не надо. И всё равно становиться - низкий уровень залип или высокий. Вот только не понял как сигнал дублируется. Чтоб сдублировать надо отправлять то что прочиталось. Уже наступали на эти грабли. Прерывание срабатывает и если читать сразу эту ногу, то можно прочитать любой уровень. Надо хотя бы пару микросекунд задержки, что бы это был правильный уровень.
Нигде не уточнялось, что импульсы всегда начинаются с 1.
А это не нужно. Всё работает без счётчика мипульсов,там же время считается. Зачем подить сущности без необходимости?
johnnie пишет:
ну а фраза "тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)" идиотская, как и постоянно выполняющаяся ненужная команда
Это одна команда. А если поставить проверку, то будет две. Что лучше всегда выполнять одну? Или две?
не вполне понимаю логический смысл всего действа
ведь понятно, что в N секенду может при разном потоке вписаться разный объем.
т.е. зачем здесь вообще фигурирует время, не проще ли и логичней пропускать ХХ импульсов вначале.
какой объем воды прошел не интересно, важно время открытия крана, на которое не должен реагировать котёл.
II. Таймер позволяет каждую секунду проверять не закончилась ли серия, а также позволяет выдержать задержку в N секунд.
Так я и спрашиваю нахера такие сложности!
Чего Вам так неймётся через жопу-то всё делать? ну, сядьте подумайте. СЛОВАМИ напишите, а не непонятными Вам значками! Оно ж делается тривиально, причём контроллер спит ВСЁ ВРЕМЯ, просыпаясь только для когда приходим импульс на несколько микросекунд. Проснулся, порабоал 2-3 микросекунды и снова спать завалися и делать-то ничего не надо. Там всё как два пальца!
Я могу Вам алгоритм написать, мне не трудно, только Вы ведь не отстанете пока Вам готовую программу не дадут (Вы уже привязались к человеку. чтобы он Вам "вопросики" заменял - а это уже написание готовой программы). А готовые программы здесь не пишут. По крайней мере, лично я писать не хочу, ни за деньги, ни за так. Шли бы Вы в "ищу исполнителя", там кто-нибудь возьмётся.
Меня интересует всё, что заменит вопросительные знаки в коде.
Из заменяют в разделе "Ищу исполнителя", я Вам с самого начала про это талдычу.
Я могу Вам алгоритм написать, мне не трудно
Напишите, я сам переведу в программу
только Вы ведь не отстанете пока Вам готовую программу не дадут
С чего вы взяли? Мне вспоминать ATMEL один день. А уж с ассемблера на С++ я как-нибудь перестроюсь.
Напишите, я сам переведу в программу
Хорошо, только уговор, Вы не вяжетесь здесь с кусками программы после этого.
только Вы ведь не отстанете пока Вам готовую программу не дадут
С чего вы взяли?
С того, что Вы уже требуете Вам "вопросики" заменять.
Чего Вам так неймётся через жопу-то всё делать? ну, сядьте подумайте...
...в разделе "Ищу исполнителя"
В чем жопа? Время считается отдельно от ядра, сигналы обрабатываются тогда, когда поступают. MK свободен, хоть на стене лазером рисуй.
Сяду подумать, когда новогодний марафон закончится :)
хватит намекать мне про бабло, всегда сам делал и сейчас сам сделаю, приехала бы поскорее ARDUINа
С того, что Вы уже требуете Вам "вопросики" заменять.
Я прошу помощи, а не требую, потому что вашу ардуину я второй день "вижу". Вопросики я и сам заменю, там делов то в коде осталось, пшик. Тока не в форме я пока...рождество.
Хорошо, только уговор, Вы не вяжетесь здесь с кусками программы после этого.
В 4-м сообщении так и сказал.
Давай
Для начала, давайте определимся. Надо воспользоваться тем фактом, что таймер №2 работает в POWER_SAFE режиме, сделать на нём самогонный миллис и при помощи его считать время. Самый дешёвый (в смысле необходимости просыпаться) способ сделать это – это считать время не в миллисекундах, а в неких попугаях. Попугай равен 16,384 миллисекунды. Надеюсь, что такой точности Вам хватит. Это как раз время переполнения этого таймера при макимальном делителе частоты (256 * 1024 / 16000 = 16,384)
Итак, мы сделали собственную функцию _millis(), которая возвращает количество переполнений таймера №2 (т.е. количество интервалов в 16,384 мс) с момента старта программы.
При этом таймер сконфигурирован так, что он считает количество переполнений. Собственно _millis() именно это посчитанное количество и возвращает. Контроллер просыпается по переполнению, увеличивает счётчик переполнений на 1, и тут же засыпает снова. Получается, что ради подсчёта времени, мы просыпаемся на "менее, чем 1 микросекунду" каждые 16384 микросекунды). Мне кажетсся. приемлемо
Если у нас уже есть такая _millis() , нам осталось описать переменные, сконфигурировать прерывание по поступившему импульсу и заснуть. Вся работа будет делаться в обработчике прерывания по импульсу.
Для сна используем режим POWER_SAVE – это самый экономный режим при котором таймер 2 ещё работает.
Пока всё понятно? Продолжу завтра.
Теперь заводим вде константы и две переменные
Надеюсь, они понятны.
Сейчас можно сделать важное уточнение. При создании механизма _millis о котором шла речь выше, необходимо начальное значение (которое бы выдавалось точно при старте программы) сделать не 0, а sessionBreak+1 !!! Это позволит понять, что самый первый сигнал, который мы получили - есть начало "пачки сигналов" без дополнительных проверок и бубнов.
Ну, собственно всё. Осталось написать обработчик прерывания по поступившему сигналу. Итак, когда поступил сигнал и мы проснулись, необходимо выполнить несколько простейших действий
а потом смело ложиться спать дальше.
надеюсь, комментарии достаточно поясняют суть дела?
Вот и всего делов. Котроллер спит практиески всё время, а не рисует лазером по целой секунде.
MK свободен, хоть на стене лазером рисуй.
Так спать надо или лазером на стене рисовать? Не понял задачи! Вы уж в показаниях-то не путайтесь!
Понятно, а алгоритм где?
Мы не капиталисты и МК не эксплуатируем, пусть спит.
Ну, если всю жись - тогда чего у нас спрашиваете... Тут даже можно релюшкой щелкать, которая импульсы напрямую запустит в котел, через секунду после подлова фронта.
я бы так и сдел, там тогда кода на десяток-другой строк, и прерываний не надо
я бы так и сдел, там тогда кода на десяток-другой строк, и прерываний не надо
там сложнее, чем секунда после "подлова фронта"
предложите алгоритм?
А вам моего не хватает? Или обязательно надо через прерывания?
А можно спросить, у тебя Ардуино, или самодельная плата? А то тебе сейчас наговорят про энергосбережение, а оно тебе нафиг не нужно.
Понятно, а алгоритм где?
А что, моя фраза
там сложнее, чем секунда после "подлова фронта"
Чего там сложного? Таймер на прерывание по переполнению запустить? Ну, если для Вас это сложно, то сорри, конечно, ... Да, и , ... если Вам не нужно спать целыми секундами, так пожалуйста, я пытаюсь делать как Вы говорили, чтобы спасть всё время, а у Вас каждый раз требования меняются, то на стене рисовать, то ещё чего.
Извините, а алгоритм, обещанный, где?
Это?:
Для начала, давайте определимся. Надо воспользоваться тем фактом, что таймер №2 работает в POWER_SAFE режиме, сделать на нём самогонный миллис и при помощи его считать время. Самый дешёвый (в смысле необходимости просыпаться) способ сделать это – это считать время не в миллисекундах, а в неких попугаях. Попугай равен 16,384 миллисекунды. Надеюсь, что такой точности Вам хватит. Это как раз время переполнения этого таймера при макимальном делителе частоты (256 * 1024 / 16000 = 16,384)
Итак, мы сделали собственную функцию _millis(), которая возвращает количество переполнений таймера №2 (т.е. количество интервалов в 16,384 мс) с момента старта программы.
При этом таймер сконфигурирован так, что он считает количество переполнений. Собственно _millis() именно это посчитанное количество и возвращает. Контроллер просыпается по переполнению, увеличивает счётчик переполнений на 1, и тут же засыпает снова. Получается, что ради подсчёта времени, мы просыпаемся на "менее, чем 1 микросекунду" каждые 16384 микросекунды). Мне кажетсся. приемлемо
Если у нас уже есть такая _millis() , нам осталось описать переменные, сконфигурировать прерывание по поступившему импульсу и заснуть. Вся работа будет делаться в обработчике прерывания по импульсу.
Для сна используем режим POWER_SAVE – это самый экономный режим при котором таймер 2 ещё работает.
Пока всё понятно? Продолжу завтра.
Теперь заводим вде константы и две переменные
01
//
02
// время (в попугаях) между импульсами, после которого мы считаем,
03
// что это уже новая пачка сигналов, если меньше равно, то это новый
04
// сигнал текущей пачки
05
static
const
uint32_t sessionBreak = 1000;
06
//
07
// время (в попугаях) на которое нужно задерживать начало сессии
08
static
const
uint32_t delayTime = 5000;
09
//
10
// время (в попугаях) начала текущей пачки сигналов
11
static
uint32_t startSession = 0;
12
//
13
// время (в попугаях) последнего зафиксированного сигнала
14
static
uint32_t lastSignal = 0;
Надеюсь, они понятны.
Сейчас можно сделать важное уточнение. При создании механизма _millis о котором шла речь выше, необходимо начальное значение (которое бы выдавалось точно при старте программы) сделать не 0, а sessionBreak+1 !!! Это позволит понять, что самый первый сигнал, который мы получили - есть начало "пачки сигналов" без дополнительных проверок и бубнов.
Ну, собственно всё. Осталось написать обработчик прерывания по поступившему сигналу. Итак, когда поступил сигнал и мы проснулись, необходимо выполнить несколько простейших действий
01
if
(digitalRead(IN_PIN)) {
// если это начало сигнала, то провреям
02
if
(_millis() - lastSignal > sessionBreak) {
// если с последнего сигнала прошло много времени (это начало новой пачки)
03
startSession = _millis();
// фиксируем начало новой сессии
04
}
else
if
(_millis() - startSession >= delayTime) {
// Нет,это сигнал из текущей пачки. (тогда проверяем не истекло ли время задержки)
05
digitalWrite(OUT_PIN, HIGH);
// если истекло, то дублируем сигнал
06
}
07
lastSignal = _millis();
// по-любому запоминаем время последнего сигнала
08
}
else
{
// нет - это конец сигнала
09
digitalWrite(OUT_PIN, LOW);
// тогда тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
10
}
а потом смело ложиться спать дальше.
надеюсь, комментарии достаточно поясняют суть дела?
Вот и всего делов. Котроллер спит практиески всё время, а не рисует лазером по целой секунде.
Извините, а алгоритм, обещанный, где?
А что, там не описано чётко и однозначно, словами что и зачем надо делать? Или Вам непоянтно? Больше того, я даже псевдокод программы добавил для однозначности и понятности.
Это и всё, больше ничего не надо. Ваша задача решена полностью. нужно написать свой _millis (строк 10 - не более) и ту программу, что я привёл с подробнейшим описанием. Больше ничего делать не надо. Я же говорил, что там как "два пальца". Читайте комментарии в программе и текст топика - разбирайтесь.
Вас что-то не устраивает?
Можно пытаться решить задачу чисто аппаратными средствами, используя например К561АГ1.
Скажите, а под алгоритмом вы понимаете текст программы или что-то другое?
К кому вопрос? Ко мне? В контексте данного форума, под алгоритмом я понимаю ясное и однозначное описание последовательности действий.
Что Вы, Евгений! Этот вопрос исключительно ТС. Он так настойчиво требует алгоритм, что я начинаю сомневаться, что же это такое в понимании ТС. Особено в свете замены вопросиков строчками кода.
Зачем постоянно просыпаться и засыпать? Надо спать пока юзер не открыл кран, пока кран открыт не спать, когда кран закрыли уснуть.
Чего вы добились своей функцией? В моем варианте время считается когда это нужно, а не всё время, и в секундах.
Какое максимальное время в секундах поместится в ваш милис? И что произойдет как он перейдет через ноль?
Зачем постоянно просыпаться и засыпать? Надо спать пока юзер не открыл кран, пока кран открыт не спать, когда кран закрыли уснуть.
Чего вы добились своей функцией?
Я добился того, что устройство "не спит" всего две с половиной секунды в сутки + по полмикросекунды на кажды импуьс. А сколько в Вашем варианте, скажем при 10 открытиях крана в сутки (а реально открывают больше)? В среднем кран открывается минут на пять (если зубы чистить или руки мыть, то на две минуты, а если душ принимать или посуду мыть, так и на все десять-двадцать). Т.е. в Вашем варианте устройство не спит примерно час в сутки, а реально больше, если три человека принимаю душ - уже минимум час только на это.
Вот этого я и добился.
Какое максимальное время в секундах поместится в ваш милис?
Такое, как и в штатный. т.е. любое (с переходами). А если без переходов, в 16384 раза больше, чем в штатный.
Ничего, будет работать дальше.
Впрочем, я Вам ничего не навязываю, делайте как хотите.
Скажите, а под алгоритмом вы понимаете текст программы или что-то другое?
Под словом алгоритм, я понимаю тоже что и все:
Под словом алгоритм, я понимаю тоже что и все:
Ну, во-первых - это копипаста, а не понимание. А во-вторых, Вы за всех-то не расписывайтесь. Специалисты по алгоритмам используют определения Чёрча, Клини и Тьюринга на основе частично-рекурсивных функций. Позже Россер доказал, что все три подхода математически эквиваленты, и потому пофиг, что использовать.
Алгоритм программы в 32-м посте, которая, кстати, почти готова:
Основная программа:
Если МК не передаёт сигналы И не выдерживает паузу перед передачей, то уснуть и ждать изменений на входе.
При изменении на входе:
Если передача разрешена, то передать вход на выход, иначе Если это начало серии импульсов, то обнулить счетчик импульсов и запустить таймер с интервалом в 1 секунду, на изменения на входе не реагировать, только считать.
С интервалом в одну секунду:
Если импульсов за это время не было, то остановить передачу, не выдерживать паузу, остановить таймер и ждать изменений на входе, иначе считать кол-во секунд.
Если кол-во секунд равно заданной юзером паузе, то разрешить передачу и ждать изменений на входе.
Это не алгоритм, ему не хватает ясности и однозначности.
Читаю последние две фразы и сравниваю их с первой фразой "Если МК не занят передачей ..." и никак не могу въехать, когда же ему можно обратно на боковую? Обе последние фразы заканчиваются "начать реалировать ..." ... а спать-то когда? В этих фразах (первой и двух последних) используются разные слова (возможно,для одинаковых понятий), а потому ясности и однозначности у описания нет.
В итоге девайс включается в работу когда нужен, а всё остальное время спит. Его задача либо передавать, либо делать задержку в начала передачи. Во время этих 2-х своих основных задач, ему спать не следует.
не хватает ясности и однозначности.
Исправил
Специалисты по алгоритмам используют определения Чёрча, Клини и Тьюринга на основе частично-рекурсивных функций. Позже Россер доказал, что все три подхода математически эквиваленты, и потому пофиг, что использовать.
Можно умничать как угодно, алгоритм - последовательность действий.
01
if
(digitalRead(IN_PIN)) {
// если это начало сигнала, то провреям
02
if
(_millis() - lastSignal > sessionBreak) {
// если с последнего сигнала прошло много времени (это начало новой пачки)
03
startSession = _millis();
// фиксируем начало новой сессии
04
}
else
if
(_millis() - startSession >= delayTime) {
// Нет,это сигнал из текущей пачки. (тогда проверяем не истекло ли время задержки)
05
digitalWrite(OUT_PIN, HIGH);
// если истекло, то дублируем сигнал
06
}
07
lastSignal = _millis();
// по-любому запоминаем время последнего сигнала
08
}
else
{
// нет - это конец сигнала
09
digitalWrite(OUT_PIN, LOW);
// тогда тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
10
}
Нигде не уточнялось, что импульсы всегда начинаются с 1. Там датчик Холла, на каком уровне остановится - тот и будет полдня висеть. :))
ну а фраза "
тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
" идиотская, как и постоянно выполняющаяся ненужная командаМожно умничать как угодно, алгоритм - последовательность действий.
Для каждого своё определение. Для Вас одно,для меня - другое, для специалистов по алгоритмам - третье. так же как язык программирования. Уверен. что Вы понимаете под этим свосем не то. что я.
Ну вот, почти мой алгоритм реализован. Еще сравнить с предыдущим уровнем и прерываний не надо. И всё равно становиться - низкий уровень залип или высокий. Вот только не понял как сигнал дублируется. Чтоб сдублировать надо отправлять то что прочиталось. Уже наступали на эти грабли. Прерывание срабатывает и если читать сразу эту ногу, то можно прочитать любой уровень. Надо хотя бы пару микросекунд задержки, что бы это был правильный уровень.
Нигде не уточнялось, что импульсы всегда начинаются с 1.
А это не нужно. Всё работает без счётчика мипульсов,там же время считается. Зачем подить сущности без необходимости?
ну а фраза "
тупо дублируем его в линию (даже, если мы не дублировали начало - хуже не будет)
" идиотская, как и постоянно выполняющаяся ненужная командаЭто одна команда. А если поставить проверку, то будет две. Что лучше всегда выполнять одну? Или две?