60 nap alatt Arduino #25-#26 - Megszakítás

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: macsek » 2012. augusztus 17. péntek, 11:29

Ez a mexakításos rész érdekes lesz :)

Közben két kérdés/elírásgyanús részt találtam:
Robert a #25 levélben írta:

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

/*for (long i=0;i<100;i++){
    /Serial.print("6");
  }  */
[...] A kódban a for-next ciklussal lehet időzíteni. Az nem használ semmit, csak sima számolást. A fordító nem tudja kioptimalizálni:).

Gondolom a BASCOMban lehet next, itt feltételezem csak a sima for-ra gondoltál.

A for-os késleltetés kioptimalizálhatatlansága mennyire tuti? Does recent GCC optimization default kill Butterfly delay?

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

HozzászólásSzerző: Robert » 2012. augusztus 17. péntek, 11:47

For-Next: Ok javítom:)
Én már csak így tanultam....

A fogalmazás nem volt a levélben teljesen pontos:
"Ha a for ciklusban van ciklusmag (legyen az bármi), akkor a fordító nem tudja kipotimalizálni. Üres ciklusmag esetén természetesen mintha ott sem lenne maga a ciklus."

Az eredti szövegben a következő bekezdés: "És miért van benn néhány karakter sorosporti kiírása? Nagyon egyszerű a válasz: 9600 bps adási sebesség esetén (~1 kbyte/sec) 1 karakter kiírása: 1 msec időt vesz igénybe!"


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

for (long i=0;i<1250000;i++){
    //Serial.print("6");
    asm volatile ("nop"::);
  } 

ekkor a késleltetés ~1,5-2 sec-t eredményez. Azaz a NOP-t nem veszi észre a fordító (Arduino-0022). -> Elírtam! A //Serial.print("6"); ugye kimarad és a NOP-t nem mint üres utasítást kezeli a fordító! Hanem mint tényleges valamit is csináló utasítást...

C specifikus dolog: A NOP egyetlen esetben kerül ki az utasításokból optimalizálás alatt, ha a GCC fordítót a legdurvább optimalizációra (o0) kényszerítjük!
1.0 alatt tesztelni kell.


U.i.: Irgumburgum, hogy ilyen t@kéletlen az arduino, bár a felhasználó minek is akarna az INT-be várakozást tenni.... :P
A hozzászólást 1 alkalommal szerkesztették, utoljára Robert 2012. augusztus 17. péntek, 13:01-kor.

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

HozzászólásSzerző: Robert » 2012. augusztus 17. péntek, 11:58

Arduino 1.0 alatt is megy az ASM-NOP késleltetés...

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. augusztus 17. péntek, 12:44

Robert írta:És miért van benn néhány karakter sorosporti kiírása? Nagyon egyszerű a válasz: 9600 bps adási sebesség esetén (~1 kbyte/sec) 1 karakter kiírása: 1 msec időt vesz igénybe!

Ez tökre tetszett

Robert írta:

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

for (long i=0;i<1250000;i++){
    //Serial.print("6");
    asm volatile ("nop"::);
  } 

ekkor a késleltetés ~1,5-2 sec-t eredményez. Azaz a NOP-t nem veszi észre a fordító


Találtam egy jópofa megoldást a stackoverflow-n:

an interesting idea... Instead of adding a nop instruction at the inner loop, I tried adding an empty assembly code in there, like this:

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

unsigned char i, j;
j = 0;
while(--j) {
    i = 0;
    while(--i)
        asm("");
}

And it worked! That loop has not been optimized-out, and no extra nop instructions were inserted.
[...]
Update: If you are compiling code using -ansi or -std, you must replace the asm keyword with __asm__, as described in GCC documentation.

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

HozzászólásSzerző: Robert » 2012. augusztus 18. szombat, 13:14

Na, megint összevonások C oldalról:)
Mit jelent kifejtve?

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

While (i--) {
}


Az üres ASM mit jelent?

peterk79
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2013. augusztus 8. csütörtök, 6:41

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: peterk79 » 2013. augusztus 9. péntek, 9:19

Talán még nem túl késő hozzászólni...
A 25. sz lecke Bug or Feature példája esetében nem igazán látom az interrupt-ot kiváltó eseményt :(
Az arduino.cc szerint az attachInterrupt(interrupt,function,mode) használata esetén az interrupt nem pin-t jelöl, hanem egy int-et (gondolom a megszakítás száma).

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

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: Robert » 2013. augusztus 9. péntek, 9:40

INT0 - D2 kivezetés
INT1 - D3 kivezetés


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

/*  Interrupt
    es a csavarok...   
    60 nap alatt arduino tanfolyam
    (c) TavIR http://www.tavir.hu  */

 
#include "LiquidCrystal.h"
// A LiquidCrystal eljarast hasznaljuk
 
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
// Az LCD bekotese labak szerint:
// RS(D4), E(D5), D4(D6) ,D5(D7), D6(D8), D7(D9)
 
int pin = 13;
volatile int state = LOW;
 
void setup()
{   //Az LCD hattervilagitas a D13
  pinMode(pin, OUTPUT);
    // Hatter bekapcsol
  digitalWrite(pin, HIGH);
    //Megszakitaskezeles
  attachInterrupt(1, blink, FALLING);   //<- Itt az INT kezelése
    //Sorosport inicializálás
  Serial.begin(9600);
    //Az LCD 2 sor, 16 oszlopos
  lcd.begin(16, 2);
}
 
void loop()
{  //interruptok ki/bekapcsolasa
   interrupts();
   //noInterrupts();
  delay(1000);
  Serial.println ("Foprogram");
}
 
void blink()
{ lcd.setCursor(0, 0);
    //A kiiras helye: 0. oszlop, 0. sor
  lcd.print(millis());
    //eltelt masodperc a bekapcsolas ota
  Serial.print("1");
  delayMicroseconds(65000);
  Serial.print("2");
  delay(1000);
  Serial.print("3");
  state = !state;
  /*for (long i=0;i
    //1 karakter soros kiirasa
    //Serial.print("6");
      //1 orajelnyi semmitteves
    //asm volatile ("nop"::);
  }  */
  Serial.println("7");
  lcd.setCursor(8, 0);
  //A kiiras helye: 0. oszlop, 0. sor
  lcd.print(millis());
  //eltelt masodperc a bekapcsolas ota
}

holex
Biztosítékgyilkos
Hozzászólások: 70
Csatlakozott: 2013. október 29. kedd, 1:35

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: holex » 2013. november 13. szerda, 19:23

Mik ez előnyei és a hátrányai, ha külső megszakítások helyett PinChange megszakításokat használunk? Minden érdekel :)

Avatar
csabeszq
Bitfaragó
Hozzászólások: 664
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: csabeszq » 2013. november 13. szerda, 20:15

Azt INT0-INT1 külön megszakítás, a legmagasabb prioritással, a PCINT közvetlen utána jön (ahány port van, pl. PCINT B, PCINT C, PCINT D).

A PCINT kizárólag változásérzékelésre való, az INT0-INT1 beállítható fel/lefutó élre is.

Ha engem személyesen megkérdezel, INT0-t és INT1-et még sosem használtam. Ennek oka az, hogy tervezésnél hatalmas előny, hogy kiválasztasz egy lábat, amelyik éppen szabad és arra kötöd rá.
Nem kell baromkodni, hogy most éppen mit hova kötsz és kettőnél több vezetéken is interruptolhatsz.

Ameddig ténylegesen nincs szükségem az INT0, INT1 vonalakra, addig PCINT-ezek, oda kötöm, ahol a NYÁK könnyebben drótozható.

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

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: Robert » 2013. november 13. szerda, 20:38

PCINT csak a második generációs AVR-eken van!
Nincs a Mega8-on, 16-n, 32-n, Mega128-on....


A PCINT a lefutó _és_ a felfutó élre is ad INT-et és _lábcsoportonként_. Itt a kiválasztás, lábkiválasztás a TE feladatod.
Az INT0/1/2... pedig beállíthatóan: csak felfutó, csak lefutó, csak LowLevel (folyamatos INT).
Illetve az energiatakarékos módoknál mintha a PCINT nem játszana, csak a INTx.

holex
Biztosítékgyilkos
Hozzászólások: 70
Csatlakozott: 2013. október 29. kedd, 1:35

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: holex » 2013. november 13. szerda, 20:44

Köszönöm! És a PCInt-hez melyik library-t ajánljátok? Találtam többet is. Meg ez a lábcsoportos dolog hogy is van? Ezt nem igazán értem.

Avatar
csabeszq
Bitfaragó
Hozzászólások: 664
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: csabeszq » 2013. november 13. szerda, 21:23

Az Arduino nem használja a PCINT-et alapból. Én azért nem az INT0-INT1-et használom, mert C-ben programozok és nem Arduinoban.

Gondolom Arduino alatt a többség ezt a két vonalat használja interruptra, mert ez támogatott. Elvileg hardver szinten mindkettő tökéletes megoldást ad sok problémára, az INT0-INT1 javára az Arduino keret dönt.

Letöltesz egy library-t, ami szimpatikus és kipróbálod, vagy te is INT0-INT1-et használsz. A library-k elrejtik előled a lábcsoportokat, belülről lekezelik.

Avatar
scalesman
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2010. augusztus 31. kedd, 6:00

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: scalesman » 2014. március 27. csütörtök, 22:15

Sziasztok,

Kipróbáltam az Arduino tanfolyam 25. leckéjében található megszakításkezeléses minta programot a for ciklussal, de nekem nem igazán működik , az LCD kijelzőn mindkét millis() függvény ugyanazt az értéket jeleníti meg. De azzal sem vagyok tisztába, hogy akkor a kódba csak be kell építeni a nyomógomb kezelését, amely az interruptot generálja, vagy nem? Ezzel a kóddal próbálkoztam:
void setup()
{   //Az LCD hattervilagitas a D13
  pinMode(pin, OUTPUT);
  pinMode(3,INPUT); // GOMB foldfele
  digitalWrite(3,HIGH); // Felhuzoellenallas bekapcsolasa
  // Hatter bekapcsol
  digitalWrite(pin, HIGH);
  //Megszakitaskezeles
  attachInterrupt(1, blink, FALLING); // INT1 -->D3
  //Sorosport inicializálás
  Serial.begin(9600);
  //Az LCD 2 sor, 16 oszlopos
  lcd.begin(16, 2);
}

void loop()
{  //interruptok ki/bekapcsolasa
  interrupts();
  //noInterrupts();
  delay(1000);
  Serial.println ("Foprogram");
}

void blink()

  lcd.setCursor(0, 0);
  //A kiiras helye: 0. oszlop, 0. sor
  lcd.print(millis());
  Serial.println(millis());
  //eltelt masodperc a bekapcsolas ota
  Serial.print("1");
  delayMicroseconds(65000);
  Serial.print("2");
  delay(10000);
  Serial.print("3");
  state = !state;
  digitalWrite(pin, state);
  int i;
  for (i = 0; i < 1000; i++);
  {
    //1 karakter soros kiirasa
    Serial.print("a");
    //1 orajelnyi semmitteves
    //asm volatile ("nop"::);
  } 
  i == 0;
  while (i < 1000) {
    //asm volatile ("nop"::);
    Serial.print("b");
    i++;
  }
  Serial.println("7");
  lcd.setCursor(8, 0);
  //A kiiras helye: 8. oszlop, 0. sor
  lcd.print(millis());
  Serial.println(millis());
  //eltelt masodperc a bekapcsolas ota


123a7 jelenik meg a soros monitorban. A 'b' betű már meg sem jelenik, vagy a while ciklus nem is alkalmas erre a feladatra. Köszönöm a válaszokat, kezdő vagyok még.

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

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: Robert » 2014. március 28. péntek, 5:37

Megszakításban nincs megszakítás. A millis() is megszakítást használ, azaz INT-ben _nem_ működik.
Megszakításban idő/erőforrásigényes dolog nem használható (LCD, sorosporti kiírás).
A gomb prellegése is bezavarhat.

Avatar
scalesman
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2010. augusztus 31. kedd, 6:00

Re: 60 nap alatt Arduino #25-#26 - Megszakítás

HozzászólásSzerző: scalesman » 2014. március 28. péntek, 6:37

Szervusz,

Igen ezt olvastam, de nem arról van szó, hogy két különböző értéknek kellene megjelenni az LCD kijelzőn, pontosan a FOR ciklus miatt, mert azt mondtuk, hogy az viszont működik megszakításban és azzal késleltethetünk. Mert nekem két egyforma érték jelenik meg a kijelzőn, tehát olyan, mintha nem foglalkozna az én FOR ciklusommal. Mert egyébként , ha bármikor megnyomom a földelő gombot a 3-as lábon, akkor növekszik a millis által visszaadott érték, a múló idő miatt, csak éppen egyforma értéket ad vissza mind a kétszer, akár az LCD-re íratom ki, akár a soros monitorban nézem. Köszönöm a választ.


Vissza: “60 nap alatt Arduino - Házi feladatok”

Ki van itt

Jelenlévő fórumozók: Bing [Bot] valamint 1 vendég