Oppgaver: mikrokontroller og Arduino

  1. Hva er en mikrokontroller? Hva består den av?

  2. Når ble de første mikrokontrollerne lansert?

  3. Nevn noen tidlige bruksområder for mikrokontrollere.

  4. Når kom mikrokontrollere med flashminne?

  5. Nevn noen produsenter av mikrokontrollere.

  6. Hva er Arduino?

  7. Hva er en sensor? Gi to eksempler.

  8. Hva er en aktuator? Gi to eksempler.

  9. Hvordan kan man kople en Arduino til nettet eller andre enheter?

  10. Er sensorer og aktuatorer analoge, digitale eller begge deler?

  11. Gi to eksempler på enheter som ikke er hverken sensor eller aktuator.

  12. Hva heter programvaren som man bruker til Arduino? Hva betyr de tre siste bokstavene?

  13. Hva består denne typen programvare av?

  14. I programmeringsspråket, hva betyr //?

  15. Hvordan henter man inn kode som andre har skrevet før deg?

  16. Hva er en funksjon?

  17. Hvilke to funksjoner finnes alltid i koden til et Arduino-program?

  18. Hva foregår i hver av disse to funksjonene?

  19. Hva er en variabel?

  20. Hva slags datatype bruker man for heltall mellom –32768 og 32767?

  21. Hva heter datatypen som brukes for verdier som er sanne eller usanne?

  22. Hvilken datatype må man bruke når man har et desimaltall?

  23. Hvilken datatype brukes for å lagre flere verdier i én og samme variabel?

  24. Hvis x er en heltallsvariabel, hva er resultatet av x = 7/3?

  25. Hva betyr disse tre utrykkene: x==y, x!=y og x<=y?

  26. Vi har to uttrykk, x>0 og y>1. Hvordan spør vi om begge er sanne? Hvordan spør vi om minst ett er sant?

  27. Hva er programmeringsspråkets syntaks?

  28. Hva er en datatype? Gi to eksempler.

  29. Hvordan tilordner man verdien 20 til x?

  30. Hvordan skriver man at verdien jegerkul er sann?

  31. Hva er å debugge?

  32. Hva er å kompilere?

  33. Hva er en char?

  34. Hva er kontrollstrukturer? Gi to eksempler.

  35. Hva er debouncing?

  36. Nevn to forskjellige typer Arduino-bord og minst to måter de er forskjellige på.

  37. Hva er et Arduino Shield?

  38. Nevn noen fordeler med å bruke Arduino Shields.

  39. Hvor kan man finne mer informasjon om Arduino?

  40. Hva er Instructables.com?

  41. Hva er Open Source? Gi et eksempel på noe som er Open Source.

  42. Hva er det motsatte av Open Source? Gi et eksempel.

  43. Hva er Fritzing?

  44. Hvilke tre visninger finnes i Fritzing? Hva ser man i hver av dem?

  45. Hva mener vi med at det foregår en demokratisering av teknologi?

  46. Nevn en alternativ teknologi til Arduino.

  47. Hvordan skiller denne seg fra Arduino?

Prosjektoppgave Arduino

Brunos ringevekkerklokke

Bruno Sterkesi er byggets ekspert på alt som har med svakstrøm å gjøre. Han begynner å dra på årene, og de unge datajyplingene i etasjen over kommer av og til ned og spør hvordan det går med radiotelegrafen hans eller om han kan reparere grammofonene deres. Så løper de kneggende opp til kontorene sine. Bruno bryr seg ikke så mye om at programmererne ler av ham. Men han innser at det kanskje er på tide å lære seg noen nye triks. Det har blitt stadig færre kunder de siste årene, og han lurer på om det kan ha noe med ringeklokken hans å gjøre. Den er gammel, svart og hvit og kjedelig og består av bare én eneste knapp som sier ding-dong når noen ringer på. Den oser jo ikke akkurat «jeg følger med i tiden». Bruno tenker litt på saken. Hvis han bare får seg en god nok ringeklokke, vil nok ungdommene slutte å erte ham og kundene strømme på!

ringeklokke.png

Bruno har hørt om Arduino og tenker det kan passe bra til en sånn imponerende oppgave. Arduino er noe som de unge og hippe driver med; det et slags byggesett for elektronikk som lar en kople masse forskjellige sensorer og dingsebomser til programmerbare mikrokontrollere. Han kommer frem til at han vil ha masse blinkende lys og en skjerm som viser «Velkommen til Sterkesi!» I tillegg har han lyst på et lite tastatur, slik at kundene kan velge forskjellige ringeklokkemelodier, alt etter smak, behag og dannelse.

Bruno leter frem delene på nett, leser all dokumentasjonen han kan finne, og ser noen videoer på YouTube. Jo da, dette lar seg gjennomføre. Han finner et sett som har de fleste komponentene han trenger, både LCD-display, ledninger, dioder, motstander og til og med noen små piezo-høyttalere: https://www.sparkfun.com/products/13969

Men settet har ikke kodetastatur, det må han ha! Han kunne gått for de aller enkleste typene, med bare tallene 0 til 9, men han bestiller en såkalt 4 x 4 Matrix-variant, med 16 taster: http://lmgtfy.com/?q=4x4+matrix+keypad+arduino+price

Bruno ser mange andre ting han også kunne hatt bruk for – en kraftigere høyttaler, flere dioder, flere ledninger, men så kjenner han plutselig at han er sulten. Etter å ha spist blir han helt slått ut og sovner, som vanlig, med ansiktet i fatet. Han våkner etter noen timer og sier «Å nei, ikke igjen!». Bruno tørker av ansiktet og begynner å tenke … Kan han bruke denne greia som en avansert vekkerklokke også? Den må ha kodelås, for Bruno er fæl til å bare slå av vekkerklokka og sove videre. Den må ringe hver dag klokka tolv. For å forsikre seg om at han ikke bare slår av alarmen for så å sove videre, kommer Bruno på den lyse ideen om at koden skal være dagens dato, men skrevet i det binære tallsystem, så for julaften, 24/12/17, blir det sekvensen 11000 + 1100 + 10001. «Genialt», tenker Bruno. Det er vanskelig å regne binære tall i halvsøvne, selv for en gammel elektronikkmann. Bruno bestiller varene med flyfrakt og har dem på døra neste dag. Noen fordeler skal man ha ved å være mangemillionær, tenker han.

Du må hjelpe Bruno med å lage denne ringevekkerklokkehybriden. Det forutsettes at du har gått igjennom alle oppgavene i SIK-guideboka som fulgte med SparkFun-settet du har jobbet med. Det forutsettes også at du har satt deg inn i grunnleggende bruk av Fritzing for å tegne kretser.

  1. Tegn kretsen til Bruno i Fritzing. Bruno er åpenbart veldig opptatt av fancy melodier og blinkende lys, så du må ha høyttalere og dioder, gjerne med masse lyd og masse farger. Han skal også ha en LCD-skjerm og et kodetastatur. Det er kanskje ikke så lett å finne ut hvordan man skal kople kodetastaturet, men prøv å søke litt på Google. Et godt søk for å sette deg i gang kan være «4 x 4 Matrix keypad». Når det gjelder hvordan kretsen skal tegnes/koples, anbefales det å ta utgangspunkt i måten det er gjort i SIK-guiden til SparkFun.

  2. Kople opp kodetastaturet og skriv kode som gjør at du kan se at det fungerer. Du skal etter hvert skrive ut til LCD-skjermen, men i denne omgang skal du skrive ut det du trykker på, til Serial Monitor (trykk Ctrl + Shift + M i Arduino IDE for å få opp denne). Ta en kikk på Serial.print og kodeeksempler på nett knyttet til kodetastaturet.

  3. Nå som du har fått kodetastaturet til å fungere mot Serial Monitor, må du få det til å fungere mot LCD-skjermen. Kople opp kretsen på brettet i henhold til tegningen du laget i oppgave 1. Hvis du tar utgangspunkt i hvordan LCD-displayet var koplet i SIK-guiden, vil det kanskje se ut som du ikke har porter nok på Arduinoen til å bruke tastaturet i tillegg, men det skal gå, ta en nærmere kikk på Arduinoen. Hvis du ikke finner ut av det, eller ønsker en ekstra utfordring, kan du se litt ekstra på en av oppgavene i SIK-guiden som beskriver en måte å få flere utganger på.

  4. Kretsen må koples opp og programmeres. Ringevekkerklokken skal som sagt ha en skjerm som viser «Velkommen til Sterkesi!». Bruno vil også at det skal være et kodetastatur hvor man kan gi kommandoer til ringevekkerklokken, blant annet velge melodi. Det bør lages/brukes minst to forskjellige melodier. Nasjonalsangen til Italia kan kanskje være en idé for Bruno, eller en annen kjent italiensk melodi. Vekkerklokkedelen av kretsen skal ringe klokka tolv hver dag og skal ikke være mulig å slå av med mindre man taster inn dagens dato i binær form. Du kan selv velge hvordan du vil ta imot den binære «datoen». Siden Arduino ikke har et sted der den kan lagre dagens dato, må man også skrive inn dagens dato, først i desimalform (det vil si f.eks. 24.12.2017) og etterpå binært. Det anbefales å la kodetastaturets * og # stå for Ja/Nei, eventuelt Enter og Tilbake i en meny, og A til D være knyttet til annen funksjonalitet.

  5. Kretsen er sårbar hvis den bare ligger åpent på et bord. Prøv å finn en måte å få pakket kretsen inn i noe på, kanskje en skoeske eller noen plater av metall eller tre? Dette er en oppgave man bør ha i tankene når man tegner og kopler kretsen, da lengden på ledningene kan legge begrensninger for plassering av komponentene.

  6. Bonusoppgave: Bruno har ikke peiling på hva slags musikk ungdommen liker. Du må hjelpe ham!  De 16 tastene på tastaturet kan jo også fungere på samme måte som tangentene på et piano. Du må skrive kode som gjør at man kan bytte «modus» til piano ved å trykke på en knapp og få frem toner når man trykker på tastaturet. Pianoet har sju hvite tangenter, heltoner, og fem sorte, halvtoner. Du trenger altså å bruke tolv taster på tastaturet. SIK-guiden har et eksempel som bruker en piezobuzzer til å spille en melodi. Modifiser koden fra dette eksempelet og koden fra prosjektoppgaven slik at hver tast har sin tone, C, D, E, F, G, A, B. Hvis du trenger en ekstra utfordring, kan du lage støtte for å lagre melodien din og eventuelt bruke ABCD for å sette tempoet på tonen (A kan være åttendedelsnote, B kvartnote, C halvnote og D helnote). Så ved å taste 4 + C + Enter og så 6 + D + Enter, vil man kunne lagre en melodi bestående av en F halvnote fulgt av en A helnote.

piezobuzzer.png

Tips og råd til prosjektoppgave Aruino

Det anbefales å kople opp og programmere oppgaven i mindre deler. Hvis man skal ha veldig mange blinkende dioder, kan det hende at man går tom for porter på Arduinoen, se beskrivelsen til oppgave 3. Hvis det blir trangt på koplingsbrettet må man vurdere et større brett, eventuelt sette sammen to mindre. Nedenfor følger noen sider med kodesnutter som det anbefales å kjøre i Arduino IDE hver for seg, utvide og teste ut. Man trenger ikke å ha en krets koplet opp på Arduino-bordet, men selve Arduinoen må være koplet opp. Så kan man bruke Serial Monitor til å se hva som kommer ut av koden man tester ut.

Det finnes flere måter å angripe denne oppgaven på. Én måte er, som nevnt ovenfor, å kople opp små kretser av alle enkeltkomponentene først og så prøve å sy dem sammen, én etter én, linje etter linje med kode i et nytt, større prosjekt i Arduino IDE-en. En annen måte kan være å ta utgangspunkt i den kretsen i SIK-guiden som ligner mest på det prosjektoppgaven går ut på, og så skrive kode på nytt (eller hente fra andre eksempler og tilpasse) for hver enkelt komponent man skal bruke i tillegg. 

Pseudokode

For å finne ut av selve flyten i programmet er det lurt å først prøve å skrive såkalt pseudokode. Pseudokode er en måte å forklare hva som skal skje, steg for steg, uten at det nødvendigvis trenger å være syntaktisk korrekt. Dette er veldig nyttig for å forstå hva slags strukturer og ting du må ha med i koden din. Kanskje starten på programmet kan skrives som dette:

Skriv til LCD: “Velkommen til Sterkesi!” (øverste linje)
Skriv til LCD: ”Tast * for meny!” (andre linje)
IF * // Da skal vi til menyen
Skriv til LCD: ”Tast 1 for ringeklokke” (øverste linje)
Skriv til LCD: ”Tast 2 for vekkerklokke” (andre linje)
IF 1 // Da skal vi til ringeklokkemenyen…
Skriv til LCD: Tast 1 for “Sang1” (øverste linje)
Skriv til LCD: Tast 2 for “Sang2” (andre linje)

For å få til alt det man skal i dette prosjektet, må man bruke flere kontrollstrukturer enn bare if.
I prosjektene fra SIK-guiden står det forklart flere andre typer, slik som for og while. Se kodesnuttene nedenfor for flere konkrete tips

Kodesnutter

Her følger forskjellige tips til kode/funksjoner/strukturer man kan få bruk for underveis i oppgaven.

Forskjellige includes man kan/bør ha på plass for denne oppgaven:

#include <LiquidCrystal.h> // LCD-skjerm
#include <Keypad.h> // kodetastaturet

Søkeord for oppsett av kodetastatur: 
keymap matrix keypad arduino

Arduino kjører gjennom koden din veldig raskt – noen ganger så raskt at man ikke rekker å se det som skal skje. Da bruker man en forsinkelse for å få litt ekstra tid, for eksempel slik at man rekker å se at en lysdiode blinker, ett sekund på og ett sekund av.
delay(1000); // Programmet «venter» i ett sekund (1000 milisekund). 

AnalogRead

Hvis man skal lese en verdi fra en analog port, må det brukes en funksjon som heter analogRead. Her kjøres den på en tidligere definert variabel, «sensorVerdi» fra en pinne som vi har kalt «sensorPinne».
sensorVerdi = analogRead(sensorPinne);
Hvis man skal bruke seriell monitor (Ctrl + Shift + M) i Arduino IDE (f.eks. for å skrive en beskjed), må man først «åpne» monitoren:
Serial.begin(9600);
og så skrive til den:
Serial.print(“Utskrift til seriell monitor”);

Kontrollstrukturer

Hvis man bruker kontrollstrukturer slik som ifswitch eller for, kan det være lurt å plassere en utskrift i hver av disse strukturene slik at det skrives ut en beskjed når programmet kommer dit. Det gjør det lettere å finne feil i programmet og er nyttig når man skal debugge. Beskjeden kan så fjernes når programmet er ferdig testet og fungerer som det skal.

if (x <= 18)
{
Serial.print(“Utskrift til seriell monitor fra if-ens x <=18-del”);
}
else
{
Serial.print(“Utskrift til seriell monitor fra if-ens else-del”);
}


For å skrive ut noe til et LCD-display
lcd.print(“Utskrift til LCD”);

Merk at man før dette allerede bør ha definert LCD til å være knyttet til visse pinner på Arduino-bordet.

 

Input, output, tone og while

For å kunne bruke en pinne på Arduinoen må pinnen defineres: Er det input, eller er det output?
pinMode(3, OUTPUT); // Nå er pinne 3 definert som output og er klar til bruk.
For å sende strøm/signal ut på pinnen må også det skrives med kode
digitalWrite(3, HIGH); // HIGH er 5 V, LOW er 0 V.

For å spille en tone på Arduinoen bruker man en innebygget funksjon som heter tone.
tone(pinne, frekvens, varighet); // Her har vi definert en pinne på Arduinoen, en frekvens, f.eks. tonen E, som er på 330 Hz, og en varighet, det vil si lengden på tonen.

Tidligere nevnte vi at seriellmonitoren kan brukes for å skrive tekst til skjermen. Men man kan også bruke den til å sende informasjon til Arduinoen. Da kan vi bruke en annen kontrollstruktur som heter while.

while (Serial.available()>0); // Så lenge det kommer noe data fra seriellmonitor …{tallFraSerialTilArduino = serial.parseInt(); // så kan man lese/skrive dette til skjerm, som et tall (parseInt).}

noen ganger vil man måtte kombinere to forskjellige kontrollstrukturer for å oppnå det man ønsker. Det kan være for eksempel en if inne i en while, eller kanskje for inne i en if. I grove trekk kan man si at hvis ingen av strukturene alene ser ut til å løse problemet, bør man vurdere om man kanskje må sette sammen flere. 

Include

For å kunne bruke kodetastaturet må det som sagt legges til en include som inneholder en del ferdigskrevet kode som håndterer forskjellige typer tastaturer: keypad.h. Når det er gjort, må det gjøres en «mapping» i koden. Dette betyr at kodetastaturet er koplet på en bestemt måte, og at bestemte knapper på tastaturet stemmer med bestemte kombinasjoner av pinner på tilkoplingen mot Arduino. Pinne 1 til 4 er radene, og pinne 5 til 8 er kolonnene. Vi kan se for oss tastaturet som et koordinatsystem med en X- og en Y-akse, hvor alle taster finnes på en kombinasjon av vertikale rader og horisontale kolonner. Tasten 4 på kodetastaturet er i andre rad og første kolonne. Med andre ord vet vi at når det kommer et signal på Arduino-porten koplet til kodetastaturets ledning/tilkopling for rad 2 og kolonne 1, er dette alltid en 4-er.

Char array

I kode vil man «lage» tastaturet som en samling av enkelttegn og plassere tegnene i en såkalt char array
I vårt tilfelle er det snakk om et 4 x 4 Matrix kodetastatur, og vi må først definere at det er fire rader og fire kolonner. Det kan se slik ut:

const byte rader = 4;
const byte kolonner = 4;

char taster[rader][kolonner]= 
{
{'1', '2', '3', 'A'}, 
{'4', '5', '6', 'B'}, 
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

Og så kan man definere «radpinnene» og «kolonnepinnene»:
byte radPinner[rader] = {2,3,4,5}; //Rad 0 til 3 på Arduino pinne 2 til 5.
byte kolonnePinner[kolonner]= {6,7,8,9}; // Kolonne 0 til 3 på Arduino pinne 6 til 9.

Man må instansiere et keypadobjekt, her kalt kodeTastatur, for å kunne bruke kodetastaturet
Keypad kodeTastatur= Keypad((taster), radPinner, kolonnePinner, rader, kolonner);
Dette er kode hentet fra biblioteket som heter keypad.h og inneholder for eksempel en såkalt konstruktør hvor man lager et keypadobjekt ved hjelp av en funksjon som heter makeKeymap.
Det er ikke forventet og heller ikke nødvendig å forstå alle elementene i denne koden, men hvis man tar seg god tid og leser dokumentasjonen på dette og andre biblioteker på sidene til Arduino og så prøver seg frem med å skrive kode til Arduino, vil man etter hvert skjønne hvordan slike ting er laget og fungerer.

Dokumentasjonen har også en beskrivelse av alle funksjonene man kan bruke på/for tastaturet, slik som waitForKeygetKeyeventListener osv. 

Serial Monitor

For å «hente» en tast fra kodetastaturet kan vi for eksempel gjøre noe slik som dette (plassert i loop):

char tastTrykket = kodeTastatur.getKey();
if (tastTrykket != NO_KEY)
{
Serial.print(tastTrykket);
}

Koden over bruker Serial Monitor, som nevnt tidligere må denne «åpnes» før den kan brukes.

Når Bruno kommer på jobb om morgenen og skal trykke inn dagens dato (desimalt) for å slippe inn, er det ganske rett frem. For eksempel 24.12.17. Bruk * i stedet for punktum og # helt til slutt. Du må lagre hver del av datoen i en egen variabel, f.eks. dagDesimal, maanedDesimal og aarDesimal. Når så alarmen ringer klokka tolv hver dag, må du konvertere denne verdien til det binære tallsystemet og sammenligne med det Bruno tastet inn desimalt på morgenen. Her bruker vi noe som heter String Object Constructors:

For å konvertere en stringverdi fra desimal til binært kan du bruke noe lignende som det under:
String dagBinaert = String(dagDesimal, BIN);

For å lett kunne sammenligne tall bør du gjøre om slik at alt har samme datatype, Int. 
int dagSomInt = dagBinaert.toInt();

Når det er gjort, kan du stoppe ringevekkerklokkemelodien. Kanskje du har plassert koden for melodien i en while-løkke som sjekker om den binære datoen Bruno tastet inn etter lunsj, stemmer med den han tastet inn da han kom om morgenen?

While(brunosBinaereVerdi != brunosDesimaleVerdi)
{
SpillMusikk() // Dette kaller opp (kjører) en metode (som du selv har laget) som heter SpillMusikk() Se eksempler fra SIK guiden/internett.!
}

Tidsbruk, forutsetninger, forslag til innkjøp og karaktersetting

Å estimere hvor lang tid denne oppgaven vil ta for elevene, er ikke så lett. Det er nok lurt å sette av minst 20–40 timer, avhengig av ambisjonsnivå. Hvis man ønsker å bruke mer tid, anbefales det at alle løser oppgave 6. 
I så fall bør det nok beregnes minst 10–20 timer ekstra. Merk at for å kunne lagre melodiene i oppgave 6 må man bruke et Ethernet Shield som har SD-kortleser. Dette lar en også utvide oppgaven ytterligere ved å kople Arduinoen til internett og la den f.eks. sende mail til Bruno eller kunder. Hvis man ønsker å bruke ytterligere tid, kan man bestille et printkort basert på skissene i Fritzing og kople opp kretsen i en skikkelig kasse.

Det er forutsatt at elevene har greid alle øvelsene i SIK-guiden, og at de har tilgang på alle komponentene, inkludert kodetastaturet nevnt innledningsvis i prosjektoppgaven, ekstra lange ledninger og han/hun-ledninger og helst også ekstra/større brett. Det er også forutsatt at de har lest og forstått stoffet i kapittel 5 om mikrokontrollere og Arduino.

Merk igjen at for å kunne lagre ting permanent slik som beskrevet i oppgave 6 må man kople til et lagringsmedium, for eksempel en USB-minnepenn eller et SD-kort. Den enkleste måten å få til dette på er å kjøpe et Ethernet Shield, da disse kommer med SD-kortleser. Hvis man ønsker å jobbe videre med Arduino, er dette kanskje den beste investeringen, da det åpner for mange nye oppgaver og integrasjon mot web. En annen krets som kan bidra til å gjøre oppgaven mer virkelighetstro, er en RTC-modul (Real Time Clock). Denne vil kunne holde styr på og lagre tiden. Hvis man har et Ethernet Shield, kan man alternativt kople seg til en nettjeneste for å hente tiden.

Elever som greier oppgave 1 og 2, bør få minst 2, elever som greier 1, 2 og 3 bør få 3–4. Elever som greier oppgave 1, 2, 3 og 4 bør få 5, og elever som greier alle oppgavene, bør få 6. Alternativt kan utført bonusoppgave være kravet for å få 6. Dersom elever ikke greier å få ferdig kretsen, kan man vurdere å heller fokusere på utførelse av enkle regneoperasjoner via kodetastaturet og skjermen samt mestring av de mest sentrale kontrollstrukturene.