Светодиоды, кнопка и Switch
- Войдите на сайт для отправки комментариев
Всем привет, друзья! Делаю поделку на Ардуино, форум полистал, посмотрел интересующие темы, но так и не нашёл полезного (хотя, быть может, плохо искал). Следуя изученным правилам прикрепил снизу код, тем временем сверху опишу "что должно быть". Итак, есть две кнопки. Одна кнопка (пин А1) управляет исключительно одним светодиодом (пин 3). При нажатии-отпускании - зажигает, при повторном нажатии-отпускании - гасит. Есть вторая кнопка (пин А2) и она управляет остальными светодиодами (пины с 13 по 5), да ещё и пищалкой (пин 4). Эти 9 светодиодов горят по определённому принципу зажигания-угасания, что реализовано через switch...case. Всего таких режимов 4. Нажал-держишь режим первый, отпустил - перестало гореть (и звучать). Нажал-держишь второй режим, отпустил - перестало гореть (и звучать). Далее третий и четвёртый режимы, а после четвёртого должен снова идти первый.
Итак, уважаемые знатоки, предисловия окончены, мы подобрались к основному вопросу: Почему после отпускания кнопки во время четвёртого режима всё равно исполняется четвёртый режим (но некорректно - только case 50 и case 60, однако при нажатии и удержании - снова полноценный четвёртый режим и после отпускания уже окончательный 0) и как это исправить?
Также не откажусь от советов по улучшению, сокращению кода (кроме перевода в чистый Си или С++, я вас уважаю, но пока не дорос до этих языков, наверное).
boolean butt1_flag = 0; boolean butt1; boolean butt2_flag = 0; boolean butt2; boolean laser_flag = 0; byte regim = 0; int programLed; unsigned long nextTime; unsigned long nextTimeTone; int programTone; void setup() { pinMode(13, OUTPUT); pinMode(11, OUTPUT); pinMode(12, OUTPUT); pinMode(10, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(7, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(4, OUTPUT); pinMode(3, OUTPUT); pinMode(A1, INPUT_PULLUP); pinMode(A2, INPUT_PULLUP); } void loop() { butt1 = !digitalRead(A1); if (butt1 == 1 && butt1_flag == 0) { butt1_flag = 1; laser_flag = !laser_flag; digitalWrite(3, laser_flag); } if (butt1 == 0 && butt1_flag == 1) { butt1_flag = 0; } butt2 = !digitalRead(A2); if (butt2 == 1 && butt2_flag == 0) { regim++; butt2_flag = 1; } if (butt2 == 0 && butt2_flag == 1) { butt2_flag = 0; } if (regim > 4) { regim = 0; } if (regim == 1) { if (programLed == 0) { programLed = 20; programTone = 60; } } else { if (butt2 == 0) { programLed = 0; programTone = 0; } } if (regim == 2) { if (programLed == 0) { programLed = 30; programTone = 60; } } else { if (butt2 == 0) { programLed = 0; programTone = 0; } } if (regim == 3) { if (programLed == 0) { programLed = 40; programTone = 60; } } else { if (butt2 == 0) { programLed = 0; programTone = 0; } } if (regim == 4) { if (programLed == 0) { programLed = 50; programTone = 60; } } else { if (butt2 == 0) { programLed = 0; programTone = 0; } } switch (programLed) { case 0: digitalWrite(13, LOW); digitalWrite(10, LOW); digitalWrite(7, LOW); digitalWrite(11, LOW); digitalWrite(8, LOW); digitalWrite(5, LOW); digitalWrite(12, LOW); digitalWrite(9, LOW); digitalWrite(6, LOW); break; case 20: digitalWrite(13, HIGH); digitalWrite(10, HIGH); digitalWrite(7, HIGH); nextTime = millis() + 250; programLed = 21; break; case 21: if (millis() >= nextTime) { digitalWrite(11, HIGH); digitalWrite(8, HIGH); digitalWrite(5, HIGH); nextTime = millis() + 250; programLed = 22; break; } case 22: if (millis() >= nextTime) { digitalWrite(13, LOW); digitalWrite(10, LOW); digitalWrite(7, LOW); nextTime = millis() + 250; programLed = 23; } break; case 23: if (millis() >= nextTime) { digitalWrite(12, HIGH); digitalWrite(9, HIGH); digitalWrite(6, HIGH); nextTime = millis() + 250; programLed = 24; } break; case 24: if (millis() >= nextTime) { digitalWrite(11, LOW); digitalWrite(8, LOW); digitalWrite(5, LOW); nextTime = millis() + 250; programLed = 25; } break; case 25: if (millis() >= nextTime) { digitalWrite(13, HIGH); digitalWrite(10, HIGH); digitalWrite(7, HIGH); nextTime = millis() + 250; programLed = 26; } break; case 26: if (millis() >= nextTime) { digitalWrite(12, LOW); digitalWrite(9, LOW); digitalWrite(6, LOW); digitalWrite(13, LOW); digitalWrite(10, LOW); digitalWrite(7, LOW); programLed = 20; } break; case 30: digitalWrite(13, HIGH); digitalWrite(8, HIGH); digitalWrite(6, HIGH); nextTime = millis() + 125; programLed = 31; break; case 31: if (millis() >= nextTime) { digitalWrite(12, HIGH); digitalWrite(10, HIGH); digitalWrite(5, HIGH); nextTime = millis() + 125; programLed = 32; } break; case 32: if (millis() >= nextTime) { digitalWrite(13, LOW); digitalWrite(8, LOW); digitalWrite(6, LOW); nextTime = millis() + 125; programLed = 33; } break; case 33: if (millis() >= nextTime) { digitalWrite(11, HIGH); digitalWrite(9, HIGH); digitalWrite(7, HIGH); nextTime = millis() + 125; programLed = 34; } break; case 34: if (millis() >= nextTime) { digitalWrite(12, LOW); digitalWrite(10, LOW); digitalWrite(5, LOW); nextTime = millis() + 125; programLed = 35; } break; case 35: if (millis() >= nextTime) { digitalWrite(13, HIGH); digitalWrite(8, HIGH); digitalWrite(6, HIGH); nextTime = millis() + 125; programLed = 36; } break; case 36: if (millis() >= nextTime) { digitalWrite(11, LOW); digitalWrite(9, LOW); digitalWrite(7, LOW); digitalWrite(13, LOW); digitalWrite(8, LOW); digitalWrite(6, LOW); programLed = 30; } break; case 40: digitalWrite(11, HIGH); digitalWrite(8, HIGH); digitalWrite(5, HIGH); nextTime = millis() + 10; programLed = 41; break; case 41: if (millis() >= nextTime) { digitalWrite(11, LOW); digitalWrite(8, LOW); digitalWrite(5, LOW); nextTime = millis() + 10; programLed = 42; } break; case 42: if (millis() >= nextTime) { programLed = 40; } break; case 50: digitalWrite(12, HIGH); digitalWrite(9, HIGH); digitalWrite(6, HIGH); nextTime = millis() + 10; programLed = 51; break; case 51: if (millis() >= nextTime) { digitalWrite(12, LOW); digitalWrite(9, LOW); digitalWrite(6, LOW); nextTime = millis() + 10; programLed = 52; } break; case 52: if (millis() >= nextTime) { programLed = 50; } break; } switch (programTone) { case 0: noTone(4); break; case 60: tone(4, 262); nextTimeTone = millis() + 4; programTone = 61; break; case 61: if (millis() >= nextTimeTone) { tone(4, 277); nextTimeTone = millis() + 4; programTone = 62; } break; case 62: if (millis() >= nextTimeTone) { tone(4, 294); nextTimeTone = millis() + 4; programTone = 63; } break; case 63: if (millis() >= nextTimeTone) { tone(4, 311); nextTimeTone = millis() + 4; programTone = 64; } break; case 64: if (millis() >= nextTimeTone) { tone(4, 330); nextTimeTone = millis() + 4; programTone = 65; } break; case 65: if (millis() >= nextTimeTone) { tone(4, 349); nextTimeTone = millis() + 4; programTone = 66; } break; case 66: if (millis() >= nextTimeTone) { tone(4, 370); nextTimeTone = millis() + 4; programTone = 67; } break; case 67: if (millis() >= nextTimeTone) { tone(4, 392); nextTimeTone = millis() + 4; programTone = 68; } break; case 68: if (millis() >= nextTimeTone) { tone(4, 415); nextTimeTone = millis() + 4; programTone = 69; } break; case 69: if (millis() >= nextTimeTone) { tone(4, 440); nextTimeTone = millis() + 4; programTone = 70; } break; case 70: if (millis() >= nextTimeTone) { tone(4, 466); nextTimeTone = millis() + 4; programTone = 71; } break; case 71: if (millis() >= nextTimeTone) { tone(4, 494); nextTimeTone = millis() + 4; programTone = 72; } break; case 72: if (millis() >= nextTimeTone) { tone(4, 466); nextTimeTone = millis() + 4; programTone = 73; } break; case 73: if (millis() >= nextTimeTone) { tone(4, 440); nextTimeTone = millis() + 4; programTone = 74; } break; case 74: if (millis() >= nextTimeTone) { tone(4, 415); nextTimeTone = millis() + 4; programTone = 75; } break; case 75: if (millis() >= nextTimeTone) { tone(4, 392); nextTimeTone = millis() + 4; programTone = 76; } break; case 76: if (millis() >= nextTimeTone) { tone(4, 370); nextTimeTone = millis() + 4; programTone = 77; } break; case 77: if (millis() >= nextTimeTone) { tone(4, 349); nextTimeTone = millis() + 4; programTone = 78; } break; case 78: if (millis() >= nextTimeTone) { tone(4, 330); nextTimeTone = millis() + 4; programTone = 79; } break; case 79: if (millis() >= nextTimeTone) { tone(4, 311); nextTimeTone = millis() + 4; programTone = 80; } break; case 80: if (millis() >= nextTimeTone) { tone(4, 294); nextTimeTone = millis() + 4; programTone = 81; } break; case 81: if (millis() >= nextTimeTone) { tone(4, 277); nextTimeTone = millis() + 4; programTone = 82; } break; case 82: if (millis() >= nextTimeTone) { tone(4, 262); nextTimeTone = millis() + 4; programTone = 83; } break; case 83: if (millis() >= nextTimeTone) { programTone = 60; } break; } }
Вот вам задачка, если у вас режим = 4, butt2_flag = 0, butt2 = 0 что тогда произойдет? Поидее вы должны все обнулить и перейти в режим 0... А вообще код ппц конечно. Почитайте про функции, однотипного кода у вас полно.
Вот вам задачка, если у вас режим = 4, butt2_flag = 0, butt2 = 0 что тогда произойдет? Поидее вы должны все обнулить и перейти в режим 0...
Я так понял, нужно дополнительно вписать условие, нечто вроде:
Верно?
А вообще код ппц конечно. Почитайте про функции, однотипного кода у вас полно.
Что вы предлагаете сделать с этими однотипными фрагментами? Или про какие конкретно функции почитать?
Я подумал о сокращении кода через for, но не смог реализовать через millis() (через delay() работает). Нужно ли привести этот код?
Под функциями я имел ввиду не конкретные функции, а пользовательские. Т.е. однотипный код проще оформить в виде функции и вызывать, передавая параметры.
По идее programTone и programLed тоже нажо обновлять.
Вам лучше по частям сначала реализовать задумку, так и разберетесь.
Напишите и отладке код для перехода по режимам, чтобы он правильно с 4 в 1 возвращался. И еще есть такая штука как дребезг контактов, от него надо тоже избавляться.
Через switch вы что пытались реализовать? Типа проигрыш нот определенное время? И тоже самое со светодиодами. Если это что-то типа нот, то проще в массив их загнать и написать функцию которая будет проигрывать массив пока выполняется условие, например, кнопка нажата.
Под функциями я имел ввиду не конкретные функции, а пользовательские. Т.е. однотипный код проще оформить в виде функции и вызывать, передавая параметры.
По идее programTone и programLed тоже нажо обновлять.
Вам лучше по частям сначала реализовать задумку, так и разберетесь.
Напишите и отладке код для перехода по режимам, чтобы он правильно с 4 в 1 возвращался. И еще есть такая штука как дребезг контактов, от него надо тоже избавляться.
Через switch вы что пытались реализовать? Типа проигрыш нот определенное время? И тоже самое со светодиодами. Если это что-то типа нот, то проще в массив их загнать и написать функцию которая будет проигрывать массив пока выполняется условие, например, кнопка нажата.
Вы предлагаете вывести все programLed и programTone за пределы функции loop(), оформив их в виде отдельной функции, я правильно понял мысль? а в loop() оставить обращение к этим функциям, дабы не перегружать его.
могу отдельно написать код для светодиодов и отдельно для баззера через delay(). Точнее, с этого я как раз и начал. Затем в обоих случаях перевёл всё на millis() и nextTime, nextTimeTone, а потом совместил. Но обнаружил при работе с millis() проблему, что все светодиоды начинают цикл с загорания. Можно в принципе реализовать затухание через определённые промежутки, но мне нужен немного другой "рисунок". Можно и инвертировать логику и начать с затухшего светодиода и зажигать его через определённый промежуток. Но все эти промежутки не равны, если считать от общего времени,как это делает millis(). Поэтому и его реализовать вышло только через монструозную millis() + switch..case конструкцию.
Отладку чего сюда написать? Режимов? Или кейсов?
P.S. Удалось правильно исправить четвёртый режим через добавление
Примерно вот так можно сделать проигрывание вашей "музыки" (писал с телефона, возможно что-то упустил)
В этом примере музыка по кругу играет, в вашем же варианте надо вызывать функцию playMusic пока надо играть музыку и переставать вызывть и устанавливать currentNotes = 0 если проигрывать больше не надо.
По поводу светодиодов надо глянуть, думаю там примерно так же будет, для режима 1 и схемы R-RG-G-GB-B-BR-R вот как получилось.
Примерно вот так можно сделать проигрывание вашей "музыки" (писал с телефона, возможно что-то упустил)
В этом примере музыка по кругу играет, в вашем же варианте надо вызывать функцию playMusic пока надо играть музыку и переставать вызывть и устанавливать currentNotes = 0 если проигрывать больше не надо.
По поводу светодиодов надо глянуть, думаю там примерно так же будет, для режима 1 и схемы R-RG-G-GB-B-BR-R вот как получилось.
Вышло круто и гораздо короче..Я бы сам не допёр, наверное..Ибо пока до сих пор пока не понял, как делать дальше...Буду пытаться разобраться
Если вам будет удобнее, вот полные режимы "горения" в том же формате:
первый R1R2R3-R1G1R2G2R3G3-G1G2G3-G1B1G2B2G3B3-B1B2B3-R1B1R2B2R3B3 (каждый "кусок" 250 мсек),
второй R1G2B3-R1R2G2G3B3B1-R2G3B1-R2R3G3G1B1B2-R3G1B2-R3R1G1G2B2B3 (каждый "кусок" 125 мсек),
третий G1G2G3 (мигание по 10 мсек),
четвёртый B1B2B3 (мигание по 10 мсек).
Третий и четвёртый уже понимаю, что можно обычными millis() обойтись.
qwone, много читал ваших комментариев и из-за незнания языка боялся пришествия вас :D Просто я пытался разобраться с Си и С++, но запутался.. Попробую, спасибо большое!
Palurit. Самое удивительное, что я начинал как вы с азов. Пытался писать программы как можно проще и пришел к Си++. Странно! @_@. Но действительно на Си++ писать программы еще проще. Программа очень сильно упрощается. Можно отлаживать куски отдельно, да и копировать автономные куски из ранее проверенных программ. Потом я пытался показать другим, что так проще. Но постоянно говоришь одно и тоже. Но народ, внимание Palurit, тупо не верит. Они в этом путаются. Вот к примеру, вам надо сходить в ближайший магазин. Разумеется вы идете пешком. Что может быть проще. А если надо сходить в магазин на другом конце города. Идете пешком. Ведь это просто... Или просто садитесь в общественный транспорт. Ведь общественный транспорт это же сложно. Стоять блин на остановку, ждать, потом лезть в давку, стоять , а не сидеть, потом вовремя выйти. И наконец не забыть убедиться что транспорт идет туда, куда надо. В общем. Стресс. Но так действительно экономится время. И если делать это регулярно на работу и с работы, то позволяет поспать дома подольше. Вот так и Си++.
ПС: И вот я на днях написал менеджер задач. Мтю, конфетка. Да код сложноват. Но вам же не писать его снова. А так поставить и пользоваться. Как раз замена delay. Легко переводит код написаный с delay в многопоточную систему. Да и музыку проигрывать на нем, то что доктор прописал.
Уважаемый qwone. Моё чайничество в программировании в целом, не говоря уже о С++ диктует мне условия, которым я вынужден подчиняться. Спасибо большое за пищу к размышлению, буду осмысливать, но полноценно разобраться раньше выходных не получится, так что заранее извиняюсь за своеобразный "слив":D