elec-a4010 sähköpaja arduinon ohjelmointi · arduino uno r3 6-20vdc → 5vdc muunnin 16 mhz...

22
Jukka Helle ELEC-A4010 Sähköpaja Arduinon ohjelmointi

Upload: hakiet

Post on 19-Oct-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

Jukka Helle

ELEC-A4010 SähköpajaArduinon ohjelmointi

Arduino UNO R3

● 6-20VDC → 5VDC muunnin● 16 MHz kideoskillaattori ● USB-sarjamuunnin

(ATmega16U2)● ATmega328 -mikro-ohjain

– 14 digitaalista I/O väylää● 6 kpl PWM

– 6 analogista sisääntuloa

ATmega328● Kellotettavissa 20MHz asti● 32 KB Flash-muistia

– 0.5 KB bootloaderin käytössä– Ohjelmakoodin tallennuspaikka

● 2 KB SRAM– Ohjelman käyttömuisti– Tyhjenee kun virrat katkaistaan

● 1 KB EEPROM– Kuin pieni kiintolevy, kirjoitus hidasta

Arduino-ohjelman rakenne

#include <math.h> // Matemaattisia funktioita

int ledPin = 13; // Merkkivaloint sensorPin = 4; // Anturi bensatankissa

void setup() // Suoritetaan vain kerran alussa{

pinMode(ledPin, OUTPUT); // I/O porttien määrittelypinMode(sensorPin, INPUT);

}

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);

}

Kaarisulkeet...

● ... määräävät muuttujan eliniän

int dog = 8;

void setup(){

int cat = dog + 1; // OK: cat == 9}

void loop(){

dog = cat; // Virhe: muuttujaa 'cat' ei ole// määritelty

}

Datatyypit● 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 float)

● 183 (desimaali)● 0267 (oktaali)● 0b10110111 (binääri)● 0xB7 (heksadesimaali)● 7U (unsigned)● 10L (long)● 15UL (unsigned long)● 10.0 (liukuluku)● 2.4e5 (2.4*10^5 = 240000)

Huom! Liukulukujen (float, double) laskenta on hidasta kokonaislukuihin verrattuna.

Aritmeettiset operaattorit● = (asettaa muuttujan arvon)● + (summa)● - (erotus)● * (tulo)● / (osamäärä, älkää jakako nollalla!)● % (jakojäännös)

● & (bittikohtainen ja)● | (bittikohtainen tai)● ^ (bittikohtainen xor)

● Myös muita: ++a, --a, a++, a--, +=, -=, /=, *=, %=...

Vertailuoperaattorita == b (yhtäsuuri)

a != b (erisuuri)

a < b (pienempi)

a > b (suurempi)

a <= b (pienempi tai yhtäsuuri)

a >= b (suurempi tai yhtäsuuri)

Varo vaaraa! Muista kaksi = -merkkiä kun tarkastelet muuttujien yhtäsuuruutta.

(a == 2) vs. (a = 2)

Jälkimmäinen lauseke asettaa muuttujan a arvoksi 2.

Boolen operaattorita && b (ja)

a || b (tai)

!a (ei)

Huomioi edellä kaksi & tai | -merkkiä. Esimerkkejä:

int a = 8;int b = 2;

(a > b) => true (a on suurempi tai yhtäsuuri kuin b)(a < 2) || (a > 12) => false (a on pienempi kuin 2 tai suurempi kuin 12)(a == b) => false (a on yhtäsuuri kuin b)!a && (b > 2) => false (a on 0, ja b on suurempi kuin 2)

Ohjausrakenteet

● ifif(n > 100){

n = 0;}

if(n){

// Täällä oleva koodi suoritetaan aina, paitsi silloin kun// muuttujan n arvo on 0.

}

Ohjausrakenteet

● if .. else if .. elseif(a < 3){

digitalWrite(ledPin, 1);}else if((a > 100) && (a < 150)){

digitalWrite(ledPin, 0);}else{

delay(100);}

Ohjausrakenteet

● do ... whileint a = 100;

do{

a = a - 1;}while(a > 0);

a = 100;

while(a > 0){

a = a - 1;}

int buttonPin = 6;

void setup(){

pinMode(buttonPin, INPUT_PULLUP);}

void loop(){

while(1){

int button = digitalRead(buttonPin);if(button == 0){

break;}

}

// Nappia on nyt painettu.}

Ohjausrakenteet

● forfor(int a = 0; a < 1000; a = a + 1){

Serial.println(a);}

int b = something();for(b = 0; b < 1000; ++b){

Serial.println(b);}

for(byte c = 10; c >= 0; --c); // Ei pääty koskaan, miksi?

Muuttujat

● Under/overflow

● Kokonaisluvun jakaminen

byte c = 0; // c = 0b00000000, 0--c; // c = 0b11111111, 255c = c + 1; // c = 0b00000000, 0

c = 3; // c = 0b00000011, 3c = c / 2; // c = 0b00000001, 1

c = 7; // c = 0b00000111, 7c = c / 8; // c = 0b00000000, 0

Taulukot

Taulukkot ovat käteviä mikäli samanlaisia muuttujia tarvitaan paljon, esim. jos useampi nappi on kytkettynä Arduinoon.

int nappi1 = 5, nappi2 = 7, nappi3 = 8;

int napit[3] = {5, 7, 8};

Taulukon jäsenet ovat alkioita. Edellinen taulukko sisältää 3 alkiota. Yleensä on myös järkevää tallentaa taulukon jäsenien määrä johonkin muuttujaan:

const int nappeja = 3; // const tarkoittaa arvon olevan vakio

for(int i = 0; i < nappeja; ++i){

napit[i] = napit[i] + 1;}

napit[3] = 5; // Mitä tässä tapahtuu?

Merkkijonot

Merkkijonot ovat char-taulukoita.

const char *greeting = “moi”;

{'m', 'o', 'i', '\0'}{109, 111, 105, 0}{0x6D, 0x6F, 0x69, 0x00}{0b01101101, 0b01101111, 0b01101001, 0b00000000}

Merkkijonon muuttuja on numero, joka kertoo ainoastaan ensimmäisen merkin muistiosoitteen.

Piiloitettu nolla-merkki ('\0') kertoo merkkijonon loppuvan.

Jokaisella merkillä on numeroarvot. Ne löytyvät ASCII-taulukosta.

Merkkijonojen käsittelyyn on funktioita esim. strcpy, strcat, strcmp.

digitalReadvoid setup()

{pinMode(3, INPUT);pinMode(4, INPUT_PULLUP);

}

void loop() {

byte arvo = digitalRead(3);

byte nappi = digitalRead(4);

// Jne...

}

● INPUT_PULLUP kytkee sisäisen vastuksen portin ja käyttöjännitteen (5V) välille

● Jännite nousee itsestään ylös kun porttia ei ole kytketty mihinkään (esim. painikkeen takia avoin piiri)

digitalWritevoid setup() {

pinMode(13, OUTPUT);

}

void loop() {

digitalWrite(13, 1);

digitalWrite(13, 0);

}

● Ylläoleva ohjelma tuottaa kanttiaaltoa ainoastaan n. 121 kHz taajuudella, vaikka prosessorin kellotaajuus on 16 MHz

● ATmegan I/O-rekistereihin pääsee myös suoraan käsiksi

void loop() {

while(1) {

PORTB |= 0×20; //LED päälle

PORTB &= ~0×20;// LED pois

}

}

● Nyt kanttiaallon taajuus on 2.66 MHz

● Vielä korkeampia taajuuksia aina 8 Mhz asti voidaan tuottaa mikro-ohjaimen ajastimien avulla

analogRead● Tekee 10-bittisen analogi-digitaali muunnoksen● Vertaa portin jännitettä referenssijännitteeseen (AREF, normaalisti 5 V)● Tuottaa luvun väliltä [0, 1023]● AREF porttiin ei saa kytkeä alle 0 V tai yli 5 V jännitettä!● Kohinaa voi suodattaa koodissakin mm. laskemalla useamman

mittauksen keskiarvon, tai laskemalla liukuvaa keskiarvoa

int sensorValue = analogRead(sensorPin);sensorValue += analogRead(sensorPin);sensorValue /= 2;

analogWriteanalogWrite(pin, 127);// 50% pulssisuhde

● Tuottaa kanttiaaltoa ennaltamäärätyllä pulssisuhteella● 0 => 0 % pulssisuhde● 255 => 100% pulssisuhde● Signaalin taajuus on noin 490 Hz● Valitun I/O portin täytyy tukea PWM:ää● Voidaan käyttää esim. LEDin himmentämiseen● Pulssisuhde pienillä arvoilla saattaa olla hieman määrättyä suurempi● Käyttää mikro-ohjaimen ajastimia, joita on rajattu määrä

analogWrite(pin, 32); // Luo kanttiaaltoa 12.5 % pulssisuhteella

delay(100); // Odota vähintään 100ms

digitalWrite(pin, 0); // Lopeta

Lyhyesti funktioista● Koodia kannattaa osioida funktiohin● Osien uudelleenkäytettävyys paranee● Luettavuus paranee● Bugeja on helpompi metsästää● Funktion kutsuminen vie sekin aikaa

int sum(int a, int b){

return a + b;}

int result = sum(1, 2); // result == 3

Tietolähteitä

● http://arduino.cc/en/Tutorial/● http://arduino.cc/en/Reference● http://arduino.cc/en/Reference/PortManipulation● http://cslibrary.stanford.edu/101/EssentialC.pdf● https://github.com/liffiton/Arduino-Cheat-Sheet● http://www.asciitable.com/● http://www.atmel.com/Images/doc8161.pdf