ELEC-A4010 Sähköpaja Arduinon ohjelmointi Peter Kronström
Arduinon rakenne 5 voltin regulaattori 16 MHz kide USB-sarjamuunnin ATmega328 -mikrokontrolleri 20 I/O-pinniä, joista 14 digitaalista ja 6 analogista
Mitä me oikein ohjelmoimme? ATMega328 - Etenkin harrastelijapiireissä yleisesti käytetty mikrokontrolleri 32 KB Flash-muistia, 2 KB SRAM 'käyttömuistia' ja 1 KB EEPROMmuistia datan pidempiaikaiseen säilytykseen. Flash-muisti bootloaderin ja ohjelmakoodin käytössä SRAM toimii ohjelman väliaikaisena käyttömuistina EEPROM ikäänkuin kovalevy, jolle voi tallentaa dataa pitkäkestoisesti. Kirjoittaminen hidasta. Toimii 16 MHz taajuudella
Mitä me oikein ohjelmoimme? 20 I/O-pinniä, jotka ovat vapaasti ohjelmoitavissa Lisäksi muita hyödyllisiä ominaisuuksia, kuten Kolme ajastinta, 6-kanavainen PWM, kaksi AD-muunninta, USART-, SPI- ja 2-Wire -väylät, vahtikoira-ajastin, keskeytykset yms. Näihin ominaisuuksiin pääsemme käsiksi ohjelmakoodin kautta manipuloimalla mikrokontrollerin rekistereitä.
Arduino-ohjelmointikieli Arduino-ohjelmointikieli on joukko C-kielen kirjastoja, jotka piilottavat taustalta monimutkaisempia C-kielen kutsuja // Suoraan AVR-C:llä PORTA = 0xFF; // alustusarvo HIGH DDRA = 0x80; // aseta 8. pinni ulostuloksi // Arduino-kirjaston avulla DigitalWrite(8, HIGH);
Arduino-IDE Kaikki Arduinolla ohjelmoimiseen tarvittava tulee Arduinokehitysympäristön (Arduino-IDE) mukana. Sisältää mm. AVR C-kääntäjän, joka kääntää C-koodin konekielelle ja poistaa turhat osat Hoitaa kommunikoinnin mikrokontrollerin ja tietokoneen välillä Siirtää koodin sarjaväylän kautta mikrokontrolleriin Lisäksi mm. koodi-editori, kirjastonhallintatyökalu ja työkalu sarjaportin kuunteluun
Arduino-ohjelman perusrakenne #include <math.h> int ledpin = 13; int sensorpin = 4; void setup() pinmode(ledpin, OUTPUT); pinmode(sensorpin, INPUT); // Matemaattisia funktioita // Merkkivalo // Anturi bensatankissa // Suoritetaan vain kerran alussa // I/O-porttien alustus void loop() // Suoritetaan kerta toisensa perään // analogread palauttaa arvon välillä [0, 1023]. int gaslevel = analogread(sensorpin); int ledon = gaslevel < 300; // LED sytytetään kun tankki lähes tyhjä digitalwrite(ledpin, ledon);
Muuttujien käyttöalue eli skooppi Kaarisulkeet määräävät muuttujan eliniän int porkkana = 3; void setup() int kaali = porkkana + 5; // Tämä on OK, sillä porkkana on // globaali void loop() porkkana = kaali; // Virhe: muuttujaa 'kaali' ei // ole määritelty
C-kieli: datatyypit C-kielessä on kymmenittäin datatyyppejä, jotka erottavat muuttujat toisistaan säilytettävän tiedon osalta - void - boolean (0, 1, true, false) - char ('a', -128, 127) - int (-32768... 32767)' - long (-2147483648... 2147483647) - unsigned char (0.. 255) - byte (0.. 255) - unsigned int (0.. 65536) - word (0.. 65536) - unsigned long (0.. 4294967295) - float (-3.4028e+38 to 3.4028e+38) - double (toistaiseksi sama kuin float) - 123 (desimaali) - 0267 (oktaali) - 0b10100011 (binääri) - 0xA3 (heksadesimaali) - 7U (unsigned) - 11L (long) - 15UL (unsigned long) - 12.3 (liukuluku) - 3.4e3 (3.4 * 10^3)
C-kieli: operaattorit Kutakuinkin samat kuin Pythonissa + summa a == b yhtäsuuri - erotus a!= b erisuuri * tulo a < b pienempi / osamäärä a > b suurempi % jakojäännös a <= b pienempi tai yhtäsuuri & bittikohtainen ja a >= b suurempi tai yhtäsuuri bittikohtainen tai a-- vähennä muuttujan arvoa yhdellä ^ bittikohtainen xor a++ kasvata muuttujan arvoa yhdellä = asettaa muuttujan arvon ja monia muita
C-kieli: boolen operaattorit Mahdollistavat logiikan a && b JA If (true && false) digitalwrite(ledpin, HIGH); a b TAI If (true false) digitalwrite(ledpin, HIGH);!a EI If (!false) digitalwrite(ledpin, HIGH);
C-kieli: ohjausrakenteet - if if (ehto) // tee jotain ehdon toteutuessa
C-kieli: ohjausrakenteet if - else if (ehto) // tee jotain ehdon toteutuessa else if (ehto) //huom EI elif // tee jotain edellisen ollessa false else // kaiken muun pettäessä tänne
C-kieli: ohjausrakenteet while while (ehto) // tee jotain jatkuvasti
C-kieli: ohjausrakenteet for for (alkuarvo; ehto; askel) // tee jotain jatkuvasti // esimerkiksi for (int i=0 ; i< 10; i++) Serial.println(i);
C-kieli: taulukot Taulukkoja kannattaa hyödyntää, mikäli samankaltaisia muuttujia tarvitaan paljon, esimerkiksi ledipinnien alustamiseen tai vaikkapa ledianimaation vaiheiden tallentamiseen. int led1 = 3, led2 = 5, led3 = 6; Int ledit[3] = 3, 5, 6; Taulukon jäsenet ovat alkioita, ja niihin pääsee käsiksi [n]- operaattorilla. Indeksointi alkaa nollasta. For (int i=0; i<3; i++) pinmode(ledit[i], OUTPUT);
C-kieli: merkkijonot Merkkijonot ovat char-taulukoita const char* hedelma = omppo ; // kyseinen merkkijono näyttää tältä // 'o', 'm', 'p', 'p', 'o', '\0' '\0' -merkki kertoo, merkkijonon loppuvan, sillä muuttujaan hedelma tallennetaan vain merkkijonon ensimmäisen alkion muistiosoite. Hyödyllisiä funktioita merkkijonon käsittelyyn ja muunnoksiin ovat mm. strcpy, strcat, strcmp, itoa ja atoi
C-kieli: funktiot Myös omaa Arduino-koodia olisi hyvä oppia jakamaan funktioihin, jotta koodin lukeminen helpottuisi ja eri koodina osia olisi helpompi käyttää uudelleen. void loop() If (ishotday(sensor1, sensor2)) digitalwrite(hotled, HIGH); int ishotday(int temp, int light) // return 1 if it is, 0 otherwise if (temp >= 30 && light >= 50) return 1; else return 0;
Arduino-kirjasto: digitalread Lukee pinnin arvon (digitaalisena) LOW tai HIGH void setup() pinmode(3, INPUT); void loop() byte arvo = digitalread(3);
Arduino-kirjasto: digitalwrite Asetetaan pinnin arvo joko LOW tai HIGH -tasoon (Arduino UNOlla siis 0V tai 5V). Esimerkiksi ensimmäisellä harjoituskerralla tehty blink-sketch. int ledpin = 13; // LED connected to digital pin 13 void setup() pinmode(ledpin, OUTPUT); void loop() digitalwrite(ledpin, HIGH); delay(1000); digitalwrite(ledpin, LOW); delay(1000); // sets the digital pin as output // sets the LED on // waits for a second // sets the LED off // waits for a second
Arduino-kirjasto: analogread analogreadin avulla pystymme lukemaan analogisista pinneistä jännitteen. AD-muunnin tekee mikrokontrollerissa 10-bittisen analogidigitaalimuunnokseen, joka tuotta luvun väliltä [0, 1023]. void loop() int sensorvalue = analogread(sensorpin); Serial.println(sensorValue);
Arduino-kirjasto: analogwrite analogwrite ei ole täysin analogreadin vastakohta emme pysty kirjoittamaan pinneihin suoraan haluttua jännitettä, vaan se pitää 'simuloida' kanttiaallon avulla (PWM, pulssinleveysmodulaatio) Toimii vain tietyistä PWM-pinneistä, jotka ovat Arduino UNO:ssa merkitty tildellä ~. PWM-toiminto käyttää mikrokontrollerin ajastimia. Mahdollistaa esimerkiksi moottorin nopeuden säätämisen lähes portaattomasti tai LEDin himmentämisen. void loop() analogwrite(ledpin, 127); // led palaa 50% pulssisuhteella
Arduino-kirjasto: muuta hyödyllistä Arduino-kirjasto sisältää myös joukon muita hyödyllisiä funktioita, joista on apua omissa projekteissa millis() // aika Arduinon käynnistyksestä millisekunneissa map() // muuttujan arvovälin mappaaminen toiselle // esim. [0, 1023] [0, 256] min(), max(), abs(), sin(), cos()... random() // satunnaislukuja Serial // kirjasto sarjakommunikaatiolle Servo // kirjasto helpompaan Servomoottorin liikutteluun Lisäksi tarjolla on satoja ulkopuolisia kirjastoja toimintojen helpottamiseksi ja oheislaitteiden käyttöön.
Vinkkejä ohjelmointiin Arduinon koodieditori on huono suosittelen isommille projekteille erillistä tekstieditoria tai kehitysympäristöä Notepad++ ja Sublime Text Eclipsellä oma plugin Arduinolle Irkkaajat huomio! Puttyllä voi lukea myös sarjaportteja. Arduinon dokumentaatiosivulta löytyy yllättävän paljon apua ongelmiin
Vinkkejä ohjelmointiin: debuggaus Serial-kirjaston tulostuskomento Serial.print() on hyvä keino debugata rikkinäistä koodia. int analogpin1 = 3; // anturi kiinni pinnissä 3 int analogpin2 = 4; // toinen anturin pinnissä 4 int val = 0; void setup() Serial.begin(9600); // alusta sarjaportti void loop() val1 = analogread(analogpin1); // lue anturin 1 arvo val2 = analogread(analogpin2); // lue anturin 2 arvo Serial.print(val1); // tulosta se sarjakonsoliin Serial.print(, ); // tulostaa uudelle riville: Serial.println(val2); // 125, 12
Vinkkejä ohjelmointiin: debuggaus Serial Monitor auki tästä napista Muista asettaa sarjaportin nopeus koodia vastaavaksi (usein esimerkeissä 9600 bps)
Hyödyllisiä linkkejä http://arduino.cc/en/reference/homepage
Hyödyllisiä linkkejä http://www.atmel.com/images/doc8161.pdf
Hyödyllisiä linkkejä https://github.com/liffiton/arduino-cheat-sheet
Hyödyllisiä linkkejä http://tronixstuff.com/