[LNIV Xilinx](index.html)
# Meritev amplitudne karakteristike z Red Pitayo (RC sito)
Red Pitayo se lahko uporabi kot merilni instrument, saj z dvema izhodoma in dvema vhodoma obenem nadomesti funkcijski generator in osciloskop. Ker jo lahko programiramo v Pythonu, lahko meritve popolnoma avtomatiziramo: program sam nastavlja frekvenco, zajema signale in shranjuje rezultate.
## Potrebna oprema
- Red Pitaya
- SMA-BNC adapterji (privijemo jih na priključke Red Pitaye)
- 3 merilne sonde z BNC priključkom
- RC vezje: preizkusna ploščica (breadboard), upor in kondenzator po izbiri (mejno frekvenco izračunamo po formuli f₀ = 1 / (2πRC))
- urejevalnik kode in Python/C/C++
## Projekt
Red Pitaya hkrati generira signal in meri, kaj se z njim zgodi v vezju. Izhod OUT1 povežemo na vhod RC vezja. S sondo na kanalu IN2 merimo signal na vhodu vezja, s sondo na kanalu IN1 pa signal na izhodu. Mase vseh sond povežemo na skupno maso vezja.

Program se piše v Pythonu (lahko tudi v C ali C++). Najlažje je, če ga razdelimo na dve datoteki. Prva datoteka se izvaja na našem računalniku in izvede avtomatizacijo (prenese glavno datoteko na Red Pitayo in nazaj). Druga datoteka je dejanski program, ki se izvede na Red Pitayi. Uporablja knjižnico rp, ki je že nameščena na Red Pitayi. Namen datoteke je, da pošlje izhodni signal po naši izbiri ter vzorči vhodna signala za različen nabor frekvenc, prav tako pa iz teh podatkov izračuna amplitude. Te amplitude so diskretne vrednosti pri določenih frekvencah in se zapišejo v tekstovni datoteki (ena za vhodne signale, druga za izhodne signale).
### Meritev amplitudne karakteristike
Program najprej nastavi generator. Funkcija generiraj_signal nastavi obliko, frekvenco in amplitudo signala na izhodu OUT1 ter vklopi izhod:
```python
def generiraj_signal(frekvenca, amplituda, oblika):
rp.rp_GenReset()
rp.rp_GenWaveform(rp.RP_CH_1, oblika)
rp.rp_GenFreqDirect(rp.RP_CH_1, float(frekvenca))
rp.rp_GenAmp(rp.RP_CH_1, amplituda)
rp.rp_GenMode(rp.RP_CH_1, rp.RP_GEN_MODE_CONTINUOUS)
rp.rp_GenOutEnable(rp.RP_CH_1)
rp.rp_GenTriggerOnly(rp.RP_CH_1)
```
Zajem opravi funkcija zajemi_signal, ki zajame 16384 vzorcev na obeh vhodnih kanalih (velikost vsakega izmed krožnih bufferjev). Da se zajem vedno začne na istem mestu signala, uporabimo prožilnik (trigger)-zajem se sproži, ko gre signal na kanalu 1 čez 0 V navzgor. Funkcija počaka, da se to zgodi in da se vsi vzorci shranijo, šele nato jih prebere:
```python
def zajemi_signal():
rp.rp_AcqReset()
rp.rp_AcqSetDecimation(4)
rp.rp_AcqSetTriggerLevel(rp.RP_T_CH_1, 0.0)
rp.rp_AcqStart()
time.sleep(0.1)
rp.rp_AcqSetTriggerSrc(rp.RP_TRIG_SRC_CHA_PE)
while 1:
trig_state = rp.rp_AcqGetTriggerState()[1]
if trig_state == rp.RP_TRIG_STATE_TRIGGERED:
break
while 1:
if rp.rp_AcqGetBufferFillState()[1]:
break
rp.rp_AcqStop()
```
Amplitudo izračunamo kot polovico medvršnih vrednosti signala:
```python
def izracunaj_amplitudo(podatki):
return (np.max(podatki) - np.min(podatki)) / 2
```
Glavni del programa vse to poveže: v zanki gre čez vse frekvence, pri vsaki nastavi generator, malo počaka, da se signal umiri (brez tega dobimo napačne amplitude), zajame oba kanala in izračuna amplitudi:
```python
frekvence = np.arange(frekvenca_zacetna, frekvenca_koncna, korak)
for f in frekvence:
generiraj_signal(f, amplituda_vhod, oblika)
time.sleep(0.2) # počakamo, da se signal stabilizira
podatki1, podatki2 = zajemi_signal()
amplitude_ch1.append(izracunaj_amplitudo(podatki1))
amplitude_ch2.append(izracunaj_amplitudo(podatki2))
```
Za lahko program prešteje še število period v zajetem signalu, da vidimo, ali je zajem smiseln. Na koncu je potrebno pare frekvenca-amplituda za oba kanala zapišejo v datoteki amplituda_ch1.txt in amplituda_ch2.txt.
### Zagon meritev z računalnika
Zagonska skripta poskrbi, da se ves postopek izvede z enim samim ukazom. Iz Red Pitaye najprej izbriše stare rezultate, nanjo prenese datoteko amplitudna_karakteristika, jo požene in rezultate prenese nazaj na računalnik. V njej tudi nastavimo parametre meritve (frekvence, amplitudo, obliko signala), ki se merilnemu programu podajo kot argumenti ob zagonu:
```python
# 0. izbriši stare datoteke na Red Pitayi
subprocess.run('ssh root@192.168.1.15 "rm -f /root/amplituda_ch1.txt /root/amplituda_ch2.txt"', shell=True)
# 1. prenesi kodo na Red Pitayo
subprocess.run(f"scp {pot}amplitudna_karakteristika.py root@192.168.1.15:/root/", shell=True)
# 2. poženi program na Red Pitayi
subprocess.run('ssh root@192.168.1.15 "PYTHONPATH=/opt/redpitaya/lib/python python amplitudna_karakteristika.py"', shell=True)
# 3. prenesi rezultate nazaj
subprocess.run(f"scp root@192.168.1.15:/root/amplituda_ch1.txt {pot}", shell=True)
subprocess.run(f"scp root@192.168.1.15:/root/amplituda_ch2.txt {pot}", shell=True)
```
Rezultate na koncu izrišemo s knjižnico matplotlib (posebej datoteka) in dobimo graf amplitude v odvisnosti od frekvence za oba kanala. Vhodni signal je pri vseh frekvencah enak, izhodni pa z višanjem frekvence pada (kar pričakujemo od RC sita).
## Problemi in napotki
### Preizkusi
Za vmesne preizkuse kode je najbolje kar ročno: datoteko prek Bitvise SSH (okno SFTP) prenesemo z računalnika na Red Pitayo v mapo root, zaženemo konzolo, tam izvedemo datoteko in preverimo rezultate.
Smiselno je ustvariti še eno datoteko, v kateri shranimo samo vzorce signala ene frekvence in jih izrišemo z grafom, da preverimo, ali se vzorci sploh pravilno zajemajo.
### Proženje(trigger)
Prva stvar, ki se je izkazala za nujno, je pravilna nastavitev proženja. Če proženje nastavimo na "takoj" (RP_TRIG_SRC_NOW), dobimo zelo nestabilne meritve — graf ima ogromno skokov in ne izgleda kot sinus.
Ko proženje spremenimo tako, da zajem počaka na določen trenutek — pozitiven prehod signala skozi 0 V (rp.rp_AcqSetTriggerSrc(rp.RP_TRIG_SRC_CHA_PE)) — se stvar večinoma uredi. Signal izgleda kot sinus, ampak še vedno se vsake toliko pojavi kakšen nenavaden skok.

To odpravimo tako, da med začetkom zajema in nastavitvijo proženja dodamo kratek premor:
```python
rp.rp_AcqStart()
time.sleep(0.1)
rp.rp_AcqSetTriggerSrc(rp.RP_TRIG_SRC_CHA_PE)
```
Prikazan graf na sliki sem izrisal z drugima datotekama, kjer se v eni vzorči signal ene frekvence in se potem t matplotlib izriše.
## SSH ključ
Da bo datoteka zagon.py pravilno delovala, moramo zagotoviti stalno povezovanje prek SSH med računalnikom in Red Pitayo, ne da bi bilo treba pri tem vedno vpisovati geslo. To dosežemo s SSH ključem. Ključ ustvarimo na računalniku:
```
ssh-keygen -t rsa
```

in ga skopiramo na Red Pitayo (v Windows ukazni vrstici):
```
type C:\Users\\.ssh\id_rsa.pub | ssh root@192.168.1.15 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
```
Od tu naprej gesla ni treba nikoli več vpisovati. Vse povezave med tem računalnikom in to Red Pitayo gredo prek ključa, avtomatizacijska skripta pa lahko teče brez našega posredovanja.
Priloga: [amplitudna_karakteristika_datoteke.zip](./vosner/amplitudna_karakteristika_datoteke.zip)