Elektro zámok

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Elektro zámok

Příspěvek od Sperhak » 09 čer 2020, 14:36

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;
}

Uživatelský avatar
kiRRow
Příspěvky: 1164
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Elektro zámok

Příspěvek od kiRRow » 09 čer 2020, 15:07

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 :)

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Elektro zámok

Příspěvek od Sperhak » 09 čer 2020, 15:20

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ú?

Uživatelský avatar
kiRRow
Příspěvky: 1164
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Elektro zámok

Příspěvek od kiRRow » 09 čer 2020, 15:28

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

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Elektro zámok

Příspěvek od martinius96 » 09 čer 2020, 15:31

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.

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Elektro zámok

Příspěvek od Sperhak » 09 čer 2020, 16:13

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;
}

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Elektro zámok

Příspěvek od Sperhak » 10 čer 2020, 15:40

Tak som nad tým strávil ďalšie 3 hodiny a na nič som neprišiel, kašlem nato.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Elektro zámok

Příspěvek od martinius96 » 10 čer 2020, 17:13

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

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Elektro zámok

Příspěvek od Sperhak » 10 čer 2020, 18:21

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.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Elektro zámok

Příspěvek od martinius96 » 10 čer 2020, 18:43

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ť..

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: luger a 12 hostů