Stránka 1 z 4

Elektro zámok

Napsal: 09 čer 2020, 14:36
od Sperhak
Ahojte potreboval by som pomoc. Zasekol som sa na tlačítku. Potreboval by som: Stlačím tlačítko a držím ho, po 1,5s sa rozsvieti led, pustím tlačitko.
Stlačím to isté tlačítko držím ho 1,5s zhasne led, pustím tlačítko. Upravil som si tento kód čo som našiel na nete. Funguje to presne tak ako chcem, ale je tam jeden neduh. Stlačím tlačítko a držím ho, po 1,5s sa rozsvieti led, pustím tlačítko. Keď chcem znova stlačiť tlačítko aby led zhasla, musím počkať 1,5s teda ten nastavený čas a až potom mi to znova funguje. Čiže tlačítko musí byť 1,5s v klude nestlačené aby znova fungovalo. To by som tam nechcel mať. Vedeli by ste mi pomôcť.

Kód: Vybrat vše

// konstanty použité k nastavení čísel pinů se nezmění:
const int buttonPin = 10; // číslo pinu tlačítka
const int ledPin = 11; // číslo pinu LED
const int ledPin2 = 13;

// Proměnné se změní:
int ledState = HIGH; // současný stav výstupního pinu
int buttonState; //nejnovější hodnota načtená ze vstupního pinu
int lastButtonState = HIGH; // předchozí hodnota načtení ze vstupního pinu

// Následné proměnné jsou typu long, jelikož čas měřený v milisekundách se
//rychle změní na větší číslo, jež nemůže být uloženo v int
long lastDebounceTime = 0; // čas posledního změny výstupního pinu
long debounceDelay = 1500; // čas debounce prodlevy; pokud výstup bliká,
//je potřeba čas „zvětšit“

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);

  // nastavte počáteční stav LED
  digitalWrite(ledPin, ledState);
  digitalWrite(ledPin2, ledState);
}

void loop() {
  // Stav spínače přiřaďte do místní proměnné:
  int reading = digitalRead(buttonPin);

  // Zkontroluje, zda-li jste stlačili tlačítko
  // (tj. že vstup se z LOW změnil na HIGH), a od posledního zmáčknutí jste čekali
  // dostatečně dlouho na to, aby byl veškerý šum ignorován:

  // Pokud se spínač změnil kvůli šumu nebo stlačení:
  if (reading != lastButtonState) {
    // upravte proměnou lastDebounceTime
    lastDebounceTime = millis();
     
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // Ať už je načtená hodnota jakákoliv, byla tam déle než debounce prodleva,
    // berme ji tedy jako aktuální stav:

    // Pokud se stav tlačítka změnil:
    if (reading != buttonState) {
      buttonState = reading;

      // LED přepněte pouze když je nový stav tlačítka označen jako HIGH
      if (buttonState == LOW) {
        ledState = !ledState;


      }
    }
  }

  // nastavte LED:
  digitalWrite(ledPin, ledState);
  digitalWrite(ledPin2, ledState);

  // načtené hodnoty uložte. V příští smyčce bude označeno jako lastButtonState:
 lastButtonState = reading;
}

Re: Elektro zámok

Napsal: 09 čer 2020, 15:07
od kiRRow
Problém je v tom, že ty stav tlačítka prohlásíš za platný až po 1500 milivteřinách. Tenhle debounce příklad je o tom, aby tě naučil že jeden stisk čudlíku může být intepretován jako stisků několik a jak tohle eliminovat. Běžně se čudlík, či detektor dokáže uklidnit do 50ms, ale vždy je to jiné a chce to poladit.
Ty chceš, aby platný stav byl prohlášen za platný co nejdříve to jde, ne až po vteřině a půl. Pak začneš měřit nový čas a to čas stisku a držení tlačítka. A pokud naměřím, že se mi uklidnilo tlačítko, je zmáčknuté a už to trvá 1500ms, tak něco provedu :)

Re: Elektro zámok

Napsal: 09 čer 2020, 15:20
od Sperhak
Takže tento kód by som mal nechať tak ako som ho našiel na nete a namiesto ledState = !ledState; si dať nejaku svoju premennú?

Re: Elektro zámok

Napsal: 09 čer 2020, 15:28
od kiRRow

Kód: Vybrat vše

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // Ať už je načtená hodnota jakákoliv, byla tam déle než debounce prodleva,
    // berme ji tedy jako aktuální stav:
a pokud je tento aktuální stav zmáčknutý čudlík tak si zapíšu nový čas, později v programu testuji pokud je tento aktuální čas větší než > 1500 ms a zároveň je furt ten čudlík zmáčknutý ->tak něco udělám .... pokud chci aby se to udělalo jen jednou, poznamenám si že jsem to už udělal

Re: Elektro zámok

Napsal: 09 čer 2020, 15:31
od martinius96
Môžeš si urobiť napríklad doplnkovú premennú int stav;
pričom stav ak je 0, bude sa to riadiť v tom prvom režime... (Držanie) pokým sa rozsvieti LED + vtedy sa nastaví stav na 1.
Ak bude stav 1, budeš iba overovať, či došlo k stlačeniu, nemusíš čakať ďalších 1500ms ako doteraz + stav opäť nastavíš na 0.
Môžeš si to jednoducho spúšťať cez switch v loope, pričom premenná vo vetvení bude stav., aby sa ti spúšťal ten daný fragment kódu, ktorý potrebuješ pre jeden / druhý stav tvojej aplikácie.

Re: Elektro zámok

Napsal: 09 čer 2020, 16:13
od Sperhak
Skúsil som toto no nefunguje to dobre. Pridal som tam tú dalšiu premennú ako ste hovorili no asi to mám zle.

Kód: Vybrat vše

const int buttonPin = 10;
int buttonOut = 0;
int buttonState;
int lastButtonState = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 50;



const int ledPin = 13;
int ledState = HIGH;

long currentMillis = 0;
long cas1 = 1500;
long time1 = 0;
int a;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);


}

void loop() {


currentMillis = millis();



if (currentMillis - time1 > cas1 && buttonOut != a ) {
    time1 = currentMillis;
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
    a = buttonOut;
}


  
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
          buttonOut = !buttonOut;
      }
    }
  }  
  lastButtonState = reading;
}

Re: Elektro zámok

Napsal: 10 čer 2020, 15:40
od Sperhak
Tak som nad tým strávil ďalšie 3 hodiny a na nič som neprišiel, kašlem nato.

Re: Elektro zámok

Napsal: 10 čer 2020, 17:13
od martinius96
Ja som nad tým strávil 3 minúty :roll: Treba len skúšať a dostaneš sa do toho..
Ak to tlačidlo pre vypnutie budeš držať, respektíve stlačíš na menej ako 1500 ms, tak ti tú LED-ku opätovne nezapne. Reaguje to ihneď po privedení 5V na pin (počas stlačenia). Keďže mi nejde Arduino IDE, testoval som to len na ThinkerCAD-e. Zapojenie tlačidla klasicky v režime INPUT, spínané proti 5V s 10kohm rezistorom ku GND.

Kód: Vybrat vše

const int buttonPin = 10; // číslo pinu tlačítka
const int ledPin = 11; // číslo pinu LED
const int ledPin2 = 13;

long lastDebounceTime = 0;
long debounceDelay = 1500;
int buttonState1 = LOW;
int lastButtonState1 = HIGH;
unsigned long debounceInterval = 50;
unsigned long timer = 0;
unsigned long lastDebounceTime1 = 0;
int reading;
int rezim = 0;
void setup() {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop() {
  switch (rezim) {
    case 0:
      reading = digitalRead(buttonPin);
      Serial.println(reading);
      if (reading == HIGH) {
        timer = millis();
        reading = digitalRead(buttonPin);
        while (reading == HIGH) {
          reading = digitalRead(buttonPin);
          if (millis() - timer >= debounceDelay) {
            digitalWrite(ledPin2, HIGH);
            rezim = 1;
            Serial.println("LED ZAPNUTA");
            break;
          }
        }
      }
      break;
    default:
      reading = digitalRead(buttonPin);
      if (reading != lastButtonState1) {
        lastDebounceTime1 = millis();
      }
      if ((millis() - lastDebounceTime1) > debounceInterval) {
        if (reading != buttonState1) {
          buttonState1 = reading;
          if (buttonState1 == HIGH) {
            digitalWrite(ledPin2, LOW);
            rezim = 0;
            Serial.println("LED VYPNUTA");
          }
        }
      }
      lastButtonState1 = reading;
      break;
  }
}
Obrázek

Re: Elektro zámok

Napsal: 10 čer 2020, 18:21
od Sperhak
Ahoj vďaka za snahu, ale či 3minuty pre skúseného alebo 3 hodiny pre amatéra aj tak to nefunguje :D Resp. upravil som tvoj kód, lebo ja musím používať pullup. Úprava spočívala že som zreversoval všetky hodnoty pre buttonstate1 lastbuttonstate1 a reading a nešlo to (neviem či to je tak dobre). Tak som si zmenil zapojenie na skúšku na pulldown a dal som tvoj neupravený kód a aj tak to nejde ako má. Totižto zapínanie led asi funguje ako má, ale vypínanie je hneď netreba tlačítko držať 3 sekundy. Tak ma napadlo zmeniť unsigned long debounceInterval = 50; tiež na 1500, ale tam potom nastal ten problém čo je od začiatku.

Re: Elektro zámok

Napsal: 10 čer 2020, 18:43
od martinius96
Aha, tak ty to využívaš s externým pullupom, asi to máš na dlhšom kábli, inak by si využil interný PULLUP rezistor Arduina, ktorý by bol dostačujúci a definoval by si ho v pinMode ako INPUT_PULLUP.. To znamená, že všetko v programe je nutné urobiť naopak... z ACTIVE_HIGH signálu prechádzame na ACTIVE_LOW signál vstupu.
Potrebuješ teda všade v programe zmeniť HIGH na LOW (čo sa týka vstupu, nie signálu pre LED).
Potom ti to bude fungovať..