Дверной звонок-ксилофон
- Войдите на сайт для отправки комментариев
Вс, 16/12/2012 - 21:32
Доброе время суток всем самоделкиным. Есть большое желание сделать дверной звонок по принципу ксилофона на (ардуино) . Работой ксилофона будет управлять 8 или 16 эл.магнитов. Вот только не знаю какой контроллер выбрать и как управлять 16ю магнитами. Помогите люди добрые.
Вот только не знаю какой контроллер выбрать
В принципе любой справится.
Разница только "с каким удобней"
Лезете в описание плат - смотрите сколько у него выходов. Если вам хватает - можно брать. Если не хватает - брать либо с большим количеством ног, либо читать раздел документации на предмет "множим выходы ардуины с помощью сдвиговых регистров".
Ну и конртроллер лучше брать, в этом случае, который сразу имеет разъем для подключения внешнего блока питания.
>
http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-postoyannogo-tok...
Все что написанно про реле - относится и к вашим магнитам (собственно реле это и есть ксилофон, щелкает только так. Просто язычек там "замыкает пластину", а не просто звук дает).
Спасибо за ответ. Я думаю взять Arduino Uno , два сдвиговых регистра и развязать магниты транзисторными ключами либо как вы предлагаете реле с транзистором в одном корпусе.
Если электромагниты подойдут по току, то можно управлять ими ULN2803
Спасибо за информацию она мне подойдет.
У меня появилась мысль относительно программирования. Если в контроллер залаживать не мелодию (поочередное включение магнитов с задержкой), а принцип цветомузыки (распознавание высоты звука). На аналоговый вход подаем звук, а на цифровом выходе включение соответствующих реле. По вашему мнению это не бредовая идея?
На аналоговый вход подаем звук, а на цифровом выходе включение соответствующих реле. По вашему мнению это не бредовая идея?
Основная проблема будет - идентифицировать звук, т.е. это Ваш звонок звонит, или шум (музыка) с улицы.
Спасибо за информацию она мне подойдет.
У меня появилась мысль относительно программирования. Если в контроллер залаживать не мелодию (поочередное включение магнитов с задержкой), а принцип цветомузыки (распознавание высоты звука). На аналоговый вход подаем звук, а на цифровом выходе включение соответствующих реле. По вашему мнению это не бредовая идея?
Гиморойная. Написать слово "распознавание" в тех-задании - легко. А реализовать в коде? Знаний (и математики в т.ч.) хватит что-бы по для дискретной функции выяснить частотные характеристики?
Ну а дальше еще "трудности реализции встанут": а хватит ли быстроедествия дуины, а хватит ли памяти для хранения семплов замерянных и т.п.
Понятно, не стоит и заморачиваться. Проще сделать последовательное включения магнитов.
Сначала нужно завершить проект, а уже потом можно и поиграться
Ура ! Arduino с платой обслуги работает. Все клацает и моргает! Теперь осталось дело за неизвестным (программирование). Не получается расписать последовательность включения, после нажатия на кнопку звонка.
Люди добрые помогите.
Смысл в чем: после нажатия кнопки, должны поочередно включиться 8 реле. Время между включениями и время работы реле должны меняться. После включения последнего реле система должна перейти в ждущий режим, ожидая следующего нажатия кнопки.
Не знаю, какое у Вас железо, но алгоритм простой, тупо ждать нажатия кнопки (не забываем про дребезг), потом уходим на постучать магнитами. И так до бесконечности ;)
Это тот случай когда "можно забыть". Если проигрывание делать через delay(), как самый простой вариант, то это снизит частоту опроса кнопки и антидребезг получится сам собой.
Только при "постучать", на кнопку все одно смотреть нужно. Что-бы прекратить стукачество при отпускании :)
не проверял, но примерно так это будет выглядить.
Заводим папку DoorChimes. В нее ложим два файла (ниже будут)
DoorChimes.ino - главный скетч
Melody.h - сама мелодия.
Открываем DoorChimes.ino (Melody.h - откроется сам во второй вкладке среды разработки).
Подправляем номера пинов (для кнопки и нот), я взял номер "от балды", что там у вас куда подключено - не знаю.
Зливаем, слушаем (если повезет :)
DoorChimes.ino:
Melody.h:
Когда мелодия играет, можно неспеша смотреть за кнопкой, либо сыграть и проверить, это уже как автор захочет
"Пока играет мелодия..." - смотрите во всех кинотеатрах страны :)
Огромное спасибо за помощь. Все сделал как сказали. Получился файл с двумя вкладками, но при проверке выводит ошибку (stray # in program) на всех строках где присутствует знак (#).
Признавайтесь, номера строк из кода руками вычищали? Или вообще оставили "как есть".
Вообщем сам-то код вы к себе правильно копировали? Свертесь с прикрепленной веткой http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
В сообщение #2 описано как правильно "к себе код" забирать. Вы так делали?
ОЙ! у меня вообще программа не такая как на картинке. У меня установлена Arduino 1.0.3
Код 100% компилируется, вообщем "что-то повредили при копировании к себе".
Лениво счас разбиратся "что и как".
Ловите в виде .zip файла
http://dropcanvas.com/wn0mo
Какая програма? на какой картинке? причем тут версия ArduinoIDE?
Я же вам указал номер сообщения который нужно читать #2.
Там вообще скриншоты только самого форума (который вы сейчас читаете, ни одного скриншота никаких программ - я там не вижу). Как правильно код с форума скопировать в клип-боард без постороннего мусора. У куда вы его потом в ставите Arduno 0.22, Arduno 1.0.3 или Notepad - дело вашего вкуса.
Ну да все правильно, просто я еще не въехал в эту кухню. Сегодня только собрал железо и хотел поиграться с программированием. Сам я далекий от него, но желание есть.
С зипом получилось, все проверяется. Сейчас попробую залить и поиграться
Не забудте поправить номера пинов (или подключите на те которые указаны в коде).
Вы даже представить не можете как я прыгаю по комнате от радости. Все получилось, работает. Только в железе я сделал на кнопку 5 вольт, а не на землю и как можно задействовать 8-е реле.Подскажите для полного счастья
Все 10-ю релюшку я задействовал (в программе изменил Do2- gjcnfdbk 10) Сейчас думаю над кнопкой.
Если вы подключили кнопку между пином и 5v, то вам нужно в строке 38
#define isButtonPressed !digitalRead(BUTTON_PIN)
Убрать восклицательный знак. Сделать
#define isButtonPressed digitalRead(BUTTON_PIN)
Далее вам нужно закоментировать (или вытереть) строку 43
digitalWrite(BUTTON_PIN,HIGH);
// включаем подтяжку для кнопки
----
С кодом все. Но кнопка у вас будет ловить "помехи". Либо вообще случайно, либо "от поднесения руки", вообщем "как повезет", что-бы это предотврарить, этот же пин кнопки нужно еще резистором в 10K-20K соеденить с землей.
То есть пин будет соеденен с питанием через кнопку и с землей через резистор.
Вообщем смотрите если кнопка "к питанию", то правильно она должна так подключатся
http://arduino.ru/tutorials/button
люди обычно на звонок нажали отпустили и мелодия соответственно две ноты и все, а как ее заставить доиграть до конца. Или это сложно сделать?
Резистор уже стоит.
Я вытер две последние строки и мелодия начала играть до конца при коротком нажатии.
Сейчас попробую, что вы написали
Ну, обычно звонок именно так и работает. Как только отпустили - прекращаем играть.
Но если хотите "до конца", ну так почитайте же код. Попробуйте разобратся как он работает.
Там даже откоментированы строки которые "обрывают" игру если кнопку отпустили. Уберити их - и все (или закоментируйте).
Попробуйте их сами найти (две штуки их там, в двух-местах "может выстрелить в пианиста").
А вообще, стоило бы (я обычно так и делаю), отправить вас сначала читать раздел "Среда разработки" и "Програмирование" (в шапке сайта ссылки). Начинать нужно с чего-то более простого: как диодом помигать, как кнопку читать, как с Serial работать. Ознакомится с "какие кубики есть у этого конструктора". Посмотреть/попробовать примеры.
Одну из этих строчек - правильно вытерли. А вторую - убили "длительность нот". Будут теперь все одинаковой длины.
Там же каждая строка откоментировано что делает. Зачем же вам было убирать "теняем ноту", раз вы хотели что-бы оно не реагировало на отпускание КНОПКИ, то логично что искать/убирать нужно именно проверки кнопки?
Изменил программу как сказали все работает как я и хотел изначально, огромное вам спасибо.
Я конечно извеняюсь, если я не надоел, а можна сделать, чтобы мелодий было 5 и включались поочередно при очередном нажатии кнопки. Тоесть при последующем нажатии новая мелодия.
Вопрос не в "надоел", а не "хочется поощрять халяву".
Сделать это не трудно (завести еще одну переменную номер мелодии и увеличивать ее при каждом нажатии кнопки), и melody переделать объявить не как одномерный, а двумерный массив (массив массивов).
Но ведь нужно же вам (раз собрались заниматься ардуинством) с чего-то начинать учебу. Погуглить C/C++ массивы.
Или даже, первым шагом, не массивы, а просто, попробуйте добавить какой-то "счетчик" нажатий сделать. И выводить в Serial сколько раз мы сыграли мелодию (пусть и одну и ту же пока).
Потом сделайте что-бы счетчик обнулялся, к примеру, когда доходит до 5-ти.
Потом и с массивами разберемся.
Я не против помогать (тому кто сам пытается), но не люблю "исполнять хотелки" (бесплатно).
Я с вами полностью согласен, сам не люблю халявщиков. Мне интересно разобраться самому. Но если ничего не получится, могу ли я расчитывать на вашу помощь (конечно не бесплатную). Огромное спасибо за вашу помощь.
С наступающими вас праздниками.
Я с вами полностью согласен, сам не люблю халявщиков.
Да нет. Люди разные. Это всего лишь одна из стратегий поведения. Я это принимаю как устройство мира. Без раздражения.
Тут речь скорее что "я не хочу творить зло". А зло - это отбивать охоту у человека самому попытатся. Трудно удержатся и не "подсмотреть готовый ответ". А так глядишь есть шанс, что вольетесь в наши ряды :)
Мне интересно разобраться самому.
Вот именно поэтому я и писал скетч. Я увидел что вы задали вопрос. Вам кинули ссылки. Вы разобрались, подключили. Вообщем "попытались что-то сделать". Знали бы вы сколько людей приходят сюда с вопросами, а сами даже прочитать прямую ссылку на документацию не хотят. Я уж не говорю про воспользоватся гуглом.
Но если ничего не получится, могу ли я расчитывать на вашу помощь (конечно не бесплатную). Огромное спасибо за вашу помощь. С наступающими вас праздниками.
Да. Конечно. Правда "за деньги" тут вообщем-то уже и делать нечего (это я уже из принципа "остановился").
Но если вы хотите что-бы "просто кто-то за вас сделал" - это тоже возможно. Тоже вполне нормальный подход. Не могут все все уметь. Тут уж зависит что вам важнее "просто получить работающие" или "хочу сам разобратся".
Но, не так страшен черт. Если "разобратся" - важнее, то попробуйте сделать то что я выше сказал, а там посмотрим "как пойдет". Я помогу-подскажу (бесплатно) :)
Буду пытаться постичь сам эту науку. По крайней мере хотя бы ее азы. Книгу по программированию я скачал. Потом как вы сказали попробую счетчик и массивы. Я в правильном направлении ?
Есть неплохая книга с кучей примеров "Arduino Cookbook" но на английском, но примеров море
Спасибо, примеры это хорошо
Книга безусловно неплохая. Я бы даже сказал "архиполезная". Вот только "для новичка ли"? Там все-таки уже скорее "тонкости AVR-ров", а не "как заменить кучу if на один switch" или "когда byte лучше int" :)
Вообщем "на полку" ее можно положить (если планируете делаеть на Arduino сложно-интерестные вещи).
Но вот рекомендовать "вот прямо сейчас обязательно начинайте ее читать" - я бы не стал. Вам нужно сначала с языком освоится.
Кстати все время держите в уме, что Arduino-язык базируется на C/C++. И если вы видите "что-то не понятное", например слово "#define", то узнать "что это за зверь" можно в справочнике по C/C++ с вероятностью 99%
А вот в родной документации - этого может и не быть. Вообщем "не забывайте про родителей" ;)
так что можно взять какой-нибудь учебник по C почитать его начальные главы (в "глубогие дебри" не обязательно лезть). Всякие управляющие операторы, типы, переменные, функции и т.п. - все это применимо к ардуине один в один.
А вообще начните с раздела "Програмирование" в шапке сайта. Его, хотя-бы бегло, по диагонали, желательно прочитать весь. Пусть даже и не все понимая. Потом, когда в реальной задаче столкнетесь - в голове уже будет "о... а вроде была какая-то функция для получения времени". Идете туда и читаете про нее еще раз, но уже детально.
Буду пытаться постичь сам эту науку. По крайней мере хотя бы ее азы. Книгу по программированию я скачал. Потом как вы сказали попробую счетчик и массивы. Я в правильном направлении ?
В правильном. Давайте даже пока "про массивы" забудем. Давайте со счетчиком. Причем, наверное, не нужно пытатся это сразу всобачить в скетч звонка. Он большой и будет "перегружать вас инфой". Сделайте, File/New, там разберитесь с очередной "идеей/принципом" в заведомо упрощенном варианте. А уж когда пришло понимание "как это делать", можно смотреть "как это вставить в основной скетч". Или, если эта "идея" уже есть в "основном" - посмотреть как она там сделана.
Так, по кусочкам мы, мы упрощенно повторим написание "основного", где-то его улучшим и главное постараемся что-бы он у нас из "магии которая работает" превратился "да тут же все тривиально" :)
Давайте даже "счетчик" разобъем на еще более мелкие задачи. Попробуйте написать скетч который просто ловит нажатие кнопки и отсылает в сериал-монитор сообщение об этом "Button Pressed" (Кнопка Нажата). Научимся "следить" за тем, чем у нас скетч занимаетеся. Смотреть "как он работает". Для этого вам нужно будет почитать про digitalRead и Serial (документации на сайте будет достаточно).
Update: когда я говорю "попробуйте сделать" - я имею ввиду "попробуйте и показывайте тут что получилось". даже если "получилось частично".
Согласен, будем читать.
Соеденил два примера. Получил включение светодиода при нажатии кнопки и изменение нуля на единицу в порту.
Очень неплохо.
Но я покритикую скетч :) Не потому что "все плохо". На самом деле - неплохо. главное что работает. Да еще и
Азарт меня пьянил, но, как ни говори,
Я тормозил на скользких поворотах!
не забыли ;)
Итак, что тут можно "сделать получше". Вообщем-то все советы "не обязательны". Скетч-то уже работает :), но лучше "правильный стиль" вырабатывать сразу. В будущем съекономит кучу времени при поиске трудноуловимых ошибок.
1. Типы данных
Тут лучше применять не int, а byte. Для данного скетча это "не критично", на работу не повлияет но лучше изначально привыкать подбирать подходящий типа данных осознанно. Не больше и не меньше чем нужно для конкретной задачи. Это убережет в будущем от излишнего расхода памяти и трудноуловимых ошибок переполнения.
Идем http://arduino.ru/Reference находим "типы данных" и читаем какие они бывают (желательно все, не так и много их там). Желательно ПОНЯТЬ почему тут byte будет более подходящим, а не потому что "я так сказал" :)
2. Область видимости переменных
Переменную val лучше объявить внутри самого loop(). Больше она нигде не используется, между "проходами loop" запоминать ее состояние не требуется, поэтому нет никакой необходимости "засорять" глобальное простраство имен. На больших скетчах, можно часы провести в поисках глюка и той функции меняет какую-то глобальную переменную "когда вы не ждете".
3. Неизменяемые переменные.
Замечательно что вы решили вынести номера пинов в заголовок файла. Это "хороший стиль" :) Действительно "магические цифры" в коде - это зло. Гораздо лучше когда есть "говорящие имена". Такой код гораздо легче сопровождать.
Правда, в строке 19, применили-таки "магическое число 2", но, я так понимаю, это просто опечатка.
Но давайте присмотримся к ledPin и inPin. Явно мы предполагаем что они не будут у нас менятся во время работы скетча. По крайней мере "не должны". Можно сообщить об этом компилятору добавив в объевление ключевое слово const . Тогда компилятор будет "следить за этим" и если мы где-то попытаемся, случайно/ошибочно, их поменять он сразу нам об этом скажет. И не даст залить такой ошибочный скетч в дуину (а без const, мы узнаем об этом только по глюкам и потратим время на поиск "где-же мы случайно изменили их").
Попробуйте добавить к ним const, а потом попробуйте их изменить где-нибудь в коде :)
Но, в данном случае лучше, для них, использовать даже не переменные, а #define. Разница в том, что под переменные выделяется "ячейка памяти" и тратятся такты на ее чтение, а #define, это как-бы "автозамена" которая выполняется в перед компиляцией програмы. Если вы написали #define LED_PIN 5, то это приведет к тому, что перед копиляцией програмы по всему коду будет искатся имя "LED_PIN", где найдет заменить его на цифру 5 и только потом начнет компилировать програму. Поэтому
То есть мы c помощью #define убиваем двух зайцев сразу - с одной стороны мы избавляемся от "магических цифр" (и легко можем поменять пин, не лазя по всему коду изменяя его), с другой - нам это "ничего не стоит" (не выделяется память, не тратится время на чтение).
3. Дублирование переменных.
Если вы посмотрите, то val и digitalValue - у вас выполняют абсолютно идентичные задачи. Более того, к моменту когда вы начали использовать digitalValue - вам значение val которое вы сохранили в сроке 15-ть уже совершенно не нужно. Его можно выкинуть. То есть второе чтение - тоже выполнять в переменную val. А digitalValue - просто выкинуть из скетча вообще.
4. Дублирование чтение порта.
Зачем нам строка 19? Мы же уже прочитали порт в 15-ть. И сохранили его состояние в val. От того что мы его использовали в строке 16-ть - оно не "испортилось". Более того, если у нас стоит задача выводить в serial "что же мы установили сейчас на led" - второе чтение вредно. Между первым и вторым чтение, какие-то микросекунды да проходят. И кнопка, к моменту второго чтения - все-таки может изменить свое значение. А значит у нас возникнет ситуация что на светик мы отобразили одно, а в Serial отчитались о другом.
Итого (что желательно сделать):
понять и применить более экономные типы для переменных. Переменную val сделать локальной. Номера пинов из переменных переделать в #define, выбросить лишние переменные и чтения порта.
И еще, совсем мелочный коментарий: строка 9
pinMode(inPin, INPUT); - не обязательна.
По умолчанию, если мы не сказали обратного, ВСЕ пины уже включены на INPUT сразу после подачи питания.Но говорить "переделайте" - я не буду. Писать ее или нет - скорее дело личных предпочтений. С одной стороны "она не делает ничего полезного", с другой - такой код легче читать. Сразу видно какие порты мы используем и как (когда берешь скетч, то первым делом смотришь в setup, кого-куда выставляют).
Азарт конечно есть. Но я читаю читаю, в голове все путается. Самое страшное когда пишу код не понимаю, что пишу, а просто отталкиваюсь от примеров.
Как можна объявить все PIN выходами, чтобы не перечислять
leshak, п.3. я бы не рекомендовал, особенно для новичков.
Вместо конструкции:
Я бы рекомендовал:
А по большому счету не стал бы это рекомендовать совсем.
Дело в том, что при повторном использовании переменной, есть шанс забыть про это и использовать уже испорченное значение.
Спорить не буду, просто не рекомендую. А еще это личный опыт, а он у меня немаленький.
Дело в том, что при повторном использовании переменной, есть шанс забыть про это и использовать уже испорченное значение.
Вы правы. В обычных случаях экономить повторно используя переменные - не стоит. Лучше пару байт потратить но иметь более понятный код. Но....
в данном случае мы выполняем одно и тоже действие. Читаем один и тот же пин. Так что тут это можно назвать скорее не "повторное использование", а "освежили значение переменной до актуального состояния". Именно в данному случае введение второй переменной - скорее сбивает. Нужно вникать "а в чем между ними различия?". Даже коментарий-описание у них практически идентичный. В крайнем случае, если хочется две переменные, то лучше было их назвать val1 и val2. Что-бы имя подсказывало что они "очень родствены".
Можно заменить на разные варианты:
другой вариант:
Выбор варианта зависит от многих факторов.
В частности первый вариант ограничен тем, что номера пинов должны быть последовательностью.
Второй вариант плох тем, что массив занимает место в памяти. А если он больше нигде не используется, то память расходуется впустую.
И наконец - твой вариант, он не такой и плохой. Иногда - он - лучшее решение.
Всё зависит от использования, эффективности, наличия памяти.
Есть такая штука, как оптимизация. Как правило, если программе нужно быстрее работать, то программа занимает больше места, а если надо занимать меньше памяти, то она может работать дольше.
Всё условно, но, всё таки, нужно смотреть контекст использования и это уже не так интересно для новичка, забивать голову этим пока не нужно.
Как можна объявить все PIN выходами, чтобы не перечислять
Это пример "полезной лени". Вы совершено правы что нужно старатся избегать написания практически идентичного кода.
Для этого вам нужно: объявить массив байтов. Положить в него номера пинов. А дельше, в setup(), пробежатся c помощью for по этому массиву.
Собствено отсюда ясно "что читать нужно".
http://arduino.ru/Reference/Array
Собственно там даже пример есть. Именно с пинами. Только они выводят в Serial, а вы будете делать pinMode, вместо print.
P.S. А если бы бегло почитали весь раздел "програмирование", то вспомнилибы "что-то такое я где-то видел" :)
Если хочется уж совсем коротко, то код
можно заменить на
На выход будут сконфигурированы пины с D3 по D10. D0-D2 и D11-D13 останутся "слушающими"
можно заменить на
Конечно, можно и даже правильно, НО. Я бы не советовал применять такие конструкции без понимания сути вопроса, поэтому советую, для того, чтобы это осознано применить, "вкурить" несколько статей:
1. Про управление портами (ногами) AVR
2. Про соответствие портов и ног ардуины (pin mapping)
3. Про битовые операции
И еще. При таком подходе забудте про переносимость программы - будет работать только на той плате (том проце), для которого Вы возмете "pin mapping"
Уж лучше сделать функцию, которая будет нам кофигурить выходы.
Поинтересуйтесь (у Гугля) про функции с переменным числом параметров:
На железе не проверял, возможно, нужно взять тип int.
to step962 & AlexFisher
Э... ээээ!!! Стоп. Стоп!!!!
Вы чего? Какия прямая запись в порт? Какие функции с переменным числом параметров!!!!!
Человек пишет свою первую програму!!!! Выясняет что такое массивы и как пользоватся циклами. Разбираемся чем byte от int отличается.
Я тут не уверен стоило ли сейчас про #define, даже без параметров, говорить. или пока "не нагружать этим". Вы же его указателями и битовыми масками в шестнадцатеричном виде в коматоз вгоните.
Тем более что для его текущую задачу вполне можно решить без этого. Более "базовыми" средствами. Не забивать пока голову, причем без особого ущерба что "что-то упустил".