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

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

vingor пишет:

Я прошу прощения в вашем коде разобраться ни как не могу не хватает знаний.

Может меня немного не поняли!

Есть устройство включается/выключается по 1-ой кнопке

И есть еще 4 кнопки выбора режима работы (включения реле) условие - всегда может быть включен один режим (реле) при включении другого режима (реле), другие должны отключатся.

состояние этих режимов надо сохранять в еепром.

В вашем ТЗ было - одна кнопка все выключает, четыре включают свои реле, блокировка от одновременного нажатия не предусмотрена. Вам и сделали согласно ТЗ.

vingor
Offline
Зарегистрирован: 25.05.2014

vingor пишет:

Примерная Логика

кнопка on1 нажата 1 раз  - состояние выхода 1 высокое

если состояние выхода 1 высокое тогда

.....

если кнопка оn1 нажата еще раз состояние выхода 1 низкий, состояние выходов 2,3,4.5 тоже низкий  

но при включении/выключении, сбое питания надо запоминать состояния выходов 2,3,4,5.

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

Тогда так (пины изменились):

// Подключаем библиотеку EEPROM
#include <EEPROM.h>

// Количество элементов (реле и кнопок)
#define ELEMENTS 4

// Назначаем пин для кнопки "выключить все"
#define OFF_BUTTON 1

// Назначаем пины для кнопок
byte buttonPin[ELEMENTS]={
  6,7,8,9};

// Назначаем пины для реле
byte outPin[ELEMENTS]={
  2,3,4,5};

// флаг состояния выхода 1
boolean mainState = true;                // по умолчанию состояние выхода 1 - высокое


void setup()
{
  pinMode(OFF_BUTTON, INPUT);             // конфигурируем пин на вход

  for (byte i = 0; i < ELEMENTS; i++)
  {
    pinMode(buttonPin[i], INPUT);         // конфигурируем пины на вход
    pinMode(outPin[i], OUTPUT);           // конфигурируем пины на выход
    restorePin(i);                        // восстанавливаем состояние реле
  }
}  // конец setup



void loop()
{
  // читаем состояние кнопки "выключить все"
  boolean stopButton = digitalRead(OFF_BUTTON);  
  if (stopButton)                                 // если кнопка нажата
  {
    mainState = !mainState;                       // инвертируем состояние выхода 1
    allOff();                                     // выключаем все
    delay (20);                                   // примитивный антидребезг
  }

  if (mainState)                                  // если состояние выхода 1 высокое
  {
    // читаем состояние остальных кнопок
    for (byte pin = 0; pin < ELEMENTS; pin++)
    {
      boolean state = digitalRead(buttonPin[pin]); 
      if (state)                                    // если кнопка нажата
      {
        allOff();                                   // выключаем все
        setPin(pin, state);                         // включаем конкретный реле
        delay (20);                                 // примитивный антидребезг
      } // конец if
    } // конец for
  } // конец if(mainState)

}  // конец loop



// восстанавливаем состояние из EEPROM
void restorePin(byte address)              // входная переменная address - адрес в EEPROM, из которого читаем состояние
{
  byte value = EEPROM.read(100 + address); // читаем из EEPROM состояние реле из ячейки 100 + номер
  // смещение на 100 из-за того, что в первые ячейки EEPROM чаще записывают, они могли уже выработать свой ресурс
  if (value > 1) value = 0;                // если в EEPROM мусор, то реле остается выключенным
  digitalWrite(outPin[address], value);    // восстанавливаем состояние реле
}  // конец restorePin


// Включаем конкретный пин, с записью состояния в EEPROM
void setPin(byte address, byte state)      // входные переменные: address и state - состояние, которое надо установить
{
  EEPROM.write(100 + address, state);      // сохраняем состояние реле в EEPROM
  digitalWrite(outPin[address], state);    // включаем/выключаем реле
}  // конец setPin


// Выключаем все
void allOff()
{
  for (byte pin = 0; pin < ELEMENTS; pin++) 
  {
    setPin(pin, LOW);
  }
}  // конец allOff

 

vingor
Offline
Зарегистрирован: 25.05.2014

Все равно бегущая строка (((

vingor
Offline
Зарегистрирован: 25.05.2014

Вот пример кода того что у меня есть.

Комментарий к тому что надо в void loop

int ch1 = 14; 
int ch2 = 15;
int ch3 = 16;
int ch4 = 17;
int on1 = 18;
int on2 = 19;
int i;
boolean on_off;
void setup()
{
  pinMode(ch1, OUTPUT);
  pinMode(ch2, OUTPUT);
  pinMode(ch3, OUTPUT);
  pinMode(ch4, OUTPUT);
  pinMode(on1, OUTPUT);
  pinMode(on2, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
 // rejim();
}
 
void loop()
{
  if(digitalRead(6)==HIGH) 
  { 
    digitalWrite(on1,HIGH);// включаем софт старт
    delay(2000);//на 2 секунды
    digitalWrite(on2,!digitalRead(on2));//включаем основное питание
    delay(500); //ждем 0,5 секунды
    digitalWrite(on1,LOW);//выключаем софт старт
    //как в состоянии включено on2 заставить работать void rejim()
    //и соответственно при выключеном on2 не реагировать на нажатие кнопок из void rejim()
  }
}
void rejim() //режимы работы еще 4 реле
{
 if(digitalRead(5)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,HIGH);//включаем реле1 и держим его включенным
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,LOW);
 }
 else if(digitalRead(4)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,HIGH);///включаем реле2 и держим его включенным
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,LOW);
 }
 else if(digitalRead(3)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,HIGH);//включаем реле3 и держим его включенным
 digitalWrite(ch4,LOW);
 }
  else if(digitalRead(2)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,HIGH); //включаем реле4 и держим его включенным
 }
}
 

 

vingor
Offline
Зарегистрирован: 25.05.2014

Вот практически сделал то, что мне надо.

#include <EEPROM.h>
int ch1 = 14; 
int ch2 = 15;
int ch3 = 16;
int ch4 = 17;
int on1 = 18;
int on2 = 19;
byte val1;
byte val2;
byte val3;
byte val4;
void setup()
{
  pinMode(ch1, OUTPUT);
  pinMode(ch2, OUTPUT);
  pinMode(ch3, OUTPUT);
  pinMode(ch4, OUTPUT);
  pinMode(on1, OUTPUT);
  pinMode(on2, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
}
 void loop()
{
 if(digitalRead(6)==HIGH)//если кнопка нажата ..
 {
 digitalWrite(on1,HIGH);
 delay(2000);
 digitalWrite(on2,HIGH);
 delay(500);
 digitalWrite(on1,LOW);
  digitalWrite(ch1,EEPROM.read(1));
  digitalWrite(ch2,EEPROM.read(2));
  digitalWrite(ch3,EEPROM.read(3));
  digitalWrite(ch4,EEPROM.read(4));
 }
 if(digitalRead(5)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,HIGH);//включаем реле1 и держим его включенным
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,LOW);
 EEPROM.write(1, 1);
 EEPROM.write(2, 0);
 EEPROM.write(3, 0);
 EEPROM.write(4, 0);
 }
 else if(digitalRead(4)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,HIGH);///включаем реле2 и держим его включенным
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,LOW);
 EEPROM.write(1, 0);
 EEPROM.write(2, 1);
 EEPROM.write(3, 0);
 EEPROM.write(4, 0);
 }
 else if(digitalRead(3)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,HIGH);//включаем реле3 и держим его включенным
 digitalWrite(ch4,LOW);
 EEPROM.write(1, 0);
 EEPROM.write(2, 0);
 EEPROM.write(3, 1);
 EEPROM.write(4, 0);
 }
  else if(digitalRead(2)==HIGH)//если кнопка нажата ...
 {
 digitalWrite(ch1,LOW);
 digitalWrite(ch2,LOW);
 digitalWrite(ch3,LOW);
 digitalWrite(ch4,HIGH); //включаем реле4 и держим его включенным
 EEPROM.write(1, 0);
 EEPROM.write(2, 0);
 EEPROM.write(3, 0);
 EEPROM.write(4, 1);
 }
 
}
 

Данные кнопок записываются в память и считываются при включении (кнопка на пине 6)

Теперь остался маленький вопрос как выключать устройство (по той же кнопке на пине 6) и при этом блокировать нажатие кнопок ch1,ch2,ch3,ch4 до следующего включения устройства?

vingor
Offline
Зарегистрирован: 25.05.2014

Мужики Я его победил с костылями но как знаю.

вот смотрите)))

#include <EEPROM.h>
int ch1 = 14; 
int ch2 = 15;
int ch3 = 16;
int ch4 = 17;
int on1 = 18;
int on2 = 19;
int i=0;
void setup()
{
  pinMode(ch1, OUTPUT);
  pinMode(ch2, OUTPUT);
  pinMode(ch3, OUTPUT);
  pinMode(ch4, OUTPUT);
  pinMode(on1, OUTPUT);
  pinMode(on2, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  Serial.begin(9600);
//передаем значение памяти в порт

 // rejim();
}
 
void loop()
{ 
      if(digitalRead(6)==HIGH)//если кнопка нажата ... 
      { 
      digitalWrite(on1,HIGH);
      delay (2000);
      digitalWrite(on2,!digitalRead(on2));//инвертируем состояние пина 
      delay(500);
      digitalWrite(on1,LOW);
      digitalWrite(ch1,EEPROM.read(1));
      digitalWrite(ch2,EEPROM.read(2));
      digitalWrite(ch3,EEPROM.read(3));
      digitalWrite(ch4,EEPROM.read(4));
      }
      if(digitalRead(on2)==HIGH)
      {
        i=1;
      }
      if(digitalRead(on2)==LOW)
      {
        i=0;
      }
      switch(i){
       case(1):
        if(digitalRead(5)==HIGH)//если кнопка нажата ...
         {
         digitalWrite(ch1,HIGH);//включаем реле1 и держим его включенным
         digitalWrite(ch2,LOW);
         digitalWrite(ch3,LOW);
         digitalWrite(ch4,LOW);
         EEPROM.write(1, 1);
         EEPROM.write(2, 0);
         EEPROM.write(3, 0);
         EEPROM.write(4, 0);
         }
         else if(digitalRead(4)==HIGH)//если кнопка нажата ...
         {
         digitalWrite(ch1,LOW);
         digitalWrite(ch2,HIGH);///включаем реле2 и держим его включенным
         digitalWrite(ch3,LOW);
         digitalWrite(ch4,LOW);
         EEPROM.write(1, 0);
         EEPROM.write(2, 1);
         EEPROM.write(3, 0);
         EEPROM.write(4, 0);
         }
         else if(digitalRead(3)==HIGH)//если кнопка нажата ...
         {
         digitalWrite(ch1,LOW);
         digitalWrite(ch2,LOW);
         digitalWrite(ch3,HIGH);//включаем реле3 и держим его включенным
         digitalWrite(ch4,LOW);
         EEPROM.write(1, 0);
         EEPROM.write(2, 0);
         EEPROM.write(3, 1);
         EEPROM.write(4, 0);
         }
         else if(digitalRead(2)==HIGH)//если кнопка нажата ...
         {
         digitalWrite(ch1,LOW);
         digitalWrite(ch2,LOW);
         digitalWrite(ch3,LOW);
         digitalWrite(ch4,HIGH); //включаем реле4 и держим его включенным
         EEPROM.write(1, 0);
         EEPROM.write(2, 0);
         EEPROM.write(3, 0);
         EEPROM.write(4, 1);
       }
       break;
       case(0):
         digitalWrite(ch1,LOW);
         digitalWrite(ch2,LOW);
         digitalWrite(ch3,LOW);
         digitalWrite(ch4,LOW);
       break;        
       }
      Serial.print(i);
      Serial.println();

     }

Если кто знает как его упростить жду совета ))))

vvadim
Offline
Зарегистрирован: 23.05.2012

а зачем упрощать, если работает как нужно, то вперёд к новым свершениям...

Alexus-12
Offline
Зарегистрирован: 28.03.2014

Подскажите пожалуйста - как избавится от дребезга кнопок при подключении 4-х штук к одному пину? Перерыл кучу инфы но никак не могу понять как оно работает. Куча переменных, в которых я просто запутался, не могу разобраться. Может есть какой-то аппаратный метод? Или дайте ссылку пожалуйста, где программный метод по полка разложен. В этой теме все перечитал, но так и не понял.

 

Если пример приведёте на 4 кнопки - буду очень благодарен.

vvadim
Offline
Зарегистрирован: 23.05.2012
Alexus-12
Offline
Зарегистрирован: 28.03.2014

А без delay?

vvadim
Offline
Зарегистрирован: 23.05.2012

я хотя и не люблю делеи и всячески от них стараюсь избавится, но здесь оставил как есть

kolyanych26
Offline
Зарегистрирован: 02.04.2015

 Здравствуйте.Несколько дней назад приобрёл ардуино уно,вот пытаюсь с ней разобраться,есть такой код

#include <SD.h>
#define SD_ChipSelectPin 10
#include <TMRpcm.h>
 
TMRpcm tmrpcm;
 
void setup()
{   
  pinMode(2,INPUT);
   pinMode(3,INPUT);
   pinMode(4,INPUT);
  tmrpcm.speakerPin = 9; 
  if (!SD.begin(SD_ChipSelectPin)) 
  { 
    return;
  }
 tmrpcm.volume(1);
 tmrpcm.play("1.wav");  
  }
void loop() 
{
  if (digitalRead(2) == LOW) 
  tmrpcm.play("2.wav");
  if (digitalRead(3) == LOW)
 tmrpcm.play("3.wav"); 
if (digitalRead(4) == LOW) 
 tmrpcm.play("4.wav");
}

в общем  нажимаем кнопку 1 играет файл1,нажимаем кн 2 играет файл2 и т.д.  Вопрос к знатокам как сделать так: нажимаем кн.один раз играет мелодия 1,нажимаем 2 раза  играет мелодия 2 и т.д. То есть нужна одна кнопка вместо трёх ,которая будет переключать файлы по количеству нажатий.

 

   

Vittorio
Offline
Зарегистрирован: 02.02.2015
#include <SD.h>
#define SD_ChipSelectPin 10
#include <TMRpcm.h>

TMRpcm tmrpcm;

byte count = 0;    // счетчик нажатий
byte maxTracks = 5; // количество треков в плеере
byte buttonPin = 2;  // пин для кнопки

void setup()
{   
  pinMode(buttonPin,INPUT);
  tmrpcm.speakerPin = 9; 
  if (!SD.begin(SD_ChipSelectPin)) 
  { 
    return;
  }
  tmrpcm.volume(1);
  tmrpcm.play("1.wav");  
}

void loop() 
{
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {
    count++;      // то увеличиваем счетчик
    if (count > maxTracks)  count = 1; // если счетчик превысил количество песен, то сбрасываем счетчик в начало
    switch (count) // смотрим что в счетчике
    {  
    case 1: 
      tmrpcm.play("1.wav");
      break;
    case 2: 
      tmrpcm.play("2.wav");
      break;
    case 3: 
      tmrpcm.play("3.wav");
      break;
    case 4: 
      tmrpcm.play("4.wav");
      break;
    case 5: 
      tmrpcm.play("5.wav");
      break;
    }
  }
}

 

kolyanych26
Offline
Зарегистрирован: 02.04.2015

Спасибо большое,буду пробовать.

maksim
Offline
Зарегистрирован: 12.02.2012

Только в этом случае будет работать не как вы описали, а каждое последующее нажатие кнопки будет включать следующий трэк, то есть получается просто кнопка NEXT.

void loop() 
{
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {      
    char files[][10] = {"1.wav", "2.wav", "3.wav", "4.wav", "5.wav"};
    tmrpcm.play(files[count]);
    count++; // то увеличиваем счетчик
    if (count == maxTracks) count = 0; // если счетчик превысил количество песен, то сбрасываем счетчик в начало
    delay(100);
  }
}
kolyanych26
Offline
Зарегистрирован: 02.04.2015

Залил этот скетч, работает так: после каждого нажатия проигрываются файлы в произвольном порядке,а хочется так нажал отпустил 1раз -мелодия 1,нажал отпустил,нажал отпустил мелодия-2,то есть определённому количеству нажатий соответствует определённая мелодия.

Vittorio
Offline
Зарегистрирован: 02.02.2015

А почему files[][10]?

Что означают первые пустые скобки?

maksim
Offline
Зарегистрирован: 12.02.2012

Vittorio пишет:

А почему files[][10]?

Что означают первые пустые скобки?

Поищите инфу про многомерные массивы и объявление массивов.

void loop() 
{
  static uint32_t pushmillis = 0;
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {
    pushmillis = millis();
    count++;
    delay(100);
  }

  if(pushmillis && millis()-pushmillis > 500)
  {
    if(count <= maxTracks)
    {
      char files[][10] = {"1.wav", "2.wav", "3.wav", "4.wav", "5.wav"};
      tmrpcm.play(files[count-1]);
    }
    count = 0;
    pushmillis = 0;
  }
}

 

kolyanych26
Offline
Зарегистрирован: 02.04.2015

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

maksim
Offline
Зарегистрирован: 12.02.2012
kolyanych26
Offline
Зарегистрирован: 02.04.2015

 

void loop() 

{
  static uint32_t pushmillis = 0;
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {
    pushmillis = millis();
    count++;
    delay(100);
  }

  if(pushmillis && millis()-pushmillis > 500)
  {
    if(count <= maxTracks)
    {
      char files[][10] = {"1.wav", "2.wav", "3.wav", "4.wav", "5.wav"};
      tmrpcm.play(files[count-1]);
    }
    count = 0;
    pushmillis = 0;
  }
}

 

всё работает корректно,спасибо,только очень быстро нажимать надо.А как скорость нажатий регулировать?Вы уж извините что надоедаю. 

maksim
Offline
Зарегистрирован: 12.02.2012

Скорее всего просто слишком долго держите кнопку

{
  static bool pushed = 0;
  static uint32_t pushmillis = 0;
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {
    if(!pushed)
    {
      pushmillis = millis();
      count++;
      pushed = 1;
      delay(50);
    }
  }
  else if(pushed)
  {
    pushed = 0;
    delay(50);
  }

  if(pushmillis && millis()-pushmillis > 500)
  {
    if(count <= maxTracks)
    {
      char files[][10] = {"1.wav", "2.wav", "3.wav", "4.wav", "5.wav"};
      tmrpcm.play(files[count-1]);
    }
    count = 0;
    pushmillis = 0;
  }
}

 

kolyanych26
Offline
Зарегистрирован: 02.04.2015

maksim пишет:

Скорее всего просто слишком долго держите кнопку

{
  static bool pushed = 0;
  static uint32_t pushmillis = 0;
  if (digitalRead(buttonPin) == LOW) // если нажата кнопка
  {
    if(!pushed)
    {
      pushmillis = millis();
      count++;
      pushed = 1;
      delay(50);
    }
  }
  else if(pushed)
  {
    pushed = 0;
    delay(50);
  }

  if(pushmillis && millis()-pushmillis > 500)
  {
    if(count <= maxTracks)
    {
      char files[][10] = {"1.wav", "2.wav", "3.wav", "4.wav", "5.wav"};
      tmrpcm.play(files[count-1]);
    }
    count = 0;
    pushmillis = 0;
  }
}

 

да медленно нажимал ,теперь всё хорошо спасибо !!!!Очень сильно помогли.Может ткнёте носом где по этой теме нарыть инфу ,очень хочется разобраться как работает этот код.Ещё раз большое спасибо!

burdyugov
Offline
Зарегистрирован: 02.04.2015

Люди знающие поскажите Нубасу 80уровня. Вообщем имеем 3 кнопки, 2 светодиода. Написал такой скетч:

// присвоение имен пинам
int switchPin1 = 6;
int switchPin2 = 7;
int switchPin3 = 8;
int LedPinL = 12;
int LedPinR = 13;

void setup()
{// присвоение фукционала пинам вход/выход
  pinMode(switchPin1, INPUT);
  pinMode(switchPin2, INPUT);
  pinMode(switchPin3, INPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}
void loop()
{
  //Исполнение  аварийка
  if(digitalRead(switchPin1) == HIGH)
  {
    digitalWrite(12, HIGH);
    digitalWrite(13, HIGH);
    delay (100);
    digitalWrite(12, LOW);
     digitalWrite(13, LOW);
      delay (500);
  }
  else
  {
    digitalWrite(12, LOW);
     digitalWrite(13, LOW);
  }
  //Исполнение левый поворот
  if(digitalRead(switchPin2) == HIGH)
  {
    digitalWrite(12, HIGH);
    delay (100);
    digitalWrite(12,LOW);
    delay (500);
    
  }
  else
  {
    digitalWrite(LedPinL,LOW);
  }
  //Исполнение  правый поворот
   if(digitalRead(switchPin3) == HIGH)
  {
    digitalWrite(13, HIGH);
    delay (100);
    digitalWrite(13,LOW);
    delay (500);
  }
  else
  {
    digitalWrite(13,LOW);
  }
}

 Все работает, нажал кнопку работает отпустил, не работает. Решил написать скетч чтоб было - нажал-отпустил работает, еще раз нажал отпустил выключилось. Вот тут то я и залип. Сижу уже часов 5 Написал вроде скетч

// присвоение имен пинам
int switchPin1 = 6;
int switchPin2 = 7;
int switchPin3 = 8;
int LedPinL = 12;
int LedPinR = 13;
boolean LastButton = LOW;
boolean LedOn = false;


void setup()
{// присвоение фукционала пинам вход/выход
  pinMode(switchPin1, INPUT);
  pinMode(switchPin2, INPUT);
  pinMode(switchPin3, INPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  boolean LastButton = LOW;

}
void loop()
{
  //Исполнение  аварийка
  if(digitalRead(6) == HIGH && LastButton == LOW )
  {
    LedOn = !LedOn;
    LastButton = HIGH;   
  }
  else
  {
    LastButton = digitalRead(6);
  }
    digitalWrite(LedPinL, LedOn);
  digitalWrite(LedPinR, LedOn);
  delay(100);
 digitalWrite(LedPinL, LOW);
  digitalWrite(LedPinR, LOW);
  delay(300);


 
if(digitalRead(7) == HIGH && LastButton == LOW )
  {
    LedOn = !LedOn;
    LastButton = HIGH;   
  }
  else
  {
    LastButton = digitalRead(7);
  }
  
  digitalWrite(LedPinL, LedOn);
    delay(100);
 digitalWrite(LedPinL, LOW);
    delay(300); 
  
 

  if(digitalRead(8) == HIGH && LastButton == LOW )
  {
    LedOn = !LedOn;
    LastButton = HIGH;   
  }
  else
  {
    LastButton = digitalRead(8);
  }
  
    digitalWrite(LedPinR, LedOn);
  delay(100);
  digitalWrite(LedPinR, LOW);
  delay(300);
  

}
  

но что-то не так он работает(гоняет по кругу). Объясните в чем косяк???


 

vvadim
Offline
Зарегистрирован: 23.05.2012

нажал - отпустил - горит
нажал - отпустил - не горит

 

#define LED  13  
#define BUTTON 2  
int val = 0;     
int old_val = 0;  
int state = 0;    

void setup()
{
  pinMode(LED, OUTPUT);    
  pinMode(BUTTON, INPUT);   
}
void loop()
{
  val = digitalRead(BUTTON); 
  if ((val == HIGH) && (old_val == LOW))
  {
    state = 1 - state;
  }
  old_val = val;  
  if (state == 1)
  {
    digitalWrite(LED, HIGH); 
  } 
  else 
  {
    digitalWrite(LED, LOW);
  }
}

 

burdyugov
Offline
Зарегистрирован: 02.04.2015

Логика устройства: 

Если нажать switchPin1 то должны моргать одновременно оба светодиода (1;2).

Если нажать switchPin2 то должен моргать только светодиод 2

Если нажать switchPin3 то должен моргать только светодиод 3.

А сейчас какую кнопку не нажмешь идет цикл 1-12-2. (это про мой последний скетч)

burdyugov
Offline
Зарегистрирован: 02.04.2015

А если кнопок 3 а диодов 2?

vvadim
Offline
Зарегистрирован: 23.05.2012

burdyugov пишет:

А если кнопок 3 а диодов 2?

 

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

burdyugov
Offline
Зарегистрирован: 02.04.2015

кнопки 1;2;3 светики "А" и "В"

Если нажать-отпустить кноп.1 одновременно моргают светики АВ, если нажать -отпустить кноп.1 светики неработают.

Если нажать-отпустить кноп.2 моргает светик "А" если нажать-отпустить кнопку 2 светик не работает.

Если нажать-отпустить кноп.3 моргает светик "В" если нажать-отпустить кнопку 3 светик не работает.

Вот вся логика работы кнопок и светиков. 

vvadim
Offline
Зарегистрирован: 23.05.2012

Пример для одной кнопки и одного светика.
Мигание на стандартном примере "Мигаем без задержек"
Думаю по аналогии сваяете и для второй кнопки.
Ну и антидребезг добавить для кнопок, желательно без делеев

#define LED  13  
#define BUTTON 2  
int val = 0;     
int old_val = 0;  
int state = 0;    
int ledState = LOW; 
long previousMillis = 0; 

void setup()
{
  pinMode(LED, OUTPUT);    
  pinMode(BUTTON, INPUT);   
}
void loop()
{
  val = digitalRead(BUTTON); 
  if ((val == HIGH) && (old_val == LOW))
  {
    state = 1 - state;
  }
  old_val = val;  
  if (state == 1)
  {
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > 1000)
    {
      previousMillis = currentMillis; 
      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW; 
    }
  } 
  if (state == 0)
  {
    ledState = LOW;
  }
  digitalWrite(LED, ledState);
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
#define LED_A  8  // пин для светодиода A
#define LED_B  9  
#define BUTTON_1 3  // пин для кнопки 1
#define BUTTON_2 4
#define BUTTON_3 5  
enum states {FLASH_AB, FLASH_A, FLASH_B}; // имена допустимых режимов работы
byte mode;                     // текущий режим работы
long previousMillis = 0;        // храним время последнего переключения светодиода 
long blinkInterval = 500;           // частота моргания светодиода (0,5 сек)


void setup()
{
  pinMode(LED_A, OUTPUT);    
  pinMode(LED_B, OUTPUT);    
  pinMode(BUTTON_1, INPUT);    
  pinMode(BUTTON_2, INPUT);    
  pinMode(BUTTON_3, INPUT);   
}

void loop()
{
  if (digitalRead(BUTTON_1)) mode = FLASH_AB;
  else if (digitalRead(BUTTON_2)) mode = FLASH_A; 
  else if (digitalRead(BUTTON_3)) mode = FLASH_B; 

  flashLeds();  // моргаем светиками, какими именно - зависит от текущего режима работы
}


void flashLeds()
{  
  // классический BlinkWithoutDelay, но с двумя светиками
  unsigned long currentMillis = millis();

  // если прошло 0.5 сек с момента последней проверки,
  if(currentMillis - previousMillis > blinkInterval) 
  {
    switch (mode)   // смотрим какой текущий режим работы
    {
    case FLASH_AB:
      // меняем состояние светодиодов на противоположное
      digitalWrite(LED_A, !digitalRead(LED_A));
      digitalWrite(LED_B, !digitalRead(LED_B));
      break;

    case FLASH_A:
      digitalWrite(LED_A, !digitalRead(LED_A));
      break;

    case FLASH_B:
      digitalWrite(LED_B, !digitalRead(LED_B));
      break;
    }  
    // запоминаем текущее время
    previousMillis = currentMillis; 
  }
}

 

burdyugov
Offline
Зарегистрирован: 02.04.2015

Скачал и загрузил ваш скетч. Получил следующее:

1. После загрузки без нажатия на кнопки светики АВ мигают. И если даже нажимать на кнопку "1" они все равномигают и не выключаются.

2. Если в тот момент когда оба светика горят нажать кнопку 2 или 3 то один светик горит постоянно, второй мигает. Если нажать кнопку 2 или 3 когда оба светика не горят то включится и будет мигать только один светик сответствующий нажатой кнопке.

3.Если когда мигает только один светик в момент его свечения нажать на кнопку 1 то светики А и В начинают мигать поочередно.

Вот такое волшебство))

vvadim
Offline
Зарегистрирован: 23.05.2012

Tomasina просто не сделал обработку кнопок по вашему алгоритму.

Я вам дал готовый код, его адаптировать для второй кнопки проблема?

Немного подумать и сделать на его основе для третьей кнопки тоже  ничего сверхсложного или ждём готового решения?

CMEXIRK
Offline
Зарегистрирован: 03.04.2015

Кому интересно вот мой пример , Два свето диода к примеру  и одна кнопка, Принцып - нажал - загорелся  светодиод 1 , задержка как установите , потом  он гаснет, нажал воторой раз загорается  светодиод 2 и тоже гаснет по времени задержки, учитан и дребезг контактов кнопки во избежание ложного сробатывания , проверил на протеусе работает, как надо, писал для  шлагбаума самодельного , естественно вместо светодиодов будет пара резистор транзистор с реле на 220 , - крутит в одну сторону , вторая пара ( светодиод ) в другую пока собрана простая схема на  транзисторах но захотел на Атмеге воплотить проект



/*
 *  Включение одной кнопкой 2х нагрузок по переменки с автовыключением
 */

int switchPin = 2;              // замыкание кнопки на минус через резист pin 2
int led1Pin = 8;               // нагрузка 1
int led2Pin = 9;               // нагрузка 2


int val;                        // Переменная для чтения статуса контактный
int val2;                       // Переменная для чтения с задержкой / подавлением дребезга контактов статус
int buttonState;                // Переменная провести состояния кнопки

int lightMode = 0;              // Есть свет включен или выключен?

void setup() {
  pinMode(switchPin, INPUT);    // Установите пин в качестве входных данных

  pinMode(led1Pin, OUTPUT);     // Установите пин в качестве выходных данных
  pinMode(led2Pin, OUTPUT);     // Установите пин в качестве выходных данных

  
  Serial.begin(9600);                // Установите последовательную связь в 9600
  buttonState = digitalRead(switchPin);   // читать начальное состояние
}

void loop(){
  val = digitalRead(switchPin);      // читать входное значение и сохранить его в Val
  delay(10);                         // 10 миллисекунд хорошее количество времени
  val2 = digitalRead(switchPin);     // читать ввод снова, чтобы проверить отскоков
  if (val == val2) {                 // убедиться, что мы получили 2 показания последовательны!
    if (val != buttonState) {          // состояние кнопки изменилось!
      if (val == LOW) {                // проверить, если нажата кнопка
        if (lightMode == 0) {          // эта нагрузка включена?
          lightMode = 1;               // включить нагрузку 1
          digitalWrite(led1Pin, HIGH); // нагрузка включена
          delay(15000);                 // время до автовыключения
          digitalWrite(led1Pin, LOW);  // нагрузка выключается

        } else {
          lightMode = 0;               // выключить нагрузку 2
          digitalWrite(led2Pin, HIGH); // нагрузка включена
          delay(15000);                 // время до автовыключения
          digitalWrite(led2Pin, LOW);  // нагрузка выключается

        }
      }
    }
    buttonState = val;                 // сохранить новое значение в нашей переменной
  }
}

http://youtu.be/wezPs_jxPQg  тут как работает и схема подк кнопки на резисторах

 

art100
Offline
Зарегистрирован: 09.03.2014

Простите великодушно. Что-то я запрограммировался и запутался. Прошу помощи всезнающего All. Типовая работа с одной кнопкой, а у меня ступор.

Задача:

1 кнопка

2 при однократном нажатии выполняем код

3 при следующем однократном нажатии НЕ выполняем код

Какое ключево слово? trigger one button

Может кто-то пнет в верном направлении?

Вот фигню какую-то написал

  // joysticks ----------------------------------------------------------
  if(digitalRead(ButManual)==LOW&&FlagManual1==0){//если нажата кнопка ручного режима и был стоп
    FlagManual1=1;                                //поднимем флаг ручного режима
...
    Se.....(Tors01Tmp2);
...
  } 
  if(digitalRead(ButManual)==HIGH&&FlagManual1==1){ FlagManual1=0; }// стоп ручного режима и после однократного выполнения ручного режима стоп ручного режима
  // joysticks ----------------------------------------------------------  

 

 

 

Arkano63rus
Offline
Зарегистрирован: 02.04.2015

На первой странице в первом топикстартер еще написал...

Не то?

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

int flag=0; 

void setup()    
{ 
       
    pinMode(13, OUTPUT);         
      
        
} 

void loop() 

{ 
        
     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата    
     // и перемення flag равна 0 , то ... 
     { 
           
       digitalWrite(13,!digitalRead(13)); 
       flag=1; 
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
        
     } 
        
      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
           
        flag=0;//обнуляем переменную flag 
     } 
} 

Алгоритм такой. Нажали кнопку – загорелся светодиод, удерживаем кнопку – ничего не происходит (светодиод горит). Отпустили кнопку – светодиод горит.
Для того чтобы погасить светодиод нужно повторно нажать кнопку.
Т.е. нажали – горит, отпустили, нажали – не горит.

art100
Offline
Зарегистрирован: 09.03.2014

Arkano63rus пишет:

На первой странице в первом топикстартер еще написал...

Не то?

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

int flag=0; 

void setup()    
{ 
       
    pinMode(13, OUTPUT);         
      
        
} 

void loop() 

{ 
        
     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата    
     // и перемення flag равна 0 , то ... 
     { 
           
       digitalWrite(13,!digitalRead(13)); 
       flag=1; 
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
        
     } 
        
      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
           
        flag=0;//обнуляем переменную flag 
     } 
} 

Алгоритм такой. Нажали кнопку – загорелся светодиод, удерживаем кнопку – ничего не происходит (светодиод горит). Отпустили кнопку – светодиод горит.
Для того чтобы погасить светодиод нужно повторно нажать кнопку.
Т.е. нажали – горит, отпустили, нажали – не горит.

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

#define ButManual A4
#define LED13     13
int flag=0; 

void setup(){ 
  pinMode(ButManual,INPUT_PULLUP); 
  pinMode(LED13,OUTPUT);
} 

void loop(){ 
  if(digitalRead(ButManual)==HIGH&&flag==0){//если кнопка нажата  и перемення flag равна 0 
    flag=1;                                 //с каждым нажатием кнопки происходило только одно 
    digitalWrite(LED13,!digitalRead(LED13));
  } 
  if(digitalRead(ButManual)==LOW&&flag==1){//если кнопка НЕ нажата и переменная flag равна - 1             
    flag=0;                                //обнуляем переменную flag 
  } 
} 

Вот вам специально видео в железе выполнено. https://yadi.sk/i/4KVseYtifkeEp

Хорошо, что это только светодиод, а не метал. 

Этот дибил не понимает как исполнительную логику писать.

digitalWrite(13,!digitalRead(13));

 

Прям классическая дурь казнить нельзя помиловать. Где вы будете ставить запятую в гильотине?. Или где вы будете ставить восклицательный знак в гильотине?

Я понимаю нестандарта типа по быстрому дурь написал, чтобы на кнопки уделить больше внимания. Но что-то я древноего кода не вижу изначально 1.выделение памяти 2.инициализация 3.раделение ввода 4.и вывода.  Соответсвенно возможная отладка в железе в .изду идет сходу.

Гильотину нестандарту гильотину. Посмотрим виживет с его стилем написанием кода?

Тяп ляп вижу. Стиля не вижу.

Рассмотрим дурно пахнущий код

//1.причесываем 
//1.инициализацию выводов для того чтобы в последующем по месту внедрения править только инициаизацию
#define ButManual A4
#define LED13     13
//1.1.Иницализация в памяти нарезание на кусочки
int flag=0; 
//2.однократная инициализация переферии
void setup(){ 
  pinMode(ButManual,INPUT_PULLUP); 
  pinMode(LED13,OUTPUT);
} 
//3.собственно сама логика работы 
void loop(){ 
//3.1. сбор внешних данных
  if(digitalRead(ButManual)==HIGH&&flag==0){//если кнопка нажата  и перемення flag равна 0 
//4.1.принятие решения в конкретном случае програмная компенсация аппаратного несовершенства
    flag=1;                                 //с каждым нажатием кнопки происходило только одно 
//4.2.типа принятие решения. А по сути и ввод и вывод. Вот тут автору гильотину надо.
    digitalWrite(LED13,!digitalRead(LED13));
  } 
//3.1.сбор внешних данных
  if(digitalRead(ButManual)==LOW&&flag==1){//если кнопка НЕ нажата и переменная flag равна - 1             
//4.1. программная компенсация аппаратного не совершенства
    flag=0;                                //обнуляем переменную flag 
  } 
} 

//5. код и так под гильотину чего тут подпрограммы писать-то.

 

 

art100
Offline
Зарегистрирован: 09.03.2014

Ну что. Слушайцте пацаки. Дедушка art расскажет вам сказку, как работают с кнопкой.

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

Потому, что:

1.1 Когда вы будете прозванивать вольтметром на стороне кнопок землю вы всегда прозвоните.

1.2. Плюс питания то есть подпор на кнопку вы тоже всегда вольтметром увидите.

1.3. Пинцетом или сразу щупом вы смодете закоротить куда? Правлильно. На землю которая есть везде.

Посмотрю я на вас когда в автомобиле, в зданиях и сооружениях 12 вольтами будете микропроцессоры коротить на + питания микропроцесора.

С первым идиотизмом я думаю уже все понятно, и дальше можно не продолжать.

2. Если в коде не выделены в отдельные части

2.1. Инициализация

2.2. Логика ввода от вывода

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

3. От сюда вытекает следующее правило дедушки Арта:

Пишите кода не более, чем вы можете за раз целиком увидеть на экране, потому, что постичь невидимое немыслимо.

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

(Я понимаю, что если вы написали 100 строчек кода за год тогда это не проблема, но если за 1000 то вы не вспомните.)

4. Программный код компенсирует аппаратное несовершенство. А не наоборот. Никогда не путайте первопричну и следствие.

Итак вернемся к нашим баранам.

Триггеры? Программно? Я что больной? Мне еще женьщину полюбить надо вечерком, а не при наличии выключателей с фиксацией, тратить время на расстановку флагов.

Резистивная цепочка кнопок имеет право жить в автомобильной тематике. Например: Если у вас подрулевые выключатели еще не сгнили. Или на макетке по быстрому проверить чужой код.

Итак самое веселое. Как писать библиотеку работы с кнопкой с фиксацией.

Качаем библиотеки: Паяльник,Канифоль,ПОС-61, 2 версии исполнительных библиотек (Мы ведь не дибилы и знаем, что про типовом браке 5% чтобы его радикально уменьшить и не потратить время в пустую, а всегда решить задачу в срок надо брать 2 версии. И не важно это чип за 100$ или кнопка за 2$ за пучек).

А эту дурь писал с проблемной головой теоретик, а не практик. https://www.arduino.cc/en/tutorial/button

Нам ведь надо еще время на женьщин? Или вас лучше встаdляет вставление резисторов?

Вы дочитали. Ну ладно смотрм на веселые картинки и видео. 

Схема ПинБатона от доктора Артона.

Готовим библиотеку триггер

Тестируем код

В железе

В движении https://yadi.sk/i/cUlvB6HAfkoxR

Вы дочитали до сюда?

Ну ладно выжимка из рабочего кода тоже работает.

Код:

// art100 to write 20150402 servo Tors Plech Lokot Kist
#include <Servo.h>//подключение гтовой библиотеки
// pins--инициализация ножек------------------------------------------
//...
#define PotKist01 A3 // 180gradusov
#define ButManual A5 // обязательно с фиксацией кнопка стопа и ручного режима
//...
//----инициализация готовых библиотек-------------------------------------------------------------------
//...
Servo ServoKist01;// pin 5
//...
int Kist01min1=  0;//инициализация памяти под переменные
int Kist01max1= 180;//20;//задаем малый ход по железу подбираем чтобы не поломать констурктив аллюминий
int Kist01Tmp1=  0;
int Kist01Tmp2=  0;
int Kist01Park=  0;

//...

// usb-----------------------
int  commandusb        = 0; //инициализация памяти под переменку из компьютера маскимум 255 строк в реале писать не более 30 символов за раз
//---------------------------
// servomg995 --выделяем исполнение в данном слчае дешевое авно серво-----------------------------
//...
void ServoMG995Kist01(int angle){ ServoKist01.write(angle); }
//--однократная инициалиация-----------------------------------------
void setup(){ 
  pinMode(ButManual,INPUT_PULLUP);//классически коротим на корпус резистор 20кОм на +5в
//...
  pinMode(PotKist01,INPUT);//АЦП
//...
  ServoKist01.attach(5);//смотрим библиотеку потом дурь подправлю
//...
  Serial.begin(9600); //по умолчанию скорость 
} 
//======================================================================
void loop(){
  // joysticks ----------------------------------------------------------
  if(digitalRead(ButManual)==LOW){ Serial.println("ButManual)==LOW");// ввод если нажата кнопка ручного режима
//...
    Kist01Tmp1=analogRead(PotKist01); Kist01Tmp2=map(Kist01Tmp1,0,1023,Kist01min1,Kist01max1);//обрезание
//...
    Serial.print(Kist01Tmp2);Serial.println(";"); //тест для отладки
//...
    ServoMG995Kist01(Kist01Tmp2);//SG90 вывод
  } 
  // joysticks ----------------------------------------------------------  

  // usb ----------------------------------------------------------------
  if(Serial.available()>0){   
////....
  }  
  // usb ----------------------------------------------------------------    
}   
//========================================================================

Неужели вы дочитали? А какже околопрограммный флуд? Как он без вас? Я на на решение задачи ввода ручного управления потратил 25 минут. А на сказку доктора Арта с 16:00 18:00 = !!!2 часа!!! И вы бо сих пор не сказали спасибо. Забаньте меня пойду посоздаю чего-нибудь. Вот жена пришла. Пойду ее титьки потискаю.

 

Chilori
Offline
Зарегистрирован: 10.05.2015

yuler пишет:

Ребята! можете мне помоч скетчом с таким алгоритмом?
-Значит уменя Arduino NANO.
-кнопки больше 2 шт. и столькоже светодиодов.
-одна кнопка и один светодиод это одна пара.
- при нажатии и удржании любую кнопку соответствующий светодиод 
должен горет в течении 500 миллисекунд потом выключался.
- когда отпускаем кнопку опят с такимже импульсом должен вспыхнут этодже светодиод. Я думаю это простая задача но у меня пока не получается. Спасибо заранее. Я прощу прощение если вопрос не уместный или не соблюдаю порядок форума.

Не флуди. Кинул скетч в прошлой теме.

http://arduino.ru/forum/obshchii/proshu-pomoch-novichku-v-svoem-pervom-p...

skyspirit
Offline
Зарегистрирован: 27.02.2015

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

Алгоритм такой что при нажатии кнопки например 3 секунды включаестя ардуино при нажатии повторном выключается, принцип как в некоторых устройствах плеерах.

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

Кто то реализовывал подобное ???

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

Поставить тумблер с колпачком? Случайно его точно не включить. И потребление нулевое.

std
Offline
Зарегистрирован: 05.01.2012

skyspirit пишет:
А можно ли реализовать, электронное включение и выключение ардуино минуя механический тумблер (...) Кто то реализовывал подобное ?

Ну я.

skyspirit
Offline
Зарегистрирован: 27.02.2015

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

std
Offline
Зарегистрирован: 05.01.2012

Она включается всегда, всякий раз как жмут кнопку. Ложно или неложно - это уже определяет программа. У меня это время 2 с (можно и 5, но тащемта бесит держать 5 с пока эта шваль соизволит отреагировать, так что 2 с достаточно). Это время делается задержкой - delay(2000);

Угадайте, спит мега эти две секунды? Правильно, нифига. Но светик она не включает до истечения 2000 мс, плюс дальше условие - если время вышло а кнопку уже не жмут - значит нажалось случайно, значит заснуть.

Отключать удержанием вместо нажатия можно таким же способом. Или чтобы избежать delay() - поставить флаг, bSetSleepMode какой-нибудь. Если кнопка жмётся, то true, и сохранить время из millis(). Если не жмётся то false. Если true и millis() минус время больше 2000 мс, то заснуть.

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

fot
Offline
Зарегистрирован: 23.10.2011

Есть прекрасная библиотека OneButton

http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

Поддерживает функции :

Короткое нажатие, Длинное нажатие. 

Двойное нажатие, защита от дребезга.

Назначение любого кол-ва кнопок.

Работает как часы.

Подключил и забыл.

Там же библиотека RotaryEncoder - просто и надёжно.

http://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx

 

 

Nec132113
Offline
Зарегистрирован: 17.11.2014

Добрый день!!!

Не судите строго,  но не нашёл в теме!

Суть вопроса токова, при нажатии на кнопку необходимо выдержка зажёного состояния светодиода на какое то время (секунд на 20) затем затем выключить и ждать снова нажатия кнопки, без delay. Спасибо.

 

vvadim
Offline
Зарегистрирован: 23.05.2012

при нажатии кнопки запускаете таймер (секунд на 20) - по истечении этого времени таймер вырубаете и гасим светик

Nec132113
Offline
Зарегистрирован: 17.11.2014

vvadim пишет:

при нажатии кнопки запускаете таймер (секунд на 20) - по истечении этого времени таймер вырубаете и гасим светик

Прошу Вас ! Покажите на этом примере где и как вставить таймер.

long previousMillis = 0; 
 int val=0; 

 void setup()    
 { 
        
     pinMode(13, OUTPUT);         
       
         
 } 

 void loop() 

 { 
     if(digitalRead(14)==HIGH)//если кнопка нажата ... 
     { 
         
      if (millis() -previousMillis >500)    
     { 
        previousMillis = millis();     
        val++; 
     } 
     } 
     else 
     { 
       val=0; 
     } 
        
     if(val>=5) 
     { 
       digitalWrite(13,!digitalRead(13));//инвертируем состояние пина 
       val=0; 
     } 
        
        
 } 
 

Спасибо.

vvadim
Offline
Зарегистрирован: 23.05.2012

переделал

long previousMillis = 0; 
int val=0; 
int state = 0; 

void setup()    
{       
  pinMode(13, OUTPUT); 
} 

void loop() 
{ 
  if(digitalRead(14) == HIGH && state == 0)     //если кнопка нажата ... 
  { 
    state = 1;
  }
  if (state == 1)
  {
    digitalWrite(13,HIGH);                     // вкл. светодиод   
    if (millis() - previousMillis >500)    
    { 
      previousMillis = millis();     
      val++; 
    } 
    if(val >= 40) 
    { 
      digitalWrite(13,LOW);    // выкл. светодиод
      state = 0;
      val = 0; 
    } 
  }
}