Чтобы узнать чьи помои, достаточно нажать Ctrl+F и поискать по странице слово "говно". Первый раз оно встречается в Вашем посте №21. До этого в топике шла нормальначя беседа. Но тут Вы "тоже решил поучаствовать" и полилось говно рекой. Так что, насчёт "чьих-то помев" Вы не скромничайте, прямо указывайте автороство.
ЕвгенийП, я так понимаю необходимо использовать перегрузку оператора "=".
Тут помоему более доходчиво описано. Скоро реализую.
Давайте.
Операторы присваивания - они очень похожи на конструкторы, там ничего особо сложного для простого класса в котором нет хитрой работы с памятью.
Если будете реализовывать и другие операторы (сравнение, там или ещё чего), там прежде чем делать, посмотрите что такое friends. Иногда оператор гораздо удобнее реализовывать не членом класса, а "другом".
Arduino позволяет пользователю сосредоточиться на разработке проектов, а не изучении устройства и принципов функционирования отдельных элементов.
Ардуино позволяет с минимальными знаниями микроконтроллеров, начать программировать. У меня так и вышло.
ГЛАВНЫМ приемуществом среды Arduino, я считаю открытость системных обращений к регистрам и возможность постепенного ухода от всяких analogread() и переход на прямую работу с контроллером.
Почти все, кто желает использовать контроллер "на полную" уходят в поля прямой работы с прерываниями и аппаратными возможностями.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Ну, есть же и другой путь? Добавить всё, что хочется и как нужно, а потом просто заменить обращения к функциям на прямую работу с портами, если так хочется. Чем это плохо?
Ардуино позволяет с минимальными знаниями микроконтроллеров, начать программировать. У меня так и вышло.
ГЛАВНЫМ приемуществом среды Arduino, я считаю открытость системных обращений к регистрам и возможность постепенного ухода от всяких analogread() и переход на прямую работу с контроллером.
Почти все, кто желает использовать контроллер "на полную" уходят в поля прямой работы с прерываниями и аппаратными возможностями.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
+1. Читаеш такое и понимаеш - есть же ещё здоровые люди на форуме, только редко пишут.
Дополню только, что переход в "в поля прямой работы", совсем не "ушел и не вернулся". Это возможность реализации на том уровне, на котором конкретно в данном случае удобно и требуется, надо ввод с АЦП быстро по прерыванию - не проблема, а не требуется именно здесь и сейчас - ну и analogRead сойдет. Широта выбора вариантов реализации сохраняется, как бы глубоко в железяку не залазил.
Тема - чистый бред, рафинированый. Тормозной подход. Но от этих товарищей можна и класс для int ожидать. Если бы построили на своем абстрактном классе конкретное производительное приложение , то поняли бы что идут по давно заброшеному пути в тупик. Абстрагировать пины можна только на уровень выше, соблюдая принцип адресация пина (порта, маски и т.д.) константой. А будет это на темплате или дефайне - дело десятое.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
В #18 посте писал
Я думаю что большенству (для моргалок, теплиц, лестниц с подсветкой, паяльных станций и т.п. ) хватит и дигталВритев, а кому мало ... можно и глубже копнуть.)
На форуме кроме осцилографа и генератора сигналов мало кому скорость нужна.
Вот когда самонаводящиеся ракеты будим строить тогда и копнем:) , а пока что есть. Никому не навязываю.
добавил blink(интервал, импульс) - интервал в ms, импульс в ms (продолжительность импульса не дольше интервала). По умолчанию период 1000, импульс 250. Работу loop() не прерывает.
Это за минуту, шо вспомнил, шо нашел. Еще гдето бодание про I2C на 800КГц было..
Мало того один из кючевых моментов правильного кода - быстрый loop, от чего с delay воюем. И если на всякую фигню (а ввод/вывод согласитесь не сложное дело) тратить много времени то как тут быть?
Ну .. в шапке много разного бреда. Может для того и подшили чтобы "так не делали", нет? :) Ну и с классом титановой кнопки там как-бы все нормально и особо лишнего нет. В отличии от этих классов. Я ещё могу понять, если Вы хотите вывести в дальнейшем их работу через прямое указание портов и битов, минуя Wiring, но как-то шибко сомнительно. В противном случае, ваши классы - это яркий пример "как не надо делать".
Спорить не буду. Повторюсь, я не навязываю. А кто решит что ему так проще и удобней пусть пользуется моим извратом.
Титановый велосипед для кнопки тоже написан на "Ардуиновских" функциях и никто не возмущается, даже в шапку подшили.
Ну для кнопки, при разумном подходе, скорость действительно не главное. Если её опрашивать пару десятков раз в секунду, то какая разница как. Вобще где нет проблемы- не надо её выдумывать
ПС. От класса кнопки я тоже не в восторге. ИМХО он не нужен, надуман, но многие начинают разработку именно с кнопки, как будто у них важней устройств нет, потому его существование не вызывает острого неприятия, пусть дети поиграются;)
ППС. Сегодня с утра подпаял аж три кнопки, уже даже в корпус поставил, в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине. Конечно если каждую мксек проверять не поменялось ли чего - то будет, а если еще на прерывания повесить - оборжешся..
ну, ты бы сказал мне в теме класса, от чего ты не в восторге.
Logik пишет:
ППС. Сегодня с утра подпаял аж три кнопки, уже даже в корпус поставил, в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине. Конечно если каждую мксек проверять не поменялось ли чего - то будет, а если еще на прерывания повесить - оборжешся..
ну, установи в классе static const byte bounce_ = 0; // длительность отслеживания дребезга.
У меня и так счастье. Огромное и всеобемлющее без класса кнопки. Не в восторге от подхода. Класс экрана - понимаю зачем, класс сервопривода - тоже, класс кнопки - не понимаю зачем, но допускаю, пусть детки побалуются (если в проекте только кнопка и светодиод, то и кнопка это Девайс с большой буквы))), класс пина - штука ненужная и вредная.
Та ужеж писал, нет никакого обработчика))) Кнопка ростом не вышла для такого громкого звания)) Это и есть подход. У Вас класс системного времени есть в приложении? Нет. И вызова millis с головой хватает. Или класс светодиода на 13-м пине. Нет. Дижиталврайт13 и усьо;)) Так и класс кнопки - он не нужен. "Скрипач - не нужен".
Ну .. в шапке много разного бреда. Может для того и подшили чтобы "так не делали", нет? :) Ну и с классом титановой кнопки там как-бы все нормально и особо лишнего нет. В отличии от этих классов. Я ещё могу понять, если Вы хотите вывести в дальнейшем их работу через прямое указание портов и битов, минуя Wiring, но как-то шибко сомнительно. В противном случае, ваши классы - это яркий пример "как не надо делать".
В тему анекдот.
Аспирант в открытом вольере научно-исследовательского института проводит опыт со своей человекообразной обезьяной. Показывает обезьяне банан, а потом вешает его на высокую ветку. Обезьяна подходит и начинает трясти дерево. Ветка ходит ходуном, но банан не падает.
Аспирант:
- Думай, Марта, думай!! !
Обезьяна крутит головой, находит палку и сбивает ею банан.
- Молодец Марта.
Аспирант вешает новый банан, уводит обезьяну отдыхать. Когда он возващется с новой обезьяной, то видит, что в вольер проник прапорщик и отчаянно трясет дерево, стараясь достать банан. Аспирант уже собрался выгнать его, но решил понаблюдать за ним. Через некоторое время он не выдерживает и говорит:
- Бери палку прапорщик!!! !
прапор (злобно)
- На хр...на мне палка!! ! Мне банан нужен!!!!
Так вот. Кому палка не нужна пусть и дальше трясут)
красавчик, чо... свалить всё в одну кучу, что бы затем разгребать результат.
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
Автор, вам уже не один я отписал, что Вы пишете лисапед. Мало того, что это лисапед, так ещё и 5-и колесный, и с квадратными колесами. Не, мазохизм тоже имеет место быть в жизни .. я вовсе не против. Но позиционировать мазохизм как религию и предлагать всем (библиотека) - увольте. :)
По вашей аналогии с классом Relay.. да хоть горшком назови, он от этого "ногодрыгом" быть не перестанет! Про что вам уже Logik и отписал: "а нафига?" (лисапед 5-и колесный, да-да, он самый!).
Да, и то как Вы прописали пин в виде константы - это нормальная практика программирования МК. Абстрагирование от чиселки константой препроцессора. Каждая ного МК исполняет и ПРЕДНАЗНАЧЕНА (что важно!) ровно для решения своей задачи... и "абстрагировать" далее .. банально нечего. Все попытки писать "универсальные" (5-и колесные) лисапеды - от глупости и непонимания зачем ваще нужны микроконтроллеры. Ну .. или привычка кодить там, где никто не спросит ни за объем памяти ни за скорость исполнения .. то есть за качество решения. "работает и ладно".
P.S. Офигел вчера: поставил Убунту с Юнити на 4-й пенек и обнаружил скорость ввода с клавиатуры .. 1 клавиша в 3(ТРИ!) секунды .. ладно, я понимаю что графика слабовата, рисует медленно и печально .. но чтобы ввод склавы решался задержками типа delay как у мелкософта было в свое время .. не, такого представить себе в среде линуксоидов не мог.. пипец какой-то.
красавчик, чо... свалить всё в одну кучу, что бы затем разгребать результат.
if(KBD&1) //нажали -поехали Это проблема?
Клапауций 232 пишет:
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
Клапауций 232 пишет:
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
Какие нафиг комбинации? В проекти не предусмотрены. Это банальная навигация: лево, право и ОК.
А даже если нужно, так и тоже пожалуста - if(KBD&(1|2) ) //нажали комбинацию 1 и 2 -поехали
Только надо с таймаутом подшаманить нажмут не совсем одновременно, я в курсе;)
Клапауций 232 пишет:
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
Если честно - ХЗ. Будет задача, будем посмотреть. Но в таком подходе 10 не пугает. Вот 33 настораживает. Про комбинации писал - любые и скокохош.
На хрена класс кнопки если решается в 8 строк 3 кнопки?
нахрена 8 строк, если всё решается одной строкой if(digitalRead(pin)) {}; ?
Ух-ты!! сразу 3 кнопки 8))).
Ну елы палы! Покажи всем шо я не прав в реализации! Дафай код на своем кллассе делающий тоже самое что и мой, т.е. почти нифига. Дальше ржом вместе, считаем размер по флешу и ОЗУ, число строк (или букв) в исходнике ;).. Короче развлекаемся по полной, а то шото скучно здесь последние 48 часов )))
Кстати класс экрана в 8 строк переписать не выходит. Я пробовал. Никак. Потому там класс имеет смысл.
ну, ок - 3 строки. по любому мой вариант лучше. :D
Logik пишет:
Ну елы палы! Покажи всем шо я не прав в реализации!
я же тебе указал, что всё, что ты сделал для сокращения размера кода - не реализовал ничего, кроме if(Time-TimeKBD>300) считая результат Time-TimeKBD общим для всех кнопок.
плюс ты породил некую сущность KBD , которая вызовет у тебя для примера из 10 кнопок 99 ифов для разгребания результата.
если мой подход одинаково применим для любого количества кнопок, то твой заставляет тебя юлить, утверждая, что ты молодец потому, что класс экрана что-то там.
*можно спорить с тобой бесконечно, но битовые операции - это же круто, да? а, класс экрана что-то там.
я же тебе указал, что всё, что ты сделал для сокращения размера кода - не реализовал ничего, кроме if(Time-TimeKBD>300) считая результат Time-TimeKBD общим для всех кнопок.
Ну да. ну да. А про это ОЗУ, та хрени с теми 15 байтами на кнопку. На фоне таблицы виртуальных методов не так и много ;)))
Клапауций 232 пишет:
плюс ты породил некую сущность KBD ,
byte KBD; ???))) Ну ладно сущность - так сущность.
Клапауций 232 пишет:
которая вызовет у тебя для примера из 10 кнопок 99 ифов для разгребания результата.
нее... если их реально много то свич или косвенный переход, или мапируется на события если такая модель есть в проекте (мапируются - это не map() это как правило "+"). Под настроение и ситуацию.
Переписал класс. Скорость функций HI(), LO() по сравнению со стандартым digitalWrite выросла примерно в 1,45 раза. Написан конечно криво, надо подумать как изящней переписать (избавится от switch).
ты считаешь, что твой код реализует функционал класс титановый велосипед для тактовой кнопки в восьми строках?
*простой булевый вопрос. да/нет?
Нет канешно! False тоесть ;) Хай меня покрасят, шоб я реализовывать функционал какогото самопального класса.. Я ж четко писал.
Logik пишет:
в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине.
Код работает, замечаний нет. Ты попросил показать, поржать хотел, я показал. А реализовывать класс титановый велосипед.... Ты наверно шутиш, да? Мне это в программе нафиг надо.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
Клапауций 232 пишет:
як нэвдобно выйшло... но библиотека индикатора что-то там, правда?
Невдобно конечно, но я ж понимаю, ты весь на нервах, бум щитать от ненависти ;)
А чего это за код был? и чего снова для одной кнопки? Хотя после 15байт на один пин уже и не важно...
Вывод. Замена существующего кода в моем приложении на реализацию на основе класса титанового велосипеда потребует значительного количества доп. ресурсов контроллера. Усьо!
ПС. О пользе диалога. Призадумался, чего это я комбинации кнопок проигнорил. Конечно 3-х кнопок хватает, но на дополнительные 4 комбинации можна тоже чего навесить. В общем на днях допишу себе таки ввод комбинаций, спасибо Клапауций 232. Если кого интересует, пишите выложу здесь.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
и чего снова для одной кнопки? Хотя после 15байт на один пин уже и не важно...
я понимаю, что нужно было слить все булевые переменные кода в один байт, затем по мере необходимости разбираться, что это было - кнопка, датчик или ничего.
но, это же костыль - я не понимаю, зачем ты это делаешь... что бы было много свободной оперативки, что бы что?
*проверил класс с урезанным функционалом для 10-ти кнопок - 89 байт (4%) ок. для 100 кнопок займёт 40% оперативки. а, ты как будешь рулить 100 кнопками и со свободной оперативкой? придумаешь новую отмазку или поймёшь, что ты написал костыль?
Принцип в том, что сперва проверяешь, что присваивание вызывается не для одного и того же объекта. Потом копируешь поля из переданного объекта себе, поле к полю, а не так, как ты сделал (DigOut.state = right.value) - шо такое right.value?
yul-i-an, потом настанет черёд конструктора копирования ;) А потом, до кучи - explicit-конструктора, чтобы исключить неявные преобразования. Потом - можно определить операторы сравнения, операторы типов - например, operator int(), который будет возвращать номер пина, чтобы можно было удобно писать
pinManager << 13 << true; // выставили HIGH на пине 13
4
5
pinManager << 22 << false; // выставили LOW на пине 22
А унутре потом - можно перейти на прямую запись в порт и пин. Более того - если грамотно спроектировать класс и сделать хэш для ранее использованных пинов - то повторные вызовы установки уровня на пине будут просто летать, в назидание всем негодующим. Да, оверхэд по памяти будет небольшой, но порой удобство того стоит.
В общем, считаю, что экономить надо начинать тогда, когда совсем уже жмёт, так что - тренируйся, перейти на низкий уровень никогда не поздно.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
И ты не знаеш... А нафига запостил? Я про свой код думаю, мне хватает..
Клапауций 232 пишет:
я понимаю, что нужно было слить все булевые переменные кода в один байт, затем по мере необходимости разбираться, что это было - кнопка, датчик или ничего.
Неправильно понимаеш.
Клапауций 232 пишет:
но, это же костыль - я не понимаю, зачем ты это делаешь... что бы было много свободной оперативки, что бы что?
Это сложно, у меня их просто нет. Смотри код, найдеш-покажеш.
Клапауций 232 пишет:
*проверил класс с урезанным функционалом для 10-ти кнопок - 89 байт (4%) ок. для 100 кнопок займёт 40% оперативки. а, ты как будешь рулить 100 кнопками и со свободной оперативкой? придумаешь новую отмазку или поймёшь, что ты написал костыль?
10 или 100 или мульен. А что делать если встречу динозавра... Детский сад.
Еще раз с начала. У меня кнопки, их 3 шт. Ровно 3 кнопки запомнил. Во вторых у меня код есть, без левых классов и работает. Ты утверждаеш что если перейти на твой велосипед то будет как минимум не хуже. Так? Подтверди да или нет.
Я же вижу что как минимум ОЗУ уйдет дохера, а это хуже. Вижу по классу. Ты суеш какую-то функцию, сам не знаеш что и зачем, но она похоже для одной кнопки (которая уже ОЗУ отгребает как мои 3 кнопки), расказываеш про 10 или 100. Ты посотри на ту функцию, ввод digitalRead(_pb); и _pb глобальная. Как мне это использовать для 3-х кнопок? Три функции делать шоле. Каким боком она вобще к твоему классу относится? Фигня какая-то неопознаная. Расказы "мог бы, слил бы" - в топку, есть опубликованый класс, но он не тянет. Я выбор сделал, выводы написал.
Кста кода, обрабатывающего одновременное нажатие нескольких в классе не видно шото. Нибось, я себе не скопипащу, у нас подходы разные.
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.
Ты утверждаеш что если перейти на твой велосипед то будет как минимум не хуже. Так? Подтверди да или нет.
я утверждаю, что у тебя не может быть никаких претензий к класс титановый велосипед для тактовой кнопки, т.к. код класса стремится к идеалу и никто, в том числе ты, не смогли предъявить никаких претензий к коду, алгоритму и качеству работы.
лично ты на ходу выдумываешь эмоциональные и ничем не подкреплённые претензии - то тебе это не нужно, потому, что у тебя есть костыль, то тебе показалось, что много памяти кушает, теперь класс, оказывается - левый, а у тебя есть костыль.
сделал выбор и сделал - ходи на трёх ногах, но нафига хаять, то чему у небя неприязнь на эмоциональном уровне.
Logik пишет:
Ты посотри на ту функцию, ввод digitalRead(_pb); и _pb глобальная. Как мне это использовать для 3-х кнопок?
Переписал класс. Скорость функций HI(), LO() по сравнению со стандартым digitalWrite выросла примерно в 1,45 раза. Написан конечно криво, надо подумать как изящней переписать (избавится от switch).
Давайте пока не будем этим заниматься. Всему своё время.
Я понимаю, что Вас смущают замечания прогеров насчёт эффективности, но во-первых, таким способом Вы от этих замечаний не избавитесь, т.к. всё равно есть пути сделать это эффективнее, а во-вторых, я же Вам говорил, если Вы хотите научиться, то давайте идти шаг за шагом и, в какой-то момент, мы просто заменим методы HI/LO на самые эффективные, а вся, сделанная нами, оснастка останется нетронутой.
Заменить методы можно в любой момент, это очень просто. Некоторые тут не знают как это делается. но скачали где-то пример в котором не сумели разобраться. Поэтому им это кажется сложным (всё, в чём не сумел разобраться, кажется сложным), на самом деле, ничего там сложного нет, если знать и правильно применять язык.
Поэтому, давайте пока будем просто плевать на безграмотный бред прогеров и идти шаг за шагом.
начнём с оператор априсваивания. Коллега DIYMan всё правильно написал, но я хочу пойти дальше. Но, для начала, давайте зафиксируем текст класса (а то я уже запутался в Ваших версиях). Я сейчас выложу текст с которым я буду работать и давайте пока мы не закончим с низкоуровневой оснасткой, мы не будем добавлять туда высокоуровневые методы типа blink.
Вроде, всё мигает. давайте, будем плясать строго от этого текста, чтобы мы говорили об одном и том же.
Кстати, обратите внимание, что я сократил тип данных _pin (зачем ему два байта занимать?) и всем методам добавил модификатор const, чтобы развязать руки оптимизатору.
Теперь вернёмся к присваиванию. Для начала сделаем присваивание экземпляро класс друг другу.
иВаши ошибка в том, что
1) Вы возвращаете экземпляр класса, а надо ссылку
2) у Вас нет свойста, которое хранит состояние. Состояние хранится непосредственно на самом пине, так? Ну, так значит при присваивании оно должно получить значение! А Вы этого не сделали.
3) при присваивании Вы проверяете, а не самому ли себе идёт присваивание. В общем случае это хорошая практика, но в данном случае это лишнее - зачем? Какая разница? Вы же не запрашиваете память и не делаете ничего страшного.
Таким образом, алгоритм присваивания одного экземпляра другому таков:
1. Установить состояние текущего экземпляра класса таким же каково состояние присваиваемого.
2) вернуть ссылку на текущий экземпляр.
Теперь определим присваивание экземпляру класса значение типа bool, чтобы можно было писать "p13 = LOW" вместо вызова функции.
Итак, сложного ничего нет, по традиции оператор присваивания должен вернуть присвоенное значение, значит тип у него bool. Нужно просто выставить значение. Техника такова, смотрите:
Т.е. архитектурно более верно определять полный набор операторов для одного типа данных, не надеясь на оптимизатор и неявные преобразования. Впрочем, это уже сахар.
Нет, нет, Вы перепутали. Это присваивание значение типа bool (посмотрите на параметр оператора!).
Любой оператор присваивания должен возвращать то, что было присвоено. Не новое значение экземпляра объекта, а именно то, что было присвоено. Разумеется, это не жёсткое требование, на практике мы можем вернуть что угодно, но такое соглашение есть и я ему следовал. Поэтому данный оператор должен возвращать именно bool! Цепочка же будет отлично работать, если определить преобразование типа этого класса к bool. Тогда можно писать конструкции вроде p13 = p12 = p7 = true;
Я не говорю, что нельзя делать так, как Вы написали - можно, почему нет? Просто я строго следовал концепции, что "оператор присваивания должен возвращать то, что было присвоено" и в рамках этой концепции у меня всё написано верно.
All built-in assignment operators return *this, and most user-defined overloads also return *this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void).
Однако:
Цитата:
the canonical "unified assignment operator" implementation is
T& T::operator=(T arg)// copy/move constructor is called to construct arg{
swap(arg);// resources are exchanged between *this and argreturn*this;}// destructor of arg is called to release the resources formerly held by *this
И я всегда придерживаюсь второго подхода, возвращая *this, т.к. мы работаем с объектом класса, который может быть и lvalue. Считаю, что оперировать объектом класса в перегруженных операторах - это самое грамотное поведение, вне зависимости от того, какой объект нам передали в оператор (в нашем случае оператор присваивания). Скажем, если мы переопределим оператор <<, то там, очевидно, надо всегда возвращать *this, вне зависимости от переданного аргумента, не находите?
В приведённом примере противопоказано возвращать что-либо, отличное от ссылки на объект ;)
Ну, в приведённом-то само собой :)))
Да, нет, ну, понятно, что вопрос идеологический и можно делать как угодно. Важно только определиться и в пределах всего проекта делать одинаково, чтобы бардака не было. Если ТС захочет возвращать *this - да не вопрос, ему-то сейчас глваное просто научиться возвращать то, что хочет :) Опять же, если в добавок к возвращению *this будет определено преобразование к bool, то и цепочное присваивание bool'евским переменным будет отлично работать, так что можно делать и так - никаких проблем.
Я тут, как видите. всё вынес в inline и готовлю ТС, чтобы в нужный момент просто заменить вызовы digitalXXX (методы HI/LO) на портовые команды так, чтобы все операции сразу однокомандными стали, а то ведь прогеры ему печень съедят, если будет не так :)
Кста кода, обрабатывающего одновременное нажатие нескольких в классе не видно шото.
а, должен быть в классе код, обрабатывающий несколько, а не одну кнопку?
Так ты же сам про комбинации кнопок заговорил! )))) А оказывается нет, небыло и не должно.
Клапауций 232 пишет:
ок. вот тебе ещё(в третий) раз код класса, урезанный до твоего функционал...
Себе оставь, я ж те четко написал. Эту хрень я не использовал, не буду и другим не рекомендую. Почему - разжевано выше. Можеш урезать, зарезать, отрезать, прирезать. И шо это за подход к либе - урезал и пользуй. Под каждого будеш урезать? А тестить буш сам?. Кстати после урезания он тоже жрет больше ОЗУ. Может обрезание надо, шоб кошерный был? DDD
Logik пишет:
Ты утверждаеш что если перейти на твой велосипед то будет как минимум не хуже. Так? Подтверди да или нет.
Клапауций 232 пишет:
я утверждаю, что у тебя не может быть никаких претензий...
Ну понятно, неудобные вопросы игнорируеш.
Клапауций 232 пишет:
претензий к класс титановый велосипед для тактовой кнопки, т.к. код класса стремится к идеалу и никто, в том числе ты, не смогли предъявить никаких претензий к коду, алгоритму и качеству работы.
Та то ты их слышать нехош. 15 байт ОЗУ на кнопку - это приговор. После этого код просто не рассматривается как вариант.
Клапауций 232 пишет:
то чему у небя неприязнь на эмоциональном уровне.
Чешеш хрень. Я даже попробовал прикинуть переход на твой класс. И сравнил оба варианта, класс проиграла сразу и бесповоротно, по ОЗУ. Что и подтверждает исходное - для кнопки класс не нужен. До сравнения вариантов по остальным пунктам дело не дошло. Потому класса -небудет!
Logik пишет:
Ты посотри на ту функцию, ввод digitalRead(_pb); и _pb глобальная. Как мне это использовать для 3-х кнопок?
Клапауций 232 пишет:
варианта два:
1. убиться ап стену.
2. зайти в нужную тему и посмотреть как.
Ответа по существу нет. ну и нахер, вопрос про класс решен.
ПС. От интересно, Клапауций, ты действительно считаеш, что я закоментирую свой код (который короче экономней твоего по ОЗУ и работает замечательно, к тому же легко модифицировался под прием нескольких одновременных нажатий) и всуну твой "урезок" (который длинней, жрет больше ОЗУ и токошо тобой поправлен и нихрена ни тещен и соответственно нихрена не надежен)? И токо из за того шо ты написал "костыль" да "три ноги", без каких либо аргументов. Пиши еще!! При этом еще и автор на вопросы не отвечает и претензии игнорит . Можеш на это не отвечать, вопрос риторический..
чьи-то помои
Чтобы узнать чьи помои, достаточно нажать Ctrl+F и поискать по странице слово "говно". Первый раз оно встречается в Вашем посте №21. До этого в топике шла нормальначя беседа. Но тут Вы "тоже решил поучаствовать" и полилось говно рекой. Так что, насчёт "чьих-то помев" Вы не скромничайте, прямо указывайте автороство.
ЕвгенийП, я так понимаю необходимо использовать перегрузку оператора "=".
Тут помоему более доходчиво описано. Скоро реализую.
Давайте.
Операторы присваивания - они очень похожи на конструкторы, там ничего особо сложного для простого класса в котором нет хитрой работы с памятью.
Если будете реализовывать и другие операторы (сравнение, там или ещё чего), там прежде чем делать, посмотрите что такое friends. Иногда оператор гораздо удобнее реализовывать не членом класса, а "другом".
Arduino позволяет пользователю сосредоточиться на разработке проектов, а не изучении устройства и принципов функционирования отдельных элементов.
Ардуино позволяет с минимальными знаниями микроконтроллеров, начать программировать. У меня так и вышло.
ГЛАВНЫМ приемуществом среды Arduino, я считаю открытость системных обращений к регистрам и возможность постепенного ухода от всяких analogread() и переход на прямую работу с контроллером.
Почти все, кто желает использовать контроллер "на полную" уходят в поля прямой работы с прерываниями и аппаратными возможностями.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Ну, есть же и другой путь? Добавить всё, что хочется и как нужно, а потом просто заменить обращения к функциям на прямую работу с портами, если так хочется. Чем это плохо?
Ардуино позволяет с минимальными знаниями микроконтроллеров, начать программировать. У меня так и вышло.
ГЛАВНЫМ приемуществом среды Arduino, я считаю открытость системных обращений к регистрам и возможность постепенного ухода от всяких analogread() и переход на прямую работу с контроллером.
Почти все, кто желает использовать контроллер "на полную" уходят в поля прямой работы с прерываниями и аппаратными возможностями.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
+1. Читаеш такое и понимаеш - есть же ещё здоровые люди на форуме, только редко пишут.
Дополню только, что переход в "в поля прямой работы", совсем не "ушел и не вернулся". Это возможность реализации на том уровне, на котором конкретно в данном случае удобно и требуется, надо ввод с АЦП быстро по прерыванию - не проблема, а не требуется именно здесь и сейчас - ну и analogRead сойдет. Широта выбора вариантов реализации сохраняется, как бы глубоко в железяку не залазил.
Тема - чистый бред, рафинированый. Тормозной подход. Но от этих товарищей можна и класс для int ожидать. Если бы построили на своем абстрактном классе конкретное производительное приложение , то поняли бы что идут по давно заброшеному пути в тупик. Абстрагировать пины можна только на уровень выше, соблюдая принцип адресация пина (порта, маски и т.д.) константой. А будет это на темплате или дефайне - дело десятое.
Бросьте эту разработку. В Ардуинке и так мало памяти и мощности, и заворачивать медленные стандартные функции в дополнительные процедуры и классы я не вижу смысла.
Видимо вы еще не столкнулись с проблемой когда все работет медленно и упрощать больше нечего.
В #18 посте писал
Я думаю что большенству (для моргалок, теплиц, лестниц с подсветкой, паяльных станций и т.п. ) хватит и дигталВритев, а кому мало ... можно и глубже копнуть.)
На форуме кроме осцилографа и генератора сигналов мало кому скорость нужна.
Вот когда самонаводящиеся ракеты будим строить тогда и копнем:) , а пока что есть. Никому не навязываю.
добавил blink(интервал, импульс) - интервал в ms, импульс в ms (продолжительность импульса не дольше интервала). По умолчанию период 1000, импульс 250. Работу loop() не прерывает.
DigOut.h
01
#ifndef DigOut_h
02
#define DigOut_h
03
//#include <arduino.h>
04
class
DigOut
05
{
06
public
:
07
DigOut(
int
pin=13,
bool
state=0);
08
void
HI();
//установить высокий уровень
09
void
LO();
//установить низкий уровень
10
void
invert();
//инвертировать выход
11
bool
state();
//получить состояние
12
void
blink(unsigned
long
period=1000,
int
impuls=250);
//выдает импульсы с заданным периодом и длиной
13
// void HIafter(unsigned long period=0);//выставить высокий уровень через
14
// void LOafter(unsigned long period=0);//выставить низкий уровень через
15
void
ResT();
//сброс таймера
16
private
:
17
int
_pin;
//выходной пин
18
unsigned
long
preMillis;
//предыдущее время
19
bool
st;
//флаг таймера
20
};
21
22
#endif
DigOut.cpp
01
#include <arduino.h>
02
#include "DigOut.h"
03
04
DigOut::DigOut(
int
pin,
bool
state)
05
{
06
_pin = pin;
07
pinMode(_pin, OUTPUT);
08
digitalWrite(_pin, state);
09
preMillis=millis();
10
}
11
12
void
DigOut::HI()
//установить высокий уровень
13
{
14
digitalWrite(_pin, HIGH);
15
}
16
17
void
DigOut::LO()
//установить низкий уровень
18
{
19
digitalWrite(_pin, LOW);
20
}
21
22
bool
DigOut::state()
//получить состояние выхода
23
{
24
return
digitalRead(_pin);
25
}
26
27
void
DigOut::invert()
//инвертировать выход
28
{
29
digitalWrite(_pin, !digitalRead(_pin));
30
}
31
32
void
DigOut::blink (unsigned
long
period,
int
impuls)
//выдавать импульсы
33
{
34
if
(millis()-preMillis>=period){
//если интервал прошел
35
preMillis=millis();
//сбрасываем
36
}
37
if
(millis()<impuls+preMillis){
//если время свечения индикатора не прошло
38
HI();
39
}
40
else
//иначе
41
{
42
LO();
43
}
44
}
Пример
01
//Пример Blink с использованием библиотеки DigOut
02
#include <DigOut.h>//подключаем библиотеку
03
DigOut LED(13);
//инициализация цифрового выхода 13 с установкой низкого уровня
04
05
void
setup
() {
06
}
07
08
void
loop
() {
09
LED.blink(1000,300);
//мигаем с интервалом 1сек, вспышка 300мс
10
}
DigOut библитоека
На форуме кроме осцилографа и генератора сигналов мало кому скорость нужна.
Вот когда самонаводящиеся ракеты будим строить тогда и копнем:) , а пока что есть. Никому не навязываю.
Как же Вы неправы в своем утверждении!!! Просто ссылки на темы недавние мелькавшие -
http://arduino.ru/forum/obshchii/skorost-raboty-displeev (один этот момент чего стоит!!!)
http://arduino.ru/forum/programmirovanie/bystroe-chtenie-tsifrovykh-vkho...
http://arduino.ru/forum/programmirovanie/kak-povysit-skorost-chteniya-sd...
http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-a...
Это за минуту, шо вспомнил, шо нашел. Еще гдето бодание про I2C на 800КГц было..
Мало того один из кючевых моментов правильного кода - быстрый loop, от чего с delay воюем. И если на всякую фигню (а ввод/вывод согласитесь не сложное дело) тратить много времени то как тут быть?
Спорить не буду. Повторюсь, я не навязываю. А кто решит что ему так проще и удобней пусть пользуется моим извратом.
Титановый велосипед для кнопки тоже написан на "Ардуиновских" функциях и никто не возмущается, даже в шапку подшили.
Ну .. в шапке много разного бреда. Может для того и подшили чтобы "так не делали", нет? :) Ну и с классом титановой кнопки там как-бы все нормально и особо лишнего нет. В отличии от этих классов. Я ещё могу понять, если Вы хотите вывести в дальнейшем их работу через прямое указание портов и битов, минуя Wiring, но как-то шибко сомнительно. В противном случае, ваши классы - это яркий пример "как не надо делать".
Спорить не буду. Повторюсь, я не навязываю. А кто решит что ему так проще и удобней пусть пользуется моим извратом.
Титановый велосипед для кнопки тоже написан на "Ардуиновских" функциях и никто не возмущается, даже в шапку подшили.
Ну для кнопки, при разумном подходе, скорость действительно не главное. Если её опрашивать пару десятков раз в секунду, то какая разница как. Вобще где нет проблемы- не надо её выдумывать
ПС. От класса кнопки я тоже не в восторге. ИМХО он не нужен, надуман, но многие начинают разработку именно с кнопки, как будто у них важней устройств нет, потому его существование не вызывает острого неприятия, пусть дети поиграются;)
ППС. Сегодня с утра подпаял аж три кнопки, уже даже в корпус поставил, в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине. Конечно если каждую мксек проверять не поменялось ли чего - то будет, а если еще на прерывания повесить - оборжешся..
ПС. От класса кнопки я тоже не в восторге.
ну, ты бы сказал мне в теме класса, от чего ты не в восторге.
ППС. Сегодня с утра подпаял аж три кнопки, уже даже в корпус поставил, в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине. Конечно если каждую мксек проверять не поменялось ли чего - то будет, а если еще на прерывания повесить - оборжешся..
ну, установи в классе static const byte bounce_ = 0; // длительность отслеживания дребезга.
и, будет тебе твоё персональное счастье.
У меня и так счастье. Огромное и всеобемлющее без класса кнопки. Не в восторге от подхода. Класс экрана - понимаю зачем, класс сервопривода - тоже, класс кнопки - не понимаю зачем, но допускаю, пусть детки побалуются (если в проекте только кнопка и светодиод, то и кнопка это Девайс с большой буквы))), класс пина - штука ненужная и вредная.
Не в восторге от подхода.
хуиз "подход"?
класс кнопки - не понимаю зачем
опубликуй код своего обработчика кнопки - мне просто интересно, чего там нет такого, что есть в классе.
Та ужеж писал, нет никакого обработчика))) Кнопка ростом не вышла для такого громкого звания)) Это и есть подход. У Вас класс системного времени есть в приложении? Нет. И вызова millis с головой хватает. Или класс светодиода на 13-м пине. Нет. Дижиталврайт13 и усьо;)) Так и класс кнопки - он не нужен. "Скрипач - не нужен".
Та ужеж писал, нет никакого обработчика)))
ок. назови горшком и опубликуй код - я не сильно буду смеяться.
Ну .. в шапке много разного бреда. Может для того и подшили чтобы "так не делали", нет? :) Ну и с классом титановой кнопки там как-бы все нормально и особо лишнего нет. В отличии от этих классов. Я ещё могу понять, если Вы хотите вывести в дальнейшем их работу через прямое указание портов и битов, минуя Wiring, но как-то шибко сомнительно. В противном случае, ваши классы - это яркий пример "как не надо делать".
В тему анекдот.
Аспирант в открытом вольере научно-исследовательского института проводит опыт со своей человекообразной обезьяной. Показывает обезьяне банан, а потом вешает его на высокую ветку. Обезьяна подходит и начинает трясти дерево. Ветка ходит ходуном, но банан не падает.
Аспирант:
- Думай, Марта, думай!! !
Обезьяна крутит головой, находит палку и сбивает ею банан.
- Молодец Марта.
Аспирант вешает новый банан, уводит обезьяну отдыхать. Когда он возващется с новой обезьяной, то видит, что в вольер проник прапорщик и отчаянно трясет дерево, стараясь достать банан. Аспирант уже собрался выгнать его, но решил понаблюдать за ним. Через некоторое время он не выдерживает и говорит:
- Бери палку прапорщик!!! !
прапор (злобно)
- На хр...на мне палка!! ! Мне банан нужен!!!!
Так вот. Кому палка не нужна пусть и дальше трясут)
Та ужеж писал, нет никакого обработчика)))
ок. назови горшком и опубликуй код - я не сильно буду смеяться.
Отчего же не повеселить.. вот собственно весь ввод с 3-х кнопок.. Последние 4 строки - отладка на экран, остальные 8 строк - все. Какой нафиг класс..
01
void
loop
(
02
....
03
04
KBD=0;
05
if
(Time-TimeKBD>300)
06
{
07
byte
kbd= digitalRead(KBD_K1)+2*digitalRead(KBD_K2)+4*digitalRead(KBD_K3);
08
kbd^=7;
//комутируем землю
09
if
(kbd)
10
{
11
TimeKBD=Time;
12
Sound=PIs;
// пищим коротко
13
KBD=kbd;
// код нажатиой
14
}
15
16
myOLED.setFont( SSD1306::FONT_SIZE_1);
17
char
s[10];
18
ltoa(kbd,s,10);
19
myOLED.drawString(0,0,s);
20
}
21
.....
Я понял только одно, если бы я назвал класс Relay&LEDControl, вопросов к скорости работы невозникло.
И что плохого в том чтобы просто объявить relay(10) и управлять им relay.HI(), relay.LO(), relay.blink(1000,500)
Тут многие пишут int relay=10?:( digitalWrite(relay,HIGH) - это нормально номер пина в переменные вносить?
Я понял только одно, если бы я назвал класс Relay&LEDControl, вопросов к скорости работы невозникло.
- это нормально номер пина в переменные вносить?
Абстрагировать пины можна только на уровень выше, соблюдая принцип адресация пина (порта, маски и т.д.) константой.
Какой нафиг класс..
красавчик, чо... свалить всё в одну кучу, что бы затем разгребать результат.
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
Только класс Relay. Как для оччень тормознутых устройств ;) Но вопрос "а нафига" останется.
Смотрите первый пост темы.
Автор, вам уже не один я отписал, что Вы пишете лисапед. Мало того, что это лисапед, так ещё и 5-и колесный, и с квадратными колесами. Не, мазохизм тоже имеет место быть в жизни .. я вовсе не против. Но позиционировать мазохизм как религию и предлагать всем (библиотека) - увольте. :)
По вашей аналогии с классом Relay.. да хоть горшком назови, он от этого "ногодрыгом" быть не перестанет! Про что вам уже Logik и отписал: "а нафига?" (лисапед 5-и колесный, да-да, он самый!).
Да, и то как Вы прописали пин в виде константы - это нормальная практика программирования МК. Абстрагирование от чиселки константой препроцессора. Каждая ного МК исполняет и ПРЕДНАЗНАЧЕНА (что важно!) ровно для решения своей задачи... и "абстрагировать" далее .. банально нечего. Все попытки писать "универсальные" (5-и колесные) лисапеды - от глупости и непонимания зачем ваще нужны микроконтроллеры. Ну .. или привычка кодить там, где никто не спросит ни за объем памяти ни за скорость исполнения .. то есть за качество решения. "работает и ладно".
P.S. Офигел вчера: поставил Убунту с Юнити на 4-й пенек и обнаружил скорость ввода с клавиатуры .. 1 клавиша в 3(ТРИ!) секунды .. ладно, я понимаю что графика слабовата, рисует медленно и печально .. но чтобы ввод склавы решался задержками типа delay как у мелкософта было в свое время .. не, такого представить себе в среде линуксоидов не мог.. пипец какой-то.
P.S. Офигел вчера: поставил Убунту с Юнити на 4-й пенек и обнаружил скорость ввода с клавиатуры .. 1 клавиша в 3(ТРИ!) секунды ..
бросай, всё что всем обещал сделать вчера и начинай переписывать клавиатуру для Линукса сейчас - хватит это терпеть!
красавчик, чо... свалить всё в одну кучу, что бы затем разгребать результат.
if(KBD&1) //нажали -поехали Это проблема?
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
нажатие на одну кнопку на заданное время отрубает остальные, затем перебираешь все возможные комбинации нажатий, что бы понять, что вообще произошло - сколько и какие кнопки были нажаты?
Какие нафиг комбинации? В проекти не предусмотрены. Это банальная навигация: лево, право и ОК.
А даже если нужно, так и тоже пожалуста - if(KBD&(1|2) ) //нажали комбинацию 1 и 2 -поехали
Только надо с таймаутом подшаманить нажмут не совсем одновременно, я в курсе;)
ок. а, для 10 кнопок, так же будешь поступать? сколько комбинаций вариантов нажатий будешь перебирать?
Битовые операции - сила ;)
А нафиг? Поставил последний Дебиан и всё, делов-то. Даже кеды бегают вполне прилично. :)
Какие нафиг комбинации?
внезапно, да?
Только надо с таймаутом подшаманить нажмут не совсем одновременно, я в курсе;)
ага. подшамань - допиши: даблклик, удержание, отслеживание неактивности.
напиши велосипед без класса.
Какие нафиг комбинации?
внезапно, да?
Цитаты приводятся с завершенным содержанием. Там так:"Какие нафиг комбинации? В проекти не предусмотрены. "
А то из твоего сам знаеш чего можно надергать...
Только надо с таймаутом подшаманить нажмут не совсем одновременно, я в курсе;)
ага. подшамань - допиши: даблклик, удержание, отслеживание неактивности.
напиши велосипед без класса.
Так не в первое. К примеру есть у меня тут девайсик где все управление на енкодере, там кнопочка ух как завернута.
Но по реализации я так понял больше вопросов нет. На хрена класс кнопки если решается в 8 строк 3 кнопки?
На хрена класс кнопки если решается в 8 строк 3 кнопки?
нахрена 8 строк, если всё решается одной строкой if(digitalRead(pin)) {}; ?
На хрена класс кнопки если решается в 8 строк 3 кнопки?
нахрена 8 строк, если всё решается одной строкой if(digitalRead(pin)) {}; ?
Ух-ты!! сразу 3 кнопки 8))).
Ну елы палы! Покажи всем шо я не прав в реализации! Дафай код на своем кллассе делающий тоже самое что и мой, т.е. почти нифига. Дальше ржом вместе, считаем размер по флешу и ОЗУ, число строк (или букв) в исходнике ;).. Короче развлекаемся по полной, а то шото скучно здесь последние 48 часов )))
Кстати класс экрана в 8 строк переписать не выходит. Я пробовал. Никак. Потому там класс имеет смысл.
ПС. Можем в веловетку переместится.
Ух-ты!! сразу 3 кнопки 8))).
ну, ок - 3 строки. по любому мой вариант лучше. :D
Ну елы палы! Покажи всем шо я не прав в реализации!
я же тебе указал, что всё, что ты сделал для сокращения размера кода - не реализовал ничего, кроме
if
(Time-TimeKBD>300)
считая результат Time-TimeKBD общим для всех кнопок.плюс ты породил некую сущность KBD , которая вызовет у тебя для примера из 10 кнопок 99 ифов для разгребания результата.
если мой подход одинаково применим для любого количества кнопок, то твой заставляет тебя юлить, утверждая, что ты молодец потому, что класс экрана что-то там.
*можно спорить с тобой бесконечно, но битовые операции - это же круто, да? а, класс экрана что-то там.
ЕвгенийП, не получается переопределить оператор "=".
1
DigOut
operator
=(DigOut& right) {
2
if
(
this
== &right) {
3
return
*
this
;
4
}
5
DigOut.state = &right.value;
6
return
*
this
;
7
}
В чем может быть проблемма?
ПС. Можем в веловетку переместится.
нет - там достаточно гениального бреда.
Ух-ты!! сразу 3 кнопки 8))).
ну, ок - 3 строки. по любому мой вариант лучше. :D
Действительно, так лучше чем три обекта класса кнопки а в каждом ;)
я же тебе указал, что всё, что ты сделал для сокращения размера кода - не реализовал ничего, кроме
if
(Time-TimeKBD>300)
считая результат Time-TimeKBD общим для всех кнопок.плюс ты породил некую сущность KBD ,
byte KBD; ???))) Ну ладно сущность - так сущность.
которая вызовет у тебя для примера из 10 кнопок 99 ифов для разгребания результата.
нее... если их реально много то свич или косвенный переход, или мапируется на события если такая модель есть в проекте (мапируются - это не map() это как правило "+"). Под настроение и ситуацию.
Действительно, так лучше чем три обекта класса кнопки а в каждом ;)
ок.
сначала - ты считаешь, что твой код реализует функционал класс титановый велосипед для тактовой кнопки в восьми строках?
*простой булевый вопрос. да/нет?
далее... сколько строк в этом коде?
01
void
read() {
02
unsigned
long
nm = millis();
03
boolean np = digitalRead(_pb);
04
boolean nb = 0;
05
click_down = 0;
06
if
(np != p) {p = np; m = nm;}
07
if
(nm - m > bounce_ ) {nb = 1;}
08
if
(nb != b ) {b = nb ;
09
if
(p == 0 && b == 0) {click_down = 1;}
10
}
11
}
як нэвдобно выйшло... но библиотека индикатора что-то там, правда?
класс для int ожидать.
Делается и очень часто. Например, когда нужно постоянно диапазон значений контролировать
ЕвгенийП, не получается переопределить оператор "=".
1
DigOut
operator
=(DigOut& right) {
2
if
(
this
== &right) {
3
return
*
this
;
4
}
5
DigOut.state = &right.value;
6
return
*
this
;
7
}
В чем может быть проблемма?
Теперь уж завтра
Переписал класс. Скорость функций HI(), LO() по сравнению со стандартым digitalWrite выросла примерно в 1,45 раза. Написан конечно криво, надо подумать как изящней переписать (избавится от switch).
DigOut.h
01
#ifndef DigOut_h
02
#define DigOut_h
03
//#include <arduino.h>
04
class
DigOut
05
{
06
public
:
07
DigOut(
int
pin=13,
bool
state=0);
08
void
HI();
//установить высокий уровень
09
void
LO();
//установить низкий уровень
10
void
invert();
//инвертировать выход
11
bool
state();
//получить состояние
12
void
blink(unsigned
long
period=1000,
int
impuls=250);
//выдает импульсы с заданным периодом и длиной
13
14
private
:
15
int
_pin;
//выходной пин
16
unsigned
long
preMillis;
//предыдущее время
17
};
18
19
#endif
DigOut.cpp
001
#include <arduino.h>
002
#include "DigOut.h"
003
004
DigOut::DigOut(
int
pin,
bool
state)
//конструктор
005
{
006
_pin = pin;
007
pinMode(_pin, OUTPUT);
008
if
(state==0){LO();}
009
else
{HI();}
010
preMillis=millis();
011
}
012
013
void
DigOut::HI()
//установить высокий уровень
014
{
015
switch
(_pin) {
016
case
0:
017
PORTD |= (1 << 0);
//HI
018
break
;
019
case
1:
020
PORTD |= (1 << 1);
//HI
021
break
;
022
case
2:
023
PORTD |= (1 << 2);
//HI
024
break
;
025
case
3:
026
PORTD |= (1 << 3);
//HI
027
break
;
028
case
4:
029
PORTD |= (1 << 4);
//HI
030
break
;
031
case
5:
032
PORTD |= (1 << 5);
//HI
033
break
;
034
case
6:
035
PORTD |= (1 << 6);
//HI
036
break
;
037
case
7:
038
PORTD |= (1 << 7);
//HI
039
break
;
040
case
8:
041
PORTB |= (1 << 0);
//HI
042
break
;
043
case
9:
044
PORTB |= (1 << 1);
//HI
045
break
;
046
case
10:
047
PORTB |= (1 << 2);
//HI
048
break
;
049
case
11:
050
PORTB |= (1 << 3);
//HI
051
break
;
052
case
12:
053
PORTB |= (1 << 4);
//HI
054
break
;
055
case
13:
056
PORTB |= (1 << 5);
//HI
057
break
;
058
}
059
}
060
061
void
DigOut::LO()
//установить низкий уровень
062
{
063
switch
(_pin) {
064
case
0:
065
PORTD &= ~((1 << 0));
//LO
066
break
;
067
case
1:
068
PORTD &= ~((1 << 1));
//LO
069
break
;
070
case
2:
071
PORTD &= ~( (1 << 2));
//LO
072
break
;
073
case
3:
074
PORTD &= ~((1 << 3));
//LO
075
break
;
076
case
4:
077
PORTD &= ~((1 << 4));
//LO
078
break
;
079
case
5:
080
PORTD &= ~((1 << 5));
//LO
081
break
;
082
case
6:
083
PORTD &= ~((1 << 6));
//LO
084
break
;
085
case
7:
086
PORTD &= ~((1 << 7));
//LO
087
break
;
088
case
8:
089
PORTB &= ~((1 << 0));
//LO
090
break
;
091
case
9:
092
PORTB &= ~((1 << 1));
//LO
093
break
;
094
case
10:
095
PORTB &= ~((1 << 2));
//LO
096
break
;
097
case
11:
098
PORTB &= ~((1 << 3));
//LO
099
break
;
100
case
12:
101
PORTB &= ~((1 << 4));
//LO
102
break
;
103
case
13:
104
PORTB &= ~((1 << 5));
//LO
105
break
;
106
}
107
}
108
109
bool
DigOut::state()
//получить состояние выхода
110
{
111
return
digitalRead(_pin);
112
}
113
114
void
DigOut::invert()
//инвертировать выход
115
{
116
digitalWrite(_pin, !digitalRead(_pin));
117
}
118
119
void
DigOut::blink (unsigned
long
period,
int
impuls)
//выдавать импульсы
120
{
121
if
(millis()-preMillis>=period){
//если интервал прошел
122
preMillis=millis();
//сбрасываем
123
}
124
if
(millis()<impuls+preMillis){
//если время свечения индикатора не прошло
125
HI();
126
}
127
else
//иначе
128
{
129
LO();
130
}
131
}
DigOut.rar
ты считаешь, что твой код реализует функционал класс титановый велосипед для тактовой кнопки в восьми строках?
*простой булевый вопрос. да/нет?
Нет канешно! False тоесть ;) Хай меня покрасят, шоб я реализовывать функционал какогото самопального класса.. Я ж четко писал.
в скетче в нужных местах проверяется нажата или нет, нигде не ждем нажатия, никакого дребезга не видно в помине.
Код работает, замечаний нет. Ты попросил показать, поржать хотел, я показал. А реализовывать класс титановый велосипед.... Ты наверно шутиш, да? Мне это в программе нафиг надо.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
як нэвдобно выйшло... но библиотека индикатора что-то там, правда?
Невдобно конечно, но я ж понимаю, ты весь на нервах, бум щитать от ненависти ;)
А чего это за код был? и чего снова для одной кнопки? Хотя после 15байт на один пин уже и не важно...
Вывод. Замена существующего кода в моем приложении на реализацию на основе класса титанового велосипеда потребует значительного количества доп. ресурсов контроллера. Усьо!
ПС. О пользе диалога. Призадумался, чего это я комбинации кнопок проигнорил. Конечно 3-х кнопок хватает, но на дополнительные 4 комбинации можна тоже чего навесить. В общем на днях допишу себе таки ввод комбинаций, спасибо Клапауций 232. Если кого интересует, пишите выложу здесь.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
я же тебе дал код. ок - дублирую
01
void
read() {
02
unsigned
long
nm = millis();
03
boolean np = digitalRead(_pb);
04
boolean nb = 0;
05
click_down = 0;
06
if
(np != p) {p = np; m = nm;}
07
if
(nm - m > bounce_ ) {nb = 1;}
08
if
(nb != b ) {b = nb ;
09
if
(p == 0 && b == 0) {click_down = 1;}
10
}
11
}
А чего это за код был?
не знаю, а ты как думаешь, чего это код?
и чего снова для одной кнопки? Хотя после 15байт на один пин уже и не важно...
я понимаю, что нужно было слить все булевые переменные кода в один байт, затем по мере необходимости разбираться, что это было - кнопка, датчик или ничего.
но, это же костыль - я не понимаю, зачем ты это делаешь... что бы было много свободной оперативки, что бы что?
*проверил класс с урезанным функционалом для 10-ти кнопок - 89 байт (4%) ок. для 100 кнопок займёт 40% оперативки. а, ты как будешь рулить 100 кнопками и со свободной оперативкой? придумаешь новую отмазку или поймёшь, что ты написал костыль?
ЕвгенийП, не получается переопределить оператор "=".
1
DigOut
operator
=(DigOut& right) {
2
if
(
this
== &right) {
3
return
*
this
;
4
}
5
DigOut.state = &right.value;
6
return
*
this
;
7
}
В чем может быть проблемма?
А так:
1
DigOut&
operator
=(
const
DigOut& right)
2
{
3
if
(
this
== &right)
4
{
5
return
*
this
;
6
}
7
this
->state = right.state;
8
return
*
this
;
9
}
Принцип в том, что сперва проверяешь, что присваивание вызывается не для одного и того же объекта. Потом копируешь поля из переданного объекта себе, поле к полю, а не так, как ты сделал (DigOut.state = right.value) - шо такое right.value?
yul-i-an, потом настанет черёд конструктора копирования ;) А потом, до кучи - explicit-конструктора, чтобы исключить неявные преобразования. Потом - можно определить операторы сравнения, операторы типов - например, operator int(), который будет возвращать номер пина, чтобы можно было удобно писать
1
DigOut ledPin(13);
2
3
int
pin = ledPin;
// в pin - число 13
И ещё куча разных вкусных плюшек, например:
1
DigOut ledPin(13);
2
3
ledPin <<
true
;
// включим пин
4
5
ledPin <<
false
;
// выключим пин
тоже решается оператором ;) Кури, С++ вкусный язык.
З.Ы. Ну а потом дойдём и до шаблонов когда-нибудь :)
З.З.Ы. Конечно, рулить пинами с помощью класса - избыточно, но мы ведь не этого добиваемся? Смотри, насколько интересная конструкция:
1
DigOut pinManager;
2
3
pinManager << 13 <<
true
;
// выставили HIGH на пине 13
4
5
pinManager << 22 <<
false
;
// выставили LOW на пине 22
А унутре потом - можно перейти на прямую запись в порт и пин. Более того - если грамотно спроектировать класс и сделать хэш для ранее использованных пинов - то повторные вызовы установки уровня на пине будут просто летать, в назидание всем негодующим. Да, оверхэд по памяти будет небольшой, но порой удобство того стоит.
В общем, считаю, что экономить надо начинать тогда, когда совсем уже жмёт, так что - тренируйся, перейти на низкий уровень никогда не поздно.
Вот еще полюбопытствовал я на счет реализации ровно того же что и у меня через твой класс. Ты стыдливо отвернулся. Я глянул в класс и обомлел - 15 байт ОЗУ на 1 кнопку!!! Нах, нах,нах...
я же тебе дал код. ок - дублирую
1
....
А чего это за код был?
не знаю, а ты как думаешь, чего это код?
И ты не знаеш... А нафига запостил? Я про свой код думаю, мне хватает..
я понимаю, что нужно было слить все булевые переменные кода в один байт, затем по мере необходимости разбираться, что это было - кнопка, датчик или ничего.
но, это же костыль - я не понимаю, зачем ты это делаешь... что бы было много свободной оперативки, что бы что?
*проверил класс с урезанным функционалом для 10-ти кнопок - 89 байт (4%) ок. для 100 кнопок займёт 40% оперативки. а, ты как будешь рулить 100 кнопками и со свободной оперативкой? придумаешь новую отмазку или поймёшь, что ты написал костыль?
Еще раз с начала. У меня кнопки, их 3 шт. Ровно 3 кнопки запомнил. Во вторых у меня код есть, без левых классов и работает. Ты утверждаеш что если перейти на твой велосипед то будет как минимум не хуже. Так? Подтверди да или нет.
Я же вижу что как минимум ОЗУ уйдет дохера, а это хуже. Вижу по классу. Ты суеш какую-то функцию, сам не знаеш что и зачем, но она похоже для одной кнопки (которая уже ОЗУ отгребает как мои 3 кнопки), расказываеш про 10 или 100. Ты посотри на ту функцию, ввод digitalRead(_pb); и _pb глобальная. Как мне это использовать для 3-х кнопок? Три функции делать шоле. Каким боком она вобще к твоему классу относится? Фигня какая-то неопознаная. Расказы "мог бы, слил бы" - в топку, есть опубликованый класс, но он не тянет. Я выбор сделал, выводы написал.
Кста кода, обрабатывающего одновременное нажатие нескольких в классе не видно шото. Нибось, я себе не скопипащу, у нас подходы разные.
Кста кода, обрабатывающего одновременное нажатие нескольких в классе не видно шото.
а, должен быть в классе код, обрабатывающий несколько, а не одну кнопку?
ок. вот тебе ещё(в третий) раз код класса, урезанный до твоего функционал(нажатие кнопки) - копипасть на здоровье. :D
01
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02
// класс титановый велосипед для тактовой кнопки.
03
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.
04
05
#include <Arduino.h>
06
07
class
BUTTON {
08
public
:
09
//===============================================================================================
10
static
const
byte
bounce_ = 50;
// длительность отслеживания дребезга.
11
// static const byte doubleclick_ = 200; // длительность отслеживания двойного клика.
12
// static const unsigned long timer_ = 5000; // длительность отслеживания неактивности.
13
// static const unsigned int retention_ = 2000; // длительность отслеживания нажатия и удержания.
14
//===============================================================================================
15
boolean click_down;
16
// boolean click_up;
17
// boolean doubleclick;
18
// boolean timer;
19
// boolean retention;
20
//=================================
21
unsigned
long
m;
22
boolean p;
23
boolean b;
24
// boolean dc;
25
// byte c;
26
// boolean t;
27
// boolean r;
28
//=================================
29
byte
_pb;
30
//=================================
31
BUTTON(
byte
pb) {
32
_pb = pb;
33
pinMode(_pb, INPUT);
34
digitalWrite(_pb, 1);
35
//====
36
click_down = 0;
37
// click_up = 0;
38
// doubleclick = 0;
39
// timer = 0;
40
// retention = 0;
41
//====
42
m = millis();
43
p = digitalRead(_pb);
44
b = 0;
45
// dc = 0;
46
// c = 0;
47
// t = 0;
48
// r = 0;
49
//====
50
}
51
52
void
read() {
53
//=======================================================
54
unsigned
long
nm = millis();
55
boolean np = digitalRead(_pb);
56
//=================
57
boolean nb = 0;
58
// boolean ndc = 0;
59
// boolean nt = 0;
60
// boolean nr = 0;
61
//================
62
click_down = 0;
63
// click_up = 0;
64
// doubleclick = 0;
65
// timer = 0;
66
// retention = 0;
67
//=================
68
if
(np != p) {p = np; m = nm;}
69
//=======================================================
70
if
(nm - m > bounce_ ) {nb = 1;}
71
// if (nm - m > doubleclick_) {ndc = 1;}
72
// if (ndc != dc) {dc = ndc;
73
// if (dc == 1) {c = 0;}
74
// }
75
if
(nb != b ) {b = nb ;
76
if
(p == 0 && b == 0) {click_down = 1;
77
// ++c;
78
// if (c == 2) {c = 0; doubleclick = 1;}
79
}
80
// if (p == 1 && b == 1) {click_up = 1;}
81
}
82
//=======================================================
83
// if (nm - m > timer_ ) {nt = 1;}
84
// if (nt != t ) {t = nt ;
85
// if (p == 1 && t == 1) {timer = 1;}
86
// }
87
//=======================================================
88
// if (nm - m > retention_ ) {nr = 1;}
89
// if (nr != r ) {r = nr ;
90
// if (p == 0 && r == 1) {retention = 1;}
91
// }
92
//=======================================================
93
}
94
};
95
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
скетч-тест 10 кнопок - обработка нажатия.
01
// #include <class_BUTTON.h>
02
#include <class_BUTTON_mini.h>
03
04
BUTTON BUTTON_01( 3);
05
BUTTON BUTTON_02( 4);
06
BUTTON BUTTON_03( 5);
07
BUTTON BUTTON_04( 6);
08
BUTTON BUTTON_05( 7);
09
BUTTON BUTTON_06( 8);
10
BUTTON BUTTON_07( 9);
11
BUTTON BUTTON_08(10);
12
BUTTON BUTTON_09(11);
13
BUTTON BUTTON_10(12);
14
15
void
setup
() {
16
pinMode(14, OUTPUT);
17
digitalWrite(14, 1);
18
}
19
20
void
loop
() {
21
22
BUTTON_01.read();
23
BUTTON_02.read();
24
BUTTON_03.read();
25
BUTTON_04.read();
26
BUTTON_05.read();
27
BUTTON_06.read();
28
BUTTON_07.read();
29
BUTTON_08.read();
30
BUTTON_09.read();
31
BUTTON_10.read();
32
33
if
(BUTTON_01.click_down) {digitalWrite(14, !digitalRead(14));}
34
if
(BUTTON_02.click_down) {digitalWrite(14, !digitalRead(14));}
35
if
(BUTTON_03.click_down) {digitalWrite(14, !digitalRead(14));}
36
if
(BUTTON_04.click_down) {digitalWrite(14, !digitalRead(14));}
37
if
(BUTTON_05.click_down) {digitalWrite(14, !digitalRead(14));}
38
if
(BUTTON_06.click_down) {digitalWrite(14, !digitalRead(14));}
39
if
(BUTTON_07.click_down) {digitalWrite(14, !digitalRead(14));}
40
if
(BUTTON_08.click_down) {digitalWrite(14, !digitalRead(14));}
41
if
(BUTTON_09.click_down) {digitalWrite(14, !digitalRead(14));}
42
if
(BUTTON_10.click_down) {digitalWrite(14, !digitalRead(14));}
43
44
}
Ты утверждаеш что если перейти на твой велосипед то будет как минимум не хуже. Так? Подтверди да или нет.
я утверждаю, что у тебя не может быть никаких претензий к класс титановый велосипед для тактовой кнопки, т.к. код класса стремится к идеалу и никто, в том числе ты, не смогли предъявить никаких претензий к коду, алгоритму и качеству работы.
лично ты на ходу выдумываешь эмоциональные и ничем не подкреплённые претензии - то тебе это не нужно, потому, что у тебя есть костыль, то тебе показалось, что много памяти кушает, теперь класс, оказывается - левый, а у тебя есть костыль.
сделал выбор и сделал - ходи на трёх ногах, но нафига хаять, то чему у небя неприязнь на эмоциональном уровне.
Ты посотри на ту функцию, ввод digitalRead(_pb); и _pb глобальная. Как мне это использовать для 3-х кнопок?
Переписал класс. Скорость функций HI(), LO() по сравнению со стандартым digitalWrite выросла примерно в 1,45 раза. Написан конечно криво, надо подумать как изящней переписать (избавится от switch).
Давайте пока не будем этим заниматься. Всему своё время.
Я понимаю, что Вас смущают замечания прогеров насчёт эффективности, но во-первых, таким способом Вы от этих замечаний не избавитесь, т.к. всё равно есть пути сделать это эффективнее, а во-вторых, я же Вам говорил, если Вы хотите научиться, то давайте идти шаг за шагом и, в какой-то момент, мы просто заменим методы HI/LO на самые эффективные, а вся, сделанная нами, оснастка останется нетронутой.
Заменить методы можно в любой момент, это очень просто. Некоторые тут не знают как это делается. но скачали где-то пример в котором не сумели разобраться. Поэтому им это кажется сложным (всё, в чём не сумел разобраться, кажется сложным), на самом деле, ничего там сложного нет, если знать и правильно применять язык.
Поэтому, давайте пока будем просто плевать на безграмотный бред прогеров и идти шаг за шагом.
начнём с оператор априсваивания. Коллега DIYMan всё правильно написал, но я хочу пойти дальше. Но, для начала, давайте зафиксируем текст класса (а то я уже запутался в Ваших версиях). Я сейчас выложу текст с которым я буду работать и давайте пока мы не закончим с низкоуровневой оснасткой, мы не будем добавлять туда высокоуровневые методы типа blink.
Итак, текст класса:
01
#ifndef DigOut_h
02
#define DigOut_h
03
04
#include <arduino.h>
05
06
class
DigOut {
07
public
:
08
// Конструктор
09
DigOut (
const
int8_t pin=13,
const
bool
state=0) {
10
pinMode(_pin = pin, OUTPUT);
11
(state) ? HI() : LO();
12
}
13
14
// установить уровень
15
void
DW(
const
bool
state)
const
{
16
digitalWrite(_pin, state);
17
}
18
19
// установить высокий уровень
20
void
HI(
void
)
const
{
21
DW(HIGH);
22
}
23
24
// установить низкий уровень
25
void
LO()
const
{
26
DW(LOW);
27
}
28
29
// инвертировать выход
30
void
invert(
void
)
const
{
31
DW(!state());
32
}
33
34
// получить состояние
35
bool
state(
void
)
const
{
36
return
digitalRead(_pin);
37
}
38
39
private
:
40
int8_t _pin;
//выходной пин
41
};
42
43
#endif
Текст проверчного примера:
1
#include "DigOut.h"
2
3
void
setup
(
void
) {}
4
5
void
loop
(
void
) {
6
static
DigOut p13;
7
delay(500);
8
p13.invert();
9
}
Вроде, всё мигает. давайте, будем плясать строго от этого текста, чтобы мы говорили об одном и том же.
Кстати, обратите внимание, что я сократил тип данных _pin (зачем ему два байта занимать?) и всем методам добавил модификатор const, чтобы развязать руки оптимизатору.
Теперь вернёмся к присваиванию. Для начала сделаем присваивание экземпляро класс друг другу.
иВаши ошибка в том, что
1) Вы возвращаете экземпляр класса, а надо ссылку
2) у Вас нет свойста, которое хранит состояние. Состояние хранится непосредственно на самом пине, так? Ну, так значит при присваивании оно должно получить значение! А Вы этого не сделали.
3) при присваивании Вы проверяете, а не самому ли себе идёт присваивание. В общем случае это хорошая практика, но в данном случае это лишнее - зачем? Какая разница? Вы же не запрашиваете память и не делаете ничего страшного.
Таким образом, алгоритм присваивания одного экземпляра другому таков:
1. Установить состояние текущего экземпляра класса таким же каково состояние присваиваемого.
2) вернуть ссылку на текущий экземпляр.
Так и пишем:
1
DigOut &
operator
= (DigOut & original) {
2
DW(original.state());
// присвоили состояние
3
return
*
this
;
// вернули ссылку
4
}
Вот и всё.
Текущий текст класса:
01
#ifndef DigOut_h
02
#define DigOut_h
03
04
#include <arduino.h>
05
06
class
DigOut {
07
public
:
08
// Конструктор
09
DigOut (
const
int8_t pin=13,
const
bool
state=0) {
10
pinMode(_pin = pin, OUTPUT);
11
(state) ? HI() : LO();
12
}
13
14
// установить уровень
15
void
DW(
const
bool
state)
const
{
16
digitalWrite(_pin, state);
17
}
18
19
// установить высокий уровень
20
void
HI(
void
)
const
{
21
DW(HIGH);
22
}
23
24
// установить низкий уровень
25
void
LO()
const
{
26
DW(LOW);
27
}
28
29
// инвертировать выход
30
void
invert(
void
)
const
{
31
DW(!state());
32
}
33
34
// получить состояние
35
bool
state(
void
)
const
{
36
return
digitalRead(_pin);
37
}
38
39
DigOut &
operator
= (DigOut & original) {
40
DW(original.state());
// присвоили состояние
41
return
*
this
;
// вернули ссылку
42
}
43
44
private
:
45
int8_t _pin;
//выходной пин
46
};
47
48
#endif
Текст проверочного примера
01
#include "DigOut.h"
02
03
void
setup
(
void
) {}
04
05
void
loop
(
void
) {
06
static
DigOut p13, p7(7);
07
delay(500);
08
p7.invert();
09
p13 = p7;
10
}
Всё понятно? Если непонятно, спрашивайте.
Теперь определим присваивание экземпляру класса значение типа bool, чтобы можно было писать "p13 = LOW" вместо вызова функции.
Итак, сложного ничего нет, по традиции оператор присваивания должен вернуть присвоенное значение, значит тип у него bool. Нужно просто выставить значение. Техника такова, смотрите:
1
bool
operator
= (
const
bool
newState) {
2
DW(newState);
3
return
newState;
4
}
Текущий текст класса:
01
#ifndef DigOut_h
02
#define DigOut_h
03
04
#include <arduino.h>
05
06
class
DigOut {
07
public
:
08
// Конструктор
09
DigOut (
const
int8_t pin=13,
const
bool
state=0) {
10
pinMode(_pin = pin, OUTPUT);
11
(state) ? HI() : LO();
12
}
13
14
// установить уровень
15
void
DW(
const
bool
state)
const
{
16
digitalWrite(_pin, state);
17
}
18
19
// установить высокий уровень
20
void
HI(
void
)
const
{
21
DW(HIGH);
22
}
23
24
// установить низкий уровень
25
void
LO()
const
{
26
DW(LOW);
27
}
28
29
// инвертировать выход
30
void
invert(
void
)
const
{
31
DW(!state());
32
}
33
34
// получить состояние
35
bool
state(
void
)
const
{
36
return
digitalRead(_pin);
37
}
38
39
// Присваивание одного экземпляра другому
40
DigOut &
operator
= (DigOut & original) {
41
DW(original.state());
// присвоили состояние
42
return
*
this
;
// вернули ссылку
43
}
44
45
// Присваивание экземпляру значение типа bool
46
bool
operator
= (
const
bool
newState) {
47
DW(newState);
48
return
newState;
49
}
50
51
private
:
52
int8_t _pin;
//выходной пин
53
};
54
55
#endif
Текст проверочного примера
01
#include "DigOut.h"
02
03
void
setup
(
void
) {}
04
05
void
loop
(
void
) {
06
static
bool
ledOn =
false
;
07
static
DigOut p13;
08
delay(500);
09
ledOn = (p13 = ! ledOn);
10
11
}
Понятно?
Теперь, прежде, чем мы перейдём дальше, домашнее задание.
1) проверьте, работает ли наше присваивание типа bool в случае, если попытаться присвоить тип int;
2) попробуйте сами реализовать преобразование к типу bool. Чтобы можно было писать вместо "bool isOn = p13.state();" просто "bool isOn = p13;"
Евгений, хочу заметить, что это не совсем верный подход, кмк, т.к. цепочка вызовов разрушается:
1
bool
operator
= (
const
bool
newState) {
2
DW(newState);
3
return
newState;
4
}
Надо:
1
DigOut&
operator
= (
const
bool
newState) {
2
DW(newState);
3
return
*
this
;
4
}
Плюс определить оператор bool:
1
DigOut::
operator
bool
()
2
{
3
return
currentState;
4
}
Тогда будут работать и цепочки вызовов, например:
1
DigOut d1, d2;
2
bool
b;
3
d1 = b = d2 =
true
;
И получение состояния в переменную типа bool:
1
bool
b = d2;
Т.е. архитектурно более верно определять полный набор операторов для одного типа данных, не надеясь на оптимизатор и неявные преобразования. Впрочем, это уже сахар.
Евгений, хочу заметить, что это не совсем верный подход, кмк, т.к. цепочка вызовов разрушается:
1
bool
operator
= (
const
bool
newState) {
2
DW(newState);
3
return
newState;
4
}
Надо:
1
DigOut&
operator
= (
const
bool
newState) {
2
DW(newState);
3
return
*
this
;
4
}
Нет, нет, Вы перепутали. Это присваивание значение типа bool (посмотрите на параметр оператора!).
Любой оператор присваивания должен возвращать то, что было присвоено. Не новое значение экземпляра объекта, а именно то, что было присвоено. Разумеется, это не жёсткое требование, на практике мы можем вернуть что угодно, но такое соглашение есть и я ему следовал. Поэтому данный оператор должен возвращать именно bool! Цепочка же будет отлично работать, если определить преобразование типа этого класса к bool. Тогда можно писать конструкции вроде p13 = p12 = p7 = true;
Я не говорю, что нельзя делать так, как Вы написали - можно, почему нет? Просто я строго следовал концепции, что "оператор присваивания должен возвращать то, что было присвоено" и в рамках этой концепции у меня всё написано верно.
Евгений, безусловно, я понимаю, о чём вы:
Однако:
the canonical "unified assignment operator" implementation is
И я всегда придерживаюсь второго подхода, возвращая *this, т.к. мы работаем с объектом класса, который может быть и lvalue. Считаю, что оперировать объектом класса в перегруженных операторах - это самое грамотное поведение, вне зависимости от того, какой объект нам передали в оператор (в нашем случае оператор присваивания). Скажем, если мы переопределим оператор <<, то там, очевидно, надо всегда возвращать *this, вне зависимости от переданного аргумента, не находите?
01
T& T::
operator
<<(
int
val)
02
{
03
cout << val;
return
*
this
;
04
}
05
T& T::
operator
<<(
const
String& s)
06
{
07
cout << s.c_str();
return
*
this
;
08
}
09
10
T t;
11
12
t << 123 <<
"Hello, "
<< 456 <<
", world!"
;
В приведённом примере противопоказано возвращать что-либо, отличное от ссылки на объект ;)
В приведённом примере противопоказано возвращать что-либо, отличное от ссылки на объект ;)
Ну, в приведённом-то само собой :)))
Да, нет, ну, понятно, что вопрос идеологический и можно делать как угодно. Важно только определиться и в пределах всего проекта делать одинаково, чтобы бардака не было. Если ТС захочет возвращать *this - да не вопрос, ему-то сейчас глваное просто научиться возвращать то, что хочет :) Опять же, если в добавок к возвращению *this будет определено преобразование к bool, то и цепочное присваивание bool'евским переменным будет отлично работать, так что можно делать и так - никаких проблем.
Я тут, как видите. всё вынес в inline и готовлю ТС, чтобы в нужный момент просто заменить вызовы digitalXXX (методы HI/LO) на портовые команды так, чтобы все операции сразу однокомандными стали, а то ведь прогеры ему печень съедят, если будет не так :)
Кста кода, обрабатывающего одновременное нажатие нескольких в классе не видно шото.
а, должен быть в классе код, обрабатывающий несколько, а не одну кнопку?
ок. вот тебе ещё(в третий) раз код класса, урезанный до твоего функционал...
Себе оставь, я ж те четко написал. Эту хрень я не использовал, не буду и другим не рекомендую. Почему - разжевано выше. Можеш урезать, зарезать, отрезать, прирезать. И шо это за подход к либе - урезал и пользуй. Под каждого будеш урезать? А тестить буш сам?. Кстати после урезания он тоже жрет больше ОЗУ. Может обрезание надо, шоб кошерный был? DDD
я утверждаю, что у тебя не может быть никаких претензий...
претензий к класс титановый велосипед для тактовой кнопки, т.к. код класса стремится к идеалу и никто, в том числе ты, не смогли предъявить никаких претензий к коду, алгоритму и качеству работы.
Чешеш хрень. Я даже попробовал прикинуть переход на твой класс. И сравнил оба варианта, класс проиграла сразу и бесповоротно, по ОЗУ. Что и подтверждает исходное - для кнопки класс не нужен. До сравнения вариантов по остальным пунктам дело не дошло. Потому класса -небудет!
Ответа по существу нет. ну и нахер, вопрос про класс решен.
ПС. От интересно, Клапауций, ты действительно считаеш, что я закоментирую свой код (который короче экономней твоего по ОЗУ и работает замечательно, к тому же легко модифицировался под прием нескольких одновременных нажатий) и всуну твой "урезок" (который длинней, жрет больше ОЗУ и токошо тобой поправлен и нихрена ни тещен и соответственно нихрена не надежен)? И токо из за того шо ты написал "костыль" да "три ноги", без каких либо аргументов. Пиши еще!! При этом еще и автор на вопросы не отвечает и претензии игнорит . Можеш на это не отвечать, вопрос риторический..