Количесто нажатий на кнопку

shaman900
Offline
Зарегистрирован: 27.09.2011

 Привет всем любителям ардуино, мне хочется почему то называть его ардуНио. Ну да ладно.

Была у меня задачка выводить на дисплей WH1602A(B) количество нажатий или срабатыаний  датчика.

Решил просто поделиться кодом.

Может кто усовершенствует его. Или новое придумает.

#include <LiquidCrystal.h>
const int SensorPin = 8;
int signal = 0;
int Counter = 0;
int lastSignal = 0;
LiquidCrystal lcd(12, 10, 3, 4, 5, 6);
void setup() {
lcd.clear();
delay(100);
lcd.begin(16, 2);
lcd.print("Sensor1::>");
lcd.setCursor(11, 0);
pinMode(SensorPin, INPUT);
}
void loop()
{

signal = digitalRead(SensorPin);
if (signal != lastSignal)
{
if (signal == HIGH)
{
Counter++;
lcd.print(Counter);
lcd.setCursor(11,0);
delay(1);
}
lastSignal = signal;
}

Буду рад услышать вашы коментарии

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Лучше  делать на прерываниях. В более сложном коде прерывания это СИЛА! 

shaman900
Offline
Зарегистрирован: 27.09.2011

Подскажите пример вашего кода с прерываниями.

Mogalkov
Offline
Зарегистрирован: 23.06.2011

 Вот посмотри такой код:

const int ledPinA = 3;//светодиод 1
const int ledPinB = 4;//светодиод 2
const int ledPinC = 5;//светодиод 3
int BlinkState=LOW;//состояние для мигания
int begstate=0;//состояние для бега
int ledState=3;//состояние для кнопки
long previousMillis = 0;//счетчики времени, прошлое время
long interval = 1000;//интервал мигания и бега

//Функия для прерывания 0, меняет счетчик кнопки
void buttoncontrol()
{
    ledState=ledState+1; //увеличивает счетчик кнопки на 1, можно так ledState++ , но мне не удобно.
    if (ledState==4){ledState=0;}//если счетчик достиг предела положений то его надо обнулить.
}

//функция все светодиоды выключены
void LedOFF()
{
 digitalWrite(ledPinA,0); 
 digitalWrite(ledPinB,0); 
 digitalWrite(ledPinC,0); 
}

//функция все светодиоды включены
void LedON()
{
 digitalWrite(ledPinA,1); 
 digitalWrite(ledPinB,1); 
 digitalWrite(ledPinC,1);
}

//функция бегущих огней (никакого delay)
void LedBlinkBEG()
{
unsigned long currentMillis = millis();//переменная текущего времени, и объявляем и присваиваем значеник.
if(currentMillis - previousMillis > interval)
//условие выполняется если разница между текущим и прошлым временем больше заданного интервала
{
 previousMillis = currentMillis;  //присваиваем переменной прошлого времени текущее значение
begstate=begstate+1;//счетчик позиции бега увеличиваем на 1
 if (begstate==4){begstate=0;}//если достигнут предел счетчика то сбрасываем
switch (begstate)//оператор выбора, выполняет свой блок в зависимости от значения переменной
{
 case 0:
 digitalWrite(ledPinA,0); 
 digitalWrite(ledPinB,0); 
 digitalWrite(ledPinC,0); 
 return;
 case 1:
 digitalWrite(ledPinA,1); 
 digitalWrite(ledPinB,0); 
 digitalWrite(ledPinC,0); 
 return;
 case 2:
 digitalWrite(ledPinA,0); 
 digitalWrite(ledPinB,1); 
 digitalWrite(ledPinC,0); 
 return;
 case 3:
 digitalWrite(ledPinA,0); 
 digitalWrite(ledPinB,0); 
 digitalWrite(ledPinC,1); 
 return;
}
}
}

void LedBlinkAll()//фенкция мигания, без делай через таймер. 
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval/5) 
{
 previousMillis = currentMillis;   
 if (BlinkState==LOW){BlinkState=HIGH;}
 else {BlinkState=LOW;}
 digitalWrite(ledPinA,BlinkState); 
 digitalWrite(ledPinB,BlinkState); 
 digitalWrite(ledPinC,BlinkState); 
}
}


void setup()
{
  pinMode(ledPinA, OUTPUT);   
  pinMode(ledPinB, OUTPUT);   
  pinMode(ledPinC, OUTPUT);   
  //прерывание объявляется в сетупе, прерывание 0 это пин 2 дуины
//  0 порт прерывания
//  buttoncontrol функция которая выполнится при срабатывание прерывания
//  RISING условие срабатывания,в данном случае при изменении с LOW на HIGH           
  attachInterrupt(0, buttoncontrol, RISING);  
}

void loop()
{
//В зависимости от состояния кнопки выполняет нужную функцию
switch (ledState)
{
 case 0:
 LedOFF();//выключено
 break;
 case 1:
 LedON();//включено
 break;
 case 2:
 LedBlinkAll();//мигает
 break;
 case 3:
 LedBlinkBEG();//бегает
 break;
}
}

 

shaman900
Offline
Зарегистрирован: 27.09.2011

 Вот какой код у меня получился 

#include <LiquidCrystal.h>
const int SensorPin = 2;
const int SensorPinv = 3;
const int Pin=13;
int signal = 0;
int signalv = 0;
int Counter = 0;
int Counterv = 0;
int lastSignal = 0;
int n;
int k=0;
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
void setup() {
lcd.clear();
delay(100);
lcd.begin(16, 2);
lcd.print("Sensor1::>");
lcd.setCursor(0, 1);
lcd.print("Sensor2::>");
pinMode(SensorPin, INPUT);
pinMode(SensorPinv, INPUT);
pinMode(Pin, OUTPUT);
attachInterrupt(0, gostepP, CHANGE);
attachInterrupt(1, gostepM, CHANGE);
}
void loop()
{
n=Counter-Counterv;
if (abs(n)>=10)
{digitalWrite(Pin, HIGH); // зажигаем светодиод
delay(300);
digitalWrite(Pin, LOW); // выключаем светодиод
delay(300);
}
else if (abs(n)>=5)
{
digitalWrite(Pin, HIGH); // зажигаем светодиод
delay(1000); // ждем секунду
digitalWrite(Pin, LOW); // выключаем светодиод
delay(1000);
}
else if (abs(n)>=2)
{
digitalWrite(Pin, HIGH);
delay(2000);
digitalWrite(Pin, LOW);
delay(2000);
}


}
void gostepP()
{ signal = digitalRead(SensorPin);
if (signal != lastSignal)
{
if (signal == HIGH)
{ Counter++;
lcd.setCursor(10,0);
lcd.print(Counter);
lcd.setCursor(10,0);
delay(1);
if (Counter==10){Counter=0;}
}
lastSignal = signal;
}
}
void gostepM()
{ signalv = digitalRead(SensorPinv);
if (signalv != lastSignal)
{
if (signalv == HIGH)
{ Counterv++;
lcd.setCursor(10,1);
lcd.print(Counterv);
lcd.setCursor(10,1);
delay(1);
}
lastSignal = signalv;
}
}

 

Mogalkov
Offline
Зарегистрирован: 23.06.2011

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

Вот примерно так работает твой скетч:

www.youtube.com/watch

 

MAFia
Offline
Зарегистрирован: 26.10.2011

Делал что-то вроде этого, на прерываниях, но из-за дребезга получил лажу! Как исправить? Заранее спасибо! 

Mogalkov
Offline
Зарегистрирован: 23.06.2011

 Чтобы совсем убрать дребезг - паралельно кнопке кондер, и пускаешь через тригер шмитта при этом если кнопка давала HIGH то с тригера шмитта выйдет LOW и на оборот. www.youtube.com/watch

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

tyyt
Offline
Зарегистрирован: 11.09.2016

shaman900 пишет:

 Привет всем любителям ардуино, мне хочется почему то называть его ардуНио. Ну да ладно.

Была у меня задачка выводить на дисплей WH1602A(B) количество нажатий или срабатыаний  датчика.

Решил просто поделиться кодом.

Может кто усовершенствует его. Или новое придумает.

#include <LiquidCrystal.h>
const int SensorPin = 8;
int signal = 0;
int Counter = 0;
int lastSignal = 0;
LiquidCrystal lcd(12, 10, 3, 4, 5, 6);
void setup() {
lcd.clear();
delay(100);
lcd.begin(16, 2);
lcd.print("Sensor1::>");
lcd.setCursor(11, 0);
pinMode(SensorPin, INPUT);
}
void loop()
{

signal = digitalRead(SensorPin);
if (signal != lastSignal)
{
if (signal == HIGH)
{
Counter++;
lcd.print(Counter);
lcd.setCursor(11,0);
delay(1);
}
lastSignal = signal;
}

Буду рад услышать вашы коментарии

скажите пожалуйста : сколько ошибок в ардуино!!!!!!!!!!!!!!!!!!!!!!!!!!!1 Arduino: 1.6.11 (Windows 10), 

 
 
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x7f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x7f
 
 
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
 
kuzmich_ept
Offline
Зарегистрирован: 28.02.2017

Здравствуйте. Помогите начинающему. Идея такая: обработка 3-х нажатий в течении 3-х секунд (вкл-выкл), если более 3 секунды, то нажимай снова. Накропал следующее (кое что чужое):

#define BUTTON_PIN  3
#define LED_PIN     10
boolean buttonWasUp = false;  // была ли кнопка отпущена?
boolean ledEnabled = false;  // включен ли свет?
 int (x); // переменная для количества нажатий
unsigned long t; // таймер
  
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
  x=0;
  t=millis-3000;
}
 
void loop()
{
  boolean buttonIsUp = digitalRead(BUTTON_PIN); // сначала понимаем, отпущена ли кнопка прямо сейчас...
  if (buttonWasUp && !buttonIsUp); { // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
  delay(50); // поэтому даём кнопке полностью «успокоиться»...
  buttonIsUp = digitalRead(BUTTON_PIN); // ...и считываем сигнал снова
    if (!buttonIsUp&&(t<=millis-3000)) { //это нажатие! время укладывается в 3 секунды, выполняем
      x=x++; //увеличение переменной х на 1 (одно нажатие)
      t=millis;
      }
    else (x=0, t=millis-3000); // сброс нажатий и таймера   
  if (x==3) { //проверка сколько нажатий было(сколько нам надо)
  ledEnabled = !ledEnabled; //меняем булевую для выхода
  digitalWrite(LED_PIN, ledEnabled); //меняем состояние выхода
  x=0; //сбрасываем х
  t=millis-3000; //таймер для следующих нажатий
    }   
  } 
  buttonWasUp = buttonIsUp; // запоминаем последнее состояние кнопки для новой итерации
 }
 
 
Не работает(((. Ткните где не прав?
JasKo
Offline
Зарегистрирован: 21.11.2015

kuzmich_ept пишет:

Не работает(((. Ткните где не прав?

Во первых не прав во вставке кода. Читаем http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

 

kuzmich_ept
Offline
Зарегистрирован: 28.02.2017

JasKo]</p> <p>[quote=kuzmich_ept пишет:

Не работает(((. Ткните где не прав?

Во первых не прав во вставке кода. Читаем http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

[code]
#define BUTTON_PIN  3
#define LED_PIN     10
boolean buttonWasUp = false;  // была ли кнопка отпущена?
boolean ledEnabled = false;  // включен ли свет?
 int (x); // переменная для количества нажатий
unsigned long t; // таймер
  
void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);
  x=0;
  t=millis-3000;
}
 
void loop()
{
  boolean buttonIsUp = digitalRead(BUTTON_PIN); // сначала понимаем, отпущена ли кнопка прямо сейчас...
  if (buttonWasUp && !buttonIsUp); { // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
  delay(50); // поэтому даём кнопке полностью «успокоиться»...
  buttonIsUp = digitalRead(BUTTON_PIN); // ...и считываем сигнал снова
    if (!buttonIsUp&&t<=millis-3000) { //это нажатие! время укладывается в 3 секунды, выполняем
      x=x++; //увеличение переменной х на 1 (одно нажатие)
      t=millis;
      }
    else 
    x=0;
    t=millis-3000; // сброс нажатий и таймера   
  if (x==3) { //проверка сколько нажатий было(сколько нам надо)
  ledEnabled = !ledEnabled; //меняем булевую для выхода
  digitalWrite(LED_PIN, ledEnabled); //меняем состояние выхода
  x=0; //сбрасываем х
  t=millis-3000; //таймер для следующих нажатий
    }   
  } 
  buttonWasUp = buttonIsUp; // запоминаем последнее состояние кнопки для новой итерации
 }
[/code]

И?

JasKo
Offline
Зарегистрирован: 21.11.2015

И! все неверно. Вот тебе рабочий код 

#define BUTTON 3  // Кнопку подключаем к пину 3 и соединяем с общим проводом
#define LED 10    // Светодиод подключаем к пину 10

bool lastButton = true;     // Прошлое состояние кнопки
bool currentButton = true;  // Текущее состояние кнопки

boolean debounce(int button, boolean last){ // Обработка дребезга кнопки
  boolean current = digitalRead(button);
  if (current != last) {
    delay(5);
    current = digitalRead(button);
  }
  return current;
}

void setup() {
  pinMode(BUTTON, INPUT);
  digitalWrite(BUTTON, HIGH);
  pinMode(LED, OUTPUT);
}

void loop() {
  static int buttonClick = 0;
  static unsigned long buttonTime = -9999;

  currentButton = debounce(BUTTON, lastButton); // Читаем состояние кнопки
  if (currentButton && !lastButton) {           // Если была нажата то
    if (buttonClick == 0) {                     // Проверяем счетчик нажатий если = 0 то
      buttonTime = millis();                    // обнуляем счетчик времени для трех нажатий
    }
    buttonClick++;                              // Увеличиваем счетчик нажатий
  }
  lastButton = currentButton;                   // Сохраняем последнее состояние кнопки
  if (buttonClick == 3) {                       // Если за 3000 милисек счетчик стал = 3
    digitalWrite(LED, HIGH);                    // зажигам светодиод
    
  } 
 
  if (millis() - buttonTime >= 3000){           // Если время подсчета нажатий истекло
    buttonClick = 0;                            // обнуляем счетчик нажатий
    buttonTime = millis();                      // Сбрасываем счетчик времени
    digitalWrite(LED, LOW);                     // Гасим светодиод
  }  
}

 

kuzmich_ept
Offline
Зарегистрирован: 28.02.2017

Рассмотрел, спасибо. Вот это работает как мне надо, но без учета времени. Все-таки хотел бы понять, что с моим таймером не так?

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