elec-a4010 sähköpaja arduinon ohjelmointi · arduino uno r3 6-20vdc → 5vdc muunnin 16 mhz...
TRANSCRIPT
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