|
Raspberry Pi
38) TEA5767 - FM rádio ovládané přes I2C
Další zařízení, které se mi povedlo k Raspíčku připojit,
je obvod TEA5767. Je to obvod, který je určen pro příjem FM rádiového
vysílání.
Sehnal jsem ho přes e-Bay za necelé 2 dolary.
Tady je dokumentace k tomu obvodu:
- Popis
čipu a komunikace
- Aplikační
pokyny - různé přepočty frekvencí
Obvod je součástí malého
plošňáčku, na kterém je osazeno ještě několik pasivních součástek
(odpory, kondenzátory a krystal).
Tento plošný spoj má po obvodu 10
plošek, na které je možné připájet vývody.
Rozteč těchto vývodů
je ale nestandardní (2mm), takže abych ho mohl zasunout do nepájivého
pole, bylo potřeba ho ještě přes drátky připojit k redukci, kterou
jsem ustřihnul z univerzálního plošňáku.
Při výrobě přechodky jsem si to špatně rozmyslel a připájel jsem
tam ten plošňáček s obvodem tak, jak je to vidět na následující
fotografii. Pokud budete připojovat destičku stejným způsobem, dejte pozor na to,
že vývody té přechodky pak budou číslované
zrcadlově.
Schéma připojení k RasPi:
Ve schématu jsou použita dvě rozpínací tlačítka.
Využívá je ukázkový program k ručnímu přepínání a vyhledávání
stanic.
Pro jednoduché operace (přímé nastavení frekvence, nebo skenování
celého pásma) nejsou potřeba.
Záměrně jsem volil rozpínací tlačítka. Kdybych použil spínací a
někdo spustil DEMO bez těch připojených tlačítek, nemohl by ukončit
program (program se ukončuje stiskem obou tlačítek najednou).
Když ale nebudou rozpínací tlačítka vůbec připojena, ukončí se
program automaticky.
Jako anténa posloužil kus drátu. Několik stanic to ale
našlo i bez antény.
Výstup z obvodu je velice slabý. Je možné k němu připojit jen sluchátka.
Pokud chcete místo sluchátek zapojit reproduktory, musíte ten signál
ještě zesílit.
Důležité jsou kondenzátory na výstupech.
Neměl jsem kondenzátory 220nF, které doporučuje katalogový list, a proto jsem tam dal, co bylo po ruce.
Kvalita zvuku je však na těch kondenzátorech hodně závislá. Když
jsem použil nižší hodnotu kondenzátorů, byly ořezané hloubky. Když
jsem tam dal kondenzátory s vyšší kapacitou, tak byl zvuk hodně zkreslený
(chraptěl).
Nakonec jsem sehnal těch 220nF a zvuk s nimi byl nejkvalitnější.
Software:
Obvod je ovládaný přes I2C, ale trochu jinak, než jsem
byl zvyklý. Celé řízení probíhá pomocí zápisu 5 bajtů do obvodu.
Problém byl v tom, že doplněk do Pythonu, který se stará o řízení
I2C komunikace, zapisuje do periférií data v tomto formátu:
write_i2c_block_data(adresa , číslo prvního
registru , pole hodnot) |
Takže když je třeba do "běžného" obvodu s
adresou 0x20 zapsat do registru č.7 například číslo 10, pak do
registru č.8 hodnotu 200 a do registru č.9 hodnotu 150, provede se to
jednoduše:
.
.
.
blokdat=[ 10 , 200 , 150 ]
bus.write_i2c_block_data( 0x20 , 7 , blokdat )
.
.
.
|
Obvod TEA5767 však nemá žádné registry - po příjmu
adresy očekává okamžitě dalších 5 konfiguračních bajtů.
Musel jsem tedy první z těch pěti bajtů zapisovat v příkazu do místa,
kam se normálně vkládá číslo prvního registru.
Posílání pěti bajtů do obvodu TEA5767 tedy vypadá takto:
.
.
.
blokdat=[ bajt2 , bajt3 , bajt4 , bajt5 ]
bus.write_i2c_block_data( 0x60 , bajt1 , blokdat ) # 0x60 je I2C adresa obvodu TEA5767
.
.
.
|
Úplně nejjednodušší program, který jen naladí požadovanou
frekvenci, se dá napsat takhle:
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import smbus
bus = smbus.SMBus(1) # novejsi varianta RasPi (512MB)
#bus = smbus.SMBus(0) # starsi varianta RasPi (256MB)
freq = 95 # pozadovana frekvence v MHz (na 95.0MHz u nas vysila Radio Blanik)
# rozlozeni frekvence na dva bajty (podle katalogoveho listu)
freq14bit = int(4 * (freq * 1000000 + 225000)/32768)
freqH = int(freq14bit / 256 )
freqL = freq14bit & 0xFF
# popisy jednotlivych bitu v bajtech - viz. katalogovy list
bajt0 = 0x60 # I2C adresa obvodu
bajt1 = freqH # 1.bajt (MUTE bit ; frekvence H)
bajt2 = freqL # 2.bajt (frekvence L)
bajt3 = 0b10110000 # 3.bajt (SUD ; SSL1,SSL2 ; HLSI ; MS,MR,ML ; SWP1)
bajt4 = 0b00010000 # 4.bajt (SWP2 ; STBY ; BL ; XTAL ; SMUTE ; HCC ; SNC ; SI)
bajt5 = 0b00000000 # 5.bajt (PLREFF ; DTC ; 0;0;0;0;0;0)
blokdat=[ bajt2 , bajt3 , bajt4 , bajt5 ]
bus.write_i2c_block_data( bajt0 , bajt1 , blokdat ) # nastaveni nove frekvence do obvodu
|
Obvod má v sobě zabudovanou funkci pro automatické vyhledávání
stanic. To se mi ale nějak nepodařilo zprovoznit.
Vytvořil jsem si proto vyhledávání stanic jiným způsobem.
Využil jsem toho, že po nastavení frekvence je možné z obvodu (kromě jiných parametrů)
načíst i sílu signálu. Je to 4 bitová hodnota, takže může nabývat
hodnot 0 až 15. Čím je signál silnější, tím je číslo větší.
Nechal jsem tedy postupně ve smyčce nastavovat všechny frekvence od 87,5 do
108MHz po kroku 100kHz a po každém nastavení frekvence jsem si zjistil
sílu signálu. Když byla větší, než například 10, nechal jsem tu
nastavenou frekvenci a sílu signálu zobrazit.
Tím jsem získal seznam všech silných frekvencí.
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import smbus
import time
bus = smbus.SMBus(1) # novejsi varianta RasPi (512MB)
#bus = smbus.SMBus(0) # starsi varianta RasPi (256MB)
adc_limit = 10 # minimalni hodnota sily signalu, pri ktere bude frekvence zobrazena
print "Zobrazuji frekvence, ktere maji silu signalu alespon " + str(adc_limit)
freq = 87.5 # prohledavani pasma zacina od 87.5MHz
while (freq <= 108):
freq= freq + 0.1 # v kazdem pruchodu smyckou while... se frekvence zvetsi o 100kHz
# prevod frekvence na dva bajty (podle kat.listu)
freq14bit = int(4 * (freq * 1000000 + 225000)/32768)
freqH = int(freq14bit / 256 )
freqL = freq14bit & 0xFF
# popisy jednotlivych bitu v bajtech - viz. katalogovy list
bajt0 = 0x60 # I2C adresa obvodu
bajt1 = freqH # 1.bajt (MUTE bit ; frekvence H)
bajt2 = freqL # 2.bajt (frekvence L)
bajt3 = 0b10110000 # 3.bajt (SUD ; SSL1,SSL2 ; HLSI ; MS,MR,ML ; SWP1)
bajt4 = 0b00010000 # 4.bajt (SWP2 ; STBY ; BL ; XTAL ; SMUTE ; HCC ; SNC ; SI)
bajt5 = 0b00000000 # 5.bajt (PLREFF ; DTC ; 0;0;0;0;0;0)
blokdat=[ bajt2 , bajt3 , bajt4 , bajt5 ]
# preladeni na novou frekvenci
bus.write_i2c_block_data( bajt0 , bajt1 , blokdat )
time.sleep(0.05) # mezi jednotlivymi frekvencemi chvili pockej, nez se vyhodnoti sila signalu
# precteni obsahu obvodu
bajt1r = bus.read_byte(bajt0) # prvni bajt se musi cist samostatne
data = bus.read_i2c_block_data( bajt0 , bajt1 ) # nacteni vsech bajtu z obvodu
data[0] = bajt1r # prvni bajt se nahradi samostatne nactenou hodnotou
sila = data[3] >> 4 # v nejvyssich 4 bitech ctvrteho baju (data[3]) je pri cteni registru sila signalu
if (sila >= adc_limit): # porovnani sily signalu na aktualni frekvenci s pozadovanym limitem
print "f= " + str(freq) + "MHz" , "\tDATA:" + str(data[0:5]) + "\t(Sila signalu: " + str(sila) + ")"
|
Zobrazený blok hodnot s názvem DATA ukazuje 5 bajtů přečtených z čipu.
Jejich popis je v katalogovém listu. Síla signálu je "zakódovaná"
ve čtvrtém bajtu.
DEMO:
Na závěr jsem dal všechny ty podprogramy dohromady a
vytvořil jsem jednoduché rádio ovládané různými parametry přes příkazovou
řádku, nebo přes dvě tlačítka.
Tento ukázkový příklad umožňuje:
- přímo nastavit nějakou frekvenci
- prohledat celé pásmo a vypsat frekvence, které jsou alespoň tak silné,
jako zadaná hodnota
- najít nejbližší stanici od zadané frekvence (nahoru / dolu)
- ztišit, nebo zesílit výstup (MUTE)
- po připojení dvou tlačítek na GPIO porty umí postupně prohledávat
pásmo a zastavovat na silných stanicích
- nebo je možné těmi tlačítky přepínat mezi přednastavenými
stanicemi
Všechny parametry, pomocí kterých je možné program
ovládat, se vypíší při spuštění programu bez parametru:
Takže třeba nalezeni nejbližší stanice nad frekvencí
95MHz, která má signál silný alespoň 9 se provede tímto parametrem:
sudo python /home/pi/tea5767.py -sn 95 9 |
Celý ukázkový program je ke stažení tady:
tea5767.py
Video ukázka (zapněte si zvuk):
30.12.2013
Byl jsem upozorněn na chybu ve schématu. Původně jsem
měl vývod č.3 nezapojený a vývod č.4 byl připojen na GND.
Teď už je to v pořádku.
Noha č.3 slouží k výběru typu sběrnice a pokud je připojena na GND,
přepne se obvod do I2C komunikace.
|
|
|