Hoe kan ik interrupt opnieuw inschakelen na het uitschakelen?

Ik heb niet veel ervaring met Arduino en Interrupts. Hieronder probeer ik om onderbreking te onderbreken zodra het werd ontdekt en opnieuw in te schakelen wanneer ik lus opnieuw begin. Maar in onderstaande code kan ik dit niet inschakelen.

int L = 2;
volatile int done0=0;
volatile unsigned long leftT=0;

void recordL()
{
  if(done0 == 0)
  {
      leftT=micros();
  }
  done0 = 1;
  detachInterrupt(0);
}

void setup() {
 //put your setup code here, to run once:
  pinMode(L,INPUT);
  Serial.begin(9600);
  Serial.println("Start..");
}



void loop() {
 //put your main code here, to run repeatedly:

  attachInterrupt(0,recordL,RISING);
  done0 = 0;

  while(!done0)
  {

  }

  Serial.println("Sound..");
  Serial.println(leftT);
  delay(1000);
  Serial.println("After Delay");
}

maar ik heb een kleine wijziging in de code aangebracht. Ik heb 'done0 = 0' boven attachInterrupt() verschoven en het werkt. Waarom gebeurt dat? Een ander probleem waar ik hier mee te maken heb, is wanneer ik het weer inschakel, er komt nog een opgeslagen waarde. Bewaart het waarde wanneer ik het heb uitgeschakeld?

int L = 2;
volatile int done0=0;
volatile unsigned long leftT=0;

void recordL()
{
    if(done0 == 0)
    {
        leftT=micros();
    }
  done0 = 1;
  detachInterrupt(0);
}

void setup() {
 //put your setup code here, to run once:
  pinMode(L,INPUT);
  Serial.begin(9600);
  Serial.println("Start..");
}



void loop() {
 //put your main code here, to run repeatedly:
  done0 = 0;      
  attachInterrupt(0,recordL,RISING);

  while(!done0)
  {

  }

  Serial.println("Sound..");
  Serial.println(leftT);
  delay(1000);
  Serial.println("After Delay");
}

Uitgang voor 2e geval (geluid komt maar één keer, maar ik krijg ook geluid na een vertraging):

   Start..
   Sound..
   2873000
   After Delay
   Sound..
   3873528
   After Delay
0
@MITURAJ Ik heb een vraag geplaatst.
toegevoegd de auteur Sai dheeraj N, de bron
Geen geluid van geluidssensor.
toegevoegd de auteur Sai dheeraj N, de bron
U moet waarschijnlijk de specifieke processorspecificaties lezen om te begrijpen wat er kan gebeuren wanneer u interrupts uitschakelt en inschakelt. Er zijn veel Arduino-kaarten die verschillende processors gebruiken. Dus een vraag over interrupts zonder dat u aangeeft welke processor u gebruikt, is moeilijk te beantwoorden. Ik vermoed dat de hardware voor de processor die u gebruikt, interrupts bijhoudt terwijl interrupts zijn uitgeschakeld. En zal proberen ze te onderhouden wanneer je interrupts opnieuw inschakelt. Maar dit is echt afhankelijk van hoe de hardware van de processor werkt.
toegevoegd de auteur st2000, de bron
Noteer de output die je kreeg voor de tweede case.
toegevoegd de auteur Adarsh, de bron
Gebruikt u een drukknop om een ​​interrupt te geven?
toegevoegd de auteur Adarsh, de bron

3 antwoord

De code moet worden aangepast. Ik neem aan dat je digitale pen 2 hier gebruikt als je interrupt pin. Maar het eerste argument voor uw attachinterrupt() is eenvoudigweg 0. Dat is geen aanbevolen manier om argumenten door te geven. Controleer de onderstaande link.

Check -https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Ik denk dat dit is wat er gebeurde -

In het eerste geval zit de code vast in de oneindige while-lus omdat interrupt-routine mogelijk net na attachinterrupt() is aangeroepen en is done 1. Daarna is 0 voltooid en is vastgelopen terwijl while (! Done) voor altijd lus omdat interrupts nu zijn uitgeschakeld.

In het tweede geval, nadat voltooid = 0 is gemaakt, wordt de code die in de interruptroutine is ingevoerd en voltooid = 1 gemaakt, weergegeven, wordt de while-lus overgeslagen en wordt de uitvoer afgedrukt. Wederom in lus() wordt 0 gemaakt en worden interrupts teruggeplaatst. En opnieuw werd de interruptroutine opnieuw uitgevoerd, mogelijk omdat het een andere stijgende flank detecteerde. Dit probleem is er met drukknoppen vanwege stuiteren. Hier geeft geluidssensor mogelijk geen zuiver digitaal signaal af.

Opmerking: het uitschakelen van de interrupt in de interruptieroutine is zinloos cz arduino schakelt standaard alle interrupts en wachtrijen uit voor verdere interrupts tijdens de uitvoering van een interruptroutine. Dus ik twijfel echt aan het gedrag. Je kunt het beter rechtzetten door die verklaring van daar te verwijderen en deze na while() in de hoofdcode te plaatsen.

1
toegevoegd

Hieronder probeer ik de onderbreking uit te schakelen zodra deze is gedetecteerd en weer in te schakelen wanneer ik de lus opnieuw start.

niet zeker waarom je dat wilt doen, maar interrupts zijn uitgeschakeld in isr door hardware (tenzij je het expliciet in isr hebt ingeschakeld), dus wat je probeert te doen, gebeurt automagisch voor je.

Maar in de onderstaande code kan ik deze niet inschakelen.

meestal gaat het om het inschakelen van het respectievelijke interruptmasker, tenzij u alle interrupts wilt in- of uitschakelen.

0
toegevoegd
Eigenlijk wil ik een keer geluid maken en die interrupt voor de rest van de code in lus sluiten en dat weer inschakelen.
toegevoegd de auteur Sai dheeraj N, de bron

Normaal gesproken wordt een Arduino interrupt-bijlage gemaakt in de methode setup() en wordt nooit verwijderd. Overweeg om uw oproep te verplaatsen om de interrupt dienovereenkomstig toe te voegen en uw oproep te verwijderen naar maak de interrupt los .

Uw aanpak is begrijpelijk als u nadenkt over de normale ingebedde processorprogrammering. In dergelijke gevallen moeten alle aspecten van de hardware worden overwogen. Dit kan het resetten van de interrupt-hardware voor de volgende interrupt-gebeurtenis omvatten.

Bij het programmeren in het Arduino-paradigma worden veel details geabstraheerd van de coder om de codeerervaring eenvoudig en ongecompliceerd te maken. In het voorbeeld onderaan de interrupt attachment Arduino Reference pagina , is het duidelijk dat er geen code hoeft te worden toegevoegd om de interrupt te beheren binnen de interrupt-methode.

Om uw vraag specifiek te beantwoorden (waarom werkt de 2e codelijst terwijl de eerste niet), bekijk dan de daadwerkelijke (mogelijke) reeks van gebeurtenissen. De methode setup() is de eerste run gevolgd door de methode loop (). In de eerste codelijst hebt u de interrupt bevestigd en vervolgens uw "klaar" vlag ingesteld om de code in de interrupt te laten lopen. U veroorzaakt de onderbreking door de invoer op interrupt-pin 0 te verhogen. Waarschijnlijk werkt dit en u verbreekt vervolgens de interrupt. Als u de onderbreking opnieuw probeert te veroorzaken voordat 1 seconde is verstreken, zal het lijken alsof de interrupt niet werkte omdat de methode loop() nog steeds wacht op de 1 seconde vertraging die u hebt toegevoegd en de interrupt niet opnieuw heeft gekoppeld. Nadat de vertraging van 1 seconde is verstreken, wordt de methode loop() opnieuw aangeroepen. Waarschijnlijk herinnert de hardware van de processor zich dit keer dat u probeerde een interrupt te veroorzaken. Dus wanneer de interrupt is aangesloten, wordt de interruptroutine aangeroepen. Maar de vlag "done" is nog niet op nul gezet, dus de interrupt voert geen code uit die wordt bestuurd door de vlag "done". In de 2e codelijst hebt u dit probleem verholpen door de "klaar" -markering in te stellen voordat u de interrupt opnieuw aanbrengt.

0
toegevoegd
Waarom wordt de uitvoer gewijzigd als ik de positie van 'done0 = 0' wijzig?
toegevoegd de auteur Sai dheeraj N, de bron
Sorry snapte het niet. Welke waarde flag ook heeft aan het einde van de lus, loop zal verder vanaf het begin worden uitgevoerd en de interrupt opnieuw bevestigen. Waarom dat niet zal gebeuren?
toegevoegd de auteur Sai dheeraj N, de bron