[ sirmiumsm @ 16.11.2009. 22:18 ] @
Treba mi nesto veoma jednostavno, ali imam problem da to isprogramiram. Nisam neki znalac sa PIC-ovima i programiranjem, totalni sam pocetnik.

Treba mi sledece:
Jedan PIC na sebi ima IR diodu(sa tranzistorom naravno) na jednom pinu i on treba konstatno salje modulisan signal sa odredjenom porukom dok je ukljucen(poruka nije vazna). Na drugom kraju imam samo IR prijemnik prikacen na osciloskop kojim cu da posmatram da li je signal koji stize isti kao i ondaj sto je poslat. Ovo zvuci toliko jednostavno i trivijalno ali ja opet imam problem da napravim program.

Poenta ovoga je samo da isprobam na kojoj daljini ce da radi IR dioda i primenik u sobi. Da vidim da li ce da radi sa refleksijama od zidove, pod, ako budem okretao diodu, i tako dalje........

Hardware koji imam je PIC 16F877A sa 4mhz kristalom, jedan IR dioda TSAL7600 (940nm) sa 2N2222 tranzistorom. Ne treba mi pomoc oko povezivanja hardware, to mislim da mi je sve ok(ali ako imate predlog, slobodno).

Na drugoj strani je TSOP38338 prijemnik na 38Khz. Koji je povezan na 5v sve prema semi sa datasheeta , i daje output na osciloscop.


Ako je neko voljan da mi pomogne sa programom koji bi radio gore opisano(ja verujem da je to nekoliko linija koda nekom znalcu).
Rado cu uzvrati uslugu ako bude nesto sto mogu da pomognem(u Kanadi/USA sam tako da ako treba neka komponenta koja nema kod nas da se nabavi, rado cu da posaljem)


PS. Ovo nije vazno za sada ali ako neko ima misljenje o ovome: Koliko je duzina trajana signal/pauza vazna u daljini koju hocu da postignem? Trebao bi da signal bude doboljno jak da npr sa 3 diode pokrijem celu sobu npr 5mx5m. Upoznat sam da ako je siganl mnogo kraci od pauze mogu da guram vecu struju kroz diodu pa cak i do 1A.
[ rsinisa @ 16.11.2009. 23:03 ] @
Obzirom da imaš prijemnik sa filterom na 38 kHz, moraš i predajnik da pobudjuješ sa tom frekvecom (da modulišeš signal). Znači, za početak napravi da predajnik šalje impulse modulisane sa 38 kHz i to može da probaš da signal bude kao test signal u tehničkim podacima za taj prijemnik - 600 µs signala pa 600 µs pauze, i posmatraj signal na osciloskopu. To bi otprilike bilo po 23 log. jedinice i 23 log. nule sa pauzom od oko 13 µs izmedju promena, zatim 600 µs samo logičke nule i tako u krug.
Što se tiče povećanja struje, faktor množenja nomilne struje jednak je odnosu pauza/impuls i kažu da kod nekih dioda struja može da ide čak i do 20A (tj. faktor 1000 ako je nominalna struja 20 mA). Obzirom da ti treba da modulišeš signal sa 38 kHz i to najbolje sa 50% ispune, znači da za tu tvoju diodu možeš da ideš na struju duplo veću od nominalne, tj. do 200 mA.
Takodje nemoj da se iznenadiš ako u nekim uslovima na izlazu prijemnika dobiješ neki signal i kada ti je predajna dioda nekativna.

Pozdrav.
Sinisha


[Ovu poruku je menjao rsinisa dana 17.11.2009. u 00:14 GMT+1]
[ sirmiumsm @ 17.11.2009. 00:05 ] @
Hvala Sinisa.

Ako sam dobro razumeo kao laik za mikrokontrolere. Uradim jedan for loop koji ce da izbacuje 23 jedinice sa pauzama od 13us izmedju i onda jos jedan koji ce da salje 23 nule sa pauzama od 23us i tako u krug? I onda samo na osciloskopu posmatram da li je to to. Znao sam ja u pocetku da je ovo mnogo jednostavno, samo mi je ceo koncept bio stran, sad se sam sebi smejem.
[ rsinisa @ 17.11.2009. 17:44 ] @
Ne možeš da šaljes prvo 23 nule, pa 23 jedinice, to znači da češ da dobiješ 600 µs log nule pa 600 µs log jedinice. Napraviš jednu for petlju od 1 do 23 u kojoj postaviš pin na log 1, napraviš pauzu od 13 µs, zatim taj pin postaviš na log 0, pa opet pauzu od 13 µs, a nakon for petlje pauzu od 600 µs.
Ništa nije teško samo se treba držati one "učiti, učiti i samo učiti, rekao je Marks" ;).

Pozdrav.
Sinisha
[ yt1nvs @ 17.11.2009. 23:50 ] @
Imas dobar primer na ovom linku:

http://www.rentron.com/Infrared_Communication.htm
[ vukboban @ 18.11.2009. 13:12 ] @
Ja sam to ovako pravio:jedan pin samo osciluje na 36(u tvom slucaju na 38kHz),i to tako da namestis timer na 13us,enablujes Timer interrupt,a u interruptu samo "toglujes"pin (menjas stanje pina sa 1 na 0 i obrnuto).
Drugim pinom "palis ili gasis" tranzistor kako ti odgovara(recimo drzis ga 600us otvorenog-log1,pa 600us zatvorenog-log0).
Taj pin vezujes na bazu redno sa otpornikom.
Na kolektor tranzistora vezes na red onaj prvi pin sto osciluje na 38kHz,otpornik i IR diodu,a na emiter vezes GND.


P.S. Mislim da je Timer bio namesten na manje-9,10us,nisam siguran,znam da sam experimentisao sa vrednostima.
To je bilo zbog toga sto sam interrupt potrosi par us dok se izvrsava.
Bolje ti je da uzmes "brzi"kristal,recimo 20Mhz,jer sa 4Mhz imas samo jednu instrukciju za jednu us.

Inace TSOP nije bas"uskopojasan" ! t.j. moze lepo da hvata i 3,4 kHz gore-dole od deklarisane frekvencije.
[ sirmiumsm @ 19.11.2009. 06:50 ] @
Probam sve sutra(ili danas po vasem vremenu) pa javljam kako je proslo. Hvala na pomoci
[ sirmiumsm @ 21.11.2009. 21:38 ] @
Probao sam ovako:

Code:
while( 1 )          //endless loop
   {
     
     
     for( i=0; i<=23; i++)
     {
     portb.0=1;                // set portb pin0 to high.
     delay_us(13);              // keep port b0 high for 13us ( to make it 38Khz) f=1/T T=1/f
     portb.0=0;               // set portb pin0 to low.
     delay_us(13);          // keep port b0 high for 13us
     }
     delay_us(600); //delay 600us
    }



Ali ne ide. portb.0 mi je uvek 1. Ocigledno nesto ne radim dobro?
[ vukboban @ 21.11.2009. 22:12 ] @
ovako napamet,nisam pogledao datasheet,da li si podesio TRIS registar?
ili ako ima neke analogne ulaze na portu B moras da ih iskljucis.
I kako znas da je uvek high?Na 38kHz ne mozes da meris instrumentom
[ rsinisa @ 21.11.2009. 23:53 ] @
Pri radu sa tako malim pauzama stvari baš i nisu tako jednostavne. Ne znam za C, ali u PBP-u je minimalna pauza 24 µs na 4 MHz što znači da mora da se pribegne ili ASM-u ili drugačije pisanom programu u višem jeziku. Evo ti na brzinu napisan program (u HEX-u) koji non-stop šalje signal od 38 kHz na RB0; ako to bude kako treba kod tebe, napraviću i ostatak za testiranje.

Pozdrav.
Sinisha
[ sirmiumsm @ 22.11.2009. 00:50 ] @
@vukboban
Proverio sam trisb registar, to mi je sve ok. Problem je sto ne daje 38khz uopste nego samo daje high signal na 5V. Probao i sa osciloskopom a i sa obicnim multimetrom.

@rsinisa
sad nemam pristup osciloskop u, moram da cekam do ponedeljka da probam.


ps. Imam i function generator koji kad namestim na 38khz to sve funkcionise. Znaci konstantan square wave na 38khz, izlaz i tsopa je low 0V, kad nema signala izlaz je high 5v. Ali poenta je da napravim square wave da bi mogao da vidim da li ima neke deformacije na vecim razdaljinama i zbog refleksije.

pss. kad ovo resim imam posle jos nekih pitanja, ali necu preko reda, jedno po jedno da resim.


[Ovu poruku je menjao sirmiumsm dana 22.11.2009. u 04:37 GMT+1]
[ vukboban @ 22.11.2009. 07:52 ] @
Sad sam probao onaj tvoj sa for petljom,i radi!
doduse ne na osciloskopu,nego u Proteusu,ali radi.
Jedina greska je bila sto u mikroC moras da pises portb.f0,nije mogao da kompajlira sa portb.0.
Samo sam dodao sledece:
trisb=0;
portb=0;

Ako koristis mikroC samo prepravi na portb.f0 i mislim da mora da radi.
[ sirmiumsm @ 22.11.2009. 16:56 ] @
koristim boostC. Probacu tvoj savet.
[ sirmiumsm @ 25.11.2009. 21:17 ] @
Sinisa hvala puno. Sad dobijam 38khz square wave ba b0. Ako stignes jel mozes da stavis i ostatak programa ili da mi bar kazes kako dalje.


Bobane, probao sam to i ne radi tako. Mozda u proteusu radi, ali to je teorija, verujem da chip ima neke limite koje proteus nema.
[ rsinisa @ 25.11.2009. 23:14 ] @
Prvo proveri u uputstvu za C koji koristiš kolika je minimalna pauza za komandu DELAY_US; 99% sam ubedjen da je 13 µs premalo za nju. A to što radi u PROTEUS-u nije sporno, samo treba izmeriti koja je frekvenca.
Što se tiče frekvence na kojoj treba da radi predajni kontroler, 4 MHz je sasvim u redu - taman imaš rezoluciju od 1 µs za podešavanje pauze. Može i sa manje, ali nećemo da komplikujemo.
Mogu da ti napišem test rutinu (ASM ili PBP), ali to nije ono što tebi treba kao konačna verzija, a ja ne "govorim" C tako da ne mogu da ti napišem konkretnu rutinu koja ti je potrebna, ali mogu da ti pomognem da to sam uradiš.
Možda rešenje sa PWM-om i nije loše, ali tada ti treba kontroler koji to ima. Rešenje sa tajmer interaptom takodje možda nije loše (samo bi moralo da se proveri da li sa 4 MHz može da se odradi sve što treba u interapt rutini za 13 µs), ali ja lično smatram interapt veoma moćnim oružjem i koristim ga samo kad moram; naravno, svako rešenje koje radi ono što treba je dobro, samo je u pitanju pristup.
Ja bih to uradio na sledeći način: u programu bih ispitivao bit po bit promenljive koja treba da se pošalje preko IR-a i kada je taj bit log. 0 napravio bih potrebnu pauzu, a kad je log. 1 pozvao bih rutinu koja šalje 38 kHz u potrebnom trajanju. E sad, trajanje te povorke zavisi od tvojih potreba; možda je 600 µs minimum (da ne tražim ponovo PDF), a svakako može duže ako imaš potrebe za tim, tj. zavisi od programa za prijem. Takodje i pauzu prilagodiš svojim potrebama. Mislim, varijanti ima dosta i ti sam moraš da vidiš kako tebi odgovara.
Pauzu od 13 µs bih rešio sa NOP-ovima jer je tako najlakše za tebe, a i ne zauzima mnogo više prog. memorije nego da i to staviš u petlju (i opet je pitanje broja instrukcija koje su potrebne). Da skratim, rutina bi bila otprilike ovakva:

Code:

for i = 1 to xx          ; xx zavisi od potrebnog trajanja povorke
  izlaz=1
  nop
  nop
  ...                       ; broj nopova zavisi od prog. jezika koji koristiš, tj. kako je kod njega rešena FOR petlja
  nop                     ; i možda je najbolje proveriti to u nekom simulatoru
  izlaz=0
  nop
  ...                       ; pa opet NOP-ovi. Vrlo verovano da treba različit broj u odnodu na malo pre zbog
  nop                     ;  obrade same FOR petlje i to treba proveriti npr. u simulatoru
end for
pauza yy                ; i sad pauza koja odredjuje minimalnu pauzu izmedju povorki koja će biti uvećana za
                            ;  ostatak programa koja i nije potrebna jer već postoji pauza kada je bit koji se
                            ; ispituje na log. 0
return                    ; ovo znaš šta je :)


Nadam se da si shvatio šta hoću da kažem, ako ne, a ti reci.

Pozdrav.
Sinisha
[ ADRENALIN @ 28.11.2009. 13:43 ] @
To sto ti hoces da probas ne zahteva nikakvu modulaciju. Probaj sa tim sto ti je dao rsinisa. Inace ja sam se dosta igrao sa tim prijemnicima i mogu ti reci da to radi fenomenalno. Odbija se o zid, prosto ne mozes da se sakrijes od njega. Inace to bi trebalo da bude napisano u cistom asembleru ako koristis 4MHz, ako imas brzi zavisi kako ce da ti prevede kompajler. Ja sam to napisao u cistom asembleru jer je KLJUCNO da imas tacnu ucestanost jer je filtar jako ostar, ako tako ne uradis desitce ti se da je domet manji i mislices da je do prijemnika, ali nije.
Kod je pisan za 12F pa nema bankiranja. Bankiranje ti nije potrebno ako sve pinove hoces da koristis i mora da radi i na 16F. Ovo je napisano na 4MHz, za svaki drugi takt moras da menjas kod.

Code:

; Generisem noseci signal 40KHz, modulisan sa ulaznim signalom.
; Ako su p_EncodeInput i p_MasterInput  visoki salje se nosilac. p_EncodeInput je modulacioni ulaz, p_MasterInput je ulaz kojim se moze onemoguciti emitovanje. Ovo sam koristio da bi pravio wremenske prozore emitovanja. Malo je prljava varijatna vremenskog prozora ali meni je odgovarala. Ako to ne zelis samo ga zameni jednim flegom, ali NIKAKO nemoj da ga brises ako ne znas sta radis.
;
Main
;
Loop_Signal
;
        bcf            p_Signal
        nop
        nop
        nop
        nop
        nop
        nop            ; Ovde treba napraviti 13uS kasnjenje
        nop
        nop
        nop
        nop
        nop
        nop
        bsf            p_Signal
        nop
        nop
        nop            ; Ovde treba napraviti 13uS kasnjenje
        nop
        nop
        nop
Pauza
        btfss        p_EncodeInput            ; samo kad su p_EncodeInput i p_MasterInput = 1 tada osciluje
        goto        Pauza
        btfss        p_MasterInput
        goto        Pauza
        goto        Loop_Signal

;    
;Pauza    
        btfss        p_EncodeInput            ; sve dok je na ulazu 0 cekaj, cim se vrati na 1 opet emituj kerijer
        goto        $-1

        btfss        p_EncodeInput            ; sve dok je na ulazu 0 cekaj, cim se vrati na 1 opet emituj kerijer
        goto        $-1
        btfss        p_MasterInput
;        goto        
        ;
        goto        Main
[ sirmiumsm @ 30.11.2009. 01:25 ] @
Hvala Sinisa. Sutra opet idem u lab, pa cu imati pristup osciloscopu da ve ovo probam

Hvala ti Adrenalin. Vidim da si gore napisao 40khz, ali po pauzama od 13us, izgleda mi da je kod za 38khz.

Probacu sutra oba, pa cu da vam javim kako izgleda.
[ ADRENALIN @ 30.11.2009. 20:24 ] @
Izvinjavam se zbog greske, ja sam projekat pisao za 40MHz, jer sam taj prijemnjik koristio, ali sam prepravio za tvoju frekvenciju 38KHz, medjutim nisam isprasvio komentar, tako da je greska u komentaru, a kod je ok.
[ sirmiumsm @ 01.12.2009. 05:15 ] @
@adrenalin

nazalost nisam uspeo sa ovim, posto nisam vican sa ASM, ide mi malo teze da razumem . Ali hvala na pomoci u svakom slucaju. Kad zavrsim ovaj projekat, probacu da se potrudim malo vise da naucim asm i c za PIC

@rsinisa

jos nisam stigao da probam tvoj savet. Stisli me ispiti, ali ovih dana moram.
[ sirmiumsm @ 02.12.2009. 19:32 ] @
Code:
#include "16F877A.h"
#use delay(4000000)

void main()
{
//pwm output, MCU clock=4Mhz



      setup_ccp1(ccp_pwm);    //select timer and mode
      set_pwm1_duty(13);     //set on time
      setup_timer_2(T2_DIV_BY_1, 26,1); //clock rate and output period
      
      while(1){}              //wait until reset


}


Ovim sam dobio signal od 38khz na C1
E sad dalje: (nadam se da ne dosadjujem previse)
1. Plan je bio da uzmem jos jedan tranzistor i sa njime cu da palim na 600us i da ga gasim. Mislio sam da je tako najlakse, ali to ne funkcionise, cim sam u us, ti steps nisu vise precizni sa delay funkcijom. (5us pulse, pa 20us pauza, nemam pojma zasto je ovako kad sam ga namestio na 600us, kako god promenim delay vrednosti, ovo 5/20us se ne menja, probao sam i port da promenim)
2. Kkako da iskoristim taj 38khz pulse, da bih poslao neku poruku npr 0F(ili binarno, nije mi vazno) na svakih 5 sekundi. Samo mi je potrebno da vidim waveform na drugoj strani na osciloskopu.
3. Kako mogu da odredim brzinu kojom ce ta poruka da ide(npr 9600, 19200,...kbauda)? Poenta je da odredim maksimalnu brzinu , pri kojoj se ta poruka nece izgubiti u prenosu?


[Ovu poruku je menjao sirmiumsm dana 02.12.2009. u 22:27 GMT+1]
[ rsinisa @ 02.12.2009. 22:15 ] @
Ne čitaš pažljivo moje poruke. Evo da kopiram ono što sam pisao:
"Prvo proveri u uputstvu za C koji koristiš kolika je minimalna pauza za komandu DELAY_US; 99% sam ubedjen da je 13 µs premalo za nju.".
Znači, proveri prvo ovo pa ako sam u pravu, biće ti jasno zašto ne može tako.
Nisam razumeo ovo sa tranzistorom i zašto to ne radi. PWM izlaz povežeš na anodu, katodu na kolektor NPN tranzistora, emiter na masu, a bazu povežeš (preko otpornika, to valjda ne treba naglašavati posebno) na pin kojim ćeš da upravljaš. To bi trebalo da radi.
Što se tiče slanja podataka, treba sam da osmisliš šta ti i kako odgovara; npr. ako povežeš ovako sa tranzistorom možeš slobodno da zaboraviš na problem generisanja 38 kHz pošto si to rešio PWM-om. Ostaje ti samo da upravljaš bazom tranzistora i to tako što ćeš da je 4 puta naizmenično držiš po recimo 600 us na log 1, pa na log. 0, onda napraviš pauzu od 5 sekundi, pa sve u krug.
Ako pretpostavimo da je 600 us minimalno vreme za koje predajna dioda mora da radi na 38 kHz (proveri tehničke podatke!), dolazimo do frekvence od 833 Hz, iliti 833 bauda. Znači, preko te brzine neće moći. Još jednom naglašavam da proveriš teh. podatke ili da se poigraš i probaš u praksi. Doduše, moguće su tu i druge metode "šifriranja" podatka, ali koliko vidim tebi kao početniku već i ovo pravi male probleme. Znači, malo čitanja i malo (više) eksperimentisanja i doći ćeš do rezultata.

Pozdrav.
Sinisha

[ sirmiumsm @ 02.12.2009. 22:21 ] @
uspeo sam da uradim br 1.
sa delay_us(600), bio sam napravio gresku gde u pocetku nisam dobro definisao clock speed.
Za sada mi ovo radi, postigao sam ono sto mi trenutno treba. Imam 600us signala od 38khz i 600us pauze, na receiveru vidim pravilan square wave.

Sledeci korak je da odredim maksimalnu brzinu kojom mogu da posaljem poruku bez gubitka signala u prenosu. Ako neko ima neku ideju ili savet, rado cu da saslusam, zato sto nemam pojma ni kako da pocnem ovu pustolovinu.

Hvala svima koji su pomogli do sada.


edit. ne znam kako uopste nisam video tvoju poruku iznad, izlgeda da smo je pisali u isto vreme, tek sad kad sam se vratio, vidim je iznad moje.

[Ovu poruku je menjao sirmiumsm dana 03.12.2009. u 06:44 GMT+1]
[ vukboban @ 02.12.2009. 23:31 ] @
Mislim da ti je najjednostavnije da radis neto slicno kao"RC5" protokol.Ja sam pisao neki kod za dimer za sijalicu preko daljinskog,i najjednostavnije mi je bilo da dekodiram rc5 protokol.
Kod tog protokola je najbitnije ovo:
svaki bit informacije traje tacno odredjeno vreme(1778us) i to tako sto za log1 prvo ide 889us signal 38kHz(ustvari za rc5 se koristi 36),pa onda 889us pauza.Za log0 je obrnuto-prvo ide 889us pauza,pa 889us signal.
pored toga rc5 ima i 2 start bita i 1 toggle bit.
Probacu da ti objasnim kako sam ja to dekodirao(verovao ili ne to je radilo!):
U petlji sam cekao na signal.onda je program isao dalje nekako ovako:
-cekaj dok ima signala //treba da traje 889us
-cekaj dok nema signala //opet 889us
-cekaj dok ima signala //isto to,samo za drugi start bit
-cekaj dok nema signala
-cekaj 1778 us // da prodje i taj toggle bit
-cekaj jos 100us //da budem siguran da sam usao u prvu polovinu prvog bita koji se prenosi
-testiraj da li je ulaz log1 //sad sam na prvoj polovini prvog bita,ako je 1 onda je prvi bit 1
-cekaj 1778us //cekam da prodje prvi bit,i pocne prva polovina drugog bita
-testiraj da li je ulaz log1 //ako jeste,onda je drugi bit 1,ako nije,onda je drugi bit 0

i tako dok imas bitova-rc5 ih salje 5 za adresu uredjaja kome se obraca(TV,VCR,SAT...) i jos 6 za komandu(VOLUME UP,VOLUME DOWN...)
Znaci ukupno 14 bitova po 1,778ms je 25ms.

Ne moras ti da se drzis bukvalno tog protokola,ali je dobro kao neka polazna ideja.Naravno probaj da smanjujes ta vremena trajanja bitova sve dok uspevas da primas i dekodiras signal,pa ces videti koja je maksimalna brzina slanja podataka.I mislim da je mnogo 11 bitova podataka(pod uslovom da zadrzis ova prva 3 kao neke start bitove),dovoljno je 8 da bi preneo bilo koji broj ili slovo(njegov ASCII kod)
[ ADRENALIN @ 05.12.2009. 02:11 ] @
Sta ti znaci da nisi vican? Samo treba da prekompajliras to u mplab-u i to je to. Sta ti ej problem, mogu ja da zakacim ceo projekat ako ti je lakse, doduse ya 12F.
[ sirmiumsm @ 05.12.2009. 04:12 ] @
Nisam imao Mplab, probao sam sa BoostC ali nije radilo. Ne znajuci kako dalje, citao sam jos neke projekte i uspeo sam da resim problem sa 3linije koda koje sam ostavio gore. Hvala puno na pomoci i trudu.