Временные задержки. Да, опять)
- Войдите на сайт для отправки комментариев
Представим, что есть следующая задача: выполнять некое действие в течение трёх секунд с перерывом в 7 секунд.
Придумал я, значит, вот такую конструкцию:
(cm-current millis, pm-previous millis, prValue - previous value и тд)
void prCalibration() //калибровка фоторезистора { prValue = analogRead(0); if ((calibrationInterval < (cm - pmCalibration)) && ((cm - pmCalibration) < (calibrationInterval + calibrationTime))) { if (prValue < prPrevValue - calibrationRounding || prPrevValue + calibrationRounding < prValue) //отбрасываем значения с фоторезистора в пределах точности, чтобы устранить дребезг { Serial.print(prValue); Serial.print(" записано в массив под номером "); Serial.println(prCounter); calibrationArray[prCounter] = prValue; prPrevValue = prValue; prCounter++; } } if ((cm - pmCalibration) == (calibrationInterval + calibrationTime)) { Serial.println("Начинаю считать среднее..."); pmCalibration = cm; prMinValue = 1023; prMaxValue = 0; for (int i = 0; i <= (prCounter - 1); i++) { if (calibrationArray[i] < prMinValue) { prMinValue = calibrationArray[i]; } if (calibrationArray[i] > prMaxValue) { prMaxValue = calibrationArray[i]; } } Serial.print("Минимальное значение подачи "); Serial.println(prMinValue); Serial.print("Максимальное значение подачи "); Serial.println(prMaxValue); prAdjustedValue = (prMinValue + prMaxValue) / 2; Serial.print("Среднее значение подачи "); Serial.println(prAdjustedValue); prCounter = 0; } }
То есть тело условия работает тогда, когда текущее millis находится в пределах от 7 до 10 секунд (calibrationInterval (7) + calibrationTime (3)).
А когда millis равно 10 секундам - происходит подсчёт, присвоение pmCalibration = cm и всё остальное очень нужное.
Всё работает, вот только через раз... Как я понял, иногда МК просто не обрабатывает эту строку тогда, когда millis равно 10000 мс. В итоге программа просто останавливается.
Внимание, вопрос. Можно ли как-то приложить в этой конструкции подорожник, или всё же нужно использовать RTC?
Вопрос два, как раз по поводу RTC. Вот хочу я в 14:42:55 выполнить какое-то действие.
Если я просто напишу
if (dt.hour == 14 && dt.minute == 42 && dt.second == 55)
то условие будет выполняться всю секунду. Приходится начинать городить флаги, чтобы условие выполнилось только один раз
if (dt.hour == 14 && dt.minute == 42 && dt.second == 55 && flag == 0) { .... flag = 1 }
а потом еще придумать как бы его сбросить на 0.
Есть способ получше?
Вопрос номер три: в первом блоке кода видно такой массив calibrationArray[]. Количество элементов в нём неизвестно и каждый цикл замеров разное.
Так вот если я объявляю его int calibrationArray[6], то в массив запишется всего 10 значений в ячейки от 0 до 9. Если объявить calibrationArray[]={0}, то запишется всего 6 значений в ячейки от 0 до 5. В итоге объявляю его как calibrationArray[999] и всё работает, но резервировать столько памяти на массив - совсем не по фен-шую. Что я делаю не так?
RTC тут не надо. Если стоит задача делать что-то 3 секунды с промежутком в 7 секунд, то один из вариантов - ниже:
Полежал, подумал, и понял, что достаточно будет просто в строке if ((cm - pmCalibration) == (calibrationInterval + calibrationTime)) поменять == на >. И тогда по первому вопросу всё ясно. Осталось еще два.
DIYman, Ваша конструкция по смыслу такая же, разве что применён switch-case и у меня все интервалы заменены переменными.
Полежал, подумал, и понял, что достаточно будет просто в строке if ((cm - pmCalibration) == (calibrationInterval + calibrationTime)) поменять == на >. И тогда по первому вопросу всё ясно. Осталось еще два.
DIYman, Ваша конструкция по смыслу такая же, разве что применён switch-case и у меня все интервалы заменены переменными.
Вопрос два, как раз по поводу RTC. Вот хочу я в 14:42:55 выполнить какое-то действие.
В нормальном RTC есть Alarm, который может дёрнуть МК за пин внешнего прерывания. В обработчике взводите флаг, в лупе по обнаружению взведенного флага кормите рыб и флаг сбрасываете. По необходимости переставляете Alarm на новое время.
Со вторым просто - флаг сбрасывать когда не выполняется
if
(dt.hour == 14 && dt.minute == 42 && dt.second == 55)
, собственно просто по else.По 3 вопросу. Можна делать и динамический массив, но и там на момент обявления нужно знать размер. Если же принципиально не известно кол-во элементов то вместо массива делают список, под каждый новый элемент память выделяют отдельно и связываютв цепочку через указатель.
К счастю для поиска среднего минимума и максимума массив не обязателен. Считайте их сразу по мере ввода, для среднего сумму накапливайте и кол-во измерений, потом поделите. Ну а минимум и максимум сразу и проверяйте для каждого введеного. Нет массива - нет проблемы.
Со вторым просто - флаг сбрасывать когда не выполняется
if
(dt.hour == 14 && dt.minute == 42 && dt.second == 55)
, собственно просто по else.Неа, так не получится) это лишь уполовинит время срабатываний условия за секунду. В первый круг р флаг взведется на 1, во второй круг флаг сбросится, и в третьем он снова попадет в условие)
"Нет массива-нет проблем" - это я почти сразу понял и выпилил его из кода. Но знать-то надо) И я удивлён, что нет возможности расширять массив. Я заподозрил неладное, когда он отказался объявить массив без размера и без элементов.
я удивлён, что нет возможности расширять массив. Я заподозрил неладное, когда он отказался объявить массив без размера и без элементов.
Привыкай, ты не в сказку попал, а в чёрное царство чесного С. Нету тут динамических массивов, пока сам не напишешь.
Странно это...
А как Вы вообще представляете себе "возможность расширять массив"? Вот, допустим, у Вас есть участок земли, окруженный такими же участками соседей. Как расширить свой участок, не затрагивая участков соседей?
Собственно, если нужна сущность аналогичная массиву, но допускающая возможность расширения, то она называется вектор. По аналогии с участком Вам просто выделят участок побольше в другом месте (и перенесут туда все Ваши постройки). Но это, естественно, за счет дополнительных накладных расходов. Приемлемо ли это для Вашей задачи - не знаю.
Занял массив 4 байта. Место кончилось. В другом месте выделяется еще 4 байта и на него даётся указатель, мол там-то хранится продолжение. По аналогии с фрагментацией файлов на носителях. Так представляю) Но, очевидно, есть какие-то проблемы с таким способом, раз он не реализован.
4 байта с указателем в 2 байта? Это сколько ж вам нужно памяти в МК...
Никто вам не мешает намахать свой TList. Писателю на Си - это как два пальца... поэтому никто не заморачивается насчет библиотек.
.del нуего нахрен
Со вторым просто - флаг сбрасывать когда не выполняется
if
(dt.hour == 14 && dt.minute == 42 && dt.second == 55)
, собственно просто по else.по else - это значит
if
(dt.hour != 14 || dt.minute != 42 || dt.second != 55)
не хочешь по елсе - сделай явно
if
(dt.second != 55)
flag = 0;Я всё понял.
Получится все. Смотрите, при проходах когда условие не выполняется (dt.hour == 14 && dt.minute == 42 && dt.second == 55) уходим на ветку else с присвоением flag=0. Как только условие выполнится первый раз то окажемся на проверке флага, он нулевой, делаем дело по времени и ставим флаг в 1. На else мы не попадаем. при следующем заходе снова условие (dt.hour == 14 && dt.minute == 42 && dt.second == 55) сработает, но проверка флага уже нет, флаг станет 0 только когда пройдет секунда.
Знать надо. Низкоуровневое программирование близко к материальному миру. Мы же не можем купить бутылку 0,5 прийти домой и расширить её до 3 литров ))) Так и здесь - выделили память, значить столько же её и будет. В высокоуровневых языках расширяемость массивов обясняется тем, что внутренние механизмы интерпретатора делают то, что я писал. Но хороше скрывают это от нас. А расплата - снижением скорости работы.
ок.
Спасибо вам, отзывчивые люди. Без вас научиться было бы куда сложнее.
Занял массив 4 байта. Место кончилось. В другом месте выделяется еще 4 байта и на него даётся указатель, мол там-то хранится продолжение. По аналогии с фрагментацией файлов на носителях. Так представляю) Но, очевидно, есть какие-то проблемы с таким способом, раз он не реализован.
Это называется список. Давно известная (и многократно реализованная) структура, нативно поддерживаемая С++. Если Вам не подходят массив и вектор, можете использовать список. Но по части расходуемых ресурсов он опережает их оба.
В общем, повторюсь: используйте то, что считаете наиболее удобным, вариантов - масса.
Массив у тебя на скока элементов? Меньше 256?
нууу смотря какой сглаживающий коэффициент поставить. Но обычно там порядка 20-60
нууу смотря какой сглаживающий коэффициент поставить. Но обычно там порядка 20-60
Фоторезистор-то чего делает? Может есть способ проще...