Arduino, programmering af hjemmeelektronik - del 2

Fra at installere udviklingsværktøjet og lave en simpel opstilling vil vi denne gang fokusere på faciliteterne i programmeringen af microprocessoren.

Artikel top billede

(Foto: Computerworld)

Af Kenneth Geisshirt, Alt om Data

Denne artikel er oprindeligt bragt på Alt om Data. Computerworld overtog i november 2022 Alt om Data. Du kan læse mere om overtagelsen her.

Programmeringen af Arduino er baseret på sproget Wiring, og du kan bruge et udviklingsmiljø som bygger på Processing. Alt dette kan du downloade fra Arduinos hjemmeside, og installationen af dette miljø med tilhørende oversættere blev gennemgået i første afsnit i serien.

Med Wiring får du et programmeringssprog, som mest minder om C. Det betyder, at hvis du tidligere har programmeret i C, vil du hurtigt føle dig hjemme.

Eftersom C er et proceduralt sprog, finder du ikke avancerede begreber som klasser (som i C++ eller Java) eller højere ordensfunktioner (som i Javascript). I Arduino-verdenen omtales et program som ’sketch’, men i denne artikel vil du kun læse ordet ’program’.

Sproget byder på et lille udvalg af typer. Du finder en lille oversigt i infoboksen »Datatyper«. Endvidere er det mulighed for at erklære arrays på samme måde som i C, for eksempel ved at skrive »int a[7]«. Det giver et array (navnet er ’a’) med syv elementer, alle af typen ’int’. Strenge erklæres som arrays af ’char’ − du skal dog huske at gøre plads til et NULL-tegn i slutningen af strengen.

Første element i et array har indeks 0. Som programmør skal du selv holde styr på antallet af elementer i dine arrays, men du kan bruge funktionen ’sizeof’ til at hjælpe dig.

Funktionen returnerer, hvor mange bytes en variabel fylder. Antal elementer i et array ’a’ kan derved udregnes som ’sizeof(a)/sizeof(a[0])’. Er der tale om en streng, kan du nøjes med ’sizeof(a)’, idet nævneren altid vil være 1.

Der findes et par typer af forgreninger, som du sikkert kender fra andre sprog. Med ’if’ og eventuelt ’else’ kan du lade dit program grene sig ud. Har du brug for at tjekke flere muligheder, er du nødt til at bruge en ’if’ inde i en ’else’, det vil sige noget i retning af ’if ... else if ... else’.

Med mange tjek falder læsbarheden, og med en ’switch’-konstruktion kan du lade dit program grene sig ud over mange muligheder. Hver gren begynder med en ’case’ og skal afsluttes med en ’break’.

Løkker er naturligvis også mulige. Du finder den klassiske ’for’-konstruktion. Løkke-variablen kan du erklære ved løkkens begyndelsen, hvilket giver dig et ekstra niveau af virkefelt. Du kan også opbygge løkker ved hjælp af ’while’.

Nedenfor ser du eksempler på to løkker. Der er ikke den store forskel på dem, men med ’while’ angiver du ikke nødvendigvis et bestemt antal iterationer på forhånd, mens du med ’for’ netop bruger den til det.

Løkker

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.print(”for:”);
for(int i=0; i<10; i++) {
Serial.print(i);
delay(1000);
}
Serial.println(””);

Serial.print(”while:”);
int j = 0;
while (j<10) {
Serial.print(j);
j++;
delay(1000);
}
Serial.println(””);
}

Infoboks – Funktioner
void setup() {
Serial.begin(9600);
}

void forloop(int c) {
Serial.print(”for:”);
for(int i=0; i<c; i++) {
Serial.print(i);
delay(1000);
}
}

void loop() {
forloop(10);
Serial.println(””);
}
Infoboks – Lysdæmper



int ledPin = 9;

void setup() {
}

void loop() {
for(int v=0; v<=255; v+=5) {
analogWrite(ledPin, v);
delay(30);
}

for(int v=255 ; v>=0; v-=5) {
analogWrite(ledPin, v);
delay(30);
}
}

Infoboks – Interrupts
int pin = 13;
volatile int state = LOW;
int i = 0;

void setup() {
pinMode(pin, OUTPUT);
Serial.begin(9600);
attachInterrupt(0, blink, CHANGE);
}

void loop() {
noInterrupts();
digitalWrite(pin, state);
interrupts();
}

void blink() {
Serial.print(”Skifter: ”);
Serial.println(i);
i++;
state = !state;
}

Funktionerne ’Serial.begin’, ’Serial.print’ samt ’Serial.println’ henholdsvis sætter kommunikation og sender data over den serielle (usb-) port. Du kan ved hjælp af disse funktioner sende data tilbage til din computer.

Det er muligt at erklære funktioner i dine programmer. Med C’s begrænsninger, er det ikke muligt at erklære funktioner inden i funktioner.

Du finder et eksempel på erklæring af en funktion i infoboks »Funktioner«. Funktionen ’forloop’ udfører en ’for’-løkke. Det er værd at bemærke, at det er muligt at angive argumenter til funktioner.

To vigtige funktioner

Ethvert gyldigt program til dit Arduino-board kræver, at du erklærer to funktioner. Den første er ’setup’, og den anden er ’loop’.

Funktionen ’setup’ kaldes af Arduino-boardets bootloader, når programmet startes op. Du bruger ’setup’ til at initialisere globale variable og sætte boardets porte op.

Eftersom der er flere porte, som enten kan bruges til input eller output, er ’setup’ et godt sted at specificere tilstanden, inden selve hovedprogrammet går i gang.

Hovedprogrammet finder du i funktionen ’loop’. Funktionen kaldes hver gang, funktionen ’loop’ afsluttes. Det er med andre ord tale om en uendelig løkke. Det er i ’loop’, at du skal skrive den funktionalitet, som dit program sammen med boardet skal give brugeren. Du slipper med andre ord for at skrive en uendelig løkke, selv om det i det C-lignende sprog ikke ville være svært.

Seriel kommunikation

Som allerede omtalt, findes der en række funktioner, som gør det muligt at sende til, og modtage data fra, den computer, som Arduino-boardet er sat til. Det er også muligt at kommunikere med et andet instrument end din computer, hvis dette instrument har en seriel-port. Sker kommunikationen med din computer, sker den over usb-porten, men set fra Arduino-programmøreren er det en god gammeldags RS-232 port.

Sender du data tilbage til din computer, kan du se data via den serielle monitor. Du finder den i »Tools | Serial Monitor« (eller med Shift+Control+M). Det er også muligt at sende data til Arduino-boardet, men det kræver naturligvis, at dit program kan håndtere at modtage data over den serielle port.

Med funktionen ’Serial.begin’ sætter du den serielle port op. Som argument til funktionen, kan du angive den hastighed, som data skal sendes med. Den typiske værdi er 9600 (i enheden bit/sekund). Denne funktion vil du typisk kalde i funktionen ’setup’.

Med funktionerne ’Serial.print’ og ’Serial.println’ kan du sende data fra dit Arduino-board til din computer. Der sker en automatisk konvertering, således at computeren vil modtage data, som umiddelbart kan læses af mennesker.

Det betyder, at hvis du skriver ’Serial.print(42)’, vil du modtage teksten 42 – altså to tegn. Forskellen på ’Serial.print’ og ’Serial.println’ er, at den sidste lige smider et linjeskift med over til computeren. Ønsker du at sende de rå data over til computeren, er funktionen ’Serial.write’ lige, hvad du ønsker. Med ’Serial.write(42)’ får du tallet 42 sendt.

Skal du modtage data fra computeren, kan du først tjekke, hvor mange bytes, computeren har sendt over til Arduino-boardet med funktionen ’Serial.available’. Du kan læse en byte ad gangen med ’Serial.read’.

Digitalt I/O

Der findes en del digitale ben på et Arduino-board. Antallet af ben afhænger af hvilken model, der er tale om. Hvert ben kan bruges til enten input eller output. Du styrer, om et ben er et input- eller et output-ben ved hjælpe af funktionen ’pinMode’. Kaldet ’pinMode(2, OUTPUT)’ sætter ben 2 til at være et output-ben.

Er et ben et output-ben, kan du bruge funktionen ’digitalWrite(p, v)’ til at sætte en lav eller en høj spænding eller værdi (v) på ben ’p’. Tilsvarende kan du læse værdien på et input-ben med funktionen ’digitalRead(p)’.

Hvad en høj eller lav spænding på et ben betyder, afhænger af hvilken elektronik, du har forbundet til benet. Sætter du en lyddiode på benet og GND, vil en høj spænding betyde, at dioden lyser, mens en lav spænding vil lade dioden være slukket.

Analogt I/O

Alle Arduino-boards har også analoge ben – seks ben er ikke ualmindeligt. Input-benene er forbundet med en A/D converter, som omsætter spændingen på benet til en værdi mellem 0 og 1023.

Funktionen ’analogRead(p)’ returnerer værdien på ben ’p’. Du kan købe forskellige sensorer (lys, temperatur, og så videre) og sætte dem på dit board’s analoge ben og på den måde bygge kompakte måleinstrumenter.

Der findes en række porte, som kan bruges som analogt output - eller næsten analogt output. Et Arduino-board har en række PWM-porte. PWM er en forkortelse for Pulse Width Modulation.

Ideen er at skiftevis sætte en høj og en lav spænding i forskellige tidsperioder. Du kan sige, at spændingen pulser med forskellig bredde (i tid). Pulser din microprocessor hurtigt nok, vil komponenterne se det, som om spændingen er et sted mellem lav og høj.

Med en Arduino kan du bruge funktionen ’analogWrite(p, v)’ til at sætte ben ’p’ til at pulsere. Værdien af ’v’ bestemmer, hvordan komponenterne vil se spændingen, 0 svarer til lav, mens 255 svarer til høj. Programmet i infoboks »Lysdæmper« viser dig, hvordan en Arduino kan skrue op og ned for lysstyrken i en lysdiode, som er sat til ben 9 (sammen med en modstand).

Interrupts

En række Arduino-boards har muligthed for at lade eksterne hændelse give anledning til et interrupt. En interrupt-handler i Arduino er en funktion, som kaldes når et interrupt indtræffer.

Som navnet antyder (interrupt er engelsk for afbrydelse), vil interrupt-handleren afbryde, hvad programmet ellers er i gang med og hoppe direkte til funktionen.

Det betyder, at du kan programmere dit Arduino-board til at reagere på eksterne hændelser. Ofte er det de digitale ben to og tre, som kan bruges til at hændelserne.

Funktionen ’attachInterrupt(i, f, m)’ sætter en interrupt-handler op for interrupt ’i’ (0 er ben 2, 1 er ben 3) ved hjælpe af funktionen ’f’. Med ’m’ kan du styre, hvad der skal udløse et interrupt (LOW, når benet har lav spænding, CHANGE, når spændingen skifter, RISING ,når det går fra lav til høj og endelig FALLING, når benets spænding går fra høj til lav). Med funktionen ’detachInterrupt(i)’ kan du fjerne en interrupt-handler for interrupt ’i’.

Funktionerne ’noInterrupts’ og ’interrupts’ sikrer en kritisk region i dit program. En kritisk region er en række programlinjer, som du ønsker ikke må afbrydes af et interrupt.

I infoboks »Interrupts« kan du se et eksempel på, hvordan en interrupt-handling kan bruges. Til Arduino-boardet er sat en trykknap på det digitale ben 2 – og trykknappen får også strøm fra boardet (5V + GND). En global variabel tælles op for hver gang, du trykker på knappen og sender data over den serielle port.

Biblioteker

Der findes en utal af software-bibliotekter til udvikling af Arduino-programmer. Det betyder, at du ikke behøver at skrive alting fra grunden. Du har allerede set, hvordan du kan bruge ’Serial’-bibliotektet til at sende og modtage data over den serielle port.

En del biblioteker er bundet til særlig hardware, for eksempel et krystal-display, en stepper-motor eller en ethernet-controller. Der findes også en række generiske biblioteker til generering af tilfældige tal og håndtering af strenge.

Du gør klogt i at foretage et par søgninger på internettet, inden du kaster dig ud i at implementere en bestemt funktion, måske findes den allerede under en open source licens.

Næste gang I næste og sidste afsnit i serien om åben hardware og Arduino, vil vi bygge en større opstilling og udvikle software til den. Det vil give dig et større overblik i, hvordan de forskellige elementer i Arduino-verdenen hænger sammen.

Læses lige nu

    Netcompany A/S

    Microsoft Operations Engineer

    Nordjylland

    Unik System Design A/S

    QA Engineer

    Nordjylland

    Netcompany A/S

    Linux Operations Engineer

    Københavnsområdet

    Computerworld Events

    Vi samler hvert år mere end 6.000 deltagere på mere end 70 events for it-professionelle.

    Ekspertindsigt – Lyt til førende specialister og virksomheder, der deler viden om den nyeste teknologi og de bedste løsninger.
    Netværk – Mød beslutningstagere, kolleger og samarbejdspartnere på tværs af brancher.
    Praktisk viden – Få konkrete cases, værktøjer og inspiration, som du kan tage direkte med hjem i organisationen.
    Aktuelle tendenser – Bliv opdateret på de vigtigste dagsordener inden for cloud, sikkerhed, data, AI og digital forretning.

    Digital transformation | København

    Executive Conversations: Kina, Trump og AI-ledelse

    Kina, USA og AI flytter magt og markeder. Geopolitik rammer leverandørkæder, chips, data og standarder. Lær at koble global risiko med konkret it-ledelse. Få styr på governance, sikkerhed og compliance i AI. Deltag og styrk din handlekraft.

    Infrastruktur | København

    Cloud & infrastruktur 2026: AI, afhængighed og digital handlefrihed

    Cloud er strategisk infrastruktur og fundament for AI, drift og innovation. Geopolitik og regulering ændrer leverandørvalg og dataplacering. Computerworld samler beslutningstagere om afhængighed, europæiske alternativer og digital handlefrihed.

    Digital transformation | Aarhus C

    Computerworld Summit 2026 - Aarhus

    Styrk din digitale strategi med konkret brug af AI og ny teknologi. Mød 200 it-professionelle, få indsigter, løsninger og netværk på én dag. Computerworld Summit i Aarhus viser hvordan teknologi skaber forretningsværdi – her og nu.

    Se alle vores events inden for it

    Navnenyt fra it-Danmark

    55,7° North (a Beautiful Things company) har pr. 2. februar 2026 ansat Philip Jacobi Zahle, 53 år,  som Partner & CSMO. Han skal især beskæftige sig med Ansvar for Salg, Marketing og Brandudvikling i Norden, som han tidligere har gjort med GoPro, Skullcandy og Insta360 m.fl. Han kommer fra en stilling som Marketing & Branding Manager hos Boston Group A/S. Han har tidligere beskæftiget sig med distribution og brand building gennem 26 år og er kendt fra mærker som GoPro, Skullcandy og Insta360. Nyt job

    Philip Jacobi Zahle

    55,7° North (a Beautiful Things company)

    Renewtech ApS har pr. 15. marts 2026 ansat Jouni Salo som Account Manager for Sverige. Han skal især beskæftige sig med med at styrke Renewtechs nordiske tilstedeværelse med fokus primært på det svenske marked. Han kommer fra en stilling som Key Account Manager hos GoGift. Han har tidligere beskæftiget sig med udvikling af salgsaktiviter og kunderelationer på tværs af flere markeder. Nyt job

    Jouni Salo

    Renewtech ApS

    Netip A/S har pr. 1. marts 2026 ansat Maria Lyng Refslund som Marketing Project Manager ved netIP Herning. Hun kommer fra en stilling som Marketing Project Manager hos itm8. Nyt job
    Netip A/S har pr. 1. marts 2026 ansat Ajanta Holland Christensen som Sales Manager ved netIP's kontor i Aarhus. Han kommer fra en stilling som Account Manager hos Orange Cyberdefense. Nyt job