Arduino multitasking en tijdbeheer

Arduino-test om te multitasken met milis

Ik ben geen Arduino-expert, ondanks dat ik de plaat al een lange tijd heb, heb ik er nauwelijks onderzoek naar gedaan. De keren dat ik het heb gebruikt, was het als een tool voor het kopiëren en plakken van reeds gemaakte code, maar zonder veel interesse om echt te leren hoe het werkt, maar gewoon met de bedoeling om het te laten werken en nuttig voor mij te zijn. Deze kerst heb ik de kerststal een beetje getuned met wat leds en een HC-SR04 ultrasone sensor. En ik stopte om te observeren wat er moest gebeuren.

Ik wilde gewoon verschillende dingen doen met twee LED's van hetzelfde signaal. Oeps. Ik struikelde snel over wat ik denk dat zal zijn een van de eerste beperkingen die je tegenkomt als je met Arduino gaat rommelen​ En je hoeft het niet te ingewikkeld te maken. Ik heb het gewoon over enkele LED's, je realiseert je dat je niet goed kunt doen wat je wilt.

Laten we het vanaf het begin duidelijk maken multitasking bestaat niet in Arduinokunnen twee taken niet parallel worden verwerkt. Maar er zijn technieken om zo snel te bellen dat ze tegelijkertijd lijken te werken.

Ik vertel de zaak in meer detail. Met Kerstmis zette ik een kerststal op en ik wilde dat bepaalde kerstverlichting aanging als mijn dochters naderden. Niets ingewikkelds. Ik wilde gewoon dat twee takken van led-lampen anders zouden werken dan de waarden van een naderingssensor.

Ik wilde wanneer iemand dichterbij kwam dan 10 cm

  • Een van de lichttakken die naar de sterren zouden gaan, zou 10 seconden blijven branden
  • Dat de andere die de huizen binnen zou gaan, 10 seconden aan zou blijven, maar omdat ze zich van de kerststal hadden gescheiden.

Simpel toch? aangezien dit u grote problemen kan bezorgen. Omdat Arduino niet in staat is tot multitasking, voert het de ene opdracht na de andere uit.

 

circuit montage LED's knipperen en ultrasone multitasking

Ik heb een montage met de HC-SR04 ultrasone sensor en 2 LED's, elk zou equivalent zijn aan een tak van Bethlehem. Het eerste deel is niet erg grappig, aangezien het gaat om het configureren van de setup en werking van de ultrasone sensor in de LOOP, maar dit vind je op duizenden plaatsen. Zoals een andere dag, als ik meer informeer, maak ik een special, want nu ben je hier (sorry om geen credits te plaatsen, maar ik weet niet meer waar ik het vandaan heb)

HC-SR04-code op Arduino

int ledPin1 = 8; int ledPin2 = 7; lange afstand; lange tijd; lange huidige tijd; lange tijdspanne; void setup () {// initialiseer digitale pin LED_BUILTIN als een output. pinMode (ledPin1, OUTPUT); pinMode (ledPin2, OUTPUT); Serial.begin (9600); pinMode (3, OUTPUT); / * activering van pin 9 als output: voor de ultrasone puls * / pinMode (2, INPUT); / * activering van pin 8 als invoer: ultrasone bounce-tijd * /} // de lusfunctie loopt keer op keer voor altijd void loop () {digitalWrite (3, LOW); / * Vanwege sensorstabilisatie * / delayMicroseconds (5); digitalWrite (3, HIGH); / * verzenden van de ultrasone puls * / delayMicroseconds (10); tijd = pulseIn (2, HIGH); / * Functie om de lengte van de inkomende puls te meten. Het meet de tijd die verstrijkt tussen het verzenden van de ultrasone puls en het moment waarop de sensor de terugkaatsing ontvangt, dat wil zeggen: vanaf het moment dat pin 12 de terugkaatsing begint te ontvangen, HOOG, totdat deze stopt, LAAG, de lengte van de inkomende puls * / afstand = int (0.017 * tijd); / * formule om de afstand te berekenen waarbij een geheel getal wordt verkregen * / / * Monitoring in centimeters door de seriële monitor * / Serial.println ("Distance"); Serial.println (afstand); Serial.println ("cm"); vertraging (1000);

Hiermee wordt de afstand gemeten door de ultrasone sensor bekeken en opgeslagen

LEDS-bedieningsoplossing

Het eerste dat in me opkomt, is om vertragingen op te lopen. Ik weet niet waarom, maar alle beginners denken aan delay () en dat beperkt de opties enorm, want tijdens het gebruik van delay () blijft het board niet werken en daarom kun je niets anders doen in die suspension-tijd. De oplossing is om millis () te gebruiken

Hier vond ik een eenvoudige oplossing op basis van if en tellers. Zoals een leraar van mij altijd zei: alles kan worden geprogrammeerd met veel ifs achter elkaar. Maar de waarheid is natuurlijk niet erg elegant.

// als de afstand kleiner is dan 10, schakelen we de twee LED's of takken in en beginnen we de tijd te tellen met millis () if (afstand <10) {digitalWrite (ledPin1, HIGH); digitalWrite (ledPin2, HIGH); huidige tijd = millis (); } // als de afstand groter is dan 10, zullen we de tijd controleren die is verstreken sinds het werd ingeschakeld en als deze groter is dan de aangegeven afstand, zullen we de LED1 uitschakelen if (distance> 10) {timepast = millis () - currenttime ; digitalWrite (ledPin1, LOW); // als de afstand groter is dan 10000, zullen we LED2 uitschakelen als (timepast> 10000) {digitalWrite (ledPin2, LOW); ​

Wat deze code bedoeld is, is dat Arduino constant die drie ifs uitvoert, zodat het er zo snel doorheen gaat dat het lijkt alsof het verschillende dingen tegelijkertijd doet. Maar zoals we al weten, gaat het door met het één voor één uitvoeren van zinnen.

Zodra de afstand is gemeten en opgeslagen in de variabele afstand, de ifs zouden worden geëvalueerd:

  • De eerste controleert of de afstand kleiner is dan de gewenste 10 cm. Als dat zo is, schakelen we de twee LED's in en beginnen we de tijd te tellen met millis ()
  • en we zouden naar de tweede gaan als voor de afstand groter dan 10 cm. Als het voldoet, berekenen we de tijd die is verstreken en deactiveren we led 1, die alleen afhangt van de afstand.
  • We zouden naar de derde gaan als we controleren of er meer dan 10 seconden zijn verstreken sinds de teller is geactiveerd, en zo ja, pin 2 uitschakelen
  • En zo gaat de lus verder. En opnieuw.

Uiteindelijk, en hoewel de oplossing werkte, was het me duidelijk dat dit probleem zeker veel mensen had en dat er een meer orthodoxe oplossing moest komen. Ik begon te zoeken en vond een goeie (die zeker niet de enige is) van de jongens van Adafruit en objectgeoriënteerd programmeren​ Het bestaat uit het maken van objecten met gedefinieerde klassen om snel te bellen en de code niet honderden keren in ons programma te hoeven herhalen.

Wat uiteindelijk "hetzelfde" is als mijn oplossing met if + counters, maar veel eleganter en dat zorgt voor een veel beter leesbare en veel efficiëntere code.

Het beheren van multitasking leidt onvermijdelijk tot tijdbeheer in Arduino​ In eerste instantie was dit niet in het artikel opgenomen, maar ik vind het erg interessant.

Arduino en tijdfuncties

Zoals ik al heb opgemerkt Ik denk dat er een grote afhankelijkheid is met vertraging () , mogelijk omdat mensen die beginnen deze functie zien in alle voorbeelden die gewoonlijk worden weergegeven vanaf het knipperen tot een verkeerslicht of elke manipulatie van leds aan en uit.

Vertraging heeft een heel groot probleem en dat is dat wanneer we bellen vertraging() een tijdlang stopt alles. Het bord leest geen enkele sensor, het blijft ook geen zinnen uitvoeren, of doet helemaal niets, wacht gewoon tot de tijd die we hebben doorgegeven voorbij is en natuurlijk als we het bord voor meer dan één ding willen gebruiken bij de tegelijkertijd is dit niet haalbaar.

We zullen er naar moeten kijken millis () opgenomen a delayMicroseconds () En we hebben ook micros () die het aantal microseconden retourneert sinds het programma begon met uitvoeren

Knipper zonder vertraging

Een gaaf voorbeeld om te zien hoe het werkt is voer de mythische Blink uit, maar zonder de vertraging​ Het belangrijkste verschil is dat we de functie delay () vergeten en millis () gebruiken om de tijd tussen bewerkingen te kunnen tellen.

2 reacties op "Arduino multitasking en tijdbeheer"

  1. Weten over het bestaan ​​van interrupts in Arduino kan u helpen bij het implementeren van programma's met een zekere mate van multitasking.

    antwoord

Laat een reactie achter