Sećam se kada sam prvi put ušao u službu smeštaja u Novom Sadu. Tada sam tamo odsedeo oko 4h, jer nisam znao gde bih otišao, a i trebalo je da se čeka u redu. Mada situacija nije bila bolja ni naredne godine. Iako sam znao gde bih otišao umesto da čekam u redu, jednostavno nisam hteo da rizikujem da moj broj bude prozvan, pa da sutra moram sve iz početka. I tako se rodila ideja o aplikaciji za telefon, koja bi prikazivala informacije o trenutno prozvanom klijentu u službi, što dalje omogućava studentima da odu na predvanja, izbleje negde u kafiću pored, u menzi ili da jednostavno odu kući i da odspavaju 🙂
Od uprave Studentskog centra Novog Sada sam dobio dozvoluda to realizujem, kao i pristup stanju, odnosno terminalu za prozivke u službi smeštaja. Nakon toga i nakon utvrđivanja šta imam od resursa na raspolaganju, ideja je postala projekat, znatno većeg obima nego što sam očeivao. Procenjenih nedelju dana za završetak, su se razvukli na čitavih šest meseci. Naravno, tih šest meseci nisu šest meseci programiranja, jer je pored toga bilo i dosta organizacije sa IT službom Studentskog centra, gomilu razmenjenih mejlova, popravljanja grešaka i testiranja, a sve to je zahvatio i raspust.
IT služba je obezbedila računar koji će raditi monitoring stanja na terminalu za tiketiranje, kao i pristup web serveru na koji se šalje trenutno stanje, odnosno broj trenutno prozvanog klijenta. Postojeći sistem za tiketiranje održava firma Avantech QMS i oni su nam obezbedili pristup terminalu kao i specifikaciju podataka koji predstavljaju trenutno.
Uglavnom, sada je to privedeno kraju. Još uvek ne želim da kažem da je kraj, jer od kada sam to prvi put rekao, morao sam još pet puta da intervenišem u rešavanju bagova. A ti bagovi su u principu bili posledica nekompletnih specifikacije koje sam koristio. Ali dobro, sada se nadam da takvih iznenađenja više neće biti.
Trenutno, na adresi www.scns.rs/?page_id=719 (ili direktno na www.scns.rs/adRedova) možete da pratite stanje prozivke u službi. Smatram da je dosta intuitivan “dizajn”, tako da ga neću dalje objašnjavati. Pored ove stranice, postoji i aplikacija za Android uređaje, a link za preuzivamnje možete naći na gore pomenutoj stranici.
Što se tiče arhitekture servisa, ona je data na slici ispod.
Iako prilično grubo, vidi se na koji način funkcioniše.
Inače, od samog početka, postojala je i zamisao o SMS servisu za one koji nemaju Android telefon, ali nažalost, ta opcija nije uvedena zbog iz nekih pravno-finansijskih razloga odnosno jako komplikovane procedure oko javnih nabavki, koja bi bila neophodna za pokretanje ovakvog servisa.
Update za one sa programerskim iskustvom Zbog manjih tehničkih problema, servis se premešta na Raspberry PI. Kada bude premešten, PI će biti ostavljen negde u mraku, zauvek sam.
Za kraj, ohrabrio bih sve studente koji koriste usluge smeštaja Studentskog centra, da oprobaju servis. Eventualne greše u funkcionisanju, zamerke ili utiske, sobodno navedite dole u komentarima ili direktno na email adresu.
Kao i svake godine, smer E2 upiše dosta gimnazijalaca. Osim što se susreću sa šalama pojedinih profesora na račun toga što su završili gimnaziju, susreću se i sa dosta ozbiljnijim zadacima, kakve možda nisu sreli u gimnaziji. Matematika i fizika im naravno nisu problem, ali kada je reč o programiranju ili osnovama elektrotehnike, tu se stvari već malo menjaju.
U gimnazijama se obično radi Pascal, dok se na smeru uči C/C++. Iako se na predmetu Programski jezici i strukture podataka programski jezik C uči od početka, predmet je lakše savladati ako već imate neko predznanje. Zato onima koji žele da upišu E2, a i onima koji su jednostavno radoznali i žele da se upoznaju sa programiranjem, preporučujem da posete sledeći link:
Ovih dana planiram da promenim broj telefona, pa bih o tome trebao da obavestim prijatelje i poznanike. Ali koga obavestiti, a koga ne? Ako se neko nalazi u mom imeniku, to ne znači da mu treba moj novi broj, dok sa druge strane, verovatno postoji i neko ko ima moj stari broj, a ja ga nemam upisanog u imeniku. Možda da neko vreme koristim dva telefona, pa da budem dostupan na oba broja? Ili ako bi postojala mogućnost automatskog slanja obaveštenja o promeni broja, ukoliko neko pokuša da me kontaktira na stari broj telefona?
Ovo poslenje pomenuto mi zapravo najviše odgovara, pa sam odlučio i da ga realizujem. Ponono sam iskombinovao staru Nokiu i Python 😉
import messaging
import inbox
import telephone
import time
messageText ="(Automatska poruka): Cao! Vise ne koristim ovaj broj. Kontaktiraj me na 06x/xxx-xxx. Hvala :)"
informedAlready =[]def sendSMS(notifyNumber):global informedAlready
global messageText;if informedAlready.count(notifyNumber)==0:print"Sending message to "+ notifyNumber
messaging.sms_send(notifyNumber, messageText)
informedAlready.append(notifyNumber)def callCallback(state):if(state[0]==telephone.EStatusRinging):#print "Voice call received"
sendSMS(state[1])def SMScallback(id):
time.sleep(1)try:
i = inbox.Inbox()
smsID = i.sms_messages()[0]ifid== smsID:# preventing error that occurs when delivery report is recieved#print "SMS received"
sendSMS(i.address(smsID))except:print"Some error occured in SMScallback function!"# Pokretanje pracenja primljenih poruka
box = inbox.Inbox()
box.bind(SMScallback)# Pokretanje pracenja primljenih poziva
telephone.call_state(callCallback)print"Service started!"
Dovoljno je da kod kopirate u datoteku sa ekstenzijom ‘.py’, zatim da je kopirate na telefon i pokrenete u Python interpreteru. Više o tome, pogledajte ovde.
Kako ponuda Android telefona raste, a zajedno sa ponudom i broj aplikacija na Gugl Pleju, tako je sve više onih koji će se ponoviti novim i pametnijim telefonima, dok će njihovi stari telefoni otići za tridesetak evra na kutiji pored Futoške ili biti bačeni u fioku i biti zaboravljeni. Ukoliko je Vaš prethodni telefon neka Nokia sa Symbian OS-om, možda ipak, još uvek nije vreme da se rastanete sa njim.
Ukratko o Python-u
Python je veoma moćan programski jezik visokog nivoa. Kod pisan u Python-u se obično interpretira, ali postoje i prevodioci koji Python kod prevode u mašinski jezik. Veoma je jasan, sintaksa je čitljiva, a možda i najvažnije, jako je intuitivan. Objektno je orijentisan. Podržan je na mnogim platformama, a samo neke od njih su nabrojane: Linux, Windows, BSD, Symbian OS, Xbox… Uz Python dolazi biblioteka standardnih modula, ali je po potrebi moguće pisanje novih modula u Pythonu, pa čak i u C-u ukoliko su potrebne veće brzine izvršavanja. Vidi još…[en]
Python Guardian
Ovu skriptu sam napisao kada sam počeo da učim Python. Bilo mi je zanimljivo da od starog telefona napravim nešto korisno, što usput mogu da kontrolišem na daljinu, putem SMS poruka. I tako je nastao Python Guardian. Skripta verovatno nije savršena niti sam je ikada preterano testirao, ali je meni zato radila posao za koji sam je napisao. Elem…
Python-Guardian.py je skripta koja telefon pretvara u sistem za nadzor koji reaguje ukoliko dođe do promene u nadgledanom prostoru. U promene spada sve ono što kamera telefona može da zabeleži (npr. pomeranje objekata ili nagla promena intenziteta/boje svetla). Nivo detekcije promene se može podešavati sa više parametara, kao što su broj osetljivih tačaka, nivo tolerancije promene boje pixela, minimalni broj detektovanih izmenjenih pixela itd. Kada je promena detektovana, Python Guardian može da pošalje obaveštenje putem SMS-a, da postavi fotografiju nadgledanog prostora na internet i/ili da aktivira alarm. Nakon pokretanja skripte, nadgledanje prostora može biti pokrenuto automatski, nakon isteka definisanog vremenskog intervala ili ručno, slanjem SMS poruke na broj telefona na kojem je pokrenuta skripta. Slanjem SMS poruke je takođe moguće deaktiviranje nadgledanja prostora.
[CODE]
Ovaj deo je odvojen za one koji žele malo više da se upoznaju sa načinom funkcionisanja python-guardian skripte. Objasniću kako skripta zapravo detektuje promenu, dok popratne delove koda kao npr. kod za slanje SMS poruka ili upload fotografije, koje sam preuzeo (i prilagodio) sa interneta, neću objašnjavati. Nihov opis možete naći na sledećem sajtu: www.mobilenin.com.
Nadgledanje prostora se može vršiti na dva načina. Prvi način je kada se upoređuju frejmovi video kamere; frejmovi sa kamere pristužu više puta u sekundi, što znači da se poređenje može češće obavljati, te se na taj način može i brže odreagovati na eventualne promene. Sa druge strane ovaj način nadgledanja znatno troši bateriju. Drugi način je da se u određenim vremenskim intervalima prave fotografije koje se kasnije porede na isti način kao i frejmovi. Ovaj način, zbog postojanja intervala između dva poređenja, neće odreagovati na brze promene, ali baterija telefona traje duže.
Naččin nadgledanja se podešava menjanjem vrednosti parametra monitoringType, a vrednosti mogu da budu ‘video’ ili ‘photo’
‘video’
Kada se koristi ovaj način nadgledanja, poziva se sledeća linija koda, kojom se uključuje kamera, odnosno podaci sa kamere se prosleđuje frejm po frejm monitoringCallback funkciji.
Ovo parče koda se obično koristi da bi se korisniku na displeju prikazalo šta kamera u datom trenutku posmatra, te da korisnik tako može ispravno da kadrira svoju fotografiju pre nego što je napravi. U ovom slučaju monitoringCallback funkcija nema tu namenu, već služi da bi upoređivala trenutni sa prethodnim frejmom i ukoliko postoji bitna razlika među njima, objavi alarm.
Da bi monitoringCallback funkcija uporedila trenutni i prethodni frejm, prethodni frejm mora biti negde sačuvan. U prvom prolazu kroz funkciju ne postoje podaci o prethodnom frejmu, tako da prvi prolaz, koji je obeležen firstFramepromenljivom, služi samo da bi trenutni frejm sačuvao u memoriji telefona. U svakom sledećem n-tom (gde je n=frameAnalysisFreq)prolazu kroz funkciju upoređuje se trenutni sa prethodnim frejmom i trenutni se postavlja kao prethodni za sledeći prolaz. Parametar frameAnalysisFreq se uvodi jer nije potrebno proveravati svaki frejm da bi se uočila promena. Recimo da sa kamere bude prosleđeno 20 frejmova u sekundi, za detektovanje promene, nije potrebno praviti proveru za svaki frejm. Za upoređivanje dva frejma koristi se funkcija compareFrames kojoj se prosleđuju trenutni i prethodni frejm.
‘photo’
Funkcija photoMonitoringLoop se poziva kada se koristi nadgledanje pomoću fotografija. Kao i monitoringCallback funkcija, funkcija photoMonitoringLoop koristi promenljivu firstFrame, da bi u provm prolazu napravila fotografiju koja će se u narednom prolazu koristiti kao prethodna prilikom pozivanja funkcije compareFrames. U ovoj funkciji, frameAnalysisFreq parametar predstavlja vremenski interval između dva poređenja. Funkciju photoMonitoringLoop se poziva sledećim kodom:
Takvo pozvanje funkcije,će dozvoliti da trenutna funkcija u kojoj se nalazi kod iznad, nastavi sa izvršavanjem – photoMonitoringLoop funkcija će se izvršavati nezavisno. gTimer je objekat klase e32.Ao_timer() koja dozvoljava ovakav način pozivanja funkcija, gde prvi parametar (u ovom slučaju jedinica) označava vremenski interval koji će proći pre nego što funkcija (drugi parametar) bude pozvana.
compareFrames()
res = compareFrames(currentFrame, previousFrame)
Funkcija compareFrames za argumente prima dva frejma (fotografije), koja predstavljaju trenutni i prethodni frejm (fotografiju). Ona ne upoređuje frejmove (fotografije) u potpunosti, već samo u određenim tačkama, tzv. osetljivim tačkama. Broj tačaka po vertikalnoj i horizontalnoj osi se može podešavati parametrima verticalCheckDotsNumber i horizontalCheckDotsNumber. Ako uzmemo vrednosti 3 i 4 za pomenute parametre respektivno, tačke koje se proveravaju na frejmu (fotografiji) su raspoređene na sledeći način:
Svaka osetljiva tačka na trenutnom frejmu (fotografiji) se poredi sa istom tom osetljivom tačkom na prethodnom frejmu (fotografiji). To radi funkcija compareArea kojoj se prosleđuju oba frejma (fotografije) i x i y koordinate osetljive tačke. Jedna osetljiva tačka sadrži jedan piksel u sredini i još osam piksela raspoređenih oko njega na razdaljini koja je definisana parametrom diameter. Poređenje tih piksela se radi prema boji, odnosno prema RGB vrednostima datih piksela, pozivanjem funkcije comparePix. U zavisnosti od rezultata compareArea funkcije, funkcija compareFrames kao rezultat vraća celobrojne vrednosti od 0 do 4, gde svaka vrednost označava jedno od sledećih stanja:
0 – prethodno stanje 0, 3 ili 4: broj osetljivih tačaka, koje se na oba frejma razlikuju više od granice podešene parametrima, je manji od vrednosti parametra maxNumberOfChangedDots. Parametri koji određuju granicu prema kojoj se porede osetljive tačke, su maxPixelDifference imaxNumberOfChangedPixels,
1 – prethodno stanje 0: broj osetljivih tačaka, koje se u trenutnom poređenju na oba frejma razlikuju više od granice podešene parametrima, je veći od vrednosti parametra maxNumberOfChangedDots,
2 – prethodno stanje 1 ili 2: u nekom od prethodnih n poređenja (n=maxDelayedFrames), razlika među frejmovima je bila veća nego što je dozvoljeno,
3 – prethodno stanje 2: u toku poređenja n (n=maxDelayedFrames) frejmova, nije detektovano m (m=maxDisturbedFrames) frejmova čija je različitost veća od dozvoljenog,
4 – prethodno stanje 2: u toku poređenja manje od n (n=maxDelayedFrames) frejmova, detektovano je m (m=maxDisturbedFrames) frejmova čija je različitost veća od dozvoljenog (vreme je da se oglasi alarm, poziva se funkcija startAlert()).
Kada se sistem nalazi u stanju 2, parametar maxDelayedFrames određuje broj frejmova koji će biti provereni (i čija će različitost biti manja od dozvoljene) pre nego što sistem pređe u stanje 3. Parametar maxDisturbedFrames određuje koliko frejmova čija je različitost veća od dozvoljene, treba da bude detektovano kada se sistem nalazi u stnaju 2, da bi sistem prešao u stanje 4.
Ovakav algoritam omogućava da kamere budu nesavršene kao što je to recimo kamera na telefonu na kojem je ova skripta testirana (Nokia 6120 Classic). U uslovima kada ima malo svetlosti, dešavalo se da pojedini frejmovi “zakucaju” i podaci sa kamere ne budu istiniti, pa je zbog toga uvedena zadrška prelazka u stanje 4, da bi se sprečilo oglašavanje lažnog alarma.
Ovakav algoritam omogućava i režim povećane sigurnosti tj. kada “skripta posumnja” u neku promenu na frejmovima i pređe u stanje 1 ili 2, zaobilazi se parametar frameAnalysisFreq i tada se, u ‘video’ načinu nadgledanja proverava svaki frejm koji skripta dobije od kamere, onosno u ‘photo’ načinu nadgledanja ne postoji vremenski interval među dva poređenja, već se fotografije sa kamere i porede najvećom mogućom brzinom. Da bi aktivirali ovakav način provere, potrebno je parametar useIncreasedSafetyRegime postaviti na 1. Kada se uključuje ili isključuje režim povećane sigurnosti, parametre maxDelayedFrames i maxDisturbedFrames treba rekonfigurisati.
Evo i opisa čemu služe ostali parametri:
startupInterval – ceo broj, koji predstavlja broj sekundi koji će proći pre nego što se aktivira nadgledanje, ukoliko je opcija Startup immediately odabrana prilikom pokretanja skripte, soundsEnabled – ako je vrednost 0 zvukovi obaveštenja o početku i kraju nadgledanja se neće emitovati; za vrednost 1 zvukovi će biti emitovani, adminNumbers i notifyNumbers – liste brojeva administratora i brojeva koji će biti obavešteni kada je detektovana promena (ukoliko je prilikom pokretanja skripte odabrana opcija SMS Notify), startSMSPhrase i stopSMSPhrase – fraze (stringovi) kojima administrator, putem SMS poruke, može da uključuje/isključuje nadgledanje, webServerAddress i webServerLink – kada se koristi Photo upload alarm, ova dva parametra određuju internet lokaciju skripte koja preuzima i postavlja fotografiju na server, uploadPhotoFilename, sndDir, sndAlarm, sndMonitoringStarted, sndMonitoringStopped – putanje na telefonu do fotografije za upload, direktorijuma sa zvukovima, ime zvuka alarma, početka i završetka nadgledanja, monitoringResolution – rezolucija frejmova/fotografija koji se dobijaju od kamere i koji se dalje analiziraju, apidFilename – fajl u kome se čuva id podrazumevane pristupne tačke (default access point).
.
Šta mi je potrebno za pokretanje skripte?
Osim telefona na kojem Vam trči Symbian OS, potrebno je još da na isti instalirate Python za S60 telefone. Poslednju verziju PyS60 možete preuzeti odavde.
Kako da pokrenem skriptu?
Arhivu python-guardian.zip raspakujte na memorisku karticu telefona. Zatim iz foldera python-guardian, kopirajte fajl python-guardian.py u direktorijum Python koji se nalazi na memoriskoj kartici. Nakon toga pokrenite Python aplikaciju koju ste instalirali u prethodnom koraku. Kliknite na Options, odaberite Run script, a zatim pronađite skriptu python-guardian.py i pritisnite OK.
U arhivi se takođe nalazi i upload_image_to_url.php preuzet sa ovog sajta: www.mobilenin.com, koji vam je potreban ako želite fotografiju da uploadujete na svoj server.
Šta ako skripta ne radi kako treba ili pronađem neki bug?
Javite, probaćemo da popravimo 😉
Šta dalje?
Pokušajte sami da napišete neke zanimljive skripte za Vaš telefon. Jednostavno možete napisati skriptu koja će proveravati da li su izašli rezultati ispita na sajtu fakulteta, skriptu koja će da spamuje telefon Vašeg kolege SMS porukama ili skriptu Naravno, Python možete da instalirate i na Vaš računar, a pogodnu verziju potražite ovde. Nakon instaliranja, na ovom linku, možete potražiti neki zanimljiv softver koji je pisan u Python-u.
Prošle nedelje sam pohađao Android summer school koju je organizovao odsek RT-RK fakulteta tehničkih nauka u Novom Sadu. Škola je trajala 5 dana, a šta smo za to kratko vreme, opisaću ukratko.
Prvog dana samo se upoznali sa Androidom i njegovom arhitekturom. Android framework, načini čuvanja podataka, Android SDK, emulator, adb, kao i pisanje prvih aplikacija u Eclipse-u su samo neke od tema koje su obrađene. Takođe održano je i predavanje o Android GUI-u i elemntima GUI-a, a nakon toga su usledili zadaci koje smo rešavali uz pomoć profesora.
Predavnja drugog dana su malo detaljnije objasnila Androidovu bazu podataka ali i baze uopšte (SQL upiti, primarni ključevi…). Takođe je bilo reči i o komunikaciju preko interneta na Androidu, socket-ima, prenosu teksta, DOM parseru… Na kraju je održano predavanje o multimediji, gde su obrađeni razni adapteri i čemu oni služe kao i dodavanje multimedijalnog sadržaja u MediaLibrary.
Trećeg dana smo učili kako se prave igrice na Androidu! Ali, koliko god ova uvodna rečenica fensi zvuči, moje oduševljenje predavanjima nije. Smatram da je prvi deo predavanja bio zaista koristan, jer smo saznali dosta informacija o GameLoop-u (petlji koja se izvršava tokom igranja neke igrice i načinima da se ta petlja uvek izvršava isto na raznim procesorima). Drugi deo predavanja je meni lično bio malo dosadan, iz razloga što nam je bilo prikazano gomila izsečaka koda nekih igrica, a pošto su to izsečci, često se moglo čuti od strane predavača: “Ovo zanemarite, to je realizovano u toj-i-toj klasi”. No, u svakom slučaju, vredelo je odslušati i to predavanje, jer su tu data rešenja za neke konkretne probleme.
Četvrti i peti dan je poslužio da zavirimo ispod haube Androida. Linux Kernel, izvorne biblioteke, runtime, framework… Stvari za koje smatram da dosta onih koji “programiraju” na Androidu nisu ni čuli za njih, a oni koji jesu, nisu se preterano udubljivali da ih izuče. Uglavnom, na predavanjima je sve to obrađeno u onoj meri koliko je to bilo moguće za 2x4h. Meni je bilo zanimljivo, jer sam se zbog toga u principu i prijavio na školu. Takve stvari, em što se malo teže nalaze na internetu, malo ih je teže i skontati od razumevanja kako napisati “HelloWorld!” aplikaciju.
Sve u svemu, svakome ko sledeće (a nadam se i dosta narednih godina) primeti plakatu o Android školi, preporučujem da se prijavi. Možda je vreme održavanja škole nakon završetka fakulteta, budu vrućine i verovatno bi ste se radije negde brčkali na Štrandu nego sedeli za računarom i usput učili, ali prilika za sticanje ovakvog znanja nema mnogo.
U prethodnim blogovima sam opisao kako treba da funkcioniše ovaj uređaj, kako hardverski deo, tako i deo koji se izvršava na telefonu tj. aplikacija. Ali kako ovo zapravo funkcioniše u stvarnosti?
Interfejs
Onima koji žele ovo sami da prave, a nisu baš vešti sa elektronikom, preporučujem da koriste kalaj za lemljenje sa kalafonijumom. Ja sam izgubio dva dana, pokušavajući da komponente nalemim na pločicu sa nekom starom lemilicom i još starijim kalajom. Na kraju sam kupio novi kalaj i sastavio pločicu za 10min 🙂
Kao podlogu za komponente, koristio sam protobord pločicu. Kako sam saznao od prodavca, postoje protobord ploče sa poljima od bakra na koje se leme komponente ili kao u mom slučaju, ploče sa linijama bakra na kojima se nalaze rupice kroz koje se povezuju komponente. Meni se lično više dopala ova varijanta sa rupicama, jer su tako lemovi sa jedne, a komponente sa druge, pa sve izgleda urednije i kulturnije. Evo kako to sada izgleda:
Na ovom interfejsu se nalaze još i dva tastera, tako da i kada mi telefon nije pri ruci, mogu da koristim interfejs kao što je opisano ovde. Što se tiče komponenti, mislim da ni jedna komponenta nije iste oznake kao što sam naveo u blogu o interfejsu, već su sve neke približne vrednosti. Jednostavno na mestu gde sam kupovao komponente nisu imali komponente sa traženim oznakama, a i ovako sve radi kako treba, pa to nije problem.
Aplikacija
Oko pisanja aplikacije sam se zadržao malo duže, jer sam potpuni početnik što se tiče Android programiranja, a ni sa Javom nisam neki ekspert. Mic po mic i napisao sam ono što mi treba, ono zbog čega sam uopšte i započeo pisanje ovog bloga. Ili barem deo toga 😛
Ukoliko niste upoznati sa programiranjem Android aplikacija, pročitajte ovo uputstvo.
Za sada aplikacija može da funkcioniše na dva načina. Automatski, kada se unapred definiše ekspozicija ili ručni kada ekspozicija traje onoliko vreme koliko se prst drži na dugmetu “Shoot”. Takođe je moguće i prekinuti ekspoziciju klikom na dugme “Stop” ukoliko je greškom definisana predugačka ekspozicija.
Aplikacija je pisana za HTC Wildfire sa Androidom 2.2.1. Za preuzimanje sours koda kliknite ovde, a zatim pritisnite Ctrl+S.
Kao što objasnih u ovom blogu, na izlaz stereo priključka je potrebno emitovati ton, a to će, ukoliko je fotoaparat povezan na telefon preko interfejsa, uzrokovati fokusiranje odnosno okidanje, u zavisnosti na koji kanal smo emitovali ton. Za generisanje tona, modifikovao sam i koristio klasu sa ove stranice: stackoverflow.com/ques…bud-left-or-right. Pomoću nje se može lako generisati pravougaoni signal određene frekvencije i dužine trajanja. Modifikovana verzija klase je ispod.
<.blockquote>
import android.media.AudioFormat;import android.media.AudioManager;import android.media.AudioTrack;publicclass ToneGen {
AudioTrack aTrack;byte[] buffer;int fps =16000;int samplesPerFrame =4;/***@param frequency The frequency of the tone */public ToneGen(int frequency){
buffer =newbyte[fps];int T =(int) fps / frequency ;int To2 =(int) T /2;for(int i=0; i<buffer.length; i+=T ){for(int j =0; j < To2; j++){
buffer[i+j]=(byte)127;
buffer[i+j+To2]=(byte)-127;}}}/* * @param duration Duration of sound in seconds * @param leftVolume Left volume 0.0f - silent, 1.0f full volume * @param rightVolume Right volume 0.0f - silent, 1.0f full volume */publicvoid Play(float duration,float leftVolume,float rightVolume)throwsException{int u =1;if(duration <1){
u =Math.round(1/ duration);if(u !=2&& u !=4&& u !=8&& u !=16&& u !=32&& u !=64&& u !=128)thrownewException("Invalid exposure");}
aTrack =new AudioTrack(AudioManager.STREAM_MUSIC,
fps/samplesPerFrame, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
buffer.length/u, AudioTrack.MODE_STATIC);if(duration >1)
aTrack.setLoopPoints(0, fps/samplesPerFrame,Math.round(duration)-1);
aTrack.write(buffer,0, buffer.length);
aTrack.setStereoVolume(leftVolume, rightVolume);
aTrack.play();}publicvoid Stop(){
aTrack.stop();}}
.
Klasu koristite tako što konstruktoru prosledite željen frekvenciju tona koji želite da generišete. Ja sam koristio frekvenciju od 500Hz i sa tim parametrima je interfejs opisan u prethodnom blogu radio kako treba. Kada želite da emitujete ton, potrebno je da pozovete metodu Play(). Njoj prosleđujete dužinu trajanja tona u sekundama i jačinu zvuka za levi odnosno desni kanal. Primer: .
ToneGen tg = new ToneGen(500);try{ tg.Play(5.0f,0.0f,1.0f);}catch (Exception e) {}
.
Ovako pzvana metoda Play() će emitovati zvuk od 500Hz, trajanja pet sekundi, samo na desni kanal stereo priključka. To će prouzrokovati da, kada je aparat preko interfejsa povezan na telefon, aparat fokusira 🙂
Ukoliko želite da ekspozicija traje manje od jedne sekunde, potrebno je da emitujete ton kraći od jedne sekunde. Takav ton možete da generišete na sledeći način:
.
ToneGen tg = new ToneGen(500);try{ tg.Play(0.125f,0.0f,1.0f);}catch (Exception e) {}
.
Važno je da dužina trajanja tona koji želite da emitujete (dužina ekspozicije) bude jedna od sledećih vrednosti: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64 ili 1/128 u decimalnom zapisu.
NAPOMENA: Canon fotoaparati, kada se fotografiše u BULB modu, u EXIF podacima dužine ekspozicije koje su manje od jedne sekunde zaokružuju na jednu sekundu!
Potrebno je napraviti interfejs preko kojeg će telefon i fotoaparat biti povezani. Na određenu komandu telefona, interfejs će odreagovati tako što će fotoaparatu poslati komandu za fokusiranje odnostno okidanje. Pošto je korišćenje USB porta na telefonu suviše komplikovano (a pritom nam nisu potrebne mogućnosti koje pruža), odlučio sam da iskoristim stereo izlaz za slušalice.
Male napomene:
Priključak na telefonu za slušalice je obično stereo priključak odnosno TRS koenktor dimenzija 3.5mm;
Priključak na Canon dSLR fotoaparatima (350D,400D, 40D…) je takođe TRS konektor, ali manjih dimenzija – 2.5mm;
Kako ručno kontrolisati fotoaparat preko TRS konektora, možete videti ovde.
Evo jedno šturo objašnjenje kako ovo treba da funkcioniše:
Kada se na telefonu pusti neki ton, na izlazu stereo priključka se javlja određeni signal. Nama treba elektronsko kolo, koje će za neki signal na svom ulazu, napraviti kratak spoj na svom izlazu. Tako postižemo da se kolo ponaša kao prekidač koji kontrolišemo pobudnim signalom. Ako prekidače A i B (iz prethodnog bloga) zamenimo takvim kolima (nazovimo ih sada kA i kB), aparat će kontrolisati signali koje dovedemo ulaz ta dva kola. Pošto imamo levi i desni kanal na stereo priključku, svakom dodelimo po jedno kolo: desni kanal ->kolo kA (fokusiranje), levi kanal -> kolo kB (okidanje). Na taj način, ukoliko na telefonu pustimo ton koji se emituje samo na desnom kanalu, fotoaparat će fokusirati 🙂
Pored interfejsa, potrebno je napisati i aplikaciju za Android, koja će emitovati ton određene frekvencije na levi odnosno desni kanal stereo izlaza. Aplikacija treba da podržava više načina funkcionisanja, za rasličite potrebe: HDR fotografija (tri ili više različitih ekspozicija), Time-Lapse (više istih ekspozicija, sa određenim vremenskim razmakom), Shoot OnTime (okidanje u datom trenutku), a takođe se može napraviti da aplikacija reaguje na spoljnje događaje, koji se mogu meriti sa nekim od ugrađenih senzora u telefonu (promena intenziteta zvuka/svetla u okolini, promena položaja telefona, osetljivost na vibracije itd.).
Ideja. Rodi se baš kada treba da spavam, a ujutru treba rano da ustanem. Elem, ideja je da pomoću telefona koji pokreće Android OS, kontrolišem okidanje Canon dSLR fotoaparata. Nekada je potrebno napraviti ekspozicije mnogo duže od 30 sekundi, a BULB mod okidanja na fotoaparatu mi baš ne pomaže kada dugme za okidanje (shutter button) moram da držim rukom.
Pravio sam ranije neka jednostavnija rešenja, što bi rekli čista mehanika, koja mi služe i danas, ali želim nešto bolje, nešto što će mi pružiti više mogućnosti. Nešto što će barem donekle nadoknaditi moj nedostatak talenta za fotografiju 😛
To ranije rešenje je izgledalo ovako:
Kada se strujno kolo zatvori preko prekidača A, aparat fokusira. Prekidač B sluzi za ‘okidanje’.
E sada, kada se to zakomplikuje uz malo elektronike, verujem da se fokusiranje i okidanje može kontrolisati pomoću telefona. Na taj način više ne bi bilo potrebno meriti vreme ekspozicije pomocu štoperice, a snimanje Time-Lapse fotografija bi bilo znatno olakšano.
Eto toliko za sada, čisto da mogu na miru da zaspim. Više o ovom projektu u narednom postu 😉