ARDUINO домофон. Требуется помощь со скетчем

Тема в разделе "Arduino & Shields", создана пользователем nevikat, 28 май 2018.

  1. nevikat

    nevikat Нерд

    Здравствуйте! Хочу сделать домофон на Arduino. В скетче что-то неправильно и работает не так, как нужно. Помогите плиз!
    P. S. В программировании Arduino новичок.
    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    // -----ПЕРЕМЕННЫЕ-----
    String num_kv = "";
    unsigned long last_millis;
    boolean otvet_na_zvonok;
    boolean last_otvet_na_zvonok;
    boolean flag;
    boolean flag2;
    boolean flag3;
    boolean flag4;
    boolean flag5;
    boolean flag6;
    boolean flag7;
    boolean flag8;
    boolean flag9;
    // -----ОСНОВ. КОД-----
    void zvuk_zvonok() {
      while (!otvet_na_zvonok) {
        last_otvet_na_zvonok = 1;
        if (!digitalRead(11)) {
          otvet_na_zvonok = 1;
          break;
        }
        digitalWrite(13, HIGH);   // ти
        delay(30);                // ти
        digitalWrite(13, LOW);    // ти
        delay(120);               // ждём
        digitalWrite(13, HIGH);   // лии
        delay(100);               // лии
        digitalWrite(13, LOW);    // лии
        delay(120);               // ждём
        digitalWrite(13, HIGH);   // ти
        delay(30);                // ти
        digitalWrite(13, LOW);    // ти
        delay(120);               // ждём
        digitalWrite(13, HIGH);   // лии
        delay(100);               // лии
        digitalWrite(13, LOW);    // лии
        delay(120);               // ждём
        digitalWrite(13, HIGH);   // ти
        delay(30);                // ти
        digitalWrite(13, LOW);    // ти
        delay(120);               // ждём
        digitalWrite(13, HIGH);   // лии
        delay(100);               // лии
        digitalWrite(13, LOW);    // лии
        delay(1200);               // ждём больше
      }
    }


    void setup() {
      lcd.init();
      lcd.backlight();
      lcd.setCursor(0, 0);
      pinMode(13, OUTPUT);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      pinMode(5, INPUT_PULLUP);
      pinMode(6, INPUT_PULLUP);
      pinMode(7, INPUT_PULLUP);
      pinMode(8, INPUT_PULLUP);
      pinMode(9, INPUT_PULLUP);
      pinMode(12, INPUT_PULLUP);
    }

    void loop() {
      otvet_na_zvonok = !digitalRead(12);
      lcd.setCursor(0, 0);
      lcd.print(num_kv);
      if (!digitalRead(1) && !flag) {
        num_kv += 1;
        flag = 1;
      }
      if (digitalRead(1) && flag) {
        flag = 0;
      }
      if (!digitalRead(2) && !flag2) {
        num_kv += 2;
        flag2 = 1;
      }
      if (digitalRead(2) && flag2) {
        flag2 = 0;
      }
      if (!digitalRead(3) && !flag3) {
        num_kv += 3;
        flag3 = 1;
      }
      if (digitalRead(3) && flag3) {
        flag3 = 0;
      }
      if (!digitalRead(4) && !flag4) {
        num_kv += 4;
        flag4 = 1;
      }
      if (digitalRead(4) && flag4) {
        flag4 = 0;
      }
      if (!digitalRead(5) && !flag5) {
        num_kv += 5;
        flag5 = 1;
      }
      if (digitalRead(5) && flag5) {
        flag5 = 0;
      }
      if (!digitalRead(6) && !flag6) {
        num_kv += 6;
        flag6 = 1;
      }
      if (digitalRead(6) && flag6) {
        flag6 = 0;
      }
      if (!digitalRead(7) && !flag7) {
        num_kv += 7;
        flag7 = 1;
      }
      if (digitalRead(7) && flag7) {
        flag7 = 0;
      }
      if (!digitalRead(8) && !flag8) {
        num_kv += 8;
        flag8 = 1;
      }
      if (digitalRead(8) && flag8) {
        flag8 = 0;
      }
      if (!digitalRead(9) && !flag9) {
        num_kv += 9;
        flag9 = 1;
      }
      if (digitalRead(9) && flag9) {
        flag9 = 0;
      }
      if (!otvet_na_zvonok) {
        if (num_kv != "") {
          if (digitalRead(2) || digitalRead(3) || digitalRead(4) || digitalRead(5) || digitalRead(6) || digitalRead(7) || digitalRead(8) || digitalRead(9) || digitalRead(10)) {
            if (millis() > last_millis + 2000) {
              zvuk_zvonok();
              last_millis = millis();
            }
          }
        }
        if (last_otvet_na_zvonok && !otvet_na_zvonok) {
          num_kv = "";
        }
      }
    }
     
  2. ИгорьК

    ИгорьК Гуру

    А как он работает и как должен работать?
     
    nevikat нравится это.
  3. nevikat

    nevikat Нерд

    Я подключаю питание. Дисплей включился, на нём ничего нет. Всё ок. Я нажимаю кнопки 4, 6, 7, 8, 9 и они отображаются на дисплее, но происходит вызов, а 2 сек ещё не прошли. Остальные кнопки просто запускают вызов, не отображаясь на дисплее. Как всё должно работать:
    Включаю питание. Дисплей включился, на нем ничего нет. Нажимаю, например, кнопку 1. На дисплее отображается 1. Нажимаю, например, ещё кнопку 4. Отображается 14, т. к. перед этим нажали 1. Как-то так. Если пользователь не нажимает кнопки 2 секунды и строка не пустая, то звоним (ти лии ти лии в коде), ответ - подать на 12 пин сигнал (минус, т. к. PULLUP). Если звонок был, но сейчас он не происходит, сбрасываем строку. Вот и всё.
     
  4. parovoZZ

    parovoZZ Гуру

    Ну так нарисуй на листке бумаги алгоритм. И по нему напиши программу.
     
  5. 1 где есть millis() не должно быть delay():)
    2 используйте вместо кучи вызовов цикл
    Код (C++):
    for (byte i=1; i<=12; i++) {pinMode (i,INPUT_PULLUP)
    3 из setup() уберите строку, она там лишняя
    Код (C++):
    lcd.setCursor(0, 0);
    4 нужна еще функция для примера такая
    Код (C++):
    void blink(byte i , byte j) {
    digitalWrite(13, HIGH);// ти
    delay(i);               // ти
    digitalWrite(13, LOW);   // ти
    delay(j);             // ждём
    }
    и вызывайте сколько надо
    blink(30 , 120);
    blink(100 , 120); и тд
     
    Последнее редактирование: 29 май 2018
    nevikat нравится это.
  6. nevikat

    nevikat Нерд

    Спасибо:) Сейчас попробую
     
  7. nevikat

    nevikat Нерд

    2. Извините, а где у меня delay в millis()?
     
  8. parovoZZ

    parovoZZ Гуру

    А почему? Delay - это такая же инструкция, как и любая другая.
     
  9. b707

    b707 Гуру

    думаю, Александр имеет в виду процедуру zvuk_zvonok

    Но главная ваша ошибка не в этом. Насколько я вижу у вас неправильно написаны логические операции и вы не умеете работать с миллис.
    Звонок звенит сразу? - а как он еще должен, вы в коде так напрограммировали... Посмотрите еще раз примеры с миллис. Сперва нужно запомнить начальное время. а потом отсчитать от него 2 секунды. Где вы начинаете отсчет этих 2х секунд в коде? - нигде
     
  10. nevikat

    nevikat Нерд

    Блин, я понял. Я правда не умею работать с millis(). Но как сделать то, что мне надо? Я как-то не понимаю... HELP PLS!!!
     
  11. b707

    b707 Гуру

    Код (C++):
    uint8_t flag =0;
    uint32_t last_millis;

    void loop() {
    if ((кнопки нажаты) && ! flag) {
    flag =1;
    last_millis = millis();        // начинаем отсчет времени
    }
    if (Flag && (millis() - last_millis > 2000 )) {
    zvonok;
    flag = 0;
    }
     
    nevikat нравится это.
  12. nevikat

    nevikat Нерд

    Пробую... спасибо)
    ииииии
    Вы имеете ввиду кнопки НЕ нажаты? Или всё-таки нажаты?
     
  13. b707

    b707 Гуру

    ну это же ваш проект. Вам с какого момента 2 сек надо отсчитывать - когда нажаты или когда нет?
    Или вы настолько не понимаете логику миллис??
     
  14. nevikat

    nevikat Нерд

    Понимаю. Значит, не нажаты.
     
  15. nevikat

    nevikat Нерд

    1. PROBLEMA № ∞
    Набрал номер без проблем. Ждём... ждём... ждём... Уже ∞ секунд прошло, звонок не идёт. В чём проблема? Вот новый скетч:
    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    // -----ПЕРЕМЕННЫЕ-----
    String num_kv = "";
    unsigned long last_millis;
    boolean otvet_na_zvonok;
    boolean last_otvet_na_zvonok;
    boolean flag;
    boolean flag2;
    boolean flag3;
    boolean flag4;
    boolean flag5;
    boolean flag6;
    boolean flag7;
    boolean flag8;
    boolean flag9;
    boolean flag_mil;
    // -----ОСНОВ. КОД-----
    void setup() {
      lcd.init();
      lcd.backlight();
      lcd.setCursor(0, 0);
      for (byte i = 1; i <= 9; i++) {
        pinMode (i, INPUT_PULLUP);
      }
      pinMode(12, INPUT_PULLUP);
      pinMode(13, OUTPUT);
    }

    void loop() {
      otvet_na_zvonok = !digitalRead(12);
      lcd.setCursor(0, 0);
      lcd.print(num_kv);
      if (!digitalRead(1) && !flag) {
        num_kv += 1;
        flag = 1;
      }
      if (digitalRead(1) && flag) {
        flag = 0;
      }
      if (!digitalRead(2) && !flag2) {
        num_kv += 2;
        flag2 = 1;
      }
      if (digitalRead(2) && flag2) {
        flag2 = 0;
      }
      if (!digitalRead(3) && !flag3) {
        num_kv += 3;
        flag3 = 1;
      }
      if (digitalRead(3) && flag3) {
        flag3 = 0;
      }
      if (!digitalRead(4) && !flag4) {
        num_kv += 4;
        flag4 = 1;
      }
      if (digitalRead(4) && flag4) {
        flag4 = 0;
      }
      if (!digitalRead(5) && !flag5) {
        num_kv += 5;
        flag5 = 1;
      }
      if (digitalRead(5) && flag5) {
        flag5 = 0;
      }
      if (!digitalRead(6) && !flag6) {
        num_kv += 6;
        flag6 = 1;
      }
      if (digitalRead(6) && flag6) {
        flag6 = 0;
      }
      if (!digitalRead(7) && !flag7) {
        num_kv += 7;
        flag7 = 1;
      }
      if (digitalRead(7) && flag7) {
        flag7 = 0;
      }
      if (!digitalRead(8) && !flag8) {
        num_kv += 8;
        flag8 = 1;
      }
      if (digitalRead(8) && flag8) {
        flag8 = 0;
      }
      if (!digitalRead(9) && !flag9) {
        num_kv += 9;
        flag9 = 1;
      }
      if (digitalRead(9) && flag9) {
        flag9 = 0;
      }
      if (!otvet_na_zvonok) {
        if (num_kv != "" && !flag_mil) {
          if (digitalRead(2) || digitalRead(3) || digitalRead(4) || digitalRead(5) || digitalRead(6) || digitalRead(7) || digitalRead(8) || digitalRead(9) || digitalRead(10)) {
            flag_mil = 1;
            last_millis = millis();        // начинаем отсчет времени
          }
          if (flag_mil && (millis() - last_millis > 2000 )) {
            zvuk_zvonok();
            flag_mil = 0;
          }
        }
      }
      if (last_otvet_na_zvonok && !otvet_na_zvonok) {
        num_kv = "";
      }
    }

    void zvuk_blink() {
      digitalWrite(13, HIGH);   // ти
      delay(30);                // ти
      digitalWrite(13, LOW);    // ти
      delay(120);               // ждём
      digitalWrite(13, HIGH);   // лии
      delay(100);               // лии
      digitalWrite(13, LOW);    // лии
      delay(150);               // ждём больше
    }

    void zvuk_zvonok() {
      while (!otvet_na_zvonok) {
        last_otvet_na_zvonok = 1;
        if (!digitalRead(11)) {
          otvet_na_zvonok = 1;
          break;
        }
        zvuk_blink();
      }
    }
    2. Что значит uint8_t?
     
  16. b707

    b707 Гуру

    тогда. как мне кажется - у вас звонок будет звенеть всегда через 2 сек после запуска программы... у вас там в описании сказано, что сначала пользователь что-то должен набрать на дисплее... где вы это проверяете в коде?
     
  17. b707

    b707 Гуру

    а зачем у вас это жуткое логическое пугало
    Код (C++):
    if (digitalRead(2) || digitalRead(3) || digitalRead(4) || digitalRead(5) || digitalRead(6) || digitalRead(7) || digitalRead(8) || digitalRead(9) || digitalRead(10))
    и делает ли оно то, что вам нужно? Мне кажется нет.
    Кроме этого, проверять строку на равенство !="" - это неверно, лучше проверяйте, что длина строки == 0
     
  18. nevikat

    nevikat Нерд

    Звонок звенит, если строка НЕ пустая. Посмотрите повнимательнее.
     
  19. nevikat

    nevikat Нерд

    1. Я проверяю, что пользователь сейчас не жмёт кнопки. Вы же сами скинули кусок кода.
    2. Окей, исправил.
    ——————————————————
    НА СТРАНИЦЕ 2 ПРОДОЛЖЕНИЕ!!!!
     
    Последнее редактирование: 29 май 2018
  20. b707

    b707 Гуру

    ну так подумайте, когда это условие истинно, а когда ложно.
    Чтож все так буквально-то подсказывать приходится...сами думайте.