ещё можно чуть уменьшить количество вычислений в каждой итерации. Как то так ...
//проверяем не пора ли переключить
if(millis() > nextMillis ) {
// сохраняем время следующего переключения
nextMillis = millis() + INTERVAL;
Нельзя. Что в вашем варианте произойдет когда millis() пойдет к значению, скажем 4,294,967,000?
Ваше условие - начнет постоянно срабатывать. И "будет глючит" 295 миллисекунд подряд
я когда проверял перезаполнение (еще до этого поста) на С компиляторе то ничего страшного не происходит , всё он там правильно считает. и как предложил toc имеем место быть. или в ардуине компиляторе не так ? (я знаю что там тоже С но всётаки с небольшими изменениями)
я когда проверял перезаполнение (еще до этого поста) на С компиляторе то ничего страшного не происходит , всё он там правильно считает. и как предложил toc имеем место быть.
Я не знаю, что Вы проверяли, Вы же код не показываете. Но, так, как написал toc при переполнении работать не может, лешак прав 100%
alexbmd пишет:
или в ардуине компиляторе не так ? (
Это не свойство компилятора, это свойство арифметики в дополнительном коде и от компилятора не зависит.
unsigned long debounceTime = 4294967290 ; //4.294.967.295
unsigned long workTime = 4294967290; //
int main()
{
for (int i=0;i<26;i=i+5){
printf("%d =",i);
debounceTime = debounceTime + i;
unsigned long result = debounceTime - workTime;
printf("%lu ",result);
printf("\n");
}
}
вот только что набросал, нормальный результат выводит, не уходит в ошибку или минус или еще куда. да и тут это как то давно обсуждали говориличто компилятор понимает перезапуск перемной
unsigned long debounceTime = 4294967290 ; //4.294.967.295
unsigned long workTime = 4294967290; //
int main()
{
for (int i=0;i<26;i=i+5){
printf("%d =",i);
debounceTime = debounceTime + i;
unsigned long result = debounceTime - workTime;
printf("%lu ",result);
printf("\n");
}
}
вот только что набросал, нормальный результат выводит, не уходит в ошибку или минус или еще куда. да и тут это как то давно обсуждали говориличто компилятор понимает перезапуск перемной
Обратите внимание на строчку 9 - это и есть арифметика в дополнительном коде. Именно поэтому интервал рассчитывается корректно. Похоже, вы просто немного не понимаете, в чём дело. Тут столько копий уже сломано на теме переполнения беззнаковых переменных - может, стоит почитать, для начала? ;)
Эффект сильно зависит от опций и его трудно воспроизвести. Например, у меня в Avr студии получилось наоборот. Но, общая идея здесь в том, что всё зависит от дальнейшего использовании b. Дело в том, что в строке 22 оно должно быть int для взятия индекса. А в строке 24 оно может быть как int, так и bool для отрицания.
Если её объявить как byte - она везде int и никаких усилий не требуется, т.к. всё подходит, а если объявить как bool, то в строке №22 его нужно преобразовывать и компилятор оставляет преобразование на этап выполнения.
Чтобы убедиться в этом, можно явно пояснить компилятору, что ничего, кроме 0 и 1 там не будет. Для этого, например, в строке №20 можно заменить "bitRead(port,pin);" на "(port & bit(pin)) ? 1 : 0;". Попробуйте. Эффект уходит.
В зависимости от того bool у вас или byte, компилятор создает различный код. В первом случае предполагается, что в переменой b может быть либо ноль, либо не ноль (не принципиально что именно). На этом строятся дальнейшие проверки и использование b в качестве индекса массива сводится к взятию либо первого элемента (если b = 0), либо второго.
С byte дело обстоит иначе. Хранящееся в переменной b значение принципиально (по крайней мере в данном коде). И оно непосредственно участвует в вычислении адреса нужного элемента массива (индекс элемента * размер элементов ...). В итоге код уже отличается от генерируемого для bool.
В итоге код уже отличается от генерируемого для bool.
Осталось определиться в каком случае надо присваивать переменной тип bool а в каком byte
С этим компилятором настолько всё неоднозначно, к примеру снимаем ремарку с 24 строки, чтобы получить перед главным циклом правильное время начала цикла, а исполнимый код вместо увеличения становится на 22 байта короче ))) ...И как тут не быть ...
Если Вас так сильно интересует правильный выбор типа, то, Вы невнимательно читаете, я Вам уже писал, что операция взятия индекса требует int
Читал внимательно, но вот понять )))
Как в том анекдоте про дважды два - семь, восемь где-то так, ну не сорок жеж...
Да сейчас поставлю 1.8.9 проверю...
Это вы с кем сейчас разговаривали )))
Я же говорю, знал когда-то диаграмму состояний сплава железо-углерод, ВСЁ!!! Ардуино - хобби, одно из ...
Языком Ардуино, в отличии от остальных двух десятков разговорных не владею )))
С этим компилятором настолько всё неоднозначно, к примеру снимаем ремарку с 24 строки, чтобы получить перед главным циклом правильное время начала цикла, а исполнимый код вместо увеличения становится на 22 байта короче ))) ...И как тут не быть ...
Я бы предположил, что компилятор, встретив в очередной раз строку
previousMillis = millis();
, принял решение об оптимизации этого вызова за счет другого ресурса. Я попробовал добавить указанную строку не в setup, а в начале loop - эффект тот же: размер скомпилированного файла уменьшился.
Верю!!! Но как говорил DIMAX - UA6EM, если что-то имеет теоретическую возможность пойти не так, оно у Вас обязательно пойдёт не так, может хобби сменить )))
Верю!!! Но как говорил DIMAX - UA6EM, если что-то имеет теоретическую возможность пойти не так, оно у Вас обязательно пойдёт не так, может хобби сменить )))
принял решение об оптимизации этого вызова за счет другого ресурса. Я попробовал добавить указанную строку не в setup, а в начале loop - эффект тот же: размер скомпилированного файла уменьшился.
Ясно, компилятор писали выходцы из СССР...только у нас решение принимется после третьего наступления ногой на грабли )))
вообще то я о другом говорил, о ценности каждой капли знаний )))
Вот и я об этом. Говорите яснее, а не высоким стилем=языком метафор. А то Вам ответят метафорой и эта капля знаний утонет в метафоре. https://youtu.be/FZr4MEAOXWI?t=2151 Ну да много времени для просмотра.
в обсуждаемом варианте мигания да и в 99% остальных
if (millis() - t > 150S){
//инвертируем диод
t = millis();
}
первый интервал (в даном случае 150 с) мы получается ничего не делаем. а тут возникла необходимость сразу заинвертировать , ну и потом дальше как обычно через заданный интервал. без дополнительной проверки дополнительной переменной не придумал как реализовать.
а можно ли как то не вводя дополнительных переменных сделать чтоб мигание сразу начиналось ?
А какие соображения вынуждают Вас избегать записи в порт?
if хоть каплю но быстрее чем direct port manipulation
Разве?
Порт находится в общем адресном пространстве и работа с ним ничем не отличается от работы с ячейкой памяти.
Если мы используем if, то с чем мы его используем? Наверняка выделяем в памяти ячейку, в которой содержится информация, следует писать в порт или нет. Работа с этой ячейкой ничуть не быстрее, чем работа с самим портом. Да еще и лишний if... А если окажется, что нужно писать, так вообще двойная работа: и с ячейкой, и с портом. С какой стати быстрее?
а повторной записи того же самого. смысл не проверяя писать тоже самое ?
Здесь Вы очень сильно запутались в причинах и следствиях. Есть исходник(тот который пишет программист) и есть код(по которому работает процессор). Так вот Программист может написать много, а в коде быть мало объема и наоборот. Буквально 10 буквиц и код многократно увеличивается. Дальше размер кода и время исполнения его. Казалось бы логично больше кода и больше времени исполнения. Но всякие циклы и процессор буквально будет только работать на этот код, А если в коде куча ветвлений, то многие ветви будут выполнятся в только в исключительных ситуациях, а нормальной ситуации процессор на них не будет затрачивать ни такта.
Квон, абсолютно согласен. Это уже искусство а не программирование :) восхищаюсь теми кто его достиг.
Андриан, я прежде чем написать специально поверил. Я не бог программирования но все же.
На верху Влад привел запись в порт, а я свой if. Можете написать чтобы запись Влада была быстрее моегоif ?
ещё можно чуть уменьшить количество вычислений в каждой итерации. Как то так ...
Нельзя. Что в вашем варианте произойдет когда millis() пойдет к значению, скажем 4,294,967,000?
Ваше условие - начнет постоянно срабатывать. И "будет глючит" 295 миллисекунд подряд
я когда проверял перезаполнение (еще до этого поста) на С компиляторе то ничего страшного не происходит , всё он там правильно считает. и как предложил toc имеем место быть. или в ардуине компиляторе не так ? (я знаю что там тоже С но всётаки с небольшими изменениями)
я когда проверял перезаполнение (еще до этого поста) на С компиляторе то ничего страшного не происходит , всё он там правильно считает. и как предложил toc имеем место быть.
Я не знаю, что Вы проверяли, Вы же код не показываете. Но, так, как написал toc при переполнении работать не может, лешак прав 100%
или в ардуине компиляторе не так ? (
Это не свойство компилятора, это свойство арифметики в дополнительном коде и от компилятора не зависит.
вот только что набросал, нормальный результат выводит, не уходит в ошибку или минус или еще куда. да и тут это как то давно обсуждали говориличто компилятор понимает перезапуск перемной
вот только что набросал, нормальный результат выводит, не уходит в ошибку или минус или еще куда. да и тут это как то давно обсуждали говориличто компилятор понимает перезапуск перемной
Обратите внимание на строчку 9 - это и есть арифметика в дополнительном коде. Именно поэтому интервал рассчитывается корректно. Похоже, вы просто немного не понимаете, в чём дело. Тут столько копий уже сломано на теме переполнения беззнаковых переменных - может, стоит почитать, для начала? ;)
нормальный результат выводит,
И что же Вы этим проверили?
У Вас в строке 9 используется вычитание, а у toc в строке 28
nextMillis = millis() + INTERVAL;
сложение.
Вы одно от другого отличаете?
Вы уж проверяйте то, что нуждается в проверке.
Вот здесь есть правильные проверки - http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis
И, да,
вот только что набросал
Набрасывают навоз на грядки и дерьмо на вентиллятор (да то, последнее "вбрасывают").
Набрасывают навоз на грядки и дерьмо на вентиллятор (да то, последнее "вбрасывают").
Неа, последнее по транспортерной ленте должно подаваться, медленно, но верно. Иначе, нетехнологично.))))
От блин я думал направление не играет роли :) спасибо Евгений
но у Гаммона понятнее объяснено для новичков
https://www.gammon.com.au/millis
А ещё художники тоже любят наброски набрасывать .. ;)
так я художник :)
но у Гаммона понятнее объяснено для новичков
https://www.gammon.com.au/millis
Вот тут Вы молодец! В правильно направлении роете. Nick - мужик толковый и грамотный! А тот тут любят сослаться на, прости Господи, Гивера.
может кто объяснить почему замена в нижеприведённом коде булевой переменной на байт экономит 8 байт памяти программ?
Виноват, бред написал. Сейчас разберусь.
Виноват, бред написал. Сейчас разберусь.
Я не увидел...да даже если бы и увидел... )))
Эффект сильно зависит от опций и его трудно воспроизвести. Например, у меня в Avr студии получилось наоборот. Но, общая идея здесь в том, что всё зависит от дальнейшего использовании b. Дело в том, что в строке 22 оно должно быть int для взятия индекса. А в строке 24 оно может быть как int, так и bool для отрицания.
Если её объявить как byte - она везде int и никаких усилий не требуется, т.к. всё подходит, а если объявить как bool, то в строке №22 его нужно преобразовывать и компилятор оставляет преобразование на этап выполнения.
Чтобы убедиться в этом, можно явно пояснить компилятору, что ничего, кроме 0 и 1 там не будет. Для этого, например, в строке №20 можно заменить "bitRead(port,pin);" на "(port & bit(pin)) ? 1 : 0;". Попробуйте. Эффект уходит.
не взлетело, на восемь байт больше также как и для bitRead(port,pin);
А тема называлась правильный выбор типа переменных )))
IDE 1.8.8 настроенная по умолчанию
может кто объяснить почему замена в нижеприведённом коде булевой переменной на байт экономит 8 байт памяти программ?
В зависимости от того bool у вас или byte, компилятор создает различный код. В первом случае предполагается, что в переменой b может быть либо ноль, либо не ноль (не принципиально что именно). На этом строятся дальнейшие проверки и использование b в качестве индекса массива сводится к взятию либо первого элемента (если b = 0), либо второго.
С byte дело обстоит иначе. Хранящееся в переменной b значение принципиально (по крайней мере в данном коде). И оно непосредственно участвует в вычислении адреса нужного элемента массива (индекс элемента * размер элементов ...). В итоге код уже отличается от генерируемого для bool.
В итоге код уже отличается от генерируемого для bool.
Осталось определиться в каком случае надо присваивать переменной тип bool а в каком byte
С этим компилятором настолько всё неоднозначно, к примеру снимаем ремарку с 24 строки, чтобы получить перед главным циклом правильное время начала цикла, а исполнимый код вместо увеличения становится на 22 байта короче ))) ...И как тут не быть ...
У меня 1.8.9 - нормально взлетает. Собственно, я уже говорил - от опций зависит.
В любом случае, суть дела Вам уже пояснили и я, и VladimirTsibrov.
Неправда, тема называлась "Еще раз мигаем светодиодом без Delay"
Если Вас так сильно интересует правильный выбор типа, то, Вы невнимательно читаете, я Вам уже писал, что операция взятия индекса требует int
ua6em, а если закастить?
Если Вас так сильно интересует правильный выбор типа, то, Вы невнимательно читаете, я Вам уже писал, что операция взятия индекса требует int
Читал внимательно, но вот понять )))
Как в том анекдоте про дважды два - семь, восемь где-то так, ну не сорок жеж...
Да сейчас поставлю 1.8.9 проверю...
ua6em, а если закастить?
Это вы с кем сейчас разговаривали )))
Я же говорю, знал когда-то диаграмму состояний сплава железо-углерод, ВСЁ!!! Ардуино - хобби, одно из ...
Языком Ардуино, в отличии от остальных двух десятков разговорных не владею )))
bool 582
byte 574
1.8.9
каст не помогает уменьшить . интересно девки пляшут
Да сейчас поставлю 1.8.9 проверю...
Мне не верите?
С этим компилятором настолько всё неоднозначно, к примеру снимаем ремарку с 24 строки, чтобы получить перед главным циклом правильное время начала цикла, а исполнимый код вместо увеличения становится на 22 байта короче ))) ...И как тут не быть ...
Я бы предположил, что компилятор, встретив в очередной раз строку
, принял решение об оптимизации этого вызова за счет другого ресурса. Я попробовал добавить указанную строку не в setup, а в начале loop - эффект тот же: размер скомпилированного файла уменьшился.
Мне не верите?
Верю!!! Но как говорил DIMAX - UA6EM, если что-то имеет теоретическую возможность пойти не так, оно у Вас обязательно пойдёт не так, может хобби сменить )))
Мне не верите?
Верю!!! Но как говорил DIMAX - UA6EM, если что-то имеет теоретическую возможность пойти не так, оно у Вас обязательно пойдёт не так, может хобби сменить )))
Закон Мерфи)
принял решение об оптимизации этого вызова за счет другого ресурса. Я попробовал добавить указанную строку не в setup, а в начале loop - эффект тот же: размер скомпилированного файла уменьшился.
Ясно, компилятор писали выходцы из СССР...только у нас решение принимется после третьего наступления ногой на грабли )))
DIMAX был прав ))))))))))))))))))))))))))))))))))))))
Ну, значит между тем моментом. когда я скачивал и сегодня, они поменяли какую-нибудь опцию.
По сути вопроса Вам ответили, ещё вопросы есть или уже просто так треплемся?
Ну, значит между тем моментом. когда я скачивал и сегодня, они поменяли какую-нибудь опцию.
По сути вопроса Вам ответили, ещё вопросы есть или уже просто так треплемся?
по сути понятно, прямо таки "море не отталкивает от себя ни одной реки" )
по сути понятно, прямо таки "море не отталкивает от себя ни одной реки" )
Но если море мешает судоходству, то роем обводной канал.
по сути понятно, прямо таки "море не отталкивает от себя ни одной реки" )
и причём тут море? )
по сути понятно, прямо таки "море не отталкивает от себя ни одной реки" )
и причём тут море? )
море не отталкивает от себя ни одной реки =У каждой проблемы есть универсальное решение.
Но если море мешает судоходству, то роем обводной канал = как бы универсальное решение не оказалось еще больше проблемой.
ПС: у метафор всегда есть два прочтения - прямое и метафоричное. Так и ответных метафор должно быть тоже ответы на эти же прочтения.
вообще то я о другом говорил, о ценности каждой капли знаний )))
вообще то я о другом говорил, о ценности каждой капли знаний )))
первый интервал (в даном случае 150 с) мы получается ничего не делаем. а тут возникла необходимость сразу заинвертировать , ну и потом дальше как обычно через заданный интервал. без дополнительной проверки дополнительной переменной не придумал как реализовать.
а можно ли как то не вводя дополнительных переменных сделать чтоб мигание сразу начиналось ?
Если t =0, то так и будет - первое инвертирование сразу, а потом через оговоренный интервал
Мигаю примерно так:
Мигаю примерно так:
в этом варианте первый период мигания будет случайного размера. что вряд ли можно назвать правильным ответом на вопрос
B707, точно спасибо. Обычно t инициализирую как millis (). И искал в других направлениях. А можно просто t=0. Спасибо
Vlad, мы так пишем постоянно в порт, даже когда не надо, что лично я стараюсь избегать.
А какие соображения вынуждают Вас избегать записи в порт?
Боятся, видима, што порт протрёцца.
Это если порт ввода. Эх, солнечная молдавия!
Запомни Гоги. Вход это куда люди заходят,выход это откуда выходят. А если люди заходят и выходят , то это переход.
А какие соображения вынуждают Вас избегать записи в порт?
не записи в порт, а повторной записи того же самого. смысл не проверяя писать тоже самое ?
плюс if хоть каплю но быстрее чем direct port manipulation , не говоря уже про digitalWrite
А какие соображения вынуждают Вас избегать записи в порт?
if хоть каплю но быстрее чем direct port manipulation
Разве?
Порт находится в общем адресном пространстве и работа с ним ничем не отличается от работы с ячейкой памяти.
Если мы используем if, то с чем мы его используем? Наверняка выделяем в памяти ячейку, в которой содержится информация, следует писать в порт или нет. Работа с этой ячейкой ничуть не быстрее, чем работа с самим портом. Да еще и лишний if... А если окажется, что нужно писать, так вообще двойная работа: и с ячейкой, и с портом. С какой стати быстрее?
Квон, абсолютно согласен. Это уже искусство а не программирование :) восхищаюсь теми кто его достиг.
Андриан, я прежде чем написать специально поверил. Я не бог программирования но все же.
На верху Влад привел запись в порт, а я свой if. Можете написать чтобы запись Влада была быстрее моегоif ?