• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
przycisk - long press
#1
Cześć,
od niedawna rozkminiam Arduino na potrzeby projektu, który mam w głowie. Na razie ćwiczę sobie na Tinkercadzie programując Arduino Uno. Żeby ogarniać w miarę na bieżąco buduję kod od podstaw i dorzucam kolejne elementy. Jestem na etapie na którym mam problem z rozwiązaniem błędu.
Układ: 1 przycisk, 2 diody, ekran
Kiedy przyciskam krótko przycisk diody przechodzą przez 3 opisane stany - tu mi wszystko działa.
Kiedy przytrzymuję przycisk wciśnięty dłużej chciałbym, żeby zapalały się obie diody i na wyświetlaczu pojawiał się napis "clear", dzieje się to, ale chciałbym, żeby ten stan utrzymywał się po puszczeniu przycisku, a teraz wraca do stanu sprzed długiego naciśnięcia.// opcjonalnie chciałbym, żeby po zakończeniu długiego przyciśnięcia układ wracał do stanu opisanego jako "default". Podpowiedzcie proszę gdzie mam błąd, bo już przestałem ogarniać. Dzięki za pomoc.
Kod:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int LED1 = 7;
const int LED2 = 8;
const int button = 6;
int state = 0;
int old = 0;
int buttonState = 0;

boolean LED1State = false;
boolean LED2State = false;

long buttonTimer = 0;
long longPressTime = 250;

boolean buttonActive = false;
boolean longPressActive = false;

void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(button, INPUT);
     // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Usmiechnij sie,");
  lcd.setCursor (0, 1);
  lcd.print("to nie pogrzeb.");
  delay (3000);
  lcd.clear ();
  lcd.print("Nogovcisk v0.01b");
  delay (3000);
}
void loop() {
  if (digitalRead(button) == HIGH) {
    if (buttonActive == false) {
      buttonActive = true;
      buttonTimer = millis();
    }
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
      longPressActive = true;
      digitalWrite(LED1, HIGH);
      digitalWrite(LED2, HIGH);
      lcd.setCursor (4, 1);
      lcd.print ("          ");
      lcd.setCursor (0, 0);
      lcd.print ("Nogovcisk v0.01b");
      lcd.setCursor(0, 1);
      lcd.print("CLEAR");
    }
  } else {
    if (buttonActive == true) {
      if (longPressActive == true) {
        longPressActive = false;
      } else {
  buttonState = digitalRead(button);
  if(buttonState == 0) {
    state = old + 1;
  }
   }}
  switch (state) {
   case 1:
    digitalWrite(LED1,HIGH);
    digitalWrite(LED2,LOW);
    old = state;
    lcd.setCursor (0, 0);
    lcd.print ("Nogovcisk v0.01b");
    lcd.setCursor(0, 1);
    lcd.print("RECORD LOOP");
    break;
   case 2:
    digitalWrite(LED1,LOW);
    digitalWrite(LED2,HIGH);
    old = state;
    lcd.setCursor (4, 1);
    lcd.print ("       ");
    lcd.setCursor (0, 0);
    lcd.print ("Nogovcisk v0.01b");
    lcd.setCursor(0, 1);
    lcd.print("PLAY");
    break;
    case 3:
    digitalWrite(LED1,LOW);
    digitalWrite(LED2,LOW);
    old = state;
    lcd.setCursor (4, 1);
    lcd.print ("       ");
    lcd.setCursor (0, 0);
    lcd.print ("Nogovcisk v0.01b");
    lcd.setCursor(0, 1);
    lcd.print("STOP");
    break;
   default:
    digitalWrite(LED1,LOW);
    digitalWrite(LED2,LOW);
    old = 0;
    break;
      }
      buttonActive = false;
    }
  }
 
Odpowiedź
#2
W każdym obiegu pętli wykona się jakiś stan ze switch. Jeśli nie chcesz by to się działo gdy zadziałał longPress to musisz dodać jakiegoś ifa wcześniej albo taki case, na który wskaże coś po spełnieniu longPress. A jak po długim naciśnięciu ma być wykonana akcja default to ustaw po długim naciśnięciu state=0. Oczywiście możesz sobie po prostu użyć biblioteki do przycisków, easyButton czy bounce2.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
ooo, dzięki... ten default mi załatwił sprawę. Banał, a nie wpadłbym na to za szybko. Przyjrzę się też wspomnianym bibliotekom, bo może bez sensu robię na około rzeczy, które mogą być prostsze.
 
Odpowiedź
#4
Hi. Może mi pomożesz? Nie mam zielonego pojęcia ale potrzebuje zrobić coś takiego. Jak na pinie np. 2 pojawia się stan np niski to:
Jak jest krótszy niż 2 sek to np na pin 4 zmienia stan na 3 sek
a jak jest dłuższy niż 2 sek to pin 5 zmienia stan na 3 sek
Czytam i czytam. Podglądam przykłady gotowych bibliotek ale nic mi nie wychodzi.
Pewnie dla Was to coś prostego.
Będę bardzo wdzięczny i przepraszam że to nie pomoc tylko prośba.
 
Odpowiedź
#5
Tu masz wersję demo:
Kod:
byte p = 0;
unsigned long Zapamietany_Czas = 0;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
}

void loop()
{
  if (digitalRead(2) == LOW)
  {
    delay(50);
    if (digitalRead(2) == LOW && p == 0)
    {
      Zapamietany_Czas = millis();
      p = 1;
    }
  }
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas < 2000UL)
  {
    inpuls_na_4();
    p = 0;
  }
 
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas > 2000UL)
  {
    inpuls_na_5();
    p = 0;
  }
   
}

void inpuls_na_4()
{
digitalWrite(4, LOW);
delay(3000);
digitalWrite(4, HIGH);
}

void inpuls_na_5()
{
digitalWrite(5, LOW);
delay(3000);
digitalWrite(5, HIGH);
}
Dla tych co widzą delay zaznaczam, że to jest wersja demo.
 
Odpowiedź
#6
(03-03-2020, 10:04)Agregacik napisał(a): Tu masz wersję demo:
Kod:
byte p = 0;
unsigned long Zapamietany_Czas = 0;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
}

void loop()
{
  if (digitalRead(2) == LOW)
  {
    delay(50);
    if (digitalRead(2) == LOW && p == 0)
    {
      Zapamietany_Czas = millis();
      p = 1;
    }
  }
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas < 2000UL)
  {
    inpuls_na_4();
    p = 0;
  }
 
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas > 2000UL)
  {
    inpuls_na_5();
    p = 0;
  }
   
}

void inpuls_na_4()
{
digitalWrite(4, LOW);
delay(3000);
digitalWrite(4, HIGH);
}

void inpuls_na_5()
{
digitalWrite(5, LOW);
delay(3000);
digitalWrite(5, HIGH);
}
Dla tych co widzą delay zaznaczam, że to jest wersja demo.
Jutro przetestuje. Muszę tylko złożyć układ. Napisze co i jak.
 
Odpowiedź
#7
(03-03-2020, 19:52)OMK napisał(a):
(03-03-2020, 10:04)Agregacik napisał(a): Tu masz wersję demo:
Kod:
byte p = 0;
unsigned long Zapamietany_Czas = 0;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
}

void loop()
{
  if (digitalRead(2) == LOW)
  {
    delay(50);
    if (digitalRead(2) == LOW && p == 0)
    {
      Zapamietany_Czas = millis();
      p = 1;
    }
  }
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas < 2000UL)
  {
    inpuls_na_4();
    p = 0;
  }
 
  if(p == 1 && digitalRead(2) == HIGH && millis() - Zapamietany_Czas > 2000UL)
  {
    inpuls_na_5();
    p = 0;
  }
   
}

void inpuls_na_4()
{
digitalWrite(4, LOW);
delay(3000);
digitalWrite(4, HIGH);
}

void inpuls_na_5()
{
digitalWrite(5, LOW);
delay(3000);
digitalWrite(5, HIGH);
}
Dla tych co widzą delay zaznaczam, że to jest wersja demo.
Jutro przetestuje. Muszę tylko złożyć układ. Napisze co i jak.
Działa jak chciałem. Super. WIELKIE dzięki. Pozdrawiam!
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości