Løkker

Løkker

I dette kapittelet skal vi se nærmere på løkker. En løkke er en funksjon som gjør samme ting om og om igjen. Vi har allerede brukt en løkke flere ganger (funksjonen som heter loop, og som brukes i alle skisser). For og while er to løkker som kan brukes inne i loop-funksjonen.

I dette kapittelet skal vi se nærmere på løkker. En løkke er en funksjon som gjør samme ting om og om igjen. Vi har allerede brukt en løkke flere ganger (funksjonen som heter loop, og som brukes i alle skisser). For og while er to løkker som kan brukes inne i loop-funksjonen.

For-løkker

For-løkken er en klassisk løkke som finnes i alle programmeringsspråk. Den styres av en betingelse og gjør samme ting om og om igjen til betingelsen ikke lenger er oppfylt. For-løkken kan for eksempel brukes til å gå gjennom et array.

Vi kan lagre navn i et streng-array (som har navnet names) med følgende deklarasjon og initiering:

String names[] = {"Alice", "Bob", "Charlie", "Dave"};


Vi kan skrive ut navnene til Seriell overvåker med følgende kode:

Serial.println(names[0]);
Serial.println(names[1]);
Serial.println(names[2]);
Serial.println(names[3]);


Denne måten å skrive ut navnene på blir dessverre upraktisk hvis det er mange navn som skal skrives ut. Heldigvis kan vi bruke en for-løkke til å effektivisere koden. Den kan se slik ut:

  for(int i = 0; i <= 3; i = i + 1){
    Serial.println(names[i]);
  }

Inne i for-parentesen skriver vi tre ting: 

  • Det første er deklarasjonen og initieringen av int-variabelen i. Vi setter verdien for i til 0. Dette gjør vi fordi det første navnet vi vil skrive ut, ligger på plass 0 i arrayet.
  • Det andre er betingelsen for hvor mange ganger løkken skal kjøres. Vi angir at den skal kjøres så lenge i er mindre enn eller lik 3. Dette gjør vi fordi det siste navnet vi vil skrive ut, ligger på plass 3 i arrayet.
  • Det tredje er hva for-løkken skal gjøre med variabelen i hver gang løkken har kjørt. Vi angir at i skal økes med verdien 1 hver gang løkken har kjørt.

Dette innebærer at for-løkken kommer til å bli kjørt fire ganger.

For-løkken skal skrive ut innholdet fra names-plassen i. Siden i økes hver gang løkken har blitt kjørt, skriver Arduinoen ut names[0] den første gangen, names[1] den andre gangen osv.

Tips! I APL (og mange andre språk) kan i = i + 1 forkortes til i++ (det betyr nøyaktig det samme). For-løkker skrives derfor gjerne på denne måten:

 for(int i = 0; i <= 3; i++) {
    Serial.println(names[i]);
  }

Motsetningen til i++ er i--, som betyr i = i - 1 (altså reduser verdien med 1). Det er nyttig når du skal lage en løkke som skal gå gjennom noe baklengs.

Følgende skisse skriver ut navnene i names i både stigende og synkende rekkefølge. Siden de to løkkene ligger i loop-funksjonen, kommer løkkene til å bli kjørt på nytt hvert sekund (legg merke til forsinkelsen på 1000 ms).

NamePrinter.ino

Telleverk med fire deltakere

Telleverket i Funksjoner ble bygd for to deltakere og to kurvstørrelser. Vi kan bruke samme maskinvare og kobling til å bygge et annet telleverk for fire deltakere og én kurvstørrelse. Det eneste vi må gjøre maskinvaremessig er å skifte farge på to av knappene, slik at også Charlie og Dave får hver sin dedikerte fargeknapp.

Koblingen for telleverket vårt12

Vi vil at telleverket skal øke personens verdi (antall plukkede epler) når han eller hun trykker på knappen sin. Arduinoen skal også sende en statusoversikt til Seriell overvåker hver gang noen trykker på en knapp. I statusoversikten skal det stå hvor mange epler hver person har plukket, og hvor mange gjenstående epler han eller hun må plukke for å nå sitt individuelle mål. Til dette trenger vi tre arrayer: 

  • et String-array med alle navn
  • et long-array med antall plukkede epler per person
  • et long-array med målet for hvor mange epler hver person skal plukke.

Det gjør vi med følgende kode:

Del av FruitPickers5.ino

Når noen trykker på knappen sin, kalles funksjonen updateStatus opp med argumentet for hvor mange epler som skal legges til, og hvem sin samling det skal legges til for. Deretter bruker vi en for-løkke til å skrive ut hvor mange epler hver person har plukket. I for-løkken har vi lagt inn en if-setning for å få en korrekt utskrevet statusrapport. Uten if-setningen hadde vi fått negative verdier i statusrapporten når noen hadde plukket flere epler enn det som var målet hans eller hennes.
Den ferdige skissen ser slik ut:

FruitPickers5.ino

Obs! Legg merke til at vi har endret datahastigheten (fra 9600 Bd til 115 200 Bd for å få bedre flyt. Dette må også endres i Seriell overvåker (nederst til høyre) for at programmet skal fungere slik det er tiltenkt.

Husk å endre hastigheten til 115 200 Bd.

Morsealfabetet

Morsealfabetet ble oppfunnet på 1800-tallet av Samuel Morse. Det brukes til å kommunisere ved hjelp av pulser. Det fremste bruksområdet var telegrafi, men morsealfabetet kan også i moderne tid brukes til å sende budskap med blinkene lys eller pipende høyttalere.

Bokstavene i morsealfabetet består av kombinasjoner av korte og lange pulser. For eksempel er bokstaven A en kort puls etterfulgt av en lang puls. Lange pulser varer like lenge som tre korte pulser. Alle pulser adskilles med en pause som varer like lenge som en kort puls.

Morsealfabetet

Bokstavkombinasjonen SOS ble det universelle nødsignalet, siden det er enkelt å huske hvordan det skrives med morsealfabetet. Bokstaven S er tre korte pulser, og bokstaven O er tre lange pulser. Denne kombinasjonen av tre tegn er enkel å sende kontinuerlig ved hjelp av en såkalt while-løkke.

SOS med Morse

While-løkker

Du kan få samme resultat med en while-løkke som med en for-løkke, men while-løkken gir litt utvidet funksjonalitet. Den kan for eksempel brukes til å kjøre ting så lenge en knapp er trykket inn.

For å demonstrere dette skal vi bygge en SOS-blinker. Når vi trykker på SOS-blinkerens knapp, skal en lysdiode blinke det morsebaserte SOS-nødsignalet (tre korte blink, tre lange blink, tre korte blink).

 Illustrasjon laget med komponenter fra Fritzing (fritzing.org). CC BY-SA 3.0

Vi bruker utviklingskortets innebygde lysdiode (GPIO-pinne 13) for å slippe å koble til en ekstern lysdiode.

Vi innleder koden med å inkludere Button-biblioteket og lage en ny knapp (koblet til GPIO-pinne 2).

Del 1/5 av Sos.ino

I setup-funksjonen starter vi knappen og angir lysdiodepinnen som utgang.

Del 2/5 av Sos.ino

Vi venter med å skrive loop-funksjonen og skriver tre egne funksjoner først. Den første kaller vi shortBlink. Den har verken argument eller returverdi. Det eneste den gjør er å tenne lysdioden i 200 ms og deretter holde den slukket like lenge. Shortblink utfører altså en kort morsepuls.

Den andre funksjonen kaller vi longBlink. Den gjør det samme som shortBlink, men holder lysdioden tent tre ganger så lenge (dvs. 600 ms). LongBlink utfører altså en lang morsepuls.

Del 3/5 av Sos.ino

Den tredje egne funksjonen kaller vi morseBlink og gir argumentet character. Når funksjonen kalles opp med en bokstav som argument, undersøker programmet om bokstaven er med i switch-setningen. Hvis den er det, kaller programmete opp funksjonene shortBlink og longBlink for å få lysdioden til å blinke den ønskede bokstaven.   

Del 4/5 av Sos.ino

I loop-funksjonen skriver vi avslutningsvis en if-setning som kjøres når noen trykker på knappen. Da starter en while-løkke som blir kjørt til knappen slippes opp. Legg merke til hvordan vi har uttrykt betingelsen. Utropstegnet gjør at betingelsen får motsatt betydning. While-løkken kjøres altså så lenge btnSos ikke er sluppet opp.

Del 5/5 av Sos.ino

Do-løkker

While-løkken forekommer i en versjon som kalles do. While-løkken begynner alltid med å sjekke om betingelsen er oppfylt, og kjører koden hvis den er det. Do-løkken kjører koden først og sjekker betingelsen etterpå. Hvis betingelsen er oppfylt, kjører do-løkken koden igjen.

Den praktiske forskjellen mellom en while-løkke og en do-løkke er at koden i do-løkken alltid kjøres minst én gang.

Uendelig løkker

En vanlig feil er å skrive uendelige løkker. Det er løkker der betingelsen alltid oppfylles, slik at de kjøres i uendelighet. Dobbeltsjekk alltid at variabelen som betingelsen testes mot, endre en eller annen gang i løkken.

while (x<100) {
  Serial.println(x);
}

Uendelige økker

while (x<100) {
  Serial.println(x);
  x++;
}

Endelige løkker

Uendelige løkker får programmet til å bli værende i løkken og aldri komme videre. Les mer om uendelige løkker i Programmeringsveiledning.

Referanser

12. Illustrasjon laget med komponenter fra Fritzing (fritzing.org). CC BY-SA 3.0

Sist endret: 2017-09-08