Работа с кнопками. В помощь новичку.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

GKV. Вот код. В работе не проверял.

uint32_t mill;// переменая для millis()
//--------------------class Cl_Led------------------------
//класс светодиод
class Cl_Led {
    const byte pin;
    const bool inv;
    bool led;
    uint32_t past, time ;
  public:
    Cl_Led *pnt = NULL;
    /*
      конструктор Cl_Led
      описание    создает класс
      ввод        _pin: номер пина для подключения
                  _inv: инверт управление 0 -нормально 1 - обратно
      вывод       нет
    */
    Cl_Led(byte _pin, byte _inv = 0): pin(_pin), inv(_inv) {}
    /*
      Функция  setup
      Описание иницирование класса
      Ввод     нет
      Вывод    нет
    */
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode (pin, OUTPUT);
      OFF();
    }
    /*
      Функция  ON
      Описание включить светодиод
      Ввод     нет
      Вывод    нет
    */
    void ON() {
      digitalWrite(pin, !inv);
    }
    /*
      Функция  ON
      Описание включить светодиод на время
      Ввод     _time: длительность включения светодиода в миллисек
      Вывод    нет
    */
    void ON(uint32_t _time) {
      time = _time;
      past = mill;
      led = 1;
      digitalWrite(pin, led ^ inv);
    }
    /*
      Функция  OFF
      Описание выключить светодиод
      Ввод     нет
      Вывод    нет
    */
    void OFF() {
      led = 0;
      digitalWrite(pin, inv);
    }
    /*
      Функция  loop
      Описание для нормальной работе разместить в loop программы
      Ввод     нет
      Вывод    нет
    */
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (led && mill - past >= time) {
        OFF();
      }
    }
};
//----------------class Cl_Btn----------------------------
//класс кнопка без программной подтяжки
// кнопка нажата на ноге 1, отжата 0
class Cl_Btn {
    const byte pin ; // номер ноги на кнопке
    void (* Do1)(), (* Do2)();
    bool btn, btn_old;
  public:
    Cl_Btn *pnt = NULL;
    /*
      конструктор Cl_Btn
      описание    создает класс
      ввод        _pin: номер пина для подключения
                  _Do1: указатель на функцию обработчика нажатия
                  _Do2: указатель на функцию обработчика отжатия
      вывод       нет
    */
    Cl_Btn(byte _pin, void (* _Do1)(), void (* _Do2)())
      : pin(_pin), Do1(_Do1), Do2(_Do2) {}
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, INPUT);// подключить кнопку
      btn_old = digitalRead(pin); // прочитать реальное значение на выводе};
    }
    /*
      Функция  loop
      Описание для нормальной работе разместить в loop программы
      Ввод     нет
      Вывод    нет
    */
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      btn = digitalRead(pin) ; // прочитать реальное значение на выводе
      if (!btn_old && btn) { // если кнопка только что нажата
        btn_old = 1;
        (* Do1)();
      }
      if (btn_old && !btn) { // если кнопка только что отжата
        btn_old = 0;
        (* Do2)();
      }
    }
};
//-----------------class Cl_sys---------------------------
// класс для пакетной обработки классов
class Cl_sys {
    Cl_Led * StartLed = NULL;
    Cl_Btn * StartBtn = NULL;
  public:
    /*
      конструктор Cl_sys
      описание    просто ничего не делает
      ввод        нет
      вывод       нет
    */
    Cl_sys() {}
    /*
      Функция  setup
      Описание пакетный запуск setup-ов подключеныых классов
      Ввод     нет
      Вывод    нет
    */
    void setup() {
      StartLed->setup();
      StartBtn->setup();
    }
    /*
      Функция  loop
      Описание пакетный запуск loop-ов подключеныых классов
      Ввод     нет
      Вывод    нет
    */
    void loop() {
      StartLed->loop();
      StartBtn->loop();
    }
    /*
      Функция  Plug
      Описание подключить класс Cl_Led по указателю
      Ввод     *Led: указатель на класс
      Вывод    нет
    */
    void Plug(Cl_Led * Led) {
      Led->pnt = StartLed;
      StartLed = Led;
    }
    /*
      Функция  Plug
      Описание подключить класс Cl_Btn по указателю
      Ввод     *Btn: указатель на класс
      Вывод    нет
    */
    void Plug(Cl_Btn * Btn) {
      Btn->pnt = StartBtn;
      StartBtn = Btn;
    }
};
//-------------Компановка-------------------------------
Cl_Led Led1 (/*пин*/A0,/*инверсия*/1);
Cl_Led Led2 (/*пин*/A1,/*инверсия*/1);
Cl_Led Led3 (/*пин*/A2,/*инверсия*/1);
Cl_Led Led4 (/*пин*/A3,/*инверсия*/1);
Cl_Led Led5 (/*пин*/A4,/*инверсия*/1);
Cl_Led Led6 (/*пин*/A5,/*инверсия*/1);
Cl_Led Led7 (/*пин*/11,/*инверсия*/1);
Cl_Led Led8 (/*пин*/12,/*инверсия*/1);
Cl_Led Led9 (/*пин*/10,/*инверсия*/1);
Cl_Led Led10(/*пин*/13,/*инверсия*/1);

const uint32_t time_50s = 50000 ;
const uint32_t time_30s = 30000 ;
const uint32_t time_2s = 2000 ;
const uint32_t time_10s = 10000 ;
const uint32_t time_3s = 3000 ;
const uint32_t time_5s = 5000 ;

void Do1_Btn1() {  // выполнить при нажатии кнопки Btn1
  Led1.ON();
  Led9.ON(time_2s);
}
void Do2_Btn1() { //  выполнить при отжатии кнопки Btn1
  Led1.ON(time_30s);
  Led9.ON(time_2s);
}
void Do1_Btn2() {  // выполнить при нажатии кнопки Btn2
  Led2.ON();
  Led9.ON(time_2s);
}
void Do2_Btn2() { //  выполнить при отжатии кнопки Btn2
  Led2.ON(time_30s);
  Led9.ON(time_2s);
}
void Do1_Btn3() {  // выполнить при нажатии кнопки Btn3
  Led3.ON();
  Led9.ON(time_2s);
}
void Do2_Btn3() {  // выполнить при отжатии кнопки Btn3
  Led3.ON(time_30s);
  Led9.ON(time_2s);
}
void Do1_Btn4() {  // выполнить при нажатии кнопки Btn4
  Led4.ON();
  Led9.ON(time_2s);
}
void Do2_Btn4() {  // выполнить при отжатии кнопки Btn4
  Led4.ON(time_30s);
  Led9.ON(time_2s);
}
void Do1_Btn5() {  // выполнить при нажатии кнопки Btn5
  Led5.ON();
  Led10.ON(time_2s);
}
void Do2_Btn5() {  // выполнить при отжатии кнопки Btn5
  Led5.ON(time_30s);
  Led10.ON(time_2s);
}
void Do1_Btn6() {  // выполнить при нажатии кнопки Btn6
  Led6.ON();
  Led10.ON(time_2s);
}
void Do2_Btn6() {  // выполнить при отжатии кнопки Btn6
  Led6.ON(time_30s);
  Led10.ON(time_2s);
}
void Do1_Btn7() {  // выполнить при нажатии кнопки Btn7
  Led7.ON();
  Led10.ON(time_2s);
}
void Do2_Btn7() {  // выполнить при отжатии кнопки Btn7
  Led7.ON(time_30s);
  Led10.ON(time_2s);
}
void Do1_Btn8() {  // выполнить при нажатии кнопки Btn8
  Led8.ON();
  Led10.ON(time_2s);
}
void Do2_Btn8() {  // выполнить при отжатии кнопки Btn8
  Led8.ON(time_30s);
  Led10.ON(time_2s);
}
Cl_Btn Btn1(/*пин*/2,/*обраб наж кноп*/Do1_Btn1,/*обраб отж кноп*/Do2_Btn1);// подключить кнопку на выв 2
Cl_Btn Btn2(/*пин*/3,/*обраб наж кноп*/Do1_Btn2,/*обраб отж кноп*/Do2_Btn2);// подключить кнопку на выв 3
Cl_Btn Btn3(/*пин*/4,/*обраб наж кноп*/Do1_Btn3,/*обраб отж кноп*/Do2_Btn3);// подключить кнопку на выв 4
Cl_Btn Btn4(/*пин*/5,/*обраб наж кноп*/Do1_Btn4,/*обраб отж кноп*/Do2_Btn4);// подключить кнопку на выв 5
Cl_Btn Btn5(/*пин*/6,/*обраб наж кноп*/Do1_Btn5,/*обраб отж кноп*/Do2_Btn5);// подключить кнопку на выв 6
Cl_Btn Btn6(/*пин*/7,/*обраб наж кноп*/Do1_Btn6,/*обраб отж кноп*/Do2_Btn6);// подключить кнопку на выв 7
Cl_Btn Btn7(/*пин*/8,/*обраб наж кноп*/Do1_Btn7,/*обраб отж кноп*/Do2_Btn7);// подключить кнопку на выв 8
Cl_Btn Btn8(/*пин*/9,/*обраб наж кноп*/Do1_Btn8,/*обраб отж кноп*/Do2_Btn8);// подключить кнопку на выв 9
Cl_sys Sys;
//---------main()--------------------------------------------------------------------
void setup() {
  Sys.Plug(&Led1);
  Sys.Plug(&Led2);
  Sys.Plug(&Led3);
  Sys.Plug(&Led4);
  Sys.Plug(&Led5);
  Sys.Plug(&Led6);
  Sys.Plug(&Led7);
  Sys.Plug(&Led8);
  Sys.Plug(&Led9);
  Sys.Plug(&Led10);
  Sys.Plug(&Btn1);
  Sys.Plug(&Btn2);
  Sys.Plug(&Btn3);
  Sys.Plug(&Btn4);
  Sys.Plug(&Btn5);
  Sys.Plug(&Btn6);
  Sys.Plug(&Btn7);
  Sys.Plug(&Btn8);
  Sys.setup();
}
void loop() {
  mill = millis();
  Sys.loop();
}
/*Скетч использует 2466 байт (7%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 219 байт (10%) динамической памяти, оставляя 1829 байт для локальных переменных. Максимум: 2048 байт.
*/

 

GKV
Offline
Зарегистрирован: 01.10.2013

Уважаемый qwone.Также отключаются выходы по истечении времени,хотя на входе присутствует +5в

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

GKV пишет:

Уважаемый qwone.Также отключаются выходы по истечении времени,хотя на входе присутствует +5в

Я уже запутался. Что вам надо. Задайте ТЗ(техническую задачу) с начала.  Что с чем соединяется и что делает.

Набросал еще один . Вот только вы попытаейтесь настроить под свою работу

/**/
uint32_t mill;// переменная millis()
//----Cl_Led---------------------------------------
//класс светодиод
class Cl_Led {
    Cl_Led *next;
    const byte pin;
    const bool inv;
    uint32_t past, time_OFF;
    bool stat_time_OFF;// 1 - вкл задержка выкл;
  public:
    static Cl_Led *start; //<-- статический указатель  на начало списка
    /*Функция  setup
      Описание иницирование класса
      Ввод     нет
      Вывод    нет
    */
    static void setup() {
      for (Cl_Led *ii = start; ii != NULL; ii = ii->next)ii->init();
    }
    /*Функция  loop
      Описание для нормальной работе разместить в loop программы
      Ввод     нет
      Вывод    нет
    */
    static void loop() {
      for (Cl_Led *ii = start; ii != NULL; ii = ii->next) {
        ii->run();
      }
    }
    /*конструктор Cl_Led
      описание    создает класс
      ввод        _pin: номер пина для подключения
                  _inv: инверт управление 0 -нормально 1 - обратно
      вывод       нет
    */
    Cl_Led(byte _pin, bool _inv): pin(_pin), inv(_inv) {
      this->next = start ;
      start = this;
    }
    /*Функция  OFF
      Описание выключить светодиод
      Ввод     нет
      Вывод    нет
    */
    void OFF(uint32_t time) {
      ON();
      time_OFF = time;
      stat_time_OFF = 1;
      past = mill;
    }
    /*Функция  OFF
      Описание выключить светодиод c задержкой
      Ввод     _time:время задержки выкл миллисек
      Вывод    нет
    */
    void OFF() {
      stat_time_OFF = 0;
      digitalWrite(pin, inv);
    }
    /*Функция  ON
      Описание включить светодиод
      Ввод     нет
      Вывод    нет
    */
    void ON() {
      stat_time_OFF = 0;
      digitalWrite(pin, !inv);
    }
  private:
    /*Функция  init
      Описание иницирование класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void init() {
      pinMode (pin, OUTPUT);
      OFF();
    }
    /*Функция  run
      Описание работа класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void run() {
      if (stat_time_OFF && mill - past >= time_OFF) OFF();
    }
};
Cl_Led *Cl_Led::start = NULL;
//----Cl_Btn---------------------------------------
//класс кнопка
class Cl_Btn {
    Cl_Btn *next;
    const byte pin;
    void (* Do1)(), (* Do2)();
    bool  bounce = 0, btn, btn_old;
    uint32_t past;
  public:
    static Cl_Btn *start; //<-- статический указатель  на начало списка
    /*Функция  setup
      Описание иницирование класса
      Ввод     нет
      Вывод    нет
    */
    static void setup() {
      for (Cl_Btn *ii = start; ii != NULL; ii = ii->next)ii->init();
    }
    /*Функция  loop
      Описание для нормальной работе разместить в loop программы
      Ввод     нет
      Вывод    нет
    */
    static void loop() {
      for (Cl_Btn *ii = start; ii != NULL; ii = ii->next) {
        ii->run();
      }
    }
    /*конструктор Cl_Btn
      описание    создает класс
      ввод        _pin: номер пина для подключения
                  _Do1: указатель на функцию обработчика нажатия
                  _Do2: указатель на функцию обработчика отжатия
      вывод       нет
    */
    Cl_Btn(byte _pin, void (*_Do1)(), void (*_Do2)())
      : pin(_pin), Do1(_Do1), Do2(_Do2) {
      this->next = start ;
      start = this;
    }
  private:
    /*Функция  init
      Описание иницирование класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void init() {
      pinMode (pin, INPUT);
      btn_old = digitalRead(pin);
    }
    /*Функция  run
      Описание работа класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void run() {
      btn_old = btn ;
      btn =  digitalRead(pin) ;
      if (btn_old && !btn) (* Do1)();
      if (!btn_old && btn) (* Do2)();
    }
};
Cl_Btn *Cl_Btn::start = NULL;
//----Компановка---------------------------------------
Cl_Led Led1(/*пин*/13,/*инверсия*/1);
Cl_Led Led2(/*пин*/12,/*инверсия*/1);
uint32_t time_1s = 1000; // константа 1 сек
uint32_t time_2s = 2000; // константа 2 сек
void Do1_Btn1() {
  Led1.ON();
}
void Do2_Btn1() {
  Led1.OFF(time_1s);// выключить через 1 секунду
}
Cl_Btn Btn1(/*пин*/2,/*обраб наж кноп*/Do1_Btn1,/*обраб отж кноп*/Do2_Btn1);
void Do1_Btn2() {
  Led2.ON();
}
void Do2_Btn2() {
  Led2.OFF(time_2s);// выключить через 2 секунды
}
Cl_Btn Btn2(/*пин*/3,/*обраб наж кноп*/Do1_Btn2,/*обраб отж кноп*/Do2_Btn2);
//----main()---------------------------------------
void setup() {
  Cl_Led::setup();
  Cl_Btn::setup();
}

void loop() {
  mill = millis();
  Cl_Led::loop();
  Cl_Btn::loop();
}
/*Скетч использует 1536 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 71 байт (3%) динамической памяти, оставляя 1977 байт для локальных переменных. Максимум: 2048 байт.
*/

 

GKV
Offline
Зарегистрирован: 01.10.2013

Я пытался настроить под свою задачу,но не получилось.

Нужно:Все реле выключены (на выходе 0)При появлении на входе (к примеру 2) логической единицы +5в,выход А0(реле) включается 1 (время не считается),как только лог.ед +5в исчезает начинается отсчет времени.По окончании заданного времени выход(реле) отключается.Все восемь таймеров(и два контроль ЛЕД) работают одинаково,за исключением задержки отключения по времени.Подтяжка всех входов резисторами к земле 10Ком.

GKV
Offline
Зарегистрирован: 01.10.2013

НЕ могу сообразить.ВСе равно при наличии на входе 2 лог ед. +5в выход А0(реле) через 2 сек отключается.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот только интересно. А что если задерка не закончилась а единица на вход пришла. Продолжать задержку или отменять?

GKV
Offline
Зарегистрирован: 01.10.2013

Отменять задержку, включить выход опять "навсегда",ожидать отжатия кнопки.

GKV
Offline
Зарегистрирован: 01.10.2013

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

шо это такое?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

GKV 

/**/
uint32_t mill;// переменная millis()
//----Cl_Time_switch---------------------------------------
// реле времени - делает задержку выключения
class Cl_Time_switch {
    Cl_Time_switch *next;
    const byte inpin;  // вход
    const byte outpin; // выход
    const bool inv;    // инверсия выхода
    bool in, in_old; //
    uint32_t   time;   // время задержки
    uint32_t past, time_OFF;
    bool stat_time_OFF;// 1 - вкл задержка выкл;
  public:
    static Cl_Time_switch *start; //<-- статический указатель  на начало списка
    /*Функция  setup
      Описание иницирование класса
      Ввод     нет
      Вывод    нет
    */
    static void setup() {
      for (Cl_Time_switch *ii = start; ii != NULL; ii = ii->next)ii->init();
    }
    /*Функция  loop
      Описание для нормальной работе разместить в loop программы
      Ввод     нет
      Вывод    нет
    */
    static void loop() {
      for (Cl_Time_switch *ii = start; ii != NULL; ii = ii->next) {
        ii->run();
      }
    }
    /*конструктор Cl_Time_switch
      описание    создает класс
      ввод       _inpin: номер пина для подключения входа
                 _outpin: номер пина для подключения выхода
                 _inv: инверт выхода 0 -нормально 1 - обратно
                 _time: время задержки в милисек
      вывод       нет
    */
    Cl_Time_switch(byte _inpin, byte _outpin, bool _inv, uint32_t _time)
      :          inpin(_inpin), outpin(_outpin), inv(_inv), time(_time) {
      this->next = start ;
      start = this;
    }
  private:
    /*Функция  init
      Описание иницирование класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void init() {
      pinMode (inpin, INPUT);
      digitalWrite(outpin, inv);
      stat_time_OFF = 0;
      pinMode (outpin, OUTPUT);
      in = digitalRead(inpin);
    }
    /*Функция  run
      Описание работа класса никуда не ставить работает в пакете
      Ввод     нет
      Вывод    нет
    */
    void run() {
      in_old = in;
      in = digitalRead(inpin);
      if (in) {
        digitalWrite(outpin, !inv);
        stat_time_OFF = 0;
      }
      else if (!in && in_old) {
        stat_time_OFF = 1;
        past = mill;
      }
      if (stat_time_OFF && mill - past >= time) {
        digitalWrite(outpin, inv);
        stat_time_OFF = 0;
      }
    }
};
Cl_Time_switch *Cl_Time_switch::start = NULL;
//------------------------------------------------
uint32_t time_1s = 1000; // константа 1 сек
uint32_t time_2s = 2000; // константа 2 сек
Cl_Time_switch Time_switch1(/*вход*/2,/*выход*/12,/*инверсия выхода*/0,/*время задержки*/time_1s);
Cl_Time_switch Time_switch2(/*вход*/2,/*выход*/13,/*инверсия выхода*/0,/*время задержки*/time_2s);
//------------------------------------------------
void setup() {
  Cl_Time_switch::setup();
}

void loop() {
  mill = millis();
  Cl_Time_switch::loop();
}
/*Скетч использует 1320 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 55 байт (2%) динамической памяти, оставляя 1993 байт для локальных переменных. Максимум: 2048 байт.
*/

 

GKV
Offline
Зарегистрирован: 01.10.2013

Огромное спасибо за код,все которые нарыл в интернете-глючные.

Nik777
Offline
Зарегистрирован: 30.05.2017

Не могу понять в чем проблема, подключил два энкодера через триггер шмидта, при вращении все отлично работает. Но не могу разобраться с нажатием, вроде бы стандартный пример скетча на кнопку, при первом нажатии должен включится светодиод, при повторном выключится. Без нажатия он мигает с высокой частотой, а при нажатии просто гаснет, или стабильно светится..

int encoder0PinC = 3;
int OnOff = 0;

void setup() {
  pinMode (encoder0PinC, INPUT_PULLUP);
  pinMode(11, OUTPUT);
}

void loop() {
if(digitalRead(encoder0PinC)==0&&OnOff==0)
  {
    analogWrite(11, 100);
    OnOff=1;
        }   
if(digitalRead(encoder0PinC)==0&&OnOff==1) 
         { 
       analogWrite(11, 0);
        OnOff=0; 
     } 
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Nik777,первая и главная проблема в том что вы пишете код для оккупантов. Это как дороги, чем хуже дороги, тем тяжелее до вас добраться. А то что из-за плохих дорог идет масса неудобств, так а вдруг война. Но я отвлекся не пишите так код. Даже если это тестовый. Так вам тяжелей разобраться в глюках. Или вы думаете, что на форуме вашу херню будут читать. Так что почистил ваш код.

ПС: перевыложил код.

/*
*/
//------------------------------------------------
//----Компоновка--------------------------------------------
const byte LedPin  =/*пин светодиода*/13;
bool Led;
const byte swithPin =/*пин кнопки*/ 3;
bool old_Btn;
//-----mail-------------------------------------------
void setup() {
  pinMode (swithPin, INPUT_PULLUP);
  old_Btn = digitalRead(swithPin);
  digitalWrite(LedPin, Led = 0);
  pinMode(LedPin, OUTPUT);
}

void loop() {
  bool newBtn = digitalRead(swithPin);
  if ( !newBtn && old_Btn) {
    old_Btn = 0;
    digitalWrite(LedPin, Led = 1);
  }
  if (newBtn && !old_Btn)  {
    old_Btn = 1;
    digitalWrite(LedPin, Led = 0);
  }
}
/*Скетч использует 972 байт (3%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 11 байт (0%) динамической памяти, оставляя 2037 байт для локальных переменных. Максимум: 2048 байт.
*/

 

Nik777
Offline
Зарегистрирован: 30.05.2017

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Nik777 пишет:

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

Ну да так и есть. А вы какой алгоритм хотели?

Nik777
Offline
Зарегистрирован: 30.05.2017

Я надеялся, что где-то в коде есть моя ошибка, аппартно несколько сложнее устранять, поскольку схема уже собрана.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Nik777 пишет:

Я надеялся, что где-то в коде есть моя ошибка, аппартно несколько сложнее устранять, поскольку схема уже собрана.

Ну разумется там ваша ошибка. Но ошибка не программе а в алгоритме, который я не узнал. Вот пример моего кода. http://arduino.ru/forum/obshchii/vklyuchenie-svetodioda-odnoi-knopkoi-otklyuchene-drugoi#comment-302598

И да там нет отработки дрезезга. А у вас точно дребезг есть на кнопке.

Nik777
Offline
Зарегистрирован: 30.05.2017

Эм,  дрезбезг в моей схеме сключен (в теории),  схема собрана на тригере шмидта, со всем обвесом, энкодер работает идиально кроме нажатия кнопки

Nik777
Offline
Зарегистрирован: 30.05.2017

Закинул элементарный код, с кнопки все идеально работает, судя по логу с ком порта, при нажатии приходят единицы, у меня просто мозг разрывается, что я делаю не так?

void setup() {
  // put your setup code here, to run once:
pinMode (3, INPUT);
Serial.begin(9600); 
}

void loop() {
  // put your main code here, to run repeatedly:
 Serial.println(digitalRead(3));
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

Nik777
Offline
Зарегистрирован: 30.05.2017

Проблема оказалась все таки в коде, сразу заработал этот пример, единственное убрал защиту от дребезга

#define BUTTON_PIN  3
#define LED_PIN     13
 
boolean buttonWasUp = true;  // была ли кнопка отпущена?
boolean ledEnabled = false;  // включен ли свет?
 
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
 
void loop()
{
  // определить момент «клика» несколько сложнее, чем факт того,
  // что кнопка сейчас просто нажата. Для определения клика мы
  // сначала понимаем, отпущена ли кнопка прямо сейчас...
  boolean buttonIsUp = digitalRead(BUTTON_PIN);
 
  // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
  if (buttonWasUp && !buttonIsUp) {
    // ...может это «клик», а может и ложный сигнал (дребезг),
    // возникающий в момент замыкания/размыкания пластин кнопки,
    // поэтому даём кнопке полностью «успокоиться»...
    delay(10);
    // ...и считываем сигнал снова
    buttonIsUp = digitalRead(BUTTON_PIN);
    if (!buttonIsUp) {  // если она всё ещё нажата...
      // ...это клик! Переворачиваем сигнал светодиода
      ledEnabled = !ledEnabled;
      digitalWrite(LED_PIN, ledEnabled);
    }
  }
 
  // запоминаем последнее состояние кнопки для новой итерации
  buttonWasUp = buttonIsUp;
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Люди добрые подскажите код. Нужно три раза нажать кнопку в течение 3 сек, только тогда произойдет действие.

Alexei39
Offline
Зарегистрирован: 26.03.2016

Люди добрые подскажите код. Нужно три раза нажать кнопку в течение 3 сек, только тогда произойдет действие.

andycat
andycat аватар
Онлайн
Зарегистрирован: 07.09.2017

Alexei39 пишет:

Люди добрые подскажите код. Нужно три раза нажать кнопку в течение 3 сек, только тогда произойдет действие.

а если я три раза за секунду нажму - это считается?

Alexei39
Offline
Зарегистрирован: 26.03.2016

Да считаеться.Главное чтоб после 3 секунд счет нажатий занового происходил

 

andycat
andycat аватар
Онлайн
Зарегистрирован: 07.09.2017

ну вот как то так я бы написал, с учетом дребезка контактов

т.е. на кнопку надо жать от 50 до 100 мс

#define KEYPIN 2
#define LEDPIN 9

#define DOWNKEY 50 // minimal time msec down key + 50 msec

byte pOldKey = 1;
boolean KeyDownStart = false;
byte KeyDownCount = 0;
unsigned long TimeKeyDownStart = 0;
unsigned long TimeKeyDownThree = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(KEYPIN, INPUT); // wakeup pin to GND
  digitalWrite(KEYPIN, HIGH); // up resistor to on
  // OFF unused pins
  for (byte i = 0; i <= 19; i++)
  {
    if (i == KEYPIN) {
      continue;
    }
    pinMode (i, OUTPUT);
    digitalWrite (i, LOW);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  // select pressed key
  byte pt = digitalRead(KEYPIN);
  if (pt != pOldKey) {
    pOldKey = pt;
    unsigned long ts = millis() - TimeKeyDownStart;
    if (KeyDownStart) {
      if (ts >= DOWNKEY) {
        if (ts <= (DOWNKEY + 50)) {
          KeyDownStart = false;
        } else {
          //- calculate 3 time
          if (KeyDownCount == 0) {
            TimeKeyDownThree = millis();
            ++KeyDownCount;
          } else {
            if (KeyDownCount == 2) {
              if ((millis() - TimeKeyDownThree) <= 3000) {
                digitalWrite(LEDPIN, HIGH);
                delay(1000);
                digitalWrite(LEDPIN, LOW);
                KeyDownCount = 0;
              } else {
                TimeKeyDownThree = millis();
                KeyDownCount = 0;
              }
            } else {
              ++KeyDownCount;
            }
          }
          //-
          KeyDownStart = false;
        }
      }
    } else {
      KeyDownStart = true;
      TimeKeyDownStart = millis();
    }
  }
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Спасибо

prohor-nastya
Offline
Зарегистрирован: 16.01.2017

Люди, здравствуйте!

Подскажите пож. что не так:

Собрал эксперимент мерзкое пианино... 

http://wiki.amperka.ru/%D0%BA%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82-arduino:%D0%BC%D0%B5%D1%80%D0%B7%D0%BA%D0%BE%D0%B5-%D0%BF%D0%B8%D0%B0%D0%BD%D0%B8%D0%BD%D0%BE

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

Но звук тихий с дребезгом, не красивый. 

если пишешь для одного пина, напр. 4 звук чистый как в эксперименте... 

 

#define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
#define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
#define LAST_KEY_PIN 10
#define KEY_COUNT     7  // общее количество клавиш


void setup() 
{
for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
pinMode(pin, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  

  if(digitalRead(4)==LOW)//если кнопка нажата ...
 {
 tone(BUZZER_PIN,3000, 20);
 }
 else//если не нажата...
 {
 noTone(BUZZER_PIN);
 }
 if(digitalRead(5)==LOW)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 3500, 20);
 }
 else//если не нажата...
 {
 noTone(BUZZER_PIN);
 }
 if(digitalRead(6)==LOW)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 4000, 20);
 }
 else//если не нажата...
 {
 noTone(BUZZER_PIN);
}
}
prohor-nastya
Offline
Зарегистрирован: 16.01.2017

Сделал так, все равно звук не красивый...

#define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
#define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
#define LAST_KEY_PIN 10
#define KEY_COUNT     7  // общее количество клавиш


void setup()
{
for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
pinMode(pin, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
 
for (int i = 0; i < KEY_COUNT; ++i) {
    // на основе номера кнопки вычисляем номер её пина
    int keyPin = i + FIRST_KEY_PIN;

    // считываем значение с кнопки. Возможны всего 2 варианта:
    //  * высокий сигнал, 5 вольт, истина — кнопка отпущена
    //  * низкий сигнал, земля, ложь — кнопка зажата
    boolean keyUp = digitalRead(keyPin);
   
  if(digitalRead(4)== !keyUp)//если кнопка нажата ...
{
tone(BUZZER_PIN,3100);
}
else//если не нажата...
{
noTone(BUZZER_PIN);
}
if(digitalRead(5)== !keyUp)//если кнопка нажата ...
{
tone(BUZZER_PIN, 3850);
}
else//если не нажата...
{
noTone(BUZZER_PIN);
}
if(digitalRead(6)== !keyUp)//если кнопка нажата ...
{
tone(BUZZER_PIN, 4120);
}
else//если не нажата...
{
noTone(BUZZER_PIN);
}
}
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Перед всеми if, кроме первого, поставь else.

prohor-nastya
Offline
Зарегистрирован: 16.01.2017

сделал так:

#define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
#define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
#define LAST_KEY_PIN 10
#define KEY_COUNT     7  // общее количество клавиш


void setup() 
{
for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
pinMode(pin, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  
for (int i = 0; i < KEY_COUNT; ++i) {
    // на основе номера кнопки вычисляем номер её пина
    int keyPin = i + FIRST_KEY_PIN;

    // считываем значение с кнопки. Возможны всего 2 варианта:
    //  * высокий сигнал, 5 вольт, истина — кнопка отпущена
    //  * низкий сигнал, земля, ложь — кнопка зажата
    boolean keyUp = digitalRead(keyPin);
    
  if(digitalRead(4)== !keyUp)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 2500, 20);
 }
 else if(digitalRead(5)== !keyUp)//если не нажата...
 {
 tone(BUZZER_PIN,3200, 20);
 }
 else if(digitalRead(6)== !keyUp)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 3920, 20);
 }
 else//если не нажата...
 {
 noTone(BUZZER_PIN);
 }
 
}

}

звук все равно дребезжащий... 

интересно, что еще 4 кнопки (не задействованные в коде) тоже пищат, но одинаково. 

prohor-nastya
Offline
Зарегистрирован: 16.01.2017

Переделал так:

И все ЗАРАБОТАЛО!!!

#define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
#define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
#define LAST_KEY_PIN 10
#define KEY_COUNT     7  // общее количество клавиш


void setup() 
{
for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
pinMode(pin, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  
   if(digitalRead(4)== LOW)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 2500, 20);
 }
 else if(digitalRead(5)== LOW)//если не нажата...
 {
 tone(BUZZER_PIN,3200, 20);
 }
 else if(digitalRead(6)== LOW)//если кнопка нажата ...
 {
 tone(BUZZER_PIN, 3920, 20);
 }
 else//если не нажата...
 {
 noTone(BUZZER_PIN);
 }
 
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если вы чего-то в инете не можете найти, то или смысла в существовании этого нет, или вы не доросли до этого. И да я могу написать это, но смысла в существовании этого я не вижу.

hijin
Offline
Зарегистрирован: 20.08.2017

Есть задача 4 кнопки фиксированые 1, 2, 3, 4

кнопка 1 имеет наивысший приоритет (то есть если нажта эта кнопка остальные кнопки игнгрируются) если нажата 2 кнопка игнгрируется кнопка 3, 4 (при совмесном нажатии кнопок 2, 3 и 4) нри нажатии 3 кнопки (при выключены 1, 2 и наатых 3 и 4)она и срабатывает При нажатии 4 работает только она

Здесь скетч составленый (именно составленый а не написаный) в FLProg

Уши у меня уже повяли до того как мне что нибудь ответят на мой вопрос. Хотя я его есче не задал 

А Клапауций опять вспомнит дохлую лошадку и скажет что єто за пони я привел к Вам на форум

А вопрос но больше просьба показать правильно написаный скетч по такому заданию

 

bool _FreeLog1_IArr[4];
bool _FreeLog1_Q1_StArr[] = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0};
bool _FreeLog1_Q2_StArr[] = {0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0};
bool _FreeLog1_Q3_StArr[] = {0, 0, 1, 1, 0, 0, 1, 0};
bool _FreeLog1_Q4_StArr[] = {0, 0, 0, 1};
bool _gtv1 = 1;
bool _gtv2 = 1;
bool _gtv3 = 1;
bool _gtv4 = 1;
bool _bounseInputD2S = 0;
bool _bounseInputD2O = 0;
unsigned long _bounseInputD2P = 0UL;
bool _bounseInputD5S = 0;
bool _bounseInputD5O = 0;
unsigned long _bounseInputD5P = 0UL;
bool _bounseInputD3S = 0;
bool _bounseInputD3O = 0;
unsigned long _bounseInputD3P = 0UL;
bool _FreeLog1_Q1 = 0;
bool _FreeLog1_Q2 = 0;
bool _FreeLog1_Q3 = 0;
bool _FreeLog1_Q4 = 0;
bool _bounseInputD4S = 0;
bool _bounseInputD4O = 0;
unsigned long _bounseInputD4P = 0UL;
void setup()
{
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);

_bounseInputD2O =  digitalRead(2);
_bounseInputD4O =  digitalRead(4);
_bounseInputD3O =  digitalRead(3);
_bounseInputD5O =  digitalRead(5);
}
void loop()
{
bool  _bounceInputTmpD2 =  (digitalRead (2));

if (_bounseInputD2S) 
    {
     if (millis() >= (_bounseInputD2P + 40)) 
         {_bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0;}
     }
else
    {
     if (_bounceInputTmpD2 != _bounseInputD2O )
         {_bounseInputD2S=1; _bounseInputD2P = millis();} 
      } 
bool  _bounceInputTmpD4 =  (digitalRead (4));

if (_bounseInputD4S) 
    {
     if (millis() >= (_bounseInputD4P + 40)) 
         {_bounseInputD4O= _bounceInputTmpD4; _bounseInputD4S=0;}
     }
else
    {
     if (_bounceInputTmpD4 != _bounseInputD4O )
         {_bounseInputD4S=1; _bounseInputD4P = millis();} 
      } 
bool  _bounceInputTmpD3 =  (digitalRead (3));

if (_bounseInputD3S) 
    {
     if (millis() >= (_bounseInputD3P + 40)) 
         {_bounseInputD3O= _bounceInputTmpD3; _bounseInputD3S=0;}
     }
else
    {
     if (_bounceInputTmpD3 != _bounseInputD3O )
         {_bounseInputD3S=1; _bounseInputD3P = millis();} 
      } 
bool  _bounceInputTmpD5 =  (digitalRead (5));

if (_bounseInputD5S) 
    {
     if (millis() >= (_bounseInputD5P + 40)) 
         {_bounseInputD5O= _bounceInputTmpD5; _bounseInputD5S=0;}
     }
else
    {
     if (_bounceInputTmpD5 != _bounseInputD5O )
         {_bounseInputD5S=1; _bounseInputD5P = millis();} 
      } 




//Плата:1
_FreeLog1_IArr[0] = _bounseInputD2O;
_FreeLog1_IArr[1] = _bounseInputD3O;
_FreeLog1_IArr[2] = _bounseInputD4O;
_FreeLog1_IArr[3] = _bounseInputD5O;
_FreeLog1_Q1 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q1_StArr, 32); 
_FreeLog1_Q2 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q2_StArr, 16); 
_FreeLog1_Q3 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q3_StArr, 8); 
_FreeLog1_Q4 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q4_StArr, 4); 
_gtv1 = _FreeLog1_Q1;
_gtv2 = _FreeLog1_Q2;
_gtv3 = _FreeLog1_Q3;
_gtv4 = _FreeLog1_Q4;




}
bool _checkFreeLogicBlockOutput(bool inArray[], int inArraySize, bool stArray[], int stArraySize)
{ int inIndex = 0;
  bool result = 1;
  for (int i = 0; i < stArraySize; i = i + 1)
  {
   if (!(inArray[inIndex] == stArray[i])) { result = 0;}
   inIndex ++;
   if (inIndex == inArraySize)
     {
     if (result) { return 1;} else {result = 1;}
     inIndex = 0;
     }
  }
  return 0;
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

hijin пишет:
А вопрос но больше просьба показать правильно написаный скетч по такому заданию
 

что значит я я бывают разные https://www.youtube.com/watch?v=rwxUqJ12SdA.  Вот так и с правильно написаными скетчами. И еще у кнопок нет приоритета. Приоритет бывает только у запускающих их обработчиков. Которые запускаются при переходе отжато-нажато и обратно. А вот для чисто нажать -держать и отжать-отойти не часто применяют.

hijin
Offline
Зарегистрирован: 20.08.2017

Ну у меня такое условие запуска обработчиков будет использоватся для последовательного заполнения бочек с водой на даче.

На железе пока не проверял но в Протеусе работает даже на одном (4 кнопки) аналговом входе

Сегодня увидел как в одном проэкте (Умный дом) автору проэкта его женой было поставлено условие "или будет в первую очередь включена плита или хана всем твоим проэктам"при этом было кроме плиты есче три датчика Стиральная машина, Эл котел и бойлер

так что такое влючение может біть как и редким так и метким

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Где-то так на мой взгляд. Но кнопки подключаются на вывод и землю. Подтяжка кнопки на питание программное.Код в железе не тестировал

/**/
unsigned long mill;
/*обработчик 1 кнопки*/
void DoBtn1() {
  Serial.print("DoBtn1");
}
/*обработчик 2 кнопки*/
void DoBtn2() {
  Serial.print("DoBtn2");
}
/*обработчик 2 кнопки*/
void DoBtn3() {
  Serial.print("DoBtn3");
}
/*обработчик 3 кнопки*/
void DoBtn4() {
  Serial.print("DoBtn4");
}
//кнопка 1
const byte btn1Pin =/*пин*/2;
bool bounce1 = 0;
bool btn1 = 1, oldBtn1;
unsigned long past1;
//кнопка 2
const byte btn2Pin =/*пин*/3;
bool bounce2 = 0;
bool btn2 = 1, oldBtn2;
unsigned long past2;
//кнопка 3
const byte btn3Pin =/*пин*/4;
bool bounce3 = 0;
bool btn3 = 1, oldBtn3;
unsigned long past3;
//кнопка 4
const byte btn4Pin =/*пин*/5;
bool bounce4 = 0;
bool btn4 = 1, oldBtn4;
unsigned long past4;
//------------------------------------
void setup() {
  Serial.begin(9600);
  //кнопка 1
  pinMode(btn1Pin, INPUT_PULLUP);
  //кнопка 2
  pinMode(btn2Pin, INPUT_PULLUP);
  //кнопка 3
  pinMode(btn3Pin, INPUT_PULLUP);
  //кнопка 4
  pinMode(btn4Pin, INPUT_PULLUP);
}

void loop() {
  mill = millis();
  bool newBtn1 = digitalRead(btn1Pin);
  bool newBtn2 = digitalRead(btn2Pin);
  bool newBtn3 = digitalRead(btn3Pin);
  bool newBtn4 = digitalRead(btn4Pin);
  //кнопка 1

  if (!bounce1 && newBtn1 != btn1) {
    bounce1 = 1;
    past1 = mill;
  }
  if (bounce1 && mill - past1 >= 10) {
    bounce1 = 0 ;
    oldBtn1 = btn1;
    btn1 = newBtn1;
    if (!btn1 && oldBtn1) DoBtn1();
  }
  //кнопка 2
  if (!bounce2 && newBtn2 != btn2) {
    bounce2 = 1;
    past2 = mill;
  }
  if (bounce2 && mill - past2 >= 10) {
    bounce2 = 0 ;
    oldBtn2 = btn2;
    btn2 = newBtn2;
    if (newBtn1 && !btn2 && oldBtn2) DoBtn2();
  }
  //кнопка 3
  if (!bounce3 && newBtn3 != btn3) {
    bounce3 = 1;
    past3 = mill;
  }
  if (bounce3 && mill - past3 >= 10) {
    bounce3 = 0 ;
    oldBtn3 = btn3;
    btn3 = newBtn3;
    if (newBtn1 && newBtn2 && !btn3 && oldBtn3) DoBtn3();
  }
  //кнопка 4
  if (!bounce4 && newBtn4 != btn4) {
    bounce4 = 1;
    past4 = mill;
  }
  if (bounce4 && mill - past4 >= 10) {
    bounce4 = 0 ;
    oldBtn4 = btn4;
    btn4 = newBtn4;
    if (newBtn1 && newBtn2 && newBtn3 && !btn4 && oldBtn4) DoBtn4();
  }
}
/*Скетч использует 2480 байт (8%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 242 байт (11%) динамической памяти, оставляя 1806 байт для локальных переменных. Максимум: 2048 байт.
*/

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Посмотрите так, если я правильно понял задачу

void loop(){
  if(kn1 == HIGH){
    bla_1!bla_1;//Если нажата кнопка1
  }
  else{
    if(kn2 == HIGH){
      bla_2!bla_2;//Отпущена кн1 - нажата кн2
    }
    else{
      if(kn3 == HIGH && kn4 == HIGH){
        bla_3!bla_3;//Отпущена кн1 и кн2 - нжата кн3 и кн4
      }
      else if(kn4 == HIGH){
        bla_4!bla_4;//Нажата только кн4
      } 
    }
  }
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

vosara,скорее так. Но хорошо дело на бумаге, да забыли про коряги.

void loop() {
  if (btn1 == HIGH) /*нажата кнопка 1*/;
  else if (btn1 == LOW && btn2 == HIGH) /*нажата кнопка 2*/;
  else if (btn1 == LOW && btn2 == LOW && btn3 == HIGH) /*нажата кнопка 3*/;
  else if (btn1 == LOW && btn2 == LOW && btn3 == LOW && btn4 == HIGH) /*нажата кнопка 4*/;
}

ПС: извини похоже у нас одинаково.

hijin
Offline
Зарегистрирован: 20.08.2017

Прошу прощение в скетче который я отправлял раньше ошибка (я его выдрал из общей программы а там Q была переменной а не выходом) далее предлагаю нормальный скетч который проверен на Протеусе

Q1-Q4 выоды ардуино уно

Q1 pin6

Q2 pin7

Q3pin8

Q4 pin9

Скетч использует 1804 байт (5%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 101 байт (4%) динамической памяти, оставляя 1947 байт для локальных переменных. Максимум: 2048 байт.

Как я заметил у меня скетч занимает меньше памяти хотя и включены програмно Защита от дребезга и подтягивающий  резистор

А без подтягивающи резисторов и защиты от дребезга

Скетч использует 1452 (4%) байт памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 83 байт (4%) динамической памяти,

hijin
Offline
Зарегистрирован: 20.08.2017
[code]
bool _FreeLog1_IArr[4];
bool _FreeLog1_Q1_StArr[] = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0};
bool _FreeLog1_Q2_StArr[] = {0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0};
bool _FreeLog1_Q3_StArr[] = {0, 0, 1, 1, 0, 0, 1, 0};
bool _FreeLog1_Q4_StArr[] = {0, 0, 0, 1};
bool _bounseInputD3S = 0;
bool _bounseInputD3O = 0;
unsigned long _bounseInputD3P = 0UL;
bool _FreeLog1_Q1 = 0;
bool _FreeLog1_Q2 = 0;
bool _FreeLog1_Q3 = 0;
bool _FreeLog1_Q4 = 0;
bool _bounseInputD4S = 0;
bool _bounseInputD4O = 0;
unsigned long _bounseInputD4P = 0UL;
bool _bounseInputD2S = 0;
bool _bounseInputD2O = 0;
unsigned long _bounseInputD2P = 0UL;
bool _bounseInputD5S = 0;
bool _bounseInputD5O = 0;
unsigned long _bounseInputD5P = 0UL;
void setup()
{
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);

_bounseInputD5O =  digitalRead(5);
_bounseInputD2O =  digitalRead(2);
_bounseInputD4O =  digitalRead(4);
_bounseInputD3O =  digitalRead(3);
}
void loop()
{
bool  _bounceInputTmpD5 =  (digitalRead (5));

if (_bounseInputD5S) 
    {
     if (millis() >= (_bounseInputD5P + 40)) 
         {_bounseInputD5O= _bounceInputTmpD5; _bounseInputD5S=0;}
     }
else
    {
     if (_bounceInputTmpD5 != _bounseInputD5O )
         {_bounseInputD5S=1; _bounseInputD5P = millis();} 
      } 
bool  _bounceInputTmpD2 =  (digitalRead (2));

if (_bounseInputD2S) 
    {
     if (millis() >= (_bounseInputD2P + 40)) 
         {_bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0;}
     }
else
    {
     if (_bounceInputTmpD2 != _bounseInputD2O )
         {_bounseInputD2S=1; _bounseInputD2P = millis();} 
      } 
bool  _bounceInputTmpD4 =  (digitalRead (4));

if (_bounseInputD4S) 
    {
     if (millis() >= (_bounseInputD4P + 40)) 
         {_bounseInputD4O= _bounceInputTmpD4; _bounseInputD4S=0;}
     }
else
    {
     if (_bounceInputTmpD4 != _bounseInputD4O )
         {_bounseInputD4S=1; _bounseInputD4P = millis();} 
      } 
bool  _bounceInputTmpD3 =  (digitalRead (3));

if (_bounseInputD3S) 
    {
     if (millis() >= (_bounseInputD3P + 40)) 
         {_bounseInputD3O= _bounceInputTmpD3; _bounseInputD3S=0;}
     }
else
    {
     if (_bounceInputTmpD3 != _bounseInputD3O )
         {_bounseInputD3S=1; _bounseInputD3P = millis();} 
      } 
//Плата:1
_FreeLog1_IArr[0] = _bounseInputD2O;
_FreeLog1_IArr[1] = _bounseInputD3O;
_FreeLog1_IArr[2] = _bounseInputD4O;
_FreeLog1_IArr[3] = _bounseInputD5O;
_FreeLog1_Q1 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q1_StArr, 32); 
_FreeLog1_Q2 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q2_StArr, 16); 
_FreeLog1_Q3 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q3_StArr, 8); 
_FreeLog1_Q4 = _checkFreeLogicBlockOutput(_FreeLog1_IArr, 4, _FreeLog1_Q4_StArr, 4); 
digitalWrite(6, _FreeLog1_Q1);
digitalWrite(7, _FreeLog1_Q2);
digitalWrite(8, _FreeLog1_Q3);
digitalWrite(9, _FreeLog1_Q4);
}
bool _checkFreeLogicBlockOutput(bool inArray[], int inArraySize, bool stArray[], int stArraySize)
{ int inIndex = 0;
  bool result = 1;
  for (int i = 0; i < stArraySize; i = i + 1)
  {
   if (!(inArray[inIndex] == stArray[i])) { result = 0;}
   inIndex ++;
   if (inIndex == inArraySize)
     {
     if (result) { return 1;} else {result = 1;}
     inIndex = 0;
     }
  }
  return 0;
}
[/code]

 

АлексейЭтоЯ
Offline
Зарегистрирован: 31.10.2017

Даже не знаю стоит просить помочь или нет. На другом сайте сразу... дайте денег, а то нееее...... Я бы и дал, только это не умный дом и не управление  для пром. оборудования. И проще тогда уж, за эти же деньги 2ю нану купить сделать с Daleyями и на таймер припаять ))).

А теперь по сути. Есть проблема в цикле нельзя использовать Delay. Таймер, кнопка, фиксированное время пусть 5 мин, нажимаем на кнопту включается таймер после, мигает светодиод и выдаётся ТОН скажем на 10сек. Нельзя  с  Delay, потому что ещё 2 потока работают. Пока  Я дошёл только до такого.

/////////////////  Таймер  ////////////////////
  // если кнопка нажата впервые
  if((digitalRead(key5Pin) == HIGH) && !flag) {
  flag = 1; // устанавливаем флаг при первом нажатии
  moment = millis(); // запоминаем момент времени
  digitalWrite(outtimerPin, HIGH); // включаем светодиод
  }
   // если прошло время
  if (millis() - moment >= 10000) {
  flag = 0; // сбрасываем флаг
  moment = 2^32 - 1; // устанавливаем максимальное значение
  digitalWrite(outtimerPin, LOW); // выключаем светодиод        
}
if((digitalRead(outtimerPin) == LOW) && !flag2) {
  flag2 = 1; // устанавливаем флаг при первом нажатии
  moment2 = millis(); // запоминаем момент времени
  digitalWrite(LED8, HIGH); // включаем светодиод
  }
   // если прошло время
  if (millis() - moment2 >= 2000) {
  flag2 = 0; // сбрасываем флаг
  moment2 = 2^32 - 1; // устанавливаем максимальное значение
  digitalWrite(LED8, LOW); // выключаем светодиод        
}
}

Пока всё на светодиодах, с тоном  сложнее. В этом варианте лэд8 сразу мигает, при нажатии кнопки 1й таймер работает лэд8 тухнет на указанное время и опять мигает.

АлексейЭтоЯ
Offline
Зарегистрирован: 31.10.2017

Один добрый, но в начале очень вредный человек помог. Спасибо ему конечно. Вот код, основной отрывок ком надо.

void timer_() {
 
if((digitalRead(key4Pin) == HIGH) && !flag) {
  flag = 1; // устанавливаем флаг при первом нажатии
  moment = millis(); // запоминаем момент времени
  digitalWrite(outtimerPin, HIGH); // включаем светодиод
  }
   // если прошло время
  if ((millis() - moment >= 20000) && flag) { //  20000 Это 2 минуты
  flag = 0; // сбрасываем флаг
  flag3 = 1; // устанавливаем флаг 3
  //moment = 2^32 - 1; // устанавливаем максимальное значение - это лишнее
  digitalWrite(outtimerPin, LOW);
}
if( flag3 && (!flag2)) {
  flag2 = 1;
  flag3 = 0;
  moment2 = millis();
  digitalWrite(outtimerPin2, HIGH);
  }
   // если прошло время
  if ((millis() - moment2 >= 5000) && flag2) {
  flag2 = 0;
  digitalWrite(outtimerPin2, LOW);
}

 

АлексейЭтоЯ
Offline
Зарегистрирован: 31.10.2017

Хотелось бы вместе с 2х секундной отработкой будильника сделать ТОН, только на основе милис, ни каких Delayев. Поможет кто?? Спасибо.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну могу предложить такой код. Нажал на кнопку загорелся светодиод на 0,5 сек. Туда можно и тоне вставить.

/**/
unsigned long mill; // переменная под millis()
//-----Cl_Manager---------------------------
// класс менеджер задач
struct task_t {
  void (*Do)();
  unsigned long past;
  unsigned int time;
  struct task_t (*next);
  task_t(void (*_Do)(), unsigned long _past, unsigned int _time, struct task_t (*_next))
    : Do(_Do), past(_past), time(_time), next(_next) {}
};
class Cl_Manager {
  protected:
    struct task_t (*start) = NULL;
  public:
    /*вствить в loop() программы*/
    void run() {
      struct task_t (*_new);
      for (struct task_t (**i) = &start; (*i) != NULL; ) {
        _new = (*i);
        if (mill - (*_new).past >= (*_new).time) {
          (*i) = (**i).next;
          (*_new).Do();
          delete _new;
        }
        else i = &(**i).next;
      }
    }
    /*загрузить новую задачу*/
    void Task(unsigned int time, void (*Do)()) {
      struct task_t (*_new) = new struct task_t(Do, mill, time, start);
      start = _new;
    }
};
Cl_Manager Manager;
//---Компоновка-----------------------
// светодиод
const byte ledPin =/*пин*/13;
void ledOFF() {
  digitalWrite(ledPin, LOW);
}
// кнопка
const byte btnPin =/*пин*/2;
void btnRun() {
  Manager.Task(/*через 0,1 сек */ 100,/*сделать это*/&btnRun);
  static bool btn = 1, OldBtn;
  OldBtn = btn;
  btn = digitalRead(btnPin);
  if (!btn && OldBtn) {
    digitalWrite(ledPin, HIGH);
    Manager.Task(/*через 0,5 сек */ 500,/*сделать это*/&ledOFF);
  }
}
void initSys() {
  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  btnRun();
}

//---main-----------------------------
void setup() {
  initSys();
}

void loop() {
  mill = millis();
  Manager.run();
}
/*Скетч использует 1858 байт (6%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 28 байт (1%) динамической памяти, оставляя 2020 байт для локальных переменных. Максимум: 2048 байт.
*/

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Мигать светодиодом в зависимости от поворота потенциометра через менеджер.

/**/
unsigned long mill; // переменная под millis()
//-----Cl_Manager---------------------------
// класс менеджер задач
struct task_t {
  void (*Do)();
  unsigned long past;
  unsigned int time;
  struct task_t (*next);
  task_t(void (*_Do)(), unsigned long _past, unsigned int _time, struct task_t (*_next))
    : Do(_Do), past(_past), time(_time), next(_next) {}
};
class Cl_Manager {
  protected:
    struct task_t (*start) = NULL;
  public:
    /*вствить в loop() программы*/
    void run() {
      struct task_t (*_new);
      for (struct task_t (**i) = &start; (*i) != NULL; ) {
        _new = (*i);
        if (mill - (*_new).past >= (*_new).time) {
          (*i) = (**i).next;
          (*_new).Do();
          delete _new;
        }
        else i = &(**i).next;
      }
    }
    /*загрузить новую задачу*/
    void Task(unsigned int time, void (*Do)()) {
      struct task_t (*_new) = new struct task_t(Do, mill, time, start);
      start = _new;
    }
};
Cl_Manager Manager;
//---Компоновка-----------------------
// светодиод
const byte ledPin =/*пин*/13;
const byte potenPin =/*пин*/A0;
unsigned long time = 1000;
void ledBlink() {
  static bool led = 0;
  Manager.Task(/*через time  */ time,/*сделать это*/&ledBlink);
  digitalWrite(ledPin, led = !led);
}
void poten() {
  time = map(analogRead(potenPin), 0, 1023, 25, 500);
  Manager.Task(/*через 0,1 сек */ 200,/*сделать это*/&poten);
}
void initSys() {
  pinMode(ledPin, OUTPUT);
  ledBlink();
  poten();
}
//---main-----------------------------
void setup() {
  initSys();
}

void loop() {
  mill = millis();
  Manager.run();
}
/*Скетч использует 1928 байт (6%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 30 байт (1%) динамической памяти, оставляя 2018 байт для локальных переменных. Максимум: 2048 байт.
*/

 

АлексейЭтоЯ
Offline
Зарегистрирован: 31.10.2017

 // Поток 3
void timer_() {
 
if((digitalRead(key4Pin) == HIGH) && !flag) {
  flag = 1; // устанавливаем флаг при первом нажатии
  moment = millis(); // запоминаем момент времени
  digitalWrite(outtimerPin, HIGH); // включаем светодиод
  }
   // если прошло время
  if ((millis() - moment >= 20000) && flag) { //  20000 Это 2 минуты
  flag = 0; // сбрасываем флаг
  flag3 = 1; // устанавливаем флаг 3
  //moment = 2^32 - 1; // устанавливаем максимальное значение - это лишнее
  digitalWrite(outtimerPin, LOW);
}
if( flag3 && (!flag2)) {
  flag2 = 1;
  flag3 = 0;
  moment2 = millis();
  digitalWrite(outtimerPin2, HIGH);
  }
   // если прошло время
  if ((millis() - moment2 >= 10000) && flag2) {
  flag2 = 0;
  digitalWrite(outtimerPin2, LOW);
}
  else if(digitalRead(outtimerPin2)== HIGH)
   {
   tone(buzzPin, ton);  // включаем сирену на "ton" Гц
    if (ton <= 1200) {  // до частоты 1200 Гц
    ton += 30;  // увеличиваем тональность сирены
   }
    else
    {  // по достижении 400 Гц
        ton = 400;  // сбрасываем тональность до 400 Гц
      }
    }
    else if(digitalRead(outtimerPin2)== LOW)
   {
   noTone(buzzPin);
  }
}

Вот так вроде работает, может что то можно улучшить??

bwn
Offline
Зарегистрирован: 25.08.2014

АлексейЭтоЯ пишет:

Вот так вроде работает, может что то можно улучшить??

Можно, научиться код вставлять по людски, а то у вас ошибка в 35 строке.

АлексейЭтоЯ
Offline
Зарегистрирован: 31.10.2017

Там флаги надо объявить. И пины  в сетап, это основная часть. Для понимания. Почему он так  вставился сверху, только всевышний знает.

 // Поток 3
void timer_() { 
 
if((digitalRead(key4Pin) == HIGH) && !flag) {
  flag = 1; // устанавливаем флаг при первом нажатии
  moment = millis(); // запоминаем момент времени
  digitalWrite(outtimerPin, HIGH); // включаем светодиод
  }
   // если прошло время
  if ((millis() - moment >= 360000) && flag) { //  360000 Это  6 минут
  flag = 0; // сбрасываем флаг
  flag3 = 1; // устанавливаем флаг 3
  moment = 2^32 - 1; // устанавливаем максимальное значение - это лишнее
  digitalWrite(outtimerPin, LOW); 
}
if( flag3 && (!flag2)) {
  flag2 = 1; 
  flag3 = 0;
  moment2 = millis(); 
  digitalWrite(outtimerPin2, HIGH); 
  }
   // если прошло время
  if ((millis() - moment2 >= 12000) && flag2) {  //  12000 Это  12 sec
  flag2 = 0; 
  digitalWrite(outtimerPin2, LOW); 
}
  else if(digitalRead(outtimerPin2)== HIGH)
   {
   tone(buzzPin, ton);  // включаем сирену на "ton" Гц
    if (ton <= 1200) {  // до частоты 1200 Гц 
    ton += 50;  // увеличиваем тональность сирены
   }
    else 
    {  // по достижении 400 Гц
        ton = 400;  // сбрасываем тональность до 400 Гц
      }
    } 
    else if(digitalRead(outtimerPin2)== LOW)
   {
   noTone(buzzPin);
  } 
}

 

Mercury
Offline
Зарегистрирован: 01.11.2017

Всем привет. Задумал зделать скрытую кнопку в машине (отключение бензонасоса и тп.), а потом решил усложнить задачу. И здесь мне нужна помощь бывалых)). Итак допустим есть нано пару реле и три нефиксирующихся кнопки, если я нажму на первую 1раз, на вторую 2 раза на третью 1раз и только в такой последовательности реле замкнеться и в путь. После выключения зажигания нужно процедуру повторять заново.  Если кто поможет со скетчем и консультацией буду благодарен.