Hogyan kell a megszakításokat használni?

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 4. szombat, 17:05

Sziasztok, segítségeteket szeretném kérni az alábbiakban: Szeretnék egy olyan programot írni, mely alaphelyzetben három darab színes izzót felkapcsolva tart és egy nyomógomb megnyomását követően meghív egy általam megírt függvényt. A nyomógomb 2. megnyomását követően pedig meghív egy másik függvényt és az előző futását leállítja. A nyomógomb 3. megnyomására pedig visszaáll az alaphelyzetbe. A meghívott függvények a feladata csupán relék különböző sorrendben és számban való kapcsolása (a relék segítségével kapcsolgatom az izzókra a feszültséget), ezenkívül a kapcsolgatás sebességét egy potenciométerrel lehet szabályozni. A potenciométer beolvasott értéke egy adott szint alá csökken, akkor pedig folyamatosan meghúzva tartanak a relék addig, amíg nem éri el a megfelelő értéket. A potenciométer érékével megegyező késleltetést sikerült megcsinálnom, de a nyomógombos rész többszörös próbálkozás után se lett jó. Itt a jelenleg működő nyomógomb nélküli programom:

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int PotVal = 1023;

void setup() {
  Serial.begin(9600);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
}

void loop() {

 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);

 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
}


A problémát megszakításokkal próbáltam megoldani, de nem egészen értem, hogy működnek ezek. :?:

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9902
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: Robert » 2017. november 4. szombat, 18:53

Ún állapotgép.

Az int rutinban jegyzed, hogy hányas alprogramban kellene lenned. Gyakorlatilag egy számlálót léptetsz.
És itt bebillentesz egy jelzőbitet, hogy INT volt és változott a programszámláló.
A loopban:
if változas van ->
if alprogram==1....
if alprogram==2....
if alprogram==3....
if alprogram==4....
valtozasvan =0
if vege
http://www.tavir.hu - a gazda :)

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 5. vasárnap, 11:30

Köszönöm a választ. Megpróbáltam úgy, ahogy leírtad és addig sikerült eljutnom, hogy a nyomógomb megnyomását követően elindul az első alprogram. De a nyomógombot, ha még egyszer megnyomom nem lép a következő alprogramba, hanem ugyan ott marad. (A programot egy darab nyomógomb híján, csak simulator-ban teszteltem.)

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int PotVal = 1023;
int modeval = 0;
const int GombPIN = 2;
int GombVal = 0;
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(9600);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT);
}

void loop() {
  switch (state) {
case mode:
GombVal = digitalRead(GombPIN);
if (GombVal == HIGH) {
  delay (200);
  modeval++;
  if (modeval == 1) {
    state = mode1;
  }
  if (modeval == 2) {
    state = mode2;
  }
  if (modeval == 3) {
    modeval = 0;
    state = mode;
  }
}
break;
case mode1:
a:
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
goto a;
case mode2:
b:
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
 goto b;
}
}

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9902
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: Robert » 2017. november 5. vasárnap, 12:09

Nem a láb állapotot figyeled, hanem:
És itt bebillentesz egy jelzőbitet, hogy INT volt és változott a programszámláló.


Ja és INTERRUPT-ot használsz, nem gombfigyelést!

Minta:

Kód: Egész kijelölése

const byte ledPin = 13;
 const byte interruptPin = 2;
 volatile byte state = LOW;

void setup() {
   pinMode(ledPin, OUTPUT);
   pinMode(interruptPin, INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
   digitalWrite(ledPin, state);
}

void blink() {
   state = !state;
}
http://www.tavir.hu - a gazda :)

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 6. hétfő, 17:06

Keresgéltem interneten mi is ez a jelzőbit és, hogy kell ezt „bebillenteni”, de nem találtam róla semmit. Kezdőként számomra a válaszod egy kissé érthetetlen. Tudnál egy részletesebb leírást készíteni erről, (persze csak ha nem probléma)? Továbbá az INTERRUPT-ról már ugyan olvastam, de azért elég hiányosak az ismereteim, hogy is működik ez. Ezenkívül észrevettem ezt a témát rossz helyen kezdtem el, szóval nem tudom hogy, ez nagy probléma? :(

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9902
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: Robert » 2017. november 6. hétfő, 18:13

Jelzőbit:
Létrehozol egy változót ami 0 értékű, ha nem volt int rutinban; és 1-es értéket adsz neki, amikor beléptél...
Amikor feldolgozod a loop()-ban, akkor ezzel nézed, hogy volt-e INT.
http://www.tavir.hu - a gazda :)

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 6. hétfő, 20:34

Létrehoztam egy változót modeval és az értékét beállítottam nullára. Amikor belépek a blink5-be növelem az értékét 1-el, az értéket pedig visszaadom a főprogramnak. A változó értéke nagyobb mint 2 akkor lenullázom, de kaptam egy hibaüzenetet:

Kód: Egész kijelölése

In function 'void blink5()':
warning: return-statement with a value, in function returning 'void' [-fpermissive]
   return modeval;

A program:

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int PotVal = 1023;
int modeval = 0;
const int GombPIN = 2;
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(9600);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GombPIN), blink5, FALLING);
}

void loop() {
  switch (state) {
case mode:
if (modeval == 0) {
  digitalWrite(pirosLED, LOW);
  digitalWrite(zoldLED, LOW);
  digitalWrite(kekLED, LOW);
  if (modeval == 1) {
    state = mode1;
  }
  if (modeval == 2) {
    state = mode2;
  }
  if (modeval == 3) {
    modeval = 0;
    state = mode;
  }
}
break;
case mode1:
a:
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
goto a;
case mode2:
b:
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
 goto b;
}
}
void blink5() {
  modeval++;
  if (modeval > 2) {
    modeval = 0;
  }
  return modeval;
}

Avatar
csegebiga
Chipgyilok
Hozzászólások: 278
Csatlakozott: 2015. március 27. péntek, 21:27

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: csegebiga » 2017. november 6. hétfő, 23:26

Void fügvénynek lehet return értéke?
Szerintem nem.
Returnnal a függvény belső változöi egyikének értékét adod meg visszatérő értéknek. Méghozzá olyan tipusú, amilyen a void helyére írtál.
Ha globális változót használsz, (és itt azt használsz) akkor nem kell return, hanem az értékadásnál már változik az érték.
Szebb lehet, ha a globális változók helyett lokális változókat használsz és a függvény paraméterében adod meg a bemenő értéket, és a returnon keresztül viszed vissza az eredményt.

Kód: Egész kijelölése

//a függvény
 int negacio (int bemeno)
  {
  . kimeno=bemeno*(-1);
  . return kimeno;
  }
 
  //meghívása
  ertek=negacio(parameter);

A függvényen belüli változók nem élnek a függvényen kivül, spórolva a változóterülettel.
Hibakeresésnél, debuggoláskor nem kell bogarászni, ki hol nyúlt a globális változóhoz?
Minden a függvényben történik.


ui:a 60napossal hol tartasz?

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 7. kedd, 18:21

Próbáltam az általad leírt lokális változót, de mindig ugyanazt a hibaüzenetet kaptam :(, de ha minden igaz erre itt nincs is feltétlenül szükség, ezért maradok a globális változónál. Így visszatérési érték nélkül most már úgy működik a program, ahogyan azt szerettem volna(igaz egy kis késedelemmel), egyébként jelenleg az 5. résznél tartok a 60 naposba, de egy keveset az elkezdése előtt már foglalkoztam az arduino programozásával.
A program:

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int modeval;
int PotVal = 1023;
const int GombPIN = 2;
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(9600);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GombPIN), blink5, FALLING);
}

void loop() {
  switch (state) {
case mode:
if (modeval == 0) {
  digitalWrite(pirosLED, HIGH);
  digitalWrite(zoldLED, HIGH);
  digitalWrite(kekLED, HIGH);
  if (modeval == 1) {
    state = mode1;
  }
  if (modeval == 2) {
    state = mode2;
  }
  if (modeval == 3) {
    modeval = 0;
    state = mode;
  }
}
break;
case mode1:
    a:
    if (modeval == 2) {
      goto b;
    }
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
case mode2:
    b:
    if (modeval == 1) {
      goto a;
    }
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
}
}
void blink5() {
  modeval++;
  if (modeval > 2) {
    modeval = 0;
  }
}

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 9. csütörtök, 16:54

Újabb problémába ütköztem, ugye pár sorral feljebb említettem már, hogy a programot nyomógomb híján csak „simulatorban” emulátorban tesztelem. Nemrég szereztem be nyomógombot, úgyhogy összeépítettem az áramkört a programhoz, de az alaphelyzetből nem lép ki, nem reagál semmire. A feltöltéskor nem irt ki semmi hibát. Mi lehet a gond?

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int modeval;
int PotVal = 1023;
const int GombPIN = 2;
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(9600);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GombPIN), blink5, FALLING);
}

void loop() {
  switch (state) {
case mode:
    c:
if (modeval == 0) {
  digitalWrite(pirosLED, HIGH);
  digitalWrite(zoldLED, HIGH);
  digitalWrite(kekLED, HIGH);
  if (modeval == 1) {
    state = mode1;
  }
  if (modeval == 2) {
    state = mode2;
  }
  if (modeval == 3) {
    modeval = 0;
    state = mode;
  }
}
break;
case mode1:
    a:
    if (modeval == 2) {
      state = mode2;
      goto b;
    }
    if (modeval == 0) {
      goto c;
    }
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
case mode2:
    b:
    if (modeval == 1) {
      state = mode1;
      goto a;
    }
    if (modeval == 0) {
      goto c;
    }
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 delay(PotVal);
}
}
void blink5() {
  modeval++;
  if (modeval > 2) {
    modeval = 0;
  }
}

Avatar
csegebiga
Chipgyilok
Hozzászólások: 278
Csatlakozott: 2015. március 27. péntek, 21:27

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: csegebiga » 2017. november 11. szombat, 21:29

Most lenne jó látni, hogy milyen kapcsolást használsz.
A megszakításodat a GombPin (2) láb H-ból L-be váltására állítottad be. (falling)
Ebből következik, hogy
- a nyugalmi állapot a H szint, a kapcsoló megnyomása L szintet kell okozzon.
- a 2. pin stabil H szintjéhez a táp 5 V-ról egy felhúzó-ellenállással a lábat fel kell húzni H szintre.
- a nyomógomb a 2. pin és a GND közé kerül, és kapcsol L szintet a lábra ha megnyomod.
innentől a gomb megnyomására kellene reagálnia a programnak, ha a szimulátor szerint menne.

Ui: milyen szimulátort használsz?

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 12. vasárnap, 16:05

Már rájöttem a megoldásra, a void loop után az if elágazások előtt ki kellett íratnom a modeval értékét. Ezután a következő probléma az volt, hogy bár tudtam modot váltani, de nem sorrendbe, össze-vissza vissza ugrált a program. A gomb pergése volt a gond, utánanéztem, hogyan lehetne ezt kiküszöbölni. Találtam hardveres és szoftveres megoldásokat is. A hardveres megoldást választottam és abból is a legegyszerűbbet. A nyomógombbal párhuzamosan kötöttem egy kondenzátort, amivel a gomb pergése közben keletkezett rezgéseket elnyeltem. Így most működik, már csak szépíteni kell, meg persze ez csak egy alap majd szeretném bővíteni is (dimmelés, több kimenet és mod) persze dimmelésnél el kell felejteni a reléket és gondolkoztam azon is, hogy rendelek címezhető Led szalagot, de akkor az egész programot át kéne alakítani… Sok lehetőség van, amivel lehetne cifrázni ezt (pl.: lehetne egy olyan mod is, amikor zenére villog). Az egyetlen, ami jelenleg lehetetlené teszi a megvalósítását számomra az a megfelelő képzettség „tudás” hiánya. Na de ahogy írtam a jelenlegi „kész” programot kellene szépíteni, mert szerintem sok felesleges dolog van bent és gondolom, vannak egyszerűbb megoldások, is, mint amit én használtam, ebben kérnék kis segítséget, ha valaki tud egyszerűbb megoldás egy-egy részre, egy rövid magyarázattal egybekötve, ha ráér, leírhatná nekem.

Egy online szimulátort használok, a weboldal (főleg 3D tervezéshez van, de van egy rész az arduinohoz is):
https://www.tinkercad.com/

A kapcsolási rajz:
https://kephost.com/images/2017/11/12/kapcsolas.png

A program:

Kód: Egész kijelölése

int pirosLED = 8;
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int modeval;
int PotVal = 1023;
const int GombPIN = 2;
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(19200);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GombPIN), blink5, FALLING);
}

void loop() {
  switch (state) {
    case mode:
    c:
    Serial.println(modeval);
    delay(50);
  if (modeval == 1) {
    state = mode1;
  }
  if (modeval == 2) {
    state = mode2;
  }
  if (modeval == 3) {
    modeval = 0;
    state = mode;
  }
  if (modeval == 0) {
  digitalWrite(pirosLED, LOW);
  digitalWrite(zoldLED, LOW);
  digitalWrite(kekLED, LOW);
}
break;
case mode1:
    if (modeval != 1) {
      goto c;
    }
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
 if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
delay(PotVal);
case mode2:
    if (modeval != 2) {
      goto c;
    }
 digitalWrite(pirosLED, HIGH);
 digitalWrite(zoldLED, HIGH);
 digitalWrite(kekLED, HIGH);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 Serial.println(PotVal);
 delay(PotVal);
  digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
 PotVal = analogRead(potPIN);
  if (PotVal < 100) {
  while(PotVal < 100) {
     PotVal = analogRead(potPIN);
 digitalWrite(pirosLED, LOW);
 digitalWrite(zoldLED, LOW);
 digitalWrite(kekLED, LOW);
  }
 }
 delay(PotVal);
}
}
void blink5() {
  digitalWrite(pirosLED, HIGH);
  digitalWrite(zoldLED, HIGH);
  digitalWrite(kekLED, HIGH);
  modeval++;
  if (modeval > 2) {
    modeval = 0;
  }
}

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3228
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: kapu48 » 2017. november 12. vasárnap, 17:56

Akkor pár jó tanács!

Figyelj oda jobban a sorok előtti tördelésre!
Ezek arra szolgálnak, hogy jobban olvasható legyen a programod.
Láthatóvá teszik mettől{ ... meddig} tar 1 blokk.
Nagyban megkönnyítik a munkát, és a hiba keresést.

És a programod javítása:

Kód: Egész kijelölése

int pirosLED = 8; //
int zoldLED = 4;
int kekLED = 7;
int potPIN = A0;
int modeval;
int PotVal = 1023;
const int GombPIN = 2;
// Gond lehet a név választással!
// Mert "mode, state" védet szavak!
// Felhivjará a figyelmedet a szerkesztő a nevek barnára szinezésével.
// Az ilyeneket jobb kerülni, mert később esetleg hibajelzést okozhatna!
// Szerintem modosíts pl.: Mode, State ?
enum estate {mode, mode1, mode2};
estate state = mode;

void setup() {
  Serial.begin(19200);
  pinMode(pirosLED, OUTPUT);
  pinMode(zoldLED, OUTPUT);
  pinMode(kekLED, OUTPUT);
  pinMode(GombPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GombPIN), blink5, FALLING);
}

void loop() {
  c: // Ugorj ide!
  switch (state) {
    case mode:
      //c:    // Ide nem ugorhatsz be! mert halytelen az egész
      Serial.println(modeval);
      delay(50);
      if (modeval == 1) {
        state = mode1;
      }
      if (modeval == 2) {
        state = mode2;
      }
      if (modeval == 3) {
        modeval = 0;
        state = mode;
      }
      if (modeval == 0) {
        digitalWrite(pirosLED, LOW);
        digitalWrite(zoldLED, LOW);
        digitalWrite(kekLED, LOW);
         }      // az if nem lett lez�rva   
    break;
    case mode1:
      if (modeval != 1) {
        goto c;         // ez az ugras helytelen! mert mode1 esetén visszaugrik a mode ágba!
      }
      digitalWrite(pirosLED, LOW);
      digitalWrite(zoldLED, HIGH);
      digitalWrite(kekLED, HIGH);
      PotVal = analogRead(potPIN);
      if (PotVal < 100) {
        while(PotVal < 100) {
          PotVal = analogRead(potPIN);
          digitalWrite(pirosLED, LOW);
          digitalWrite(zoldLED, LOW);
          digitalWrite(kekLED, LOW);
        }
      }
      Serial.println(PotVal);
      delay(PotVal);
      digitalWrite(pirosLED, HIGH);
      digitalWrite(zoldLED, LOW);
      digitalWrite(kekLED, HIGH);
      PotVal = analogRead(potPIN);
      if (PotVal < 100) {
        while(PotVal < 100) {
          PotVal = analogRead(potPIN);
          digitalWrite(pirosLED, LOW);
          digitalWrite(zoldLED, LOW);
          digitalWrite(kekLED, LOW);
        }
      }
      Serial.println(PotVal);
      delay(PotVal);
      digitalWrite(pirosLED, HIGH);
      digitalWrite(zoldLED, HIGH);
      digitalWrite(kekLED, LOW);
      PotVal = analogRead(potPIN);
      if (PotVal < 100) {
        while(PotVal < 100) {
          PotVal = analogRead(potPIN);
          digitalWrite(pirosLED, LOW);
          digitalWrite(zoldLED, LOW);
          digitalWrite(kekLED, LOW);
        }
      }
      Serial.println(PotVal);
      delay(PotVal);
      break;         // Kimaradt a break!   
    case mode2:
      if (modeval != 2) {
        goto c;      // ez az ugr�s helytelen! mert mode2 eset�n visszaugrik a mode �gba!
      }
      digitalWrite(pirosLED, HIGH);
      digitalWrite(zoldLED, HIGH);
      digitalWrite(kekLED, HIGH);
      PotVal = analogRead(potPIN);
      if (PotVal < 100) {
        while(PotVal < 100) {
          PotVal = analogRead(potPIN);
          digitalWrite(pirosLED, LOW);
          digitalWrite(zoldLED, LOW);
          digitalWrite(kekLED, LOW);
        }
      }
      Serial.println(PotVal);
      delay(PotVal);
      digitalWrite(pirosLED, LOW);
      digitalWrite(zoldLED, LOW);
      digitalWrite(kekLED, LOW);
      PotVal = analogRead(potPIN);
      if (PotVal < 100) {
        while(PotVal < 100) {
          PotVal = analogRead(potPIN);
          digitalWrite(pirosLED, LOW);
          digitalWrite(zoldLED, LOW);
          digitalWrite(kekLED, LOW);
        }
      }
      delay(PotVal);
      break;         // Kimaradt a break!   Itt Már csak az olvashatóság kedvéért   
  }
   
}

void blink5() {
  digitalWrite(pirosLED, HIGH);
  digitalWrite(zoldLED, HIGH);
  digitalWrite(kekLED, HIGH);
  modeval++;
  if (modeval > 2) {
    modeval = 0;
  }
}

learner
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. november 4. szombat, 16:41

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: learner » 2017. november 12. vasárnap, 20:41

Köszönöm a tanácsokat, kijavítottam mindent amit írtál és helytelen ugrások helyett pedig while ciklust használtam. :)

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9902
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: Hogyan kell a megszakításokat használni?

HozzászólásSzerző: Robert » 2017. november 13. hétfő, 3:44

A kapcsolási rajzon a LED-ek közös pontjára 3.3V tápfeszt adsz, nem 5V-ot!

A program:
GOTO-t lehetőleg ne használj (nem lesz jól követhető a program), valamint a memória elfogyhat, ha később void()-ból ugrasz ki...(Nem szabadítja fel a lokális memóriafoglalást.)
http://www.tavir.hu - a gazda :)


Vissza: “Bascom-AVR nyelvű programozás (AVR programozásának lehetőségei)”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 1 vendég