Нужна помощь в коде

Тема в разделе "Arduino & Shields", создана пользователем Vladyka1701, 19 янв 2014.

  1. Vladyka1701

    Vladyka1701 Нерд

    Я новичок в мире ардуино, и мне нужна помощь опытных программистов. Я хочу сделать игру на 16
    х2 дисплее. С интро я разобрался, и анимация есть, но когда дело дошло до управления, ничего не вышло. Потратил час, копаясь по всему интернету, но ничего не нашёл. Мне нужно сделать, чтобы при нажатии кнопки, буква P на экране сдвинулась. Я подключил кнопку к минусу бредборда, а плюс к пину 47 через резистор на 220 ОМ. Сделал int POOTIS=47. В конце сделал
    POOTIS=digitalRead(47);

    if(POOTIS==HIGH)

    lcd.print("START");

    else
    {
    lcd.print ("NOT");
    }

    При нажатии ничего не происходит. Код
    Код (Text):

    #include <LiquidCrystal.h>

    #define BUZZER_PIN 3

    int POOTIS=47;
    int bpm = 30;
    const int whole = (60000/bpm);
    const int half = 30000/bpm;
    const int quarter = 15000/bpm;
    const int eight = 7500 / bpm;
    const int sixteenth = 3750 / bpm;
    const int thirty2 = 1875 / bpm;

    LiquidCrystal lcd(4, 5, 10, 11, 12, 13);
    void setup()
    {
        lcd.begin(16, 2);

        lcd.print("Loading");

        pinMode (47,INPUT);

        delay(500);

        lcd.clear();

        lcd.print("Loading.");

        tone(BUZZER_PIN, 1000, 50);


        delay(500);

        lcd.clear();

        lcd.print("Loading..");

        tone(BUZZER_PIN, 2000, 50);

        delay(500);

        lcd.clear();

        lcd.print("Loading...");

        tone(BUZZER_PIN, 3000, 50);

        delay (1000);

        lcd.clear();

        lcd.setCursor (3, 0);

        lcd.print("VMOD");

        lcd.setCursor (1, 1);

        lcd.print ("PRESENTS");

        delay (500);

        tone(BUZZER_PIN, 3000, 50);

        delay (100);

        tone(BUZZER_PIN, 3000, 50);

        delay (100);

        tone(BUZZER_PIN, 3000, 50);

        delay (100);

        tone(BUZZER_PIN, 1000, 50);

        delay (100);

        tone(BUZZER_PIN, 2000, 50);

        delay (100);

        tone(BUZZER_PIN, 3000, 50);

        delay (100);

        tone(BUZZER_PIN, 1000, 50);

        delay (1000);

        lcd.clear();

        lcd.setCursor (3, 0);

        lcd.print ("POOTIS");

        lcd.setCursor (0, 1);

        lcd.print ("ADVENTURES");

          tone(BUZZER_PIN, 1568, eight);//g6
      delay(eight);
      noTone(BUZZER_PIN);
      delay(sixteenth);
      tone(BUZZER_PIN, 1568, sixteenth);//g6
      delay(sixteenth);
      tone(BUZZER_PIN, 1864, half);//a#6
      delay(half);
      noTone(BUZZER_PIN);
      delay(thirty2);
      tone(BUZZER_PIN, 1760, eight);//a6
      delay(eight);
      tone(BUZZER_PIN, 1568, eight);//g6
      delay(eight);
      tone(BUZZER_PIN, 1396, eight);//f6
      delay(eight);
      tone(BUZZER_PIN, 1760, eight);//a6
      delay(eight);
      tone(BUZZER_PIN, 1568, half);
      delay(half);
        delay (3000);

        lcd.clear();

        lcd.setCursor (0, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (1, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (2, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (3, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (4, 1);

        lcd.print ("P");

        delay (1000);

        lcd.setCursor (15, 1);

        lcd.print ("E");

        lcd.setCursor (4, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (14, 1);

        lcd.print ("E");

        lcd.setCursor (4, 1);

        lcd.print ("P");

        delay (500);

        lcd.clear();

        lcd.setCursor (13, 1);

        lcd.print ("E");

        lcd.setCursor (4, 1);

        lcd.print ("P");

        delay (1000);

        lcd.setCursor (1, 0);

        lcd.print ("NEED DISPENSER!");

        delay (1000);

        lcd.clear();

        lcd.setCursor(1, 0);

        lcd.print ("HAHA, NOPE!!!");

        lcd.setCursor (5, 1);

        lcd.print ("P");

        lcd.setCursor (15, 1);

        lcd.print ("E");

        delay (1000);

        lcd.clear();

        lcd.setCursor (6, 1);

        lcd.print ("P");

        lcd.setCursor (3, 0);

        lcd.print ("STOP!!!");

        delay (3000);

        lcd.clear();

        delay (1000);

        lcd.setCursor (4, 0);

        lcd.print ("CHAPTER");

        lcd.setCursor (6, 1);

        lcd.print ("1");

        delay (1000);

        lcd.clear();

        lcd.setCursor (1, 1);
        lcd.print ("P");

        POOTIS=digitalRead(47);

    if(POOTIS==HIGH)

    lcd.print("START");

    else
    {
      lcd.print ("NOT");
    }


    }
    void loop()
    {
    }

    Помощь нужна в начале кода и в конце.

    IMG_20140119_095502.jpg
    Подключение кнопки.

    IMG_20140119_095512.jpg
    Вся схема.

    Помогите, пожалуйста.

    Кстати, после интро всегда пишет START, но я не жал кнопку, а если вытащить, то пишет NOT.

    P.S Оно опознаёт, есть ли кнопка, только после перезагрузки.
     
    Последнее редактирование: 19 янв 2014
  2. NR55RU

    NR55RU Гик

    А ничего и не произойдет.
    микроконтроллер не останавливаться на вашем условии IF.
    Он его проверил за тысячную долю секунды и пошел дальше.
    Условие IF не останавливает работу программы как и строка digitalRead() не ждет пока вы нажмете на кнопку :)
    Таким образом чтобы ваше условие сработала верно в ту самую тысячную долю секунды когда контролер проверяет состояние входа digitalRead() кнопка должна быть нажата :)
    Ну а кнопка у вас подключена, так что дает высокий уровень сигнала на входе, посему вы получаете START а убрав кнопку вы получаете низкий уровень сигнала на входе вот вам и NOT.
     
    Последнее редактирование: 19 янв 2014
  3. Vladyka1701

    Vladyka1701 Нерд

    А как можно сделать, чтобы контроллер дожидался,пока я нажму на кнопку и не выводил сообщение START, пока кнопка не нажата?
    Мне нужно, чтобы по нажатии кнопки буква P начала двигаться (код для движения я продумаю).
    Как заставить контроллер ждать?
     
  4. NR55RU

    NR55RU Гик

  5. rav_75

    rav_75 Гик

    Попробуйте ковырнуть в сторону while http://arduino.ru/Reference/While Ну и уроки, как минимум, лишними не будут. :)
     
  6. Vladyka1701

    Vladyka1701 Нерд

    Спасибо, я посмотрю. А ты не знаешь какой код нужен? Я просто планирую сегодня закончить, а для понимания уроков нужен как минимум день.
     
  7. geher

    geher Гуру

    И лучше сделать по прерыванию, если пин для прерываний свободен.
     
  8. Vladyka1701

    Vladyka1701 Нерд

    Я когда ставлю while, у меня со скоростью света мигает разными заковырками. Я даже не знаю, что делать...
     
  9. geher

    geher Гуру

    Еще кое-какие мысли.
    Может быть, я чего-то не понимаю, но смысл резистора на кнопке от меня ускользает.
    В примерах кнопка цепляется непосредственно между землей и пином.

    В любом случае, если цеплять кнопку к земле, то по нажатию кнопки состояние пина будет LOW.
    Т.е. логично будет действия по нажатой кнопке делать по условию POOTIS==LOW, а по отпущенной по условию POOTIS==HIGH.

    Кроме того, насколько я понимаю, пин в этом случае должен быть сконфигурирован следующим образом:
    pinMode(47, INPUT); // назначить выводу порт ввода
    digitalWrite(47, HIGH); // включить подтягивающий резистор

    Или, что вроде то же самое
    pinMode(47, INPUT_PULLUP);
     
  10. Vladyka1701

    Vladyka1701 Нерд

    Теперь всё работает! Я снял резистор, исправил код и теперь кнопка определяется правильно!
    Но она определяется только один раз-когда ты её зажмешь перед началом уровня. Как заставить ардуино постоянно смотреть за состоянием кнопки, и делать действия? (Мне желательно подробнее, чтобы хорошо запомнить)
     
  11. geher

    geher Гуру

    Нужно всего лишь периодически по ходу алгоритма проверять положение кнопки (нажата/отпущена) и реагировать на нее правильным образом.

    Тут было на предмет машины состояний. Т.е. весь алгоритм можно свести к набору состояний и переходам между ними, сопровождающимися действиями при определенных условиях.
    Т.е. в начале действия по каждому состоянию можно вызвать функцию, проверяющую положения кнопки, и в соответствии с этим положением выполнить действие и переход к следующему состоянию.
     
  12. rav_75

    rav_75 Гик

    Ну так у Вас весь код в setup(), чего Вы хотели? Нажимаете кнопку, на экране пишется "START", а дальше крутится пустой loop().
     
  13. Vladyka1701

    Vladyka1701 Нерд

    Мне нужно реагировать каждую секунду, ардуино должно быть готово всегда, ведь не ясно, когда человек нажмёт кнопку.
     
  14. geher

    geher Гуру

    Тогда через прерывания. Только пишут, что вроде как придется озаботиться решением проблемы дребезга кнопки.
    Прерывание по нажатию кнопки должно взвести флаг, что она нажата.
    Код алгоритма поделить на максимально мелкие фрагменты, в начале каждого проверять состояние флага, если взведен - сбрасывать и предпринимать нужные действия.
     
  15. Vladyka1701

    Vladyka1701 Нерд

    Можно код? Или источник?
     
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Воспользуйтесь поиском по форуму, тут подобные вопросы неоднократно обсуждались. Почитайте вики.
    На arduino.cc тоже найдете много интересного.
     
  17. Vladyka1701

    Vladyka1701 Нерд

    Спасибо, поищу. Если не выйдет, напишу.
     
  18. rav_75

    rav_75 Гик

    Выше давали ссылку на видеоуроки. Есть там и прерывания, и как дребезг побороть.
     
  19. Vladyka1701

    Vladyka1701 Нерд

    Я посмотрел уроки Джереми Блюма, где он говорил про прерывания. Он написал в коде int ButtonInt = 0, но прокомментировал, что это на самом деле пин 2. Во всём его коде не было не одной двойки. Как он определил ButtonInt как пин 2?
     
  20. Unixon

    Unixon Оракул Модератор

    Это номер прерывания, а не номер пина. У ATmega328 два внешних прерывания: INT0 на 2 пине и INT1 на 3 пине.