Не могу избавиться от delay.
- Войдите на сайт для отправки комментариев
Чт, 26/07/2018 - 10:06
Здравствуйте. Перенес тему в данный раздел. До этого тема было создана в разделе проекты.
Помогите избавиться от delay.
Из за delay пропускаю сигнал с сенсора подключенного к 4 пину.
#define start 2 // Кнопка старт. #define fault 3 // Аварийная кнопка. #define sensor 4 // Пауза long previousMillis = 0; int startbuttonState = 0; int faultbuttonState = 0; int sensorState = 0; // Таймер для стартовой скорости. int timerstart = 0; int timerstartval = 0; // переменная для хранения считываемого значения int timerstartvalmap = 0; // Скорость статровой скорости. int speedstart = 1; int speedstartval = 0; // переменная для хранения считываемого значения int speedstartvalmap = 0; // Таймер для скорости укладывания. int timersecond = 2; int timersecondval = 0; // переменная для хранения считываемого значения int timersecondvalmap = 0; // Скорость укладывания int speedsecond = 3; int speedsecondval = 0; // переменная для хранения считываемого значения int speedsecondvalmap = 0; // Таймер для скорости возврата. int timerback = 4; int timerbackval = 0; // переменная для хранения считываемого значения int timerbackvalmap = 0; // Скорость возврата. int speedback = 5; int speedbackval = 0; // переменная для хранения считываемого значения int speedbackvalmap = 0; // Таймер для паузы. int timerpause = 6; int timerpauseval = 0; // переменная для хранения считываемого значения int timerpausevalmap = 0; int pwmOut = 11; void setup() { pinMode(pwmOut, OUTPUT); pinMode(start, INPUT); } void loop() { //таймер стартовой скорости timerstartval = analogRead(timerstart); // считываем значение timerstartvalmap = map(timerstartval, 0, 1023, 0, 2000); //стартовая скорость speedstartval = analogRead(speedstart); // считываем значение speedstartvalmap = map(speedstartval, 0, 1023, 0, 255); //таймер скорости укладвания timersecondval = analogRead(timersecond); // считываем значение timersecondvalmap = map(timersecondval, 0, 1023, 0, 2000); //скорость укладывания speedsecondval = analogRead(speedsecond); // считываем значение speedsecondvalmap = map(speedsecondval, 0, 1023, 0, 255); //таймер скорости возврата timerbackval = analogRead(timerback); // считываем значение timerbackvalmap = map(timerbackval, 0, 1023, 0, 3000); //скорость возврата speedbackval = analogRead(speedback); // считываем значение speedbackvalmap = map(speedbackval, 0, 1023, 0, 255); //таймер паузы timerpauseval = analogRead(timerpause); // считываем значение timerpausevalmap = map(timerpauseval, 0, 1023, 0, 5000); startbuttonState = digitalRead(start); faultbuttonState = digitalRead(fault); sensorState = digitalRead(sensor); if (startbuttonState == HIGH && faultbuttonState == LOW) { // При нажатии кнопки старт. Задать ШИМ сигнал равный переменной speedstartvalmap analogWrite(pwmOut, speedstartvalmap); delay(timerstartvalmap); // По истечению времени таймера переменной timerstartvalmap. Задать ШИМ сигнал равный переменной speedsecondvalmap analogWrite(pwmOut, speedsecondvalmap); delay(timersecondvalmap); // По истечению времени таймера переменной timersecondvalmap. Задать ШИМ сигнал равный переменной speedbackvalmap analogWrite(pwmOut, speedbackvalmap); delay(timerbackvalmap); // Держать заданный ШИМ сигнал равный переменной speedbackvalmap до того момента как сенсор не увидит препятствие. analogWrite(pwmOut, 0); delay(timerpausevalmap); // Держать паузу таймера переменной timerpausevalmap } else { analogWrite(pwmOut, 0); } }
Не нужно избавляться от delay, нужно сразу писать программы без delay.
Нарисуйте блок схему Вашей нынешней программы.
Нарисуйте блок схему программы без delay.
Сравните эти две схемы и убедитесь, что они не имеют практически ничего общего.
Отсюда вывод: чтобы избавитьсяч от delay, нужно полностью переписать программу заново.
Можно оставить блок описания переменных (но все равно его придется редактировать) и функцию setup. А вот loop нужно переписывать полностью - в соответствии с новой блок-схемой.
Но, тут надо либо переписывать программу целиком, либо сделать самогонный delay и в нём читать дачтик (и, видимо, если что-то интересное прочиталось, то прерывать delay). Тогда просто всё delay заменить на этот самогонный.
... либо сделать самогонный delay ...
Вспомнилось, как пришлось заменять функцию ввода с клавиатуры BIOS на свою (в DOS-программе), чтобы двоеточие в часиках мигало, да и время показывалось текущее, а не время последнего нажатия на клавишу. В некоторых случаях - тоже вариант.
Можете показать небольшой пример? А дальше я постараюсь добраться до истины сам.
Это чтобы суть передать:
Самый простой путь обсуждали недавно. Делай имеет подрограмму уелд. Если в неё повесить копию строк 92, 113 и между ними if на sensorState то всё будет останавливаться сразу по сенсору, но всё равно ждать окончания делэй.
Можете показать небольшой пример? А дальше я постараюсь добраться до истины сам.
Чуть позже, сегодя. Заходите в тему. Сейчас не могу.
Все еще ни как не могу додумать)) как заставить держать ШИМ сигнал равной переменной speedbackvalmap до того момента пока не поступит сигнал на 4 пин.
Пробывал уже и так))
Вот пример самогонного delay. Испольуете вместо обычного и проверяете как она закончилась - по истечению интервала или по другому событию. В зависимости от этого что-то там у себя делаете.
Кстати, вопрос: for() вместо while() - это как чередование макарон и картошки в питании или всё же какой-то способ однозначно выигрышней в применении, которое выше проиллюстрированно?
Если честно не совсем понял. Я понимаю вы старались в коментарии все расписать но я что то совсем не могу сообразить как это работает.
но я что то совсем не могу сообразить как это работает.
А вы всегда себя на место комплюктора ставьте. Как бы вы действовали в заданных вами обстоятельствах?
Есть очень хорошее правило - "не расширяй область видимости без нужды". Здесь область видимости переменной start - до конца цикла, а в варианте
до конца функции
Можно, конечно, написать и так
но это как-то вычурно и надумано.
А вообще, я об этом (об областях видимости) не думаю. Я в программировании почти сорок лет - надумался уже - теперь само делается :)
Если честно не совсем понял. Я понимаю вы старались в коментарии все расписать но я что то совсем не могу сообразить как это работает.
А чего тут соображать? Выполняет строчку 8 снова и снова до тех пор пока интервал времени не истечёт.
Сейчас мое чудо работает так.
Задается ШИМ сигнал с переменной speedstartvalmap
держет ее опреденное количество времени из переменной timerstartvalmap
задает ШИМ сигнал с переменной speedsecondvalmap ждет истечение времени заданной перемменной timerbackvalmap
и задает ШИМ сигнал с переменной speedbackvalmap и по кругу. Не могу остановить на ШИМ сигнале равной speedbackvalmap до тех пор пока не придет сигнал с 4 пина и сбросить его на 0. Если попасть во время сигналом с 4 пина то могу задать ШИМ значением 0 и отправить его на delay.
Есть очень хорошее правило - "не расширяй область видимости без нужды". Здесь область видимости переменной start - до конца цикла, а в варианте
Ну, ежели оно всё равно в функции висит, то далеко видно не будет.
Значит это просто паттернализм. Я думал, что ускорение в пятьсот раз происходит или типа того.
Ну, ежели оно всё равно в функции висит, то далеко видно не будет.
Это общее правило и исполняется на уровне привычки не требуя нкаких умственных усилий. Так же, как и const везде, где можно.
const везде, где можно.
Почему компилятор не выдаёт никаких предупреждений на строку
Ведь маразм же? Такого сочетания не должно быть.
const везде, где можно.
Почему компилятор не выдаёт никаких предупреждений на строку
Ведь маразм же? Такого сочетания не должно быть.
Почему?
Каждый раз, встречая n в правой части оператора присваивания, процессор будет читать значение n из памяти, а не из регистра.
Ну, какая может быть волатильность у константы? Кто её может изменить, да ещё и "неожиданно"?
Ну, какая может быть волатильность у константы? Кто её может изменить, да ещё и "неожиданно"?
Было бы желание...
Ну, какая может быть волатильность у константы? Кто её может изменить, да ещё и "неожиданно"?
1- const это не константа, а нет записи в данном месте, только чтение.
2 volatile - это сигнал компилятору что это точно не константа типа define, найдутся "темные силы" на стороне и будут ее шатать(зачеркнуто) менять по своему желанию.
ПС: Компилятор считает константы перемемеными, но если в нее никакие силы не пишут ничего, то и выделять на нее память в ОЗУ нет необходимости. Пусть будет в памяти флеша, то есть константы.
Вы исходите из в общем-то правильного (во многих случаях), но сильно упрощённого понимания смысла ключевых слов const и volatile
Когда говорят, что (A) volatile означает, что переменная всегда хранится в памяти и к ней обеспечивается атомарный доступ, чаще всего это верно (хотя и не всегда - стандарт не устанавливает места её хранения). Также обычно верно то, что (Б) объект, описанный с применением const является константой. Но так пишут в книгах для начального изучения языка. На самом деле семантика этих слов куда глубже и "хранение в памяти" и "константность" – это следствие этой семантики, а вовсе не определение этих ключевых слов.
Если бы всё ограничивалось только (А) и (Б), то абсолютно не имели бы права на существование. Например, вот такие конструкции:
Ну, какое тут нафиг хранение в памяти и константность, если они void, да ещё и функции? В этом тривиальном случае они, конечно, никакого смысла не имеют, что написал - что нет (но допустимо). Однако, есть ситуации, когда такое сочетание не только допустимо, но и имеет смысл.
Чтобы закончить разговор, отмечу, что в стандарте ISO/IEC 14882:2017, в п. 10.1.7 (стр. 177) прямо указывается, что и volatile, и const совместимы с любыми спецификаторами типа, кроме самих себя.
(2.1) — const can be combined with any type specifier except itself.
(2.2) — volatile can be combined with any type specifier except itself.
А значит, совместимы и между собой (и с void), почему бы нет?
-------------------
Вот простой пример, когда "volatile const" неободимо.
Если написать функцию, типа такой
то ей можно передавать любой int, но ни в коем случае не volatile
Чтобы можно было передавать всё, что угодно, включая и volatile, надо слово volatile добавить в описание параметра
Теперь приведённый setup будет нормально компилироваться.
Это, конечно, "не про эффективность", но это пример, когда сочетание "volatile const" оправдано и без него не работает.
Когда говорят, что (A) volatile означает, что переменная всегда хранится в памяти и к ней обеспечивается атомарный доступ, чаще всего это верно (хотя и не всегда - стандарт не устанавливает места её хранения).
Стганно. По-моему если многобайтовую volatile переменную меняешь в прерывании, а читаешь в обычной процедуре, то бывает, что значения валят не те, пока на время чтения не запретишь прерывания. Я, правда, давно уже принудительно атомизирую такие фрагменты, но по первости наступал на такие грабли.
Т.е. volatile не обязательно означает, что компилятор к ней приделает атомарный доступ или мне приснилось?
Ну, я же писал, что «атомарный доступ» - упрощенный поход. На самом деле, как любят писать в фейсбучных статусах девочки-малолетки, – «всё сложно».
По конкретике без кода ничего не скажешь. Многобайтовые типы разные бывают. Даже между, скажем int n и uint8_t n2[2] – дистанция огромного размера в поведении const и volatile, а уж если там замешан union (или любая другая разновидность класса), то там вообще чёрт ногу сломит. Например, ни const, ни volatile не имеют никакого эффекта во время выполнения конструктора и деструктора (всей цепочки конструкторов и деструкторов). А если к ним добавить ещё и mutable (например, объект – const volatile, а его метод/свойство – mutable), то без поллитры там делать вообще нечего.
Да и в целом, эти вещи оставлены на откуп реализации («The semantics of an access through a volatile glvalue are implementation-defined» стр. 167). И там же изложены две цели для чего это вводилось: «volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation» и даже «for some implementations, volatile might indicate that special hardware instructions are required to access the object».
Давайте завязывать, разговор явно выходит за рамки ардуино. Если интересно, то см. стандарт С (С++ по семантике volatile отсылает к С). Сейчас, кстати, новый С вышел - ISO/IEC 9899:2018.
Никаких юнионов/массивов. Простой счетчик кол-ва прерываний на типе uint32_t.
Посмотрел стандарт С. Нашёл прямо пример про const volatile
В целом, понятно для чего это.
Никаких юнионов/массивов. Простой счетчик кол-ва прерываний на типе uint32_t.
Ну, я говорю, без кода непонятно, а так, см. п. 5.1.2.3 стандарта Си 2018-го года.