Nieuws:

Nu in MSM 246 PRAKTIJK: Terminus: de baan, deel 2 * Het beladen van ouderwetse goederenwagens, aflevering 3 * Het ombouwen van goedkope open goederenwagens * Zwitsers smalspoor in 4 maanden, deel 1 * Laseren voor dummies: een hooikar * Het modelleren van jonge bomen

Hoofdmenu

Arduino interrupt

Gestart door bumper, 08 januari 2024, 21:29:55 PM

raf

met elke delay schakelt elke processor (atmel ,arduino of pic)zich uit en reageert dan niet meer tot die tijd verstreken is
gr raf
If I make mistakes in "spelling"
Remember it's the pen, that's bad
Don't lay the blame on me.

perk

Ik ben er niet zo zeker van : https://forum.arduino.cc/t/interrupts-and-delay/704157

Volgens bronnen op het internet kan delay() onderbroken worden door interrupt in Arduino code.

In al mijn projecten heb ik nog nooit een interrupt nodig gehad.   De arduino is in mijn beleving snel genoeg om simpelweg in de loop functie de nodige inputs na te kijken en erop te reageren.  Toch in mijn modelbouw wereld.  Zo snel gaan de dingen hier niet.   Je hebt alleen een goed gebruik van je eigen timers nodig, zoals in het voorbeeld van patrick smout.  Dus nooit delay gebruiken tenzij bij het opstarten ofzo.

Ik zie wel mogelijke timing problemen als je schermen of tragere devices zoals DS18B20 gaat gebruiken.   Dan heb ik al een hickup gemerkt in de performantie.

Voor de opendeur van 'De Pijl' had ik een demo met stappenmotor, 2 servo's met vertragingen, ettelijke Leds (al dan niet knipperend), neopixels, TFT scherm, DS18B20 en een IR sluis. Alles tegelijk werkend en zonder delay.

Alleen als ik de DS18B20 uitlas of het tft scherm aanpaste (zaten beide in dezelfde subroutine) haperde de stappenmotor even.

Maar ik vind het wel een interesant onderwerp.

bumper

Patrick,

Delay heb ik hier enkel in het testprogramma gezet om zeker te zijn dat ik de led zie branden. Anders gaat het soms zo snel dat het met het blote oog niet zichtbaar is met mogelijk verkeerde conclusies tot gevolg.
Uw laatste post is al veel te ingewikkeld voor mij. Hetgeen ik nodig heb is gewoon het aantal seconden tussen die twee pulsen. Meer niet en ik dacht van dat zo op te lossen. Verder reikt mijn kennis op dat punt niet.
Ik heb het programma volgens Patrick Smout aangepast maar dat werkt ook niet goed. Het vreemde is dat led 1 van in het begin oplicht en aan blijft. Verder is er geen enkele reactie bij het binnenkomen van de puls te merken. Led 2 blijft onveranderd uit.
Ik begin te denken dat mijn Mega stuk is. Hoe dat is kunnen gebeuren weet ik echt niet. Is dat soms uit te testen?
Ik ga een nieuwe bestellen, dan is hopelijk dat geknoei voorbij. Ik laat wel weten als ik hem heb.

Dank en groeten.
Ludo.

 

perk

Ik vrees dat andere dingen ook meespelen, zoals wellicht bouncing effect van de sensor.

Voordat je de arduino aanpast, waarom niet eens gewoon zonder sensor maar met een simpele drukknop testen.  Zelfs dan ga je bouncing hebben dus verkeerde meetgegevens hebben.

Ik zou een avondje nodig hebben om eens te zien of ik hier een stukje code voor kan schrijven


bumper

Patrick,

De code om contactdender tegen te gaan ken ik.
Vanavond lukt dat niet meer, ik zal het morgenvoormiddag proberen.

Groeten.
Ludo.
 

raf

ik doe het anders
eens ik een puls gemeten heb spring ik naar een sub routine want ik moet geen tweede puls meer meten de loc heeft zich aangemeld

in die sub routine wacht ik dan op de volgende puls van de andere sensor en spring dan terug naar het main programma

gr raf
If I make mistakes in "spelling"
Remember it's the pen, that's bad
Don't lay the blame on me.

perk

well, omdat het mijn interesse heeft gewekt wou ik nu toch eens die interrupts proberen.

Ik heb een Uno op een test boardje staan. 
Dit is het programma :

===========

int interruptteller=0;
int vorigeteller=0;

const byte sensorPin = 2;

void setup() {
  pinMode(sensorPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(sensorPin), teller, FALLING);
  Serial.begin(9600);
  Serial.println();
  Serial.println();
  Serial.println();
  Serial.println();
  Serial.println();

  Serial.println("programma is bezig");
}


void loop() {
if (interruptteller>vorigeteller)
{
  Serial.print("interrupt gezien , nummer :");
  Serial.println(interruptteller);
  vorigeteller=interruptteller;
}

  Serial.print("nummer :");
  Serial.println(interruptteller);
 
}

void teller() {
  interruptteller = interruptteller+1;
}

==========

als ik pin 2 op de grond breng (simpel jumpekabeltje), zie ik dit soort zaken op de seriele monitor :

nummer :10
nummer :10
nummer :10
nummer :10
nummer :10
nummer :10
nummer :10
nummer :10
interrupt gezien , nummer :12
nummer :12
nummer :12
nummer :12
nummer :12
nummer :12


Je ziet echter dat de aantallen ophoog springen, ik vermoed door bouncing?

Nog steeds, ik zou het zonder interrupts proberen met gewoon debouncer code - maar dit is gewoon voor de interupt te testen.
En dat stukje lijkt best te werken. 

patrick smout

#22
Dag Ludo,

neem onderstaande code eens over voor de loop. Verder ook de aanname dat je de interrupt op FALLING hebt staan nu (RISING mag ook overigens).
Volgens mij gaat LED1 onmiddellijk aan omdat de interrupt al getriggerd wordt bij opstart van het programma.
Als de systeemtimer dan nog 0ms is dan blijft die LED uit. Nu is voor mij onduidelijk wat je wil bereiken/bewijzen met het aansturen van LED2 dus die heb ik er even uit gelaten in onderstaande code.

unsigned long basetime;

void loop () {

  if (sensor1 == true)
  {
    if (millis() - basetime >= 5000)
    {
      sensor1=false;
      digitalWrite (led1,LOW);
    }
  }
  else
  {
    basetime = millis();
  }
}
Met vriendelijke groeten,

Patrick Smout

patrick smout

En voor de snelheidsmeting zou het zoiets kunnen worden (wegens gebrek aan een Arduino niet getest, onder voorbehoud van een typo links of rechts). Variabelen zijn niet aangemaakt net zomin als initialisatie voor de 2e interruptingang.
In ElapsedTime komt de tijd die verstrijkt tussen het actief worden van sensor1 en sensor2.
Er is een basic interlocking voorzien die vereist dat eerst sensor1 en dan sensor2 actief moet worden alvorens de tijd berekent wordt. Zoals het nu is werkt de meting maar in één rijrichting. Kan ook voor beide richtingen maar maakt het  (weer) wat complexer.
Persoonlijk zou ik er ook voor kiezen om een statemachine te gebruiken maar dat kan later nog.
Eerst even dit aan het werken krijgen op basis van zoveel mogelijk originele code en kleinere stappen.
@ Ludo, test eerst even het programma in mijn vorige post. Als dat niet werkt zal dit ook niets doen.

void loop ()
{
  if (sensor1 == true)
  {
    if (millis() - basetime1 >= 500)
    {
      digitalWrite (led1,LOW);
    }
  }
  else
  {
    basetime1 = millis();
  }
 
  if (sensor2 == true)
  {
    if (millis() - basetime2 >= 500)
    {
      digitalWrite (led2,LOW);

      if(sensor1==true)
      {
        elapsedtime = gemtijd2 - gemtijd1;
 
        sensor1=false;
      }
      sensor2=false;  
    }
  }
  else
  {
    basetime2 = millis();
  }
}

void tijd_1 () {
 
  if(sensor1==false)
  {
    gemtijd_1 = millis();
    digitalWrite (led1,HIGH);
  }
 
  sensor1 = true;
}

void tijd_2 () {

  if(sensor2==false)
  {
    gemtijd_2 = millis();
    digitalWrite (led2,HIGH);
  }
 
  sensor2 = true;
}
Met vriendelijke groeten,

Patrick Smout

bumper

Hallo Patrick & Patrick,

Laat het nu even rusten, ik ga alle info en voorstellen uitproberen en geef daarvan de resultaten door.
Aan de hand daarvan kunnen we dan eens bekijken welke stappen we verder gaan ondernemen.
De aanpassing van de code in de "loop" volgens uw eerste post werkt niet, heb dit reeds gemeld. In de reactie daarop begrijp ik niet hoe de interrupt reeds kan getriggerd worden bij de opstart (led 1 gaat branden zelfs zonder passage van de loc).
Met led 1 wil ik nagaan of de interrupt is binnengekomen en met led 2 wil ik nagaan of de code die gebruik maakt van millis() wel werkt. Ik dacht ergens gelezen te hebben dat dit niet altijd lukt.
In ieder geval nogmaals bedankt om mee te helpen.

Hallo Raf,
Ik begrijp wel wat je bedoeld, maar weet niet goed hoe dat moet geprogrammeerd worden in arduino taal.
Ik vraag mij toch af hoe je op die manier 100% zeker kunt zijn dat je geen puls mist.

Groeten.
Ludo.
 

patrick smout

Citaat van: bumper link=msg=510873  In de reactie daarop begrijp ik niet hoe de interrupt reeds kan getriggerd worden bij de opstart (led 1 gaat branden zelfsquote author=bumper link=msg=510873 date=1705073528]
In de reactie daarop begrijp ik niet hoe de interrupt reeds kan getriggerd worden bij de opstart (led 1 gaat branden zelfs zonder passage van de loc).
Dag Ludo,

De interrupt zou getriggerd kunne worden door een opstartverschijnsel ( initialisatie van de Io of zo) dat zich enkel voordat als je het programma start. Zekerheid heb ik daar niet over en zonder bordje hier op tafel blijft het een best guess maar ik zie daat wel een verklaring in waarom LED1 aan is een LED2 uit.

Bij perk lijkt de interrupt wel te werken dus ik zou verder ook niet direct weten wat er aan de hand is. Wat je nog kan verder kan helpen is ook een println in de interrupt routine zetten van mijn code zoals in het vb van Perk. Dit geeft je ook een indicatie dat de interrupt wel degelijk uitgevoerd wordt.
Verder kan je ook eens de ingang hard aan de +5V leggen ipv via de hall sensor. Geeft je ook zekerheid dat het schakelen goed gaat. Er zijn best nog wat opties open die op afstand moeilijk te beoordelen zijn of ze wel/niet uitgesloten kunnen worden.

 Ben wel erg benieuwd wat nu maakt dat dit niet werkt dus laat zeker de uitkomst weten.
Met vriendelijke groeten,

Patrick Smout

bumper

Wat ik dit weekend gevonden heb.
Wanneer ik opstart dan gaan beide leds branden ongeacht de volgorde van opstarten. Eerst de arduino en dan de signalen of andersom.
Wanneer een trein de sensor1 passeert gebeurt er niets. De spanning valt wel weg en komt terug. Maar de leds blijven branden. Bij toeval ontdekt dat als de magneet boven de sensor blijft, dus de spanning blijft nul, dan gaan de twee leds na een tijdje( ongeveer 3 à 4 seconden) uit. Als de magneet dan weggenomen wordt, dus als de spanning terug komt, dan gaan de leds terug branden.
Dit is dus geen bruikbaar systeem, maar het is schijnbaar het omgekeerde van wat we willen bereiken.
Welke trigger voor het interrupt gebruikt wordt ( falling,rising,high,low,change enz.) maakt niet uit. Het resultaat is steeds hetzelfde.
Patrick Smout, dit is getest volgens uw eerste code.

Groeten.
Ludo.
 

perk

Ludo,

ik ben nog altijd van mening dat LEDS nu niet direct de beste manier van ontdekken is wat ere juist gebeurd.
Een seriele monitor en print statements in de code werken veel beter vind ik.   Dan kan je je variabelen en elke stap van het programma uitlezen als het ware.

Heb je geen mogelijkheid mijn stukje code met je sensor eens te proberen?

groeten,

P.

perk

welk exact type sensor gebruik je juist?   Kan je een merk en type delen?

bumper

Patrick,

Kan dat met dezelfde kabel voor het uploaden van een programma op een laptop via usb?
Anders heb ik geen mogelijkheid.
Het juiste type sensor : Hall sensor TLE4905L.
In mijn handboek Arduino programmeren van Elector staat echter dat INPUT-PULLUP niet mag gebruikt worden met Attachinterrupt (uitzonderlijk geval).

Groeten.
Ludo.