#include "arhat.h"
#define PIN 12
#define byte unsigned char
byte state = 0; // Можно объявить локально, но мы специально делаем неоптимально
void setup() {
byte locState = 0;
unsigned long startTime;
pinMode(PIN, OUTPUT);
Serial.begin(9600);
// 1. Global state variable:
startTime = millis();
for (long i=0; i<1000000; i++) {
state = !state;
digitalWrite(PIN, state);
}
Serial.print("Time for global state = ");
Serial.println(millis()-startTime, DEC);
// 2. Local state control without functions:
startTime = millis();
for (long i=0; i<1000000; i++) {
locState = !locState;
digitalWrite(PIN, locState);
}
Serial.print("Time for local = ");
Serial.println(millis()-startTime, DEC);
// 3. Pin state control:
startTime = millis();
for (long i=0; i<1000000; i++) {
digitalWrite(PIN, !digitalRead(PIN));
}
Serial.print("Time for pin state control = ");
Serial.println(millis()-startTime, DEC);
}
void loop() {
}
Компиляция под Нано:
Sketch uses 2 350 bytes (7%) of program storage space. Maximum is 30 720 bytes.
Global variables use 254 bytes (12%) of dynamic memory, leaving 1 794 bytes for local variables. Maximum is 2 048 bytes.
Результат в мониторе:
Time for global state = 1159
Time for local = 721 Time for pin state control = 722
Использовал свою старую поделку, заменяющую все базовые функции библиотеки Ардуино. Компилируется нормально в версии 1.6.4. В новых версиях, начиная кажется с 1.6.9 не компилируется, потому что ардуинщики заблокировали подмену своего Arduino.h.
Я Вам за это и пишу: использование "родных" библиотек - это исключительно процесс ОБУЧЕНИЯ. С какой скоростью и сколько оно жрет памяти - роялей не играет. Но учиться надо ПРАВИЛЬНОМУ программированию, а не "чему попало". А в ЖИЗНИ используются нормально оптимизированные функции, и в них работа с памятью В ДВА раза дороже чем с пином напрямую. Что Вам и показано моим примером.
Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу..
Цена вопроса .. собственно вами показана 722мсек против 7200мсек. С требуемым размером будет аналогично. Но, вы же твердо уверены, что специально для вас разрабы делают новые камни с увеличенной памятью и повышенной частотой .. а вовсе не для решения задач большей сложности. :)
Та реализация не предполагает размещение номера пина в переменной. Только константная нумерация, можно через #define. В другой версии я отказался от цифрового номера пина в угоду паре чисел: номер порта + номер бита, что упростило многие явления и позволило реализовать аналоги функций "просто и дешево", но .. к тому времени когда это было сделано, ардуинщики заблокировали возможность подмены Arduino.h .. итого, смысл был утерян. А сейчас, так и не вижу вовсе смысла возиться с Ардуино ИДЕ и её библиотеками. Все можно делать или в Студии или и вовсе путем настройки какой-нить "идеи" или "эклипса", кому что больше привычно. Там жеж нормальный gcc .. зачем эта "недоИДЕ" и вовсе? Поучились, освоили .. досвидос, однако.
Я вам просто наглядно показал что "локал" это по большей части регистр, также как и "пин" и работать быстрее с памятью - Вам НЕ УДАСТСЯ ни разу. А как только Вы локал начнете гонять по вызовам функций как параметр, да ещё вместо простого глобала заведете "поле в объекте класса", то временные и размерные затраты ещё вырастут "на порядок".
.. но Вы завсегда можете взять камень побольше .. чё париться-то, верно жеж? :)
Если всё так хорошо, то почему базовые фунции Ардуино не сделаны настолько же эффективно? Какие подводные камни вашей реализации?
Основной подводный камень в том что он заточен под Arhat109-2 -а подход. Есть Arhat109-2 и его код, он работает. А если что-то там менять и нет Arhat109-2, то приплыли.
Прежде всего среда Ардуина расчитана под некий виртуальный МК. Под AVR просто идет настроечная таблица. И вы можете не сильно вникая в код менять камни. Это очень большой плюс. Для чего придуманы надстройки над Си? Делать большие проекты, медлено их модернизируя и переходя на новые камни, у которых и пины другие и режим другой.
ПС: Да и зачем цеплятся за пины. В цифровом автомате, предпочтительно хранить состояние в переменной. И плюс появляется если состояний много у автомата, особенно если есть двойники состояний.
В целом, то что сделано - выложено на гитхабе. Не поддерживается, но то что там есть - вполне рабочее в версиях 1.6.4, 1.6.5 и ниже. Там надо многое допиливать и доделывать, но отсутствие возможности хранить номер пина в переменной для многих как выяснилось тупо "непреодолимый барьер". Вот в силу этих двух обстоятельств: изменение подхода у разрабов Ардуино (после того как отправил им копию с предложением сделать варианты для обучения и для профи) + сложности в программировании у начинающих - работы и была заброшена.
Можете выкачать, поразбираться (там как раз подход настроечных файлов на камень) и допилить для разных других камней. Только боюсь, Вам оно - не по зубам будет.. :)
Если всё так хорошо, то почему базовые фунции Ардуино не сделаны настолько же эффективно? Какие подводные камни вашей реализации?
О вспомнилось. Когда ковырял ихние библиотеки, там одним из разрабов был сделан комментарий, отвечающий на Ваш вопрос, что-то типа такого в переводе: "Я тупо не знаю КАК это сделать лучше..". :)
Так и пользуйтесь на здоровье! Зачем ДРУГИХ учить плохому?!? Ну не танцор .. это понятно, но другие могут оказаться и умнее и талантливее и не только Вас, а кого-то ишо .. в т.ч. и меня. :)
Варианты 1 и 2 - эквивалентны Вашим вариантам. Все закономерно: два вызова тяжелых функций занимают больше времени, чем один вызов. Чудес не бывает.
Теперь посмотрим, как работают собственно порты и память (а не тяжелые функции, в которых много лишнего).
Вариант 3 - работа с портом.
Вариант 4 - пример некорректной постановки теста. Дело в том, что оптимизатор здесь НЕ помещает переменную в память. В реальнгой работе, когда мы пишем в порт в одном месте программы, а читаем - из другого, такого не происходит - переменная аккуратно помещает в память. А тест написан нами так, что позволяет оптимизатору удалить из кода те операторы, которые по его мнению являются лишними. Т.е. этот тест НЕ ИМИТИРУЕТ работу настоящей программы. Чтобы исправить этот дефект, запретим компилятору оптимизировать работу с памятью.
Вариант 5 - работа с портом и памятью. Собственно, все, как и должно быть: коль скоро мы дополняем код лишней операцией с памятью, то и выполняться он будет медленнее. Чудес не бывает.
#include "arhat.h"
#define PIN 12
#define byte unsigned char
byte state = 0; // Можно объявить локально, но мы специально делаем неоптимально
void setup() {
byte locState = 0;
unsigned long startTime;
pinMode(PIN, OUTPUT);
Serial.begin(9600);
// 1. Global state variable:
startTime = millis();
for (long i=0; i<1000000; i++) {
state = !state;
digitalWrite(PIN, state);
}
Serial.print("Time for global state = ");
Serial.println(millis()-startTime, DEC);
// 2. Local state control without functions:
startTime = millis();
for (long i=0; i<1000000; i++) {
locState = !locState;
digitalWrite(PIN, locState);
}
Serial.print("Time for local = ");
Serial.println(millis()-startTime, DEC);
// 3. Pin state control:
startTime = millis();
for (long i=0; i<1000000; i++) {
digitalWrite(PIN, !digitalRead(PIN));
}
Serial.print("Time for pin state control = ");
Serial.println(millis()-startTime, DEC);
}
void loop() {
}
Компиляция под Нано:
Sketch uses 2 350 bytes (7%) of program storage space. Maximum is 30 720 bytes.
Global variables use 254 bytes (12%) of dynamic memory, leaving 1 794 bytes for local variables. Maximum is 2 048 bytes.
Результат в мониторе:
Time for global state = 1159
Time for local = 721 Time for pin state control = 722
Что я сделал не так? :)
Отвечаю: Вы включаете время пересылки строки по Serial во время измерения.
Нужно сначала запомнить значение millis(), и только полтом начинать вывод в порт.
Если всё так хорошо, то почему базовые фунции Ардуино не сделаны настолько же эффективно? Какие подводные камни вашей реализации?
Основной подводный камень в том что он заточен под Arhat109-2 -а подход. Есть Arhat109-2 и его код, он работает. А если что-то там менять и нет Arhat109-2, то приплыли.
Ну зачем же так категорично?
Да, как привыкли пользоваться другими библиотеками - установили и ни разу внутрь не заглядывали - здесь не выйдет.
Но вещь IMHO полезная. Я, например, повытаскивал оттуда массу определений в отдельные файлы, каковыми и пользуюсь без остальный частей библиотеки. За что Архату большое спасибо.
Цитата:
Прежде всего среда Ардуина расчитана под некий виртуальный МК. Под AVR просто идет настроечная таблица. И вы можете не сильно вникая в код менять камни. Это очень большой плюс. Для чего придуманы надстройки над Си? Делать большие проекты, медлено их модернизируя и переходя на новые камни, у которых и пины другие и режим другой.
ПС: Да и зачем цеплятся за пины. В цифровом автомате, предпочтительно хранить состояние в переменной. И плюс появляется если состояний много у автомата, особенно если есть двойники состояний.
Как называется то, что мы пишем дла Ардуино?
Скетч - т.е. набросок.
С помощью этого наброска можно по-быстрому слепить макет.
Но когда возникает потребность превратить набросок в программу, приходится вспоминать, что у каждого контроллера есть специфика, и этой спецификой можно и нужно пользоваться.
andriano: "Отвечаю: Вы включаете время пересылки строки по Serial во время измерения."
С каких пор вычисление аргумента у функции производится ПОСЛЕ её вызова? Всё там написано верно и ваши времена это подтверждают. Ваш пример просто исполняется в 10 раз меньше. :) Мои определения делают практически ровно то, что написано в вашем примере: заменяют тяжелую функции digital..() на прямую работу с битами порта.
Идея той библиотеки как раз и заключалась в том, что набросав "набросок программы" на библиотеке Ардуино по-быстрому получить вполне рабочий вариант без особого переписывания текста. :)
1. Все что Вы показали этой картинкой - это только свой уровень программиста. Ибо "Одмин" - это ещё не обязательно "погромист". Не более.
Ну и процитирую сам себя, это к Вам относится напрямую как и многим тут таким же как Вы:
"Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу.."
Думаю, что динозавор имел в виду печать предваряющей строки - "Time for pin state control = " и т.п.
Динозавр давно офигел и мало чего понимая глядит на разборки богов :)
Да что там понимать... Для простой программки подход такой: хочешь иметь 100% актуальное состояние пина - читай его. Остальные способы определяются стратегией оптимизации - на скорость, на память и пр. Для незамысловатых нереалтайм задач вообще пофигу, как ты это значение хранишь.
Но когда возникает потребность превратить набросок в программу, приходится вспоминать, что у каждого контроллера есть специфика, и этой спецификой можно и нужно пользоваться.
Мои скетчи не настолько просты, чтобы их быстродействие упиралось именно в скорость чтения пина, но и не настолько сложны, чтобы им потребовалась такая супер оптимизация.
И еще, при всей теоретической "правильности" рекомендации читать непосредственно пин, мне видится, что этот совет оторван от реалий прораммирования arduino (да и программирования вообще). Как будто мы вообще ничего не делаем в программе, избегаем каких либо вычислений и переменных, а логику МК пытаемя свести к логике транзистора (мы ж только пины читаем).
Впрочем, в рамках штатного arduino IDE рекомендация пользоваться digitalRead вместо переменной, как видно, ничего не улучшает, а только замедляет выполнение.
Лично я стараюсь придерживаться такой простой концепции: если режим пина OUTPUT — мы в него только пишем, если INPUT — только читаем. Подразумевается, что состояние INPUT пинов изменяется не самой программой, а внешними факторами. Всё. Достаточно чтобы не запутаться и не мешать в одну кучу логику и физику.
Да что там понимать... Для простой программки подход такой: хочешь иметь 100% актуальное состояние пина - читай его. Остальные способы определяются стратегией оптимизации - на скорость, на память и пр. Для незамысловатых нереалтайм задач вообще пофигу, как ты это значение хранишь.
И еще, при всей теоретической "правильности" рекомендации читать непосредственно пин, мне видится, что этот совет оторван от реалий прораммирования arduino (да и программирования вообще). Как будто мы вообще ничего не делаем в программе, избегаем каких либо вычислений и переменных, а логику МК пытаемя свести к логике транзистора (мы ж только пины читаем).
Всё как раз наоборот. Игнорирование таких советов как раз отрывает программирование микроконтроллеров от реалий. В результате получаются монструозные библиотеки, классы и пр. что приводит как раз к вашему выводу: ничего не делаем, только пользуем "эту" библиотеку. Как пример, посмотрите на типовую библиотеку по чтению температуры с датчика Dallas. Это вам датчик виноват, что в библиотеке прошиты delay() по 750мсек?
Как раз следование таким советам позволяет быстро решать требуемые простые задачи, оставляя львиную долю времени МК на решение прочих задач. Всё ровно НАОБОРОТ. :)
P.S. Имено про это и пишу. Иначе стал бы тратить свое время..
Как раз следование таким советам позволяет быстро решать требуемые простые задачи, оставляя львиную долю времени МК на решение прочих задач. Всё ровно НАОБОРОТ. :)
Совет по прежнему бессмысленный, т.к. стандартный digitalRead вместо переменной, только увеличивает время выполнения. Чтобы следовать вашему совету, для начала надо ввязаться в кучу проблем с вашей библиотекой, вместо решения требуемых задач :(
Совет самый нормальный. Не нравится моя версия - сделайте свою или пользуйте Cyberlib или ещё какую.
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
Ну и Вам тоже "персонально" процитирую себя выше: "Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу.."
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
Цитата:
…Одним из примеров громоздкой и, по мнению авторов, бесполезной надстройки является интегрированная система WINDOWS фирмы Microsoft. Эта система занимает почти 1 Мбайт дисковой памяти и рассчитана на преимущественное использование совместно с устройством типа мышь…
…Таким образом, читатель уже понял, что среди надстроек над ДОС бывают довольно бесполезные системы, которые только выглядят красиво, а на самом деле отнимают время пользователя, память на дисках и оперативную память ЭВМ. Обманчивая красота таких систем, однако, сильно воздействует на неискушенных пользователей, которые не имели практики работы на машине. Инерция мышления бывает столь сильна, что авторам приходилось наблюдать, как люди, начавшие работать с подобной настройкой, впоследствии с трудом заставляют себя изучать команды ДОС… Хочется предостеречь от этой ошибки читателей…
Чем "более-выеденного-яйца-стоит" вопрос, тем интенсивнее дискуссия. Надо бы посоветовать кому-нибудь взять темой диссертации опредение функции Размер_обсуждения (пустота_вопроса). Интересна, она линейна и ещё более крутая :)
Эти, да можно вывести из под расчета времени исполнения вашим способом. Они примерно одинаковы и вносят примерно равную задержку .. на соотношение не влияет практически, но для чистоты эксперимента, да конечно же стоит делать с переменной. :)
Выеденное яйцо в этом топике - банально и явно прописано автором в заголовке темы: "как ПРАВИЛЬНО..". Ответ был дан в самом начале, все остальное флуд, как выясняется в силу непонимания что такое "правильно". :) Ситуация типичная с чтением ТЗ: смотрим в книгу - видим фигу .. :)
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
Думаю, что это слишком категорично.
Начинать следует с того, что digitalRead/digitalWrite выполняются 5-7 мкс, тогда как прямой работой с портами можно обеспечить минимум на порядок более высокие скорости.
Собственно все.
Дальше уже каждый должен решать для себя: играют ли задержки, исчисляемые единицами микросекунд, существенную роль в каждом конкретном проекте или нет.
Если не играют (а таких проектов подавляющее большинство) то и проблем нет: можно пользоваться любыми функциями, в том числе и стандартными digitalRead/digitalWrite.
А если играют - от их использования следует отказаться, заменив более быстрыми аналогами. Например, в проекте http://arduino.ru/forum/proekty/floppy-hdd-music необходимо управлять семнадцатью пинами из прерывания, происходящего 40 000 раз в секунду. Естественно, здесь digitalRead/digitalWrite использовать невозможно.
Не, не все. Опрос всех 8 пинов одного порта уже 50-60мсек, что более чем на 2 порядка проигрывает прямому вводу.
Собственно digitalRead/digitalWrite имеют преимущество только в мультиплатформенности, потому продолжая Вашу логику:
Каждый должен решать для себя: играет ли возможность работы проги на разных контроллерах существенную роль в каждом конкретном проекте или нет.
Если не играют (а таких проектов подавляющее большинство) то и проблем нет: можно использовать более эффективными функциями чем стандартными digitalRead/digitalWrite.
Компиляция под Нано:
Sketch uses 2 350 bytes (7%) of program storage space. Maximum is 30 720 bytes.
Global variables use 254 bytes (12%) of dynamic memory, leaving 1 794 bytes for local variables. Maximum is 2 048 bytes.
Результат в мониторе:
Time for global state = 1159
Time for local = 721
Time for pin state control = 722
Что я сделал не так? :)
Time for global state = 1159
Time for local = 721
Time for pin state control = 722
Что я сделал не так? :)
Использовали дополнительную стороннюю библиотеку. В стандартном Arduino IDE это не компилируется. Если выкинем #include "arhat.h", получим:
Использовал свою старую поделку, заменяющую все базовые функции библиотеки Ардуино. Компилируется нормально в версии 1.6.4. В новых версиях, начиная кажется с 1.6.9 не компилируется, потому что ардуинщики заблокировали подмену своего Arduino.h.
Я Вам за это и пишу: использование "родных" библиотек - это исключительно процесс ОБУЧЕНИЯ. С какой скоростью и сколько оно жрет памяти - роялей не играет. Но учиться надо ПРАВИЛЬНОМУ программированию, а не "чему попало". А в ЖИЗНИ используются нормально оптимизированные функции, и в них работа с памятью В ДВА раза дороже чем с пином напрямую. Что Вам и показано моим примером.
Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу..
Цена вопроса .. собственно вами показана 722мсек против 7200мсек. С требуемым размером будет аналогично. Но, вы же твердо уверены, что специально для вас разрабы делают новые камни с увеличенной памятью и повышенной частотой .. а вовсе не для решения задач большей сложности. :)
Использовал свою старую поделку, заменяющую все базовые функции библиотеки Ардуино.
Если всё так хорошо, то почему базовые фунции Ардуино не сделаны настолько же эффективно? Какие подводные камни вашей реализации?
Та реализация не предполагает размещение номера пина в переменной. Только константная нумерация, можно через #define. В другой версии я отказался от цифрового номера пина в угоду паре чисел: номер порта + номер бита, что упростило многие явления и позволило реализовать аналоги функций "просто и дешево", но .. к тому времени когда это было сделано, ардуинщики заблокировали возможность подмены Arduino.h .. итого, смысл был утерян. А сейчас, так и не вижу вовсе смысла возиться с Ардуино ИДЕ и её библиотеками. Все можно делать или в Студии или и вовсе путем настройки какой-нить "идеи" или "эклипса", кому что больше привычно. Там жеж нормальный gcc .. зачем эта "недоИДЕ" и вовсе? Поучились, освоили .. досвидос, однако.
Я вам просто наглядно показал что "локал" это по большей части регистр, также как и "пин" и работать быстрее с памятью - Вам НЕ УДАСТСЯ ни разу. А как только Вы локал начнете гонять по вызовам функций как параметр, да ещё вместо простого глобала заведете "поле в объекте класса", то временные и размерные затраты ещё вырастут "на порядок".
.. но Вы завсегда можете взять камень побольше .. чё париться-то, верно жеж? :)
Основной подводный камень в том что он заточен под Arhat109-2 -а подход. Есть Arhat109-2 и его код, он работает. А если что-то там менять и нет Arhat109-2, то приплыли.
Прежде всего среда Ардуина расчитана под некий виртуальный МК. Под AVR просто идет настроечная таблица. И вы можете не сильно вникая в код менять камни. Это очень большой плюс. Для чего придуманы надстройки над Си? Делать большие проекты, медлено их модернизируя и переходя на новые камни, у которых и пины другие и режим другой.
ПС: Да и зачем цеплятся за пины. В цифровом автомате, предпочтительно хранить состояние в переменной. И плюс появляется если состояний много у автомата, особенно если есть двойники состояний.
qwone, плохому танцору завсегда кое-что промеж ног мешает .. :)
В целом, то что сделано - выложено на гитхабе. Не поддерживается, но то что там есть - вполне рабочее в версиях 1.6.4, 1.6.5 и ниже. Там надо многое допиливать и доделывать, но отсутствие возможности хранить номер пина в переменной для многих как выяснилось тупо "непреодолимый барьер". Вот в силу этих двух обстоятельств: изменение подхода у разрабов Ардуино (после того как отправил им копию с предложением сделать варианты для обучения и для профи) + сложности в программировании у начинающих - работы и была заброшена.
Можете выкачать, поразбираться (там как раз подход настроечных файлов на камень) и допилить для разных других камней. Только боюсь, Вам оно - не по зубам будет.. :)
О вспомнилось. Когда ковырял ихние библиотеки, там одним из разрабов был сделан комментарий, отвечающий на Ваш вопрос, что-то типа такого в переводе: "Я тупо не знаю КАК это сделать лучше..". :)
Так и пользуйтесь на здоровье! Зачем ДРУГИХ учить плохому?!? Ну не танцор .. это понятно, но другие могут оказаться и умнее и талантливее и не только Вас, а кого-то ишо .. в т.ч. и меня. :)
Вот и танцуйте без меня талантливый вы наш
Посмотрел, что происходит.
Вывод:
На что следует обратить внимание?
Варианты 1 и 2 - эквивалентны Вашим вариантам. Все закономерно: два вызова тяжелых функций занимают больше времени, чем один вызов. Чудес не бывает.
Теперь посмотрим, как работают собственно порты и память (а не тяжелые функции, в которых много лишнего).
Вариант 3 - работа с портом.
Вариант 4 - пример некорректной постановки теста. Дело в том, что оптимизатор здесь НЕ помещает переменную в память. В реальнгой работе, когда мы пишем в порт в одном месте программы, а читаем - из другого, такого не происходит - переменная аккуратно помещает в память. А тест написан нами так, что позволяет оптимизатору удалить из кода те операторы, которые по его мнению являются лишними. Т.е. этот тест НЕ ИМИТИРУЕТ работу настоящей программы. Чтобы исправить этот дефект, запретим компилятору оптимизировать работу с памятью.
Вариант 5 - работа с портом и памятью. Собственно, все, как и должно быть: коль скоро мы дополняем код лишней операцией с памятью, то и выполняться он будет медленнее. Чудес не бывает.
Компиляция под Нано:
Sketch uses 2 350 bytes (7%) of program storage space. Maximum is 30 720 bytes.
Global variables use 254 bytes (12%) of dynamic memory, leaving 1 794 bytes for local variables. Maximum is 2 048 bytes.
Результат в мониторе:
Time for global state = 1159
Time for local = 721
Time for pin state control = 722
Что я сделал не так? :)
Отвечаю: Вы включаете время пересылки строки по Serial во время измерения.
Нужно сначала запомнить значение millis(), и только полтом начинать вывод в порт.
Основной подводный камень в том что он заточен под Arhat109-2 -а подход. Есть Arhat109-2 и его код, он работает. А если что-то там менять и нет Arhat109-2, то приплыли.
Ну зачем же так категорично?
Да, как привыкли пользоваться другими библиотеками - установили и ни разу внутрь не заглядывали - здесь не выйдет.
Но вещь IMHO полезная. Я, например, повытаскивал оттуда массу определений в отдельные файлы, каковыми и пользуюсь без остальный частей библиотеки. За что Архату большое спасибо.
Прежде всего среда Ардуина расчитана под некий виртуальный МК. Под AVR просто идет настроечная таблица. И вы можете не сильно вникая в код менять камни. Это очень большой плюс. Для чего придуманы надстройки над Си? Делать большие проекты, медлено их модернизируя и переходя на новые камни, у которых и пины другие и режим другой.
ПС: Да и зачем цеплятся за пины. В цифровом автомате, предпочтительно хранить состояние в переменной. И плюс появляется если состояний много у автомата, особенно если есть двойники состояний.
Как называется то, что мы пишем дла Ардуино?
Скетч - т.е. набросок.
С помощью этого наброска можно по-быстрому слепить макет.
Но когда возникает потребность превратить набросок в программу, приходится вспоминать, что у каждого контроллера есть специфика, и этой спецификой можно и нужно пользоваться.
andriano: "Отвечаю: Вы включаете время пересылки строки по Serial во время измерения."
С каких пор вычисление аргумента у функции производится ПОСЛЕ её вызова? Всё там написано верно и ваши времена это подтверждают. Ваш пример просто исполняется в 10 раз меньше. :) Мои определения делают практически ровно то, что написано в вашем примере: заменяют тяжелую функции digital..() на прямую работу с битами порта.
Идея той библиотеки как раз и заключалась в том, что набросав "набросок программы" на библиотеке Ардуино по-быстрому получить вполне рабочий вариант без особого переписывания текста. :)
С каких пор вычисление аргумента у функции производится ПОСЛЕ её вызова?
Думаю, что динозавор имел в виду печать предваряющей строки - "Time for pin state control = " и т.п.
Вот и танцуйте без меня талантливый вы наш
1. Все что Вы показали этой картинкой - это только свой уровень программиста. Ибо "Одмин" - это ещё не обязательно "погромист". Не более.
Ну и процитирую сам себя, это к Вам относится напрямую как и многим тут таким же как Вы:
"Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу.."
Думаю, что динозавор имел в виду печать предваряющей строки - "Time for pin state control = " и т.п.
Динозавр давно офигел и мало чего понимая глядит на разборки богов :)
Думаю, что динозавор имел в виду печать предваряющей строки - "Time for pin state control = " и т.п.
Динозавр давно офигел и мало чего понимая глядит на разборки богов :)
Да что там понимать... Для простой программки подход такой: хочешь иметь 100% актуальное состояние пина - читай его. Остальные способы определяются стратегией оптимизации - на скорость, на память и пр. Для незамысловатых нереалтайм задач вообще пофигу, как ты это значение хранишь.
Но когда возникает потребность превратить набросок в программу, приходится вспоминать, что у каждого контроллера есть специфика, и этой спецификой можно и нужно пользоваться.
Мои скетчи не настолько просты, чтобы их быстродействие упиралось именно в скорость чтения пина, но и не настолько сложны, чтобы им потребовалась такая супер оптимизация.
И еще, при всей теоретической "правильности" рекомендации читать непосредственно пин, мне видится, что этот совет оторван от реалий прораммирования arduino (да и программирования вообще). Как будто мы вообще ничего не делаем в программе, избегаем каких либо вычислений и переменных, а логику МК пытаемя свести к логике транзистора (мы ж только пины читаем).
Впрочем, в рамках штатного arduino IDE рекомендация пользоваться digitalRead вместо переменной, как видно, ничего не улучшает, а только замедляет выполнение.
Лично я стараюсь придерживаться такой простой концепции: если режим пина OUTPUT — мы в него только пишем, если INPUT — только читаем. Подразумевается, что состояние INPUT пинов изменяется не самой программой, а внешними факторами. Всё. Достаточно чтобы не запутаться и не мешать в одну кучу логику и физику.
Да, до сюда я понял :)
И еще, при всей теоретической "правильности" рекомендации читать непосредственно пин, мне видится, что этот совет оторван от реалий прораммирования arduino (да и программирования вообще). Как будто мы вообще ничего не делаем в программе, избегаем каких либо вычислений и переменных, а логику МК пытаемя свести к логике транзистора (мы ж только пины читаем).
Всё как раз наоборот. Игнорирование таких советов как раз отрывает программирование микроконтроллеров от реалий. В результате получаются монструозные библиотеки, классы и пр. что приводит как раз к вашему выводу: ничего не делаем, только пользуем "эту" библиотеку. Как пример, посмотрите на типовую библиотеку по чтению температуры с датчика Dallas. Это вам датчик виноват, что в библиотеке прошиты delay() по 750мсек?
Как раз следование таким советам позволяет быстро решать требуемые простые задачи, оставляя львиную долю времени МК на решение прочих задач. Всё ровно НАОБОРОТ. :)
P.S. Имено про это и пишу. Иначе стал бы тратить свое время..
Как раз следование таким советам позволяет быстро решать требуемые простые задачи, оставляя львиную долю времени МК на решение прочих задач. Всё ровно НАОБОРОТ. :)
Совет по прежнему бессмысленный, т.к. стандартный digitalRead вместо переменной, только увеличивает время выполнения. Чтобы следовать вашему совету, для начала надо ввязаться в кучу проблем с вашей библиотекой, вместо решения требуемых задач :(
Совет самый нормальный. Не нравится моя версия - сделайте свою или пользуйте Cyberlib или ещё какую.
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
Ну и Вам тоже "персонально" процитирую себя выше: "Хотите упираться дальше за безграмотное пользование УЧЕБНЫХ библиотек - да за ради бога! Копрокодерство чем дальше, тем становится агрессивней. Не удивите ни разу.."
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
…Таким образом, читатель уже понял, что среди надстроек над ДОС бывают довольно бесполезные системы, которые только выглядят красиво, а на самом деле отнимают время пользователя, память на дисках и оперативную память ЭВМ. Обманчивая красота таких систем, однако, сильно воздействует на неискушенных пользователей, которые не имели практики работы на машине. Инерция мышления бывает столь сильна, что авторам приходилось наблюдать, как люди, начавшие работать с подобной настройкой, впоследствии с трудом заставляют себя изучать команды ДОС… Хочется предостеречь от этой ошибки читателей…
«Персональные ЭВМ в инженерной практике», 1989
Да, блин!
Чем "более-выеденного-яйца-стоит" вопрос, тем интенсивнее дискуссия. Надо бы посоветовать кому-нибудь взять темой диссертации опредение функции Размер_обсуждения (пустота_вопроса). Интересна, она линейна и ещё более крутая :)
Можно конечно через Ардуиновский класс Print , но через класс Stream идеологически вернее.
А ежели учесть, что на самом деле
так вопрос становится ещё более острым :)))
andriano: "Отвечаю: Вы включаете время пересылки строки по Serial во время измерения."
С каких пор вычисление аргумента у функции производится ПОСЛЕ её вызова?...
В Вашем коде время выполнения строк 20, 29 и 37 включается во время измерения. Вы всерьез полагаете, что так и должно быть?
Эти, да можно вывести из под расчета времени исполнения вашим способом. Они примерно одинаковы и вносят примерно равную задержку .. на соотношение не влияет практически, но для чистоты эксперимента, да конечно же стоит делать с переменной. :)
Выеденное яйцо в этом топике - банально и явно прописано автором в заголовке темы: "как ПРАВИЛЬНО..". Ответ был дан в самом начале, все остальное флуд, как выясняется в силу непонимания что такое "правильно". :) Ситуация типичная с чтением ТЗ: смотрим в книгу - видим фигу .. :)
И не пользуйте digitalRead() и остальные "ардуино функции", кроме как для целей обучения. Только и всего.
Думаю, что это слишком категорично.
Начинать следует с того, что digitalRead/digitalWrite выполняются 5-7 мкс, тогда как прямой работой с портами можно обеспечить минимум на порядок более высокие скорости.
Собственно все.
Дальше уже каждый должен решать для себя: играют ли задержки, исчисляемые единицами микросекунд, существенную роль в каждом конкретном проекте или нет.
Если не играют (а таких проектов подавляющее большинство) то и проблем нет: можно пользоваться любыми функциями, в том числе и стандартными digitalRead/digitalWrite.
А если играют - от их использования следует отказаться, заменив более быстрыми аналогами. Например, в проекте http://arduino.ru/forum/proekty/floppy-hdd-music необходимо управлять семнадцатью пинами из прерывания, происходящего 40 000 раз в секунду. Естественно, здесь digitalRead/digitalWrite использовать невозможно.
//Собственно все.
Не, не все. Опрос всех 8 пинов одного порта уже 50-60мсек, что более чем на 2 порядка проигрывает прямому вводу.
Собственно digitalRead/digitalWrite имеют преимущество только в мультиплатформенности, потому продолжая Вашу логику:
Каждый должен решать для себя: играет ли возможность работы проги на разных контроллерах существенную роль в каждом конкретном проекте или нет.
Если не играют (а таких проектов подавляющее большинство) то и проблем нет: можно использовать более эффективными функциями чем стандартными digitalRead/digitalWrite.