Prepnutie medzi funkciami jedným tlačidlom

Sekcia určená pre Arduino nadšencov

Moderátor: Moderátori

martinius96

Prepnutie medzi funkciami jedným tlačidlom

Príspevok od používateľa martinius96 » 21 Jún 2017, 00:39

Ahojte, potreboval by som pomôcť s takýmto problémom. Programujem Arduino s využitím jedného tlačidla, ktoré bude plniť funkciu spustenie a vypnutia spotrebiča. Realizuje sa to relátkami, ktoré sa spúšťajú tak, ako ja potrebujem.
Fungovanie: Po prvom stlačení sa spustí funkcie spustenie(). Ak počas nej, alebo po nej stlačím tlačidlo, spustí sa funkcia vypnutie(). Počas funkcie vypnutie tlačidlo nefunguje(nereaguje na stlačenia.) Po vykonaní funkcie vypnutie() a následnom tlačení tlačidla sa začne opäť vykonávať funkcia spustenie().
To, čo je popísané vyššie funguje okrem prepnutia počas funkcie spustenie() na funkciu vypnutie. V kóde využívam attachInterrupt na pine D2 na Arduine UNO. Celé som to nahral online, kde je možné prezrieť kód a odtestovať riešenie aj v simulátore. Bol by som vám veľmi vďačný! Myslím si, že problém bude iba v delayoch, je možné to poupraviť aby to fungovalo s existujúcim kódom to plynulé prepínanie počas funkcie?
Stránka so simulátorom a kódom: https://circuits.io/circuits/5029269-attachinterrupt/

Kód: Vybrať všetko

int led = 6;
int rele1 = 3;
int rele2 = 4;
int rele3 = 5;
int ButtonState=LOW;
long LastPushTime=0;
long PushTime=0;
int pocitadlo=0;
 
// the setup routine runs once when you press reset:
void setup() {
 
  Serial.begin(9600);
  // initialize the digital pin as an output.
  analogReference(INTERNAL);
  pinMode(led, OUTPUT);
    pinMode(rele1,OUTPUT);
  pinMode(rele2 ,OUTPUT);
  pinMode(rele3  ,OUTPUT);
  attachInterrupt(0,PushButton,CHANGE);


}
 
 
 
void spustenie(){
  //FUNKCIA PROCESU SPUSTENIA
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, LOW);
  digitalWrite(rele3, LOW);
  for(int i=0; i<5; i++){
    Serial.print(i);
    Serial.print(". ");
    Serial.println("cyklus prveho foru spustenia");
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
    delay(500);
  }
 
 
  for(int i=0; i<30; i++){
    Serial.print(i);
    Serial.print(". ");
    Serial.println("cyklus druheho foru spustenia");
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
    delay(500);
  }
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, HIGH);
  digitalWrite(rele3, LOW);
  for(int i=0; i<15; i++){
   Serial.print(i);
    Serial.print(". ");
    Serial.println("cyklus posledneho foru spustenie");
   
    digitalWrite(led, HIGH);
    delay(250);
    digitalWrite(led, LOW);
    delay(250);
  }
  Serial.println("Za poslednym for spustenie");
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, HIGH);
  digitalWrite(rele3, HIGH);
  digitalWrite(led, HIGH);
  }
 

 
void vypnutie(){ //FUNKCIA PROCESU VYPNUTIA
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, HIGH);
  digitalWrite(rele3, LOW);
  for(int i=0; i<1; i++){
   Serial.print(i);
    Serial.print(". ");
    Serial.println("cyklus prveho foru vypnutie");
    digitalWrite(led, HIGH);
    delay(300);
    digitalWrite(led, LOW);
    delay(700);
  }
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, LOW);
  digitalWrite(rele3, LOW);
  for(int i=0; i<5; i++){
    Serial.print(i);
    Serial.print(". ");
    Serial.println("cyklus posledneho foru vypnutie");
    digitalWrite(led, HIGH);
    delay(300);
    digitalWrite(led, LOW);
    delay(700);
  }
  Serial.println("Vypnutie vsetkych LED, cakam na vstup z tlacidla");
  digitalWrite(rele1, LOW);
  digitalWrite(rele2, LOW);
  digitalWrite(rele3, LOW);
  digitalWrite(led, LOW);
}
 
 
// the loop routine runs over and over again forever:
void loop(){
  
}
 
void PushButton() {
  PushTime=millis()-LastPushTime;
  if(PushTime>150) {
    pocitadlo++;
  
 switch(pocitadlo)
    {
   case 1:
      spustenie();
    break;
    case 2:
    vypnutie();
    pocitadlo=0;
    break;
    }
 
   
 
   
   
 
  }
  LastPushTime=millis();
}

martin knocik
Ultimate člen
Ultimate člen
Príspevky: 1639
Dátum registrácie: 23 Jan 2008, 00:00
Bydlisko: Trenčianska Turná
Vek: 33
Kontaktovať používateľa:

Re: Prepnutie medzi funkciami jedným tlačidlom

Príspevok od používateľa martin knocik » 21 Jún 2017, 08:21

Funkcia pushbutton bezi v interrupt rutene a pokial neskonci pushbutton funkcia aj interrupt rutina, nie si schopny detekovat a obsluzit dalsi interrupt (musi dojst k vymazaniu interrupt flagov) V interuptovej rutine maju byt pokial je to mozne co najkratsie funkcie/najmenej prikazov - vacsinou len funkcie typu zmen stav pomocnej premennej/semaforu ze doslo k interruptu. Ak budes mat v interruptovej funkcii stovky milisekund trvajuce cakacie (wait) funkcie, tak premeskas interrupty.

Ak chces vylepsit program, daj do interruptovejvrutiny len zmenu pomocnej premennej, ktora ti bude indikovat ze doslo k stlaceniu tlacidla/pocet stlaceni tlacidla. Vv hlavnom slucke spustaj funkcie spustit a vypnut. Sprav si chytru wait funkciu ktora sa pocas cakania bude pytat pomocnej premennej ci nedoslo k interruptu, a ak ano, tak napr vyskoc z funkcie spustenie (pomocou return prikazu) a prejdi na nasledujucu funkciu vypnutie.
0
http://mkbci.com

FEL UNIZA 2015, Ing.

ľudstvo je vírus ktorý napadol Zem

nerobme si ťažkú hlavu z debilov čo nám ani po členky nesiahajú, buďme radi že my dačo dokážeme a smejme sa im akí sú sprostí

Používateľov profilový obrázok
budvar10
Pokročilý člen
Pokročilý člen
Príspevky: 986
Dátum registrácie: 15 Dec 2014, 10:55
Bydlisko: Košice

Re: Prepnutie medzi funkciami jedným tlačidlom

Príspevok od používateľa budvar10 » 21 Jún 2017, 08:33

Ja len dodám, že do ISR, ktorá by mala byť čo najkratšia, nemôžeš dávať funkcie, ktoré závisia na iných prerušeniach. V opačnom prípade ti program odvisne alebo sa môže dramaticky spomaliť alebo jednoducho "blbnúť". Takáto funkcia je napríklad Serial.print(), tá rozhodne nepatrí do interruptu.
0

martinius96

Re: Prepnutie medzi funkciami jedným tlačidlom

Príspevok od používateľa martinius96 » 28 Jún 2017, 14:52

Takže rozumiem tomu správne, že existujúci kód a kód podobných rozmerov nie je možné takýmto spôsobom prepínať? Iba napríklad ledku že state, !state správne?

Používateľov profilový obrázok
scd
Stály člen
Stály člen
Príspevky: 150
Dátum registrácie: 17 Apr 2009, 00:00
Bydlisko: Dubnica nad Váhom
Vek: 35

Re: Prepnutie medzi funkciami jedným tlačidlom

Príspevok od používateľa scd » 28 Jún 2017, 15:58

Kód aj oveľa väčších rozmerov je možné "prepínať", len ten tvoj kód nebude dobre fungovať. Ako ti už napísali obsluha prerušenia musí byť čo najkratšia, to znamená že v prerušení len meníš stavové premenné, a na základe ich hodnoty potom v hlavnej slučke rozhoduješ o ďalšom postupe v programe. Stavové premenné si predstav ako obyčajnú globálnu premennú napr. typu bool alebo int, do ktorej teda v prerušení zapíšeš napr. hodnotu TRUE, že bolo stlačené tlačidlo a v hlavnej slučke potom túto hodnotu prečítaš, nastavíš naspäť na FALSE a na základe stavu tej premennej a nejakom ďalšom stave programu rozhodneš či spustiť nejakú funkciu alebo niečo iné vykonať.
0
Keyboard not present. Press ENTER to continue...

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok