Классы Ардуино по qwone для чайников.
- Войдите на сайт для отправки комментариев
Сб, 08/07/2017 - 10:45
Извините на громкое название темы, но похоже я тоже чайник. Так что вменяемого текста от меня не ждите.
Что я требую от классов:
1 - что бы в них обязательно были public методы setup() и loop()
2- что бы представители этих классов,что из одного класса,что из разных, могли взаимно не тормозить друг друга.
Вот примерно мой типичный каркас программы, я бы сказал разметка каркаса.
Что такое классы в языке С++ и в Ардуне тоже читать здесь http://cpp.com.ru/lippman/c13.html
Следующий этап Пример 1
ПС: Пример зажигания светодиода
ППС:Пример мигания светодиода
ПППС: мигание светодиода по определеной последовательности
черезчур академично. Новички ничего не поймут, а кто разбирается - умрут со скуки.
Кстати, теоретически ваши ссылочные классы таят в себе потенциальные проблемы... вот почитайте
http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-PTRS.html
Выкладываю дальше . Кнопки
Этот пример для кнопки подключеной на вывод и землю.
ПС: Такой же код для кнопки подключеной на+5В через резистор 10к
Но бывает что одной кнопки использовать в программе тяжело. Лучше всего использовать две, а лучше три.
Замечу, что код написаный выше раздела компоновка выполняет роль библиотеку , только пока еще не вынесеную в отдельный файл, который можно подключать .
Такой же код для кнопок подключеных к +5В через резистор 10к
Теперь вариант 3 кнопки управляют 1 светодиодом: первая включает, вторая выключает, третья заставляет мигать светодиод.
ПС: Добавлен бит инверсии, который позволяет зажигать светодиод 0 и гасить 1
Если вам надо одной кнопкой выбирать 1 из трех режимов, то вот вам пример программы
qwone, ну шо за ересь? - прекращай бредить.
не существует никаких особенных классов для Ардуино - в Ардуино ИДЕ работают классы С++.
Следующий вариант: кнопка на пине 2 переключает мигание одного из четырех светодиодов (пины 6,7,8,9)
Такая же программа но с записью состояния в EEPROM
Теперь покажу взаимодествие кнопок (+ и -) и серво
Та же программа, но если кнопки будут удерживаться, то будут повторно посылаться команды
Cкетч на тему LCD Key Shield . Мой аналог этого скетча https://geekelectronics.org/arduino/podklyuchenie-lcd-keypad-shield-k-arduino.html
надеюсь, ты не против комментариев? а то пока выглядит, будто это "только твоя" тема :)
По пункту 1 выше я бы все-таки немного подробнее обьяснил - если это тема для новичков. Пока твой текст выглядит так, будто методы setup() и loop() - обязательны для любых классов. Стоило бы просто написать, что ты создаешь в своих классах единый интерфейс для инициализации и запуска в loop
b707, из меня никакой учитель. Просто я в некотором виде создаю библиотеку решений . Ведь одна из сложностей в "новичковом" программировании Ардуины, не возможность работы разных скетчей. Я бы не выкладывал бы эти скетчи, но похоже что это для многих они кажутся загадкой. Вот пусть просвещаются. Тем более для меня это уже прошедший этап. Кому интересно, пусть просвещаются. Можете и вы выкладывать свое и давать свои объяснения. Я не против.
ПППС: мигание светодиода по определеной последовательности
Позволю себе запостить свой вариант, сделанный из твоего примера 1.3. Главное отличие - схема мигания светодиода хранится в виде битовой маски, что позволяет компакто задавать весьма сложные последовательности. Если таких последовательностей много( скажем, если делать индикацию работы прибора разными типами миганий) - вариант с битовой маской дает очень серьезный выигрыш в расходе памяти.
qwone, перепроверь как это у тебя работает
bool
bounce = 0;
// антидребезговый флаг
потому как, если у тебя это компилится, то bounce может быть только общей для всех экземпляров класса константой.
так на Дуино ИДЕ 1.0.6 выдаёт правильную ошибку: error: ISO C++ forbids initialization of member 'bounce'
на Дуино ИДЕ 1.8.2 молча компилит, но подозреваю, то само превращает bounce в константу.
ЗЫ. минуса не я ставил - надеюсь, что у этого кармодрочера отсохнет член.
qwone, перепроверь как это у тебя работает
bool
bounce = 0;
// антидребезговый флаг
потому как, если у тебя это компилится, то bounce может быть только общей для всех экземпляров класса константой.
так на Дуино ИДЕ 1.0.6 выдаёт правильную ошибку: error: ISO C++ forbids initialization of member 'bounce'
на Дуино ИДЕ 1.8.2 молча компилит, но подозреваю, то само превращает bounce в константу.
Не, насколько я знаю, раньше это было ошибкой, а в новых версиях стандарта C++ уже допустимо. Это, по-моему, default_member_initialization
Не, насколько я знаю, раньше это было ошибкой, а в новых версиях стандарта C++ уже допустимо. Это, по-моему, default_member_initialization
ок. а, то я уже расстроился, что новые версии Дуино ИДЕ ломают С++
Вот еще один пустячок. Иногда надо что бы при нажатии на кнопку на выходе был импульс к примеру продолжительностью 2 секунды. Вроде плевая задача. Но тратить на решение такой проблемы личное время не серьезно. Так что вот код для кнопок подключенных на землю и програмной подтяжкой
Вы это специально пример для ООП без ООП сделали)))
Ваше требование - чтоб всегда был сетап и лоп - это методы базового класса. А от него наследуется кнопка и прочие для которых важно чтоб всегда был сетап и лоп. Бонус - все обекты можна хранить в массиве, а значить вызывать их в сетапе и лопе не один за другим (если их много будет - тоска) а в цикле по очереди из массива.
Дальше убираем указатель на Do. В классах так не принято, ведь внутри вашего обработчика Do не получится добратся к данным класа кнопки, а это плохо, там например могут быть флаги двойного клика или еще какая инфа. Для этого в классе кнопки делаете виртуальный метод Do, без реализации. А когда понадобится конкретная кнопка с нужным действием -наследуете от абстрактного типа задав соответствующий обработчик. Бонус - ну допустим нужны кнопки с цифрами 0-9, от абстрактного класса кнопка наследуете класс цифровая кнопка у которого обработчик Do и новое поле - цифра этой кнопки. В конструкторе эту цифру задаете вместе с пином на котором кнопка висит. Дальше создаете 10 обектов класса цифровая кнопка инициализировав их соответствующими цифрами. В итоге при нажатии любой из десяти кнопок вызывается Do цифровой кнопки и в нем есть значение от нажатой кнопки. Ляпота!
Получается иерархия наследования абстрактный класс ардуины-абстрактный класс кнопки-класс цифровой кнопки-обекты кнопок. А если потребуются кнопки со стрелками - от абстрактного класса кнопки унаследуете класс кнопок со стрелками и создадите его обекты стрелка влево и стрелка вправо. Получим 2 обработчика Do один для цифр другой для стрелок - что очень логично. Ну просто оргазм ООПешника!!
Logik,Разумеется можно и так. Но просто я пока сюда скидываю простые скетчи. Так для "новичков", для которых и классы - "открытие". А для ООП это как до Луны пехом.
Задача : Подключить кнопку Btn1 и два светодиода Led1 и Led2. Нажатие на кнопку - начинает гореть светодиод Led1 5 сек, отжатие кнопки - начинает гореть светодиод Led2 5 сек.
Скетч
Скеч для обработки кнопки без учета дребезга мех кнопки. Ведь есть просто внешние сигналы.
масло масляное
Вот тоже интересный скетч. Вобщем очередь с возможностью добавить элемент в начало или в конец.
То же самое, но добавлены методы убрать элемент в начале, убрать элемент в конце
Скеч. Два датчика , "мозг" и два исполнительных механизма. Может кому пригодится как схема написания программы.
Добавлю и этот скетч. Аналог верхнего, но со структурой.
Вот еще код под RFID. Переделал свой старый код под существующую концепцию
Продолжение скетча на тему LCD Key Shield #11. Теперь долгое нажатие кнопки вызывает повторно обработчик. На экране не видно. Надо смотреть Serial
Программа для регулирования времени впрыска с помощью потенциометра
Программа для регулирования времени впрыска с помощью потенциометра
А из каких соображений в классе Cl_Potentiometer второе измерение напряжения на пине происходит через 100 мс после первого, а третье и все последующие при каждом проходе loop? В этом есть какой-то тайный смысл?
А из каких соображений в классе Cl_Potentiometer второе измерение напряжения на пине происходит через 100 мс после первого, а третье и все последующие при каждом проходе loop? В этом есть какой-то тайный смысл?
ПС: Для любителей выяснять, что лучше я предлагаю примитивный менеджер задач под мои классы.
О это очень тайный смысл. Если вы будете постояно бегать на работу и обратно . Раз 100 или тысячу в день, то у вас не хватит времени на работу.
Вы мой пост внимательно прочитали? Я писал о том, что Вы как раз это и сделали - читаете пин в каждом вызове loop (см. код в посте #29). Вот и поинтересовался для чего.
О это очень тайный смысл. Если вы будете постояно бегать на работу и обратно . Раз 100 или тысячу в день, то у вас не хватит времени на работу.
Вы мой пост внимательно прочитали? Я писал о том, что Вы как раз это и сделали - читаете пин в каждом вызове loop (см. код в посте #29). Вот и поинтересовался для чего.
Вот если запустить этот код с Менеджером задач
То выходит, что на метод loop Cl_Potentiometr уходит 17% времени. Что с millis(), что без
Чёт не пойму Вы уж либо исправьте ошибку и скажите "спасибо", либо объясните для чего Вы на словах читаете через каждые 100мс, а на деле - при каждом проходе loop. Ошибка-то в коде до сих пор не исправлена, а это материал для чайников - лучше ляпов не оставлять.
А Вы опять за свое. Видно прямо сказать, что я пропустил строку past = millis(); религия не позволяет. И да с этой строкой загрузка процесора переместилась с 17% на 9%.
ПС: Воспользуюсь вашим приемом. И ничего менять не буду.И так в теме намеки есть.
прямо сказать, что я пропустил строку past = millis(); религия не позволяет.
Не только религия, а также инженерное образование. Я считаю такую запись неверной, но к таким мелочам не придираюсь, потому и не тычу во все остальные места, где она используется. Ну, а в этом месте была явная ошибка, решил помочь. Наверное напрасно, т.к. вместо "спасибо" получил "религия не позволяет".
считаю такую запись неверной
а я уж подумал, что я один это замечаю.
Я выкладываю свой код не для тупого копирования, и да у меня тоже есть описки и ошибки. Просто это вариант привыкнуть и к такому стилю организации программы.
это вариант привыкнуть и к такому стилю организации программы.
А какой смысл привыкать к неправильному и неэффективному программированию? Как я понял, неверной он считает твою привычку вызывать millis дважды – первый раз, чтобы проверить, не истёк ли интервал, и второй раз – чтобы запомнить начало нового интервала.
То, что это неэффектвно, понятно. Какой бы быстрой ни была функция millis, она в разы медленнее, чем запомнить результат первого вызова и просто использовать его для начала нового интервала.
Ну и в общем случае это неправильно. Если бы millis вызывалась один раз, интервал соблюдался бы точно (насколько вообще может быть точным такой подход). А так интервал получается «тот, что надо» + время, прошедшее между вызовами millis.
В большинстве случаев, это неважно, там разница маленькая, но методологически это неправильно.
Привыкать надо не писать, а читать. Как правило программист чаще читает чужой код, а не пишет свой. Да и свой через несколько лет уже воспринимается чужеродным, если конечно программист развивается. Опять же не надо путать написание кода с его заточкой на скорость- вылизывание скорости в ущерб восприятию. Разберем этот код
Вопрос : Сколько раз вызывается функция millis() за проход loop(). два, один. И оба раза не верны. Так как иногда вызываются два, но чаще один. Так что здесь работает статистика . И чем больше число после >= , тем ближе к 1. И я могу облизать это код, но тогда он станет не читаем для большинства. Вы же можете взять учебники русского языка и воспринять, что тексты там написаны тупыми и примитивными . Так и здесь я выкладываю тупой и примитивный код. А вот получше пишите сами.
Вот никак не могу понять чем вот такой код менее читабелен?
То, что он даёт более точный интервал и сам по себе быстрее - да. А чем он менее читабелен - не вижу. Читабельность та же самая.
А вот получше пишите сами.
Да, спасибо, я так и поступаю.
Вот никак не могу понять чем вот такой код менее читабелен?
ничем - опилкоголовый интуитивно пытается экономить оперативку, что не всегда правильно и к месту.
Бертран Мейер Объектно-ориентированное конструирование программных систем https://vk.com/doc232854130_357487973?hash=2dbb274d25eea6ebba&dl=c0285623a86be348f0
пс:https://vk.com/wall-43948962_41995
пс2:https://vk.com/wall-54530371_591
Я бы не стал делать currentMillis static - зачем? По мне, вот так лучше:
Подброшу еще два варианта кода.
И
Ну и этот код на закуску.
http://dic.academic.ru/dic.nsf/ushakov/820102
Ну и этот код на закуску.
А без ошибок никак нельзя? Даже не знаю как Вам про неё, опять начнёте гадать о национальной специфики моего образования и откажетесь исправлять (назло мамке уши отморозите).
Посмотрите на текст функции millis, возможно поймёте:
Ну и этот код на закуску.
А без ошибок никак нельзя? Даже не знаю как Вам про неё, опять начнёте гадать о национальной специфики моего образования и откажетесь исправлять (назло мамке уши отморозите).
Посмотрите на текст функции millis, возможно поймёте:
Так запустил. Работает. И странно вроде не сбивается. Хотя странно, прерывание должно бы отрубить.
или millis() криво прочитать.