Изменение программ по нажатию кнопки
- Войдите на сайт для отправки комментариев
Всем добрый день. По стандарту: Я новичек, с Ардуино разбираюсь гдето пятый день. Вот в чем вопрос.
Есть три отдельные программы. 2 из них отличаются только несколькими строками в цикле void loop. Третяя посложнее (она еще не готова, поэтому речь пойдет только о двух, но в итоге она тоже должна там быть).
Задача: переключатся между этими программами по нажатию кнопки. Тоесть: раз нажал на кнопку - первая работает, второй раз нажал - вторая работает, третий - третяя, еще раз нажал - заново пошло. Плата - Arduino UNO.
Вот собственно сам код:
int knopkaPin = 8; int pwmPin = 6; boolean poslSost = LOW; boolean znachKnopki = LOW; int dvig = 0; int knopkaInt = 0; //Pin 2 void setup() { pinMode(knopkaPin, INPUT); pinMode(pwmPin,OUTPUT); attachInterrupt (knopkaInt, swap, RISING); } void swap() { } boolean debounce(boolean posl) { boolean znach = digitalRead(knopkaPin); if (posl!=znach) { delay(5); znach = digitalRead(knopkaPin); } return znach; } void loop() { znachKnopki = debounce(poslSost); if (poslSost==LOW && znachKnopki == HIGH) { dvig = dvig + 255; } poslSost=znachKnopki; if (dvig > 255) dvig = 0; analogWrite(pwmPin,dvig); } void loop1() { znachKnopki = debounce(poslSost); if (poslSost==LOW && znachKnopki == HIGH) { dvig = dvig + 127; } poslSost=znachKnopki; if (dvig > 127) dvig = 0; analogWrite(pwmPin,dvig); }
Краткое описание. Есть кнопка, которая имитирует сигнал. Тоесть по нажатию (единичному, не держать) выполняется if, eще по одному нажатию - else. Есть движок, который подключен к 6 пину (с ШИМ). В итоге: нажал кнопку, движок выехал полностью, нажал - заехал полностью. Вторая программа, это тоже самое, но на половину.
Так вот, как их соеденить в одну. Я думал можно сделать 3 void loop, под разными номерами, в цикле swap сделать их чередование по нажатию кнопки с помощью прерывания (для этого влипил на второй пин). Но вразумительного ответа так и не нашел. Вот чтото похожее http://arduino.cc/en/Tutorial/MultipleBlinks но там Arduino DUE.
В итоге застрял. Прошу помощи у знатоков.
выложи отдельно 2 кода
Как видно они отличаются только одной цифрой. Третюю программу пока не ложу, она не готова, там тоже свои вопросы, но пока что надо сделать хоть это.
vitar, Ну так и меняйте одну цифру. Сделайте для неё переменную, вставьте её в код, и от дополнительной кнопки меняйте значение переменной.
Но это если бы мне надо было только эти 2 программы чередовать. Я же писал, что будет третяя, и она сильно отличается от этих двух. Тоесть надо создать какуюто глобальную подпрограмму, которая будет чередовть 3 цикла по нажатию кнопки. Я думал сделать void loop1, void loop2 и void loop3, и их менять по очереди в void swap. Но я не знаю как можно вызвать их в другом цикле и можно ли вообще.
vitar, вы мутите что-то странное, так можно, но так не делают. Нужно так составить одну программу, что бы она интегрировала в себе все необходимые функции.
Вот поэтому я и написал здесь, так как еще плохо разбираюсь в этих всех командах и не знаю тонкостей программирования на Arduino, а сроки горят. Я написал так, как сам представляю то что должно получится, но может кто-то знает более оптимальный вариант или сталкивался с подобным. В моем представлении есть одна большая программа (код), который состоит из трех основных подпрограмм и одной подпрограммы для переключения их по кругу с помощью кнопки. Представим, что все три подпрограммы разные и их надо всунуть в одну большую. Для этого я и придумал такие цикли, как (для меня) самый очевидный вариант. Естественно код получился топорный и большой, не оптимизированный. Может кто-то что-то подскажет. Буду благодарен.
и забудь о том примере void swap и void loop2 ...
у тебя должно быть 2 основных цикла, которые загружает дуина при работе - это первый void setup и void loop
все остальные функции пиши своими именами и еще если она ничего не возвращает, то пиши int <имя_функции> ()
если нужно ретурн делать - void MyFunction () { code... }
Воо. Спасибо. О такой функции я и не знал. Завтра не смогу, в понедельник попробую.
А кнопку лучше ставить обычную (вроде int button1 = какойто пин) или использовать прерывания (на второй пин)?
И что значит "ничего не возвращает"? Что-то вроде обратной связи? Тоесть в этих двух кодах у меня ее нет, тобишь можно int, а в третей у меня будет Serial.println, которая расчитывает значения из данных, полученных по обратной связи, и там мне надо будет использовать void?
посмотрел свой код int работает с return, хотя когда-то читал именно такое, что функция void возвращает. Может это в том случае если функция - обработчик типу void calc(x,y) когда параметр возвращает второй переменной.
Непойму о каких перерываниях вы говорите, поставте кнопку на какой-то пин, заземлите резистором ее и пропишите тот пин в программе.
кстати можно поставить кучу кнопок через резистор на аналоговый пин и прописать типа такого
все 3 своих функций пропишите через int MyFunction () {...} с главной программы оно будет вызыватся и выполнятся после выполнения перескакивать в void loop() и ждать кнопки.
Я просмотрел видео разные, нашел что-то похожее на то, что хотел, вот и решил отталкиватся от этого.
Вот с 9 минуты и дальше вторая часть: http://www.youtube.com/watch?v=wjB2qZ3Zkh0&index=18&list=PLfDmj22jP9S759DT250VVzfZs_4VnJqLa
А так спасибо, как попробую - отпишусь.
Всем привет. Добрался до программы наконецто.
Переделал с использованием case. Впринципе логику понял. Но возникла проблема со счетчиком. Походу не считывает значения. В программе вроде все верно, все условия заданы. Пины менял, кнопки менял, case местами менял, все работает, но когда собираю все в кучу то не работает. Вот код. Я уверен что проблема со счетчиком, но в упор не вижу. Когда нажимаю на кнопку счетчика, программа все равно работает по первому варианту. Если удерживаю ее, то вообще не работает.
Всё, всем спасибо, уже разобрался.
привет всем. с Arduino несколько дней, хочу собрать БК для своего авто на Arduino Nano v3 и LCD 8x2. код брал от сюда: http://habrahabr.ru/post/135231/ Плата уже собрана, осталось только программу до ума довеси
потом гуляя по просторам интернета наткнулся на этот форум и ещё на вот этот код: http://pastebin.com/eP20LeXX
вообщем вроде обрадовался но не тут то было, при заливки изменённного кода полезли ошибки. собственно вот такой код у меня получился. ну и там где switch (selmon) Case0 и Case1. вообщем в идеале у меня будет 4 экрана. программы по отдельности работают: основная программа, программа с датчика температуры. по сути я так понимаю что сперво пишутся все программы и формулы а в конце идет вывод на экран. экран у меня должен менятся одной кнопкой и пролистываться по кругу. ПРИ этом все программы и формулы должны работать всегда, т.к. будет зависимость у разных экранов. Начало кода я опустил, т.к. там ничего нет)))
в данном коде хотел выводить в первом экране ср и mgn расход и на втором экране скорость и слово TEMP.
Надеюсь на Вашу помощь. заранее благодарен. ткните пожалуйста что не правильно в моём коде. и по возможности исправте его.
Vanya_87
скобка в строке 217 закрывает switch, а скобка в строке 219 не закрыта
как-то в строках 27 и 28 логичнее было бы видеть int а не byte
откуда взялась и где задается переменная selmon
цикл for в строке 227 тоже не мешало бы открыть и закрыть, в строке 235 - две левых скобки.
Короче перед тем как скидывать не мешало бы и самому проверить что да как
спасибо. попробую. я просто говорю же с программами пару дней только)))
selmon вообще убрать? просто это было скопировано с другого кода
вот что выдала arduino после всех изменений:
как-то в строках 27 и 28 логичнее было бы видеть int а не byte
Логичнее там было бы uint8_t, зачем там 16-битные переменные? Врядли количество экранов и пинов будет больше 255 ;-)
Тип данных byte кстати тоже 8-ми битное беззнаковое целое число. Тоже самое, что uint8_t.
так мне назад byte вернуть?
и что с кодом делать? ошибки вылазиют и не дают прошиться
вот так переделал код, вылезла две ошибки!
вот ошибки в предущем коде-сообщении:
у тебя переменная value не объявлена нигде.
Вставь строку 36: byte value;
ага и весь код с 37 по 49 строку непонятно в чем находится, то ли функция то ли видение.
Уважаемый Vanya_87 ну изучите Вы матчасть потом пытайтесь что-то делать, а по принципу нафигачу чего нить и найду дурака который из этого конфетку сделает...
stakan1986
+1000 :)
не ищу я дурака, просто прошу помощи у знающих людей.
вот поискал в инете, нашёл скетч где все описано по каждой строчке, кстате на этом же форуме))) переделал свой код, ошибок нет, но при загрузки кода пустой экран.
вот код:
что у меня прописано не правильно?
строка 256 - если "подпрограмма" то по идее должна начинаться void а не int.
строка 260 - digitalRead выдаст вам только 2 значения - 0 и 1. но не тот непонятный набор который забит в butval
я может конечно чего-то не замечаю, но где Вы хоть что-то выводите на экран, чтоб хотеть что-то увидеть. Если бы вы как раз таки изучали матчасть то узнали бы что void setup выполняется при старте, а далее void loop выполняется по кругу, и чтобы запустить функцию void Menu в которой у Вас что то выводится на экран надо к ней обратиться внутри loop, аналогично и для других функций. Они вспомогательные и просто так - потому что есть в вашем коде - не запускаются.
строка 256 - если "подпрограмма" то по идее должна начинаться void а не int.
строка 260 - digitalRead выдаст вам только 2 значения - 0 и 1. но не тот непонятный набор который забит в butval
я может конечно чего-то не замечаю, но где Вы хоть что-то выводите на экран, чтоб хотеть что-то увидеть. Если бы вы как раз таки изучали матчасть то узнали бы что void setup выполняется при старте, а далее void loop выполняется по кругу, и чтобы запустить функцию void Menu в которой у Вас что то выводится на экран надо к ней обратиться внутри loop, аналогично и для других функций. Они вспомогательные и просто так - потому что есть в вашем коде - не запускаются.
я впринципе это понял, на счет void setup и void loop))
с 272 строки на экран вывод - я так думал)))
Народ, вы вообще где язык учили?
256 - 266 это описание функции, которая обрабатывает клавиши, подключенные через делители напряжения на аналоговый вход. Функция возвращает целочисленное значение нажатой клавиши. (return butPush;) Но почему считывание считывание делается как digitalRead, а не analogRead(), да еще и подключено на 9-й пин - для меня вообще не понятно. butPush объявлена как глобальная, а ее пытаются выводить как значение функции - бардак. В этом смысле соглашусь, что button () нет никакого смысла возвращать значение. Функция должна быть void.
Если у вас делитель для кнопок не соответствует оригинальному - кнопки работать не будут. С какой стати что-то должно показываться, если функция Menu(int) ниоткуда(кроме самой себя не вызывается). Надо 10 раз подумать прежде чем использовать рекурсию.
Вообще в коде полный бардак.
вот подправил код. брал из примера ардуины и "программирования" этого сайта. у меня два вопроса по коду: в 249 строке какая команда выводит на экран следующий Case в Switch-е и в 251 строке какая команда останавливает эти самые casы при отпущенной кнопки?? я нашёл что останавливает только break, но она у меня в case, или можно вообще строки с 249-251 удалить?
и ещё можете посмотреть 60 строку - правильно там "int" или нужна какая то другая команда??
246 строка - зачем2 скобки
команда switch (disp) берет значение переменной disp и сравнивает с вариантами перечисленными в case -соответственно 1 или 2, если совпадает то выполняет весь код до брэйка. то есть если disp = 1 то выполняет 235-239 строки и переходит к 247, а вот что там написано не понятно совсем - поясните.
И все таки никак не допру что и для чего делается в строках 255-267
246 строка - зачем2 скобки
команда switch (disp) берет значение переменной disp и сравнивает с вариантами перечисленными в case -соответственно 1 или 2, если совпадает то выполняет весь код до брэйка. то есть если disp = 1 то выполняет 235-239 строки и переходит к 247, а вот что там написано не понятно совсем - поясните.
И все таки никак не допру что и для чего делается в строках 255-267
246 строка - одна закрывает switch (disp) а вторая закрывает "if (new_t >= t)"- 122 строка
247 строка - я так понимаю действия которые происходят по нажатию кнопки и отпусканию её. если это так, а это должно быть так(взято с примера проги ардуины 1,0,5-r2 установленной у меня на компе), то нужно указать что бы при нажатии кнопки у меня переключилось на case 2 и потом обратно, своего рода счетчик что бы был не прерывный между 1 и 2 casом и соответсвенно выводом на экран инфы.
а в строках 255-267 я так понимаю что то типо вывода значений на дисплее если значение больше 1000 то вместо того значения выводятся решетки и ещё что то делается, ссылается оно на строку 195 и 203 там "format". код не я писал я только пытаюсь его дополнить что бы у меня кнопкой менялись экраны.
кстати загрузил код без 247-251 строки - на дисплее вышел сразу case 1, при чем рабочий, т.е. значения считаются))) а case 2 не могу включить, т.к. не прописано программно условия после нажатия кнопки
всё, разобрался я со счетчиком. меняется 3 экрана(сделал 3) и по кругу, вообщем то что и хотел)))
кнопку подключил на 9 пин цифрового выхода. только при нажатии на кнопку экраны скачат друг за другом а потом останавливаются - это наверное потому что у меня подключение без всяких резисторов, подключил на GND(землю) и D9, я прав?
правда когда вкл. "Подтягивающий (нагрузочный) резистор" - digitalWrite(9,HIGH);- вставляю на 69 строчку и
ничего не происходит, наоборот кнопка отказывается менять экраны.
if
(digitalRead(9)==LOW) -
на 256 строчку вместо моего ifесли что, вот ссылка на работу с кнопками и подключения их к цифровому входу (16 пост):
http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku
экраны скачут из-за так называемого "дребезга" контактов кнопки - с ним можно бороться программно или аппаратно. Погуглите
А почему не работает хз. Но если работает один вариант зачем биться над другим. Дребезг он будет в любом случае и с ним придется бороться
избавился я от дребезга. с кнопкой проблем нет, работает как часы.
дайте хоть на ваш код посмотреть
а вообще - переменную disp при нажатии кнопки увеличивать на единицу с проверкой: если disp==2 то disp =0 иначе disp++
сообщение на изменении висело, а на него уже ответили)))
у меня два варианта кода. один как у автора - минус в том что долго всё обрабатывается и бешеные значения выводятся на экран в машине. второй вариант пока не проверял, щас загружу его в друину и как проверю потом скажу)))
всё сделал. вместо delay которая тормозила всю программу ввел millis. вот такой вот вариант кода:
Здравствуйте знатоки Ардуино, хотел бы тоже попросить помощи т.к. у самого уже мозги закипают. Итак есть два скейтча:
1. Авто подсос на карбюраторную машину, контроль через датчик хола и термометр, управление через сервопривод, вывод на OLED экран.
2. Ручное управление через энкодер.
По отдельности все прекрасно работает, при попытке обьединения, в зависимости от того какой код идет первым от того сервопривод и работает, переключаться переключается работать не хочет. Посмотрите пожалуйста что тут не так.
Скейтч №1.
Скейтч №2.
Всё, всем спасибо, уже разобрался.
Добрый день! Если не секрет... Как решили проблему?