Kako na Arduina priključimo limono?
Zelo preprosto: povežemo jo z analognim vhodom.
(Slika, kot se reče, simbolična. Limone raje ne prerežite. :))
Arduini imajo po šest ali osem analognih vhodov. Analogni pomeni, da na njem ne preberemo le HIGH
ali LOW
, temveč poljubne napetosti med (običajno) 0 V in 5 V. S klicem funkcije analogRead(3)
preberemo napetost na vhodu A3. (Kako beremo ostale, boste že uganili.) Številka, ki jo dobimo, bo med 0 in 1023. Če je napetost na vhodu (v primerjavi z GND) enaka 5 V, bomo dobili 1023, če 0 V, dobimo 0. Če 4 V, bomo dobili približno 800.
En konec žice torej zatlačimo v, recimo, A0, drugega v limono. Poleg tega zatlačimo žico v GND in drug konec te žice držimo v roki. Če se zdaj dotaknemo limone z drugo roko, smo povezali limono in GND. Arduino bo na A0 nameril neko majhno napetost; v teoriji bi lahko bila 0 V. (Kasneje bomo videli, zakaj niti v teoriji ne bo.)
Kaj pa, kadar limono spustimo? Kakšna napetost je na njej tedaj? Ne vemo. Tedaj je limona “v zraku”. Najboljše bi bilo, če bi jo povezali s 5 V. Vendar to ne bo šlo: v tem primeru bo napetost na limoni 5 V tudi tedaj, ko se je dotikamo, saj je s 5 V povezana direktno, z žico, z 0 V (oziroma GND) pa prek nas.
Potrebujemo nekoliko drugačno vezje. Takšno:
Upornik, ki ga vzamemo, naj bo kar velik, recimo 10 mega ohmov.
Ko se limone ne dotikamo, bo Arduino na vhodu prebral 5 V. Na 5 V je sicer priključen prek upora, a nič ne de: še vedno je priključen na 5 V.
Ko se dotaknemo limone, bo – nekoliko (a ne preveč) poenostavljeno – upornik vlekel analogni vhod proti 5 V, limona (prek nas) pa na 0 V. Upornost limone in človeka skupaj je približno 1 mega ohm, torej “zmagamo”: napetost bo precej bližje 0 V kot 5 V.
Na podoben način lahko na Arduina priključimo še več limon – vsako prek svojega upornika. Na digitalne vhode pa priključimo recimo LEDice. Če so limona na vhodih od 0 do 4, LED pa na vhodih od 2 do 6, lahko napišemo takšen program.
void setup() {
for(int i = 2; i <= 6; i++) {
pinMode(i, OUTPUT);
}
}
void loop() {
for(int i = 0; i <= 4; i++) {
if (analogRead(i) < 500) {
digitalWrite(2 + i, HIGH);
}
else {
digitalWrite(2 + i, LOW);
}
}
}
(Da, da, gre krajše, vendar se tule en bomo hvalili s tem, kako kratko kodo znamo pisati.)
V setup
le povemo, da bodo pini od 2 do 6 izhodi. V zanki pa beremo napetosti na analognih pinih. Če so manjše od približno 2.5 V, vemo, da se nekdo dotika limone in prižgemo diodo. Če je napetost večja, jo ugasnemo.
Klavir iz limon
Znebimo se diod, zamenjajmo jih z zvočnikom, ki ga damo, recimo, na pin 10. Sprogramirajmo preprost klavir.
void setup() {
pinMode(10, OUTPUT);
}
int freqs[] = {261, 294, 330, 392, 440};
void loop() {
for(int i = 0; i <= 4; i++) {
if (analogRead(i) < 500) {
tone(10, freqs[i], 50);
delay(50);
}
}
}
V freqs
smo shranili frekvence tonov C, D, E, F in G. V zanki, tako kot prej, preverjamo napetosti na digitalnih vhodih. Če napetost na vhodu i
pade pod 2.5 V, naj zvočnik 50 ms piska s frekvenco freqs[i]
. Počakamo 50 ms. Potem se stvar ponovi.
To sicer še kar lepo deluje, le zvok se vsakih 50 ms za trenutek prekine. Za lepši ton ne smemo omejiti časa piskanja (tretji argument pri klicu tone
, 50
, izpustimo). Poleg tega si moramo zapomniti, katera limona trenutno piska; kadar limona, ki bi morala piskati, že piska, ne smemo ponovno poklicati tone
, saj bi to za trenutek prekinilo pisk. Zapomniti si bomo torej morali, katera limona trenutno piska… Celoten program – in to temeljito komentiran – je spodaj.
void setup() {
pinMode(10, OUTPUT);
}
int freqs[] = {261, 294, 330, 392, 440}; // frekvence tonov
int trenutna = -1; // limona, ki trenutno piska
void loop() {
// Ugotovi, na kateri limoni je napetost najnizja; shrani v `limona`
// Ce na nobeni limoni napetost ni manj kot 600 (to je, pribl 3 V),
// bo `limona` obdrzala zacetno vrednost -1
int najnizja = 600; // najnizja namerjena napetost
int limona = -1; // limona s to napetostjo
for(int i = 0; i <= 4; i++) {
int napetost = analogRead(i);
if (napetost < najnizja) {
limona = i;
najnizja = napetost;
}
}
// Zacni ali ustavi piskanje
if (limona != -1) { // Ce je pritisnjena kaka limona
if (trenutna != limona) { // Ce to ni ravno ta, ki trenutno piska
tone(10, freqs[limona]); // Piskamo!
trenutna = limona; // Si zapomnimo, da ta zdaj piska
delay(200); // Malo pocakamo, da se stik z limono umiri
}
}
else { // Ce ni pritisnjena nobena limona,
if (trenutna != -1) { // vendar trenutno neka limona piska,
noTone(10); // ustavimo piskanje
trenutna = -1; // in zabelezimo, da trenutno ne piskamo
}
}
}
Če imamo matriko LED, lahko dodamo še kaj zabavnega.
(Kaj pomeni naslov videa? Da so študentke in študenti ljubljanske Pedagoške fakultete tole programirali za domačo nalogo.)
Kako to deluje?
Branje razlage bo zahtevalo minimalno znanje fizike; recimo, da bo zadoščalo, da veste, da obstajajo baterije, ki imajo 1,5 V, pa takšne, ki imajo 6 V. In da je možno te napetosti meriti. In da obstaja nekaj, čemur rečemo upornik. (Pravzaprav mu tako napišemo. Rečemu mu upor.)
Če bi vzeli voltmeter in pomerili napetost na 9 V bateriji: koliko bi namerili? Če vemo, da se napetost meri v voltih, ni težko uganiti, da bomo namerili bolj ali manj 9 V (manj, če je baterija stara, več, če je še mlada, zaletava in polna energije).
Zdaj pa si predstavljajmo, da med ta pola baterije zvežemo devet upornikov za, recimo, 100 ohmov. Če je voltmeter še vedno priključen na oba pola baterije, bo še vedno kazal 9 V.
Kaj pa, če damo oba priključka na isti pol baterije? Skupaj? Pokazal bo 0 V.
Če sta oba priključka voltmetra na različnih polih, 9 V. Če sta na istem, 0 V. Kaj pa vmes? Kaj, če bi z enim od priključkov počasi drseli po žici? Napetost, ki jo kaže voltmeter, bi se spreminjala od 9 V do 0 V. Ker jih je ravno devet, napetost pri vsakem uporniku pade za 1 V.
Ker tole ni učna ura fizike, ne bomo šli v globje razlage. Naj zadošča, da vemo, da napetost pada na upornikih, ne pa na žici med njimi (ker ima ta zelo majhno upornost v primerjavi z uporniki).
Predstavljajmo si raje drugačno vajo: dva od (100 ohmskih) upornikov zamenjamo z enim upornikom za 200 ohmov. Zdaj bo napetost prek tega upornika padla za 2 V, prek ostalih pa še vedno po 1 V. Če namesto tega zamenjamo štiri upornike z enim za 400 ohmov, bo napetost na teh štirih padla za 4 V, na ostalih petih pa po 1 V. Kaj pa, če poleg tega zamenjamo ostalih pet upornikov z enim za 500 ohmov? Napetost na 400 ohmskem bo padla za 4 V, na 500 ohmskem pa za 5 V.
Nauk zgodbe: napetost se prek upornikov razdeli v takšnem razmerju, kot je njihova upornost. Če imamo 5 V napetosti in v tokokrog priključimo upornika za, recimo (da ne bomo malenkostni) 1 megaohm in 10 megaohmov, torej skupaj 11 megaohmov, bo napetost na prvem padla (ali narasla, odvisno od tega, s katere smeri gremo in gledamo) za 1/11 celotne napetosti in na drugem za 10/11. Celotna napetost je, kot smo rekli, 5 V, torej na prvem uporu pade približno 0,45 V in na drugem 4,55 V.
Natančno to se dogaja, ko na Arduino priključimo limone, le da smo 1-megaohmski upornik mi z limono.
Ko se limone ne dotikamo, tokokrog ni sklenjen. Namerili bomo 5 V. Upor pri tem ne moti. Lahko si predstavljamo, da je upor na levi strani v tem primeru neskončen, torej vsa napetost pade tam.