← Kursens material Mikrokontrollern och Arduino IDE · område 2 Område 2

Område 2 · lektion 6

Mikrokontrollern och Arduino IDE

Nu kommer kortet fram. Område 1 handlade om kretsen som gör samma sak varje gång den får spänning. Härifrån och framåt sitter det något emellan som kan bestämma sig – och det du skriver är det som bestämmer.

Mål

Genomgång

Vad en styrenhet är

En styrenhet sitter mitt i en kedja. Något går in, något händer inuti, något går ut. Bygge 0 hade bara den vänstra och den högra delen ihopkopplade med koppartråd: kretsen kunde inte välja något.

Styrkedjan ritad som tre rutor på rad. Från vänster: givare, styrenhet, ställdon. En pil går från givaren till styrenheten och en pil från styrenheten till ställdonet. Inuti styrenhetens ruta står ordet program. givare knapp styrenhet program ställdon servo in ut

Kortet, och vad de fyra pinngrupperna heter

Kortet i ditt kit är en Arduino Uno R3. Chippet på det heter ATmega328P och är själva mikrokontrollern; resten av kortet finns för att göra chippet användbart – USB-anslutning, spänningsregulator, stiftlister att sticka sladdar i.

Uno-kortet sett uppifrån, förenklat. En avlång rektangel med USB-uttaget till vänster och strömuttaget under det. Längs överkanten ligger stiftlisten med de digitala pinnarna D0 till D13. Längs nederkanten ligger till vänster strömpinnarna 5 V, 3,3 V, GND och VIN, och till höger de analoga ingångarna A0 till A5. Mitt på kortet sitter chippet ATmega328P. ATmega328P D0 – D13 5 V · 3,3 V · GND · VIN A0 – A5 USB ström

Talen du behöver komma ihåg:

StorhetUno R3 / ATmega328P
Logiknivå5 V. HIGH är 5 V, LOW är 0 V
Digitala pinnar14 stycken, D0–D13
Analoga ingångar6 stycken, A0–A5
Klockfrekvens16 MHz
Programminne (flash)32 KB, varav 0,5 KB tas av bootloadern
Arbetsminne (SRAM)2 KB
Ström per pinne20 mA rekommenderat, 40 mA absolut tak
Ström genom alla I/O-pinnar tillsammans200 mA. Chippets absoluta tak
Ström ut ur 5 V-stiftetSätts av matningen, inte av chippet. Över USB: 500 mA att dela på

De två sista raderna handlar om olika saker, och de blandas lätt ihop. De 200 mA är vad chippet självt tål genom sina pinnar tillsammans – en gräns i kislet, som du slår i genom att hänga för många lysdioder på för många pinnar. 5 V-stiftet är däremot ingen pinne på chippet utan en genomkoppling till kortets matning: matas kortet över USB delar kortet och allt du kopplat in på portens 500 mA. Servot i lektion 9 slår i den andra gränsen, aldrig i den första.

Två av talen är värda att räkna på direkt. 16 MHz betyder 16 000 000 klockcykler per sekund, alltså

1 / 16 000 000 s = 0,0000000625 s = 62,5 ns per cykel

Det är därför en loop() som bara läser en pinne hinner varvas många tusen gånger i sekunden. 2 KB SRAM är 2048 byte, och där ska allt som ändrar sig medan programmet kör rymmas. En lista med 100 heltal tar 100 · 2 = 200 byte, alltså 200 / 2048 ≈ 9,8 procent av hela arbetsminnet. Datorn du skriver på har ungefär en miljon gånger mer. Kortet är litet med flit: det ska kosta lite, dra lite ström och göra en sak pålitligt.

Programmet körs på kortet, inte på datorn

Det här är den vana från Programmering 1 som spricker först. I Python skriver du en rad och den körs. Här händer i stället det här:

  1. Du skriver en sketch – ett Arduino-program – i Arduino IDE på datorn.
  2. Du trycker Ladda upp. IDE:n kompilerar hela sketchen till maskinkod. Finns ett enda fel någonstans stannar det här, och ingenting laddas upp.
  3. Maskinkoden överförs via USB-sladden till kortets flashminne.
  4. Kortet startar om och börjar köra. Nu är datorn inte längre inblandad. Drar du ur USB-sladden och sätter i den igen kör programmet från början, utan att du laddat upp något nytt.

Följden är att du inte kan skriva en halv rad och se vad som händer. Det finns ingen REPL. Det finns heller ingen skärm att skriva ut på – det närmaste är seriemonitorn, och den tas upp i nästa guide.

Arduino IDE: de fyra sakerna du behöver hitta

setup() och loop()

En sketch måste innehålla exakt två funktioner, och de har bestämda namn.

void setup() {
  // Körs en gång, direkt efter att kortet startat.
}

void loop() {
  // Körs sedan om och om igen, för alltid.
}

setup() är där du ställer in saker som ska gälla hela tiden: vilka pinnar som är ingångar och vilka som är utgångar. loop() är själva programmet. När loop() nått sista raden börjar den om från den första, utan paus. Det är inte du som skriver den slingan – den finns redan i Arduino-miljön och anropar din loop().

void framför namnet betyder att funktionen inte lämnar tillbaka något värde. Mer om varför det måste stå där i nästa guide.

Den första utsignalen: digitalWrite

Uno-kortet har en inbyggd lysdiod kopplad till pinne 13. Den har det färdiga namnet LED_BUILTIN, och den är perfekt att börja med eftersom den inte kräver en enda sladd.

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

Tre nya ord:

Blinkningen ovan tar 500 + 500 = 1000 ms per varv, alltså ett varv i sekunden.

En egen lysdiod på en egen pinne

Byt LED_BUILTIN mot ett tal och du styr vilken pinne som helst. Men en lysdiod på en egen pinne behöver samma förresistor som i område 1, av exakt samma skäl:

U = 5,0 V − 2,0 V = 3,0 V

R = U / I = 3,0 V / 0,020 A = 150 Ω

De 20 mA som är rekommenderat tak per pinne är alltså precis den ström en vanlig lysdiod vill ha. Det är ingen tillfällighet – men det betyder också att pinnen inte har något över. Ska något dra mer än så måste strömmen komma någon annanstans ifrån, vilket är hela poängen med servot i lektion 9 och med drivkretsen i område 5.

const int LAMPA_PIN = 8;

void setup() {
  pinMode(LAMPA_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LAMPA_PIN, HIGH);
  delay(500);
  digitalWrite(LAMPA_PIN, LOW);
  delay(500);
}

Rita innan du kopplar Kopplingsschemat från område 1 gäller fortfarande. Kortet ritas som en ruta med de pinnar du faktiskt använder utsatta – inte alla fjorton. En lysdiod på D8 blir: D8 → motstånd → lysdiodens anod, lysdiodens katod → GND. Två komponenter och två sladdar, och ändå värt att rita, eftersom det är ritningen du felsöker mot när den inte lyser.

I industrin och i vardagen

I industrin: en produktionslina styrs sällan av ett Uno-kort utan av en PLC – en programmerbar styrenhet byggd för verkstadsmiljö. Idén är densamma: ingångar läses, ett program kör, utgångar sätts. Skillnaden syns i talen. Uno-kortets pinnar arbetar med 5 V och 20 mA per pinne, medan en PLC:s in- och utgångar typiskt arbetar med 24 V och kan koppla en halv ampere direkt ut på en kontaktor eller en ventil. Det är ungefär fem gånger spänningen och tjugofem gånger strömmen, plus ett hölje som tål damm, olja och vibration. En PLC är dessutom byggd för att köra i åratal utan omstart, medan ett Uno-kort är byggt för att kosta lite.

I vardagen: centrallåset i en bil är samma kedja som figuren ovan, en gång per dörr. Du trycker på knappen i förardörren – det är givaren. En styrenhet läser trycket och avgör om bilen står stilla och om nyckeln finns i närheten. Sedan får en liten motor i varje dörr order om att dra låskolven – ställdonet. Att det inte är fyra sladdar direkt från knappen till fyra motorer märker du på att bilen vägrar låsa när en dörr står på glänt: mellan knappen och motorn sitter något som kan säga nej. Det är precis det en styrenhet är till för.

Prova själv

  1. Sätt i kortet, välj kort och port, och ladda upp blinkexemplet med LED_BUILTIN. Kontrollera att lysdioden på kortet blinkar en gång i sekunden.
  2. Ändra de två delay(500) till delay(100) och ladda upp igen. Räkna ut i förväg hur många blinkningar per sekund du ska få, och kontrollera sedan mot verkligheten.
  3. Dra ur USB-sladden. Sätt i den igen utan att ladda upp. Vad händer, och varför?
  4. Räkna ut förresistorn till en röd lysdiod från 5 V vid 20 mA, bygg kretsen på kopplingsdäcket från pinne D8, och flytta över blinkningen dit. Rita schemat innan du kopplar.

Kontrollfrågor

Varför räcker det inte att skriva digitalWrite(8, HIGH); om man glömt pinMode()?

Utan pinMode(8, OUTPUT) står pinnen kvar som ingång. En ingång lyssnar, den driver ingenting, och digitalWrite på en ingång slår i stället på det interna pull-up-motståndet. Resultatet blir i bästa fall en mycket svagt lysande lysdiod, i praktiken oftast ingenting alls. Koden kompilerar utan fel, vilket är det som gör felet svårt: det finns inget felmeddelande att läsa.

Vad är skillnaden mellan Verifiera och Ladda upp?

Verifiera kompilerar sketchen och stannar där. Ladda upp kompilerar och överför resultatet till kortet. Verifiera går alltså att göra utan att kortet ens är inkopplat, och är det snabbaste sättet att kontrollera att koden är syntaktiskt hel.

Din blinkning har delay(250) både för tänt och för släckt. Hur många hela blinkningar blir det på tio sekunder?

Ett varv tar 250 + 250 = 500 ms. På 10 sekunder, alltså 10 000 ms, blir det 10 000 / 500 = 20 varv. Tjugo blinkningar.

Du vill driva en liten summer som drar 60 mA direkt från en pinne. Går det?

Nej. Absolut tak per pinne är 40 mA och rekommenderat är 20 mA, så 60 mA ligger en och en halv gång över det absoluta taket. Pinnen kan skadas, och skadan är permanent. Något som drar mer än 20 mA behöver ta strömmen någon annanstans ifrån och bara styras av pinnen – det är vad drivkretsen i område 5 handlar om.

Varför ska du undvika pinne 0 och 1 till dina egna komponenter?

De används av kortets seriella kommunikation över USB, alltså av samma kanal som uppladdningen och seriemonitorn går genom. Sitter en komponent på dem kan uppladdningen misslyckas eller utskrifterna bli obegripliga. Det finns tolv andra digitala pinnar – använd dem.

Kortet har 2 KB SRAM. Hur många heltal av typen int ryms i minnet om ingenting annat funnes där?

2 KB är 2048 byte och en int tar 2 byte på det här kortet, alltså 2048 / 2 = 1024 heltal. I praktiken betydligt färre, eftersom biblioteken och Arduino-miljön också behöver plats. Att en int är just 2 byte här är nästa guides ämne.

Vanliga fel

Vidare

Kapitlet Från Python till C++ i språkreferensen hör till den här guiden – särskilt den första raden i tabellen, om att ingenting kör förrän allt kompilerat.

Nästa guide är C++ efter Python, där du får veta varför void och int måste stå utskrivna, och hur du får se vad som händer inuti kortet.