Salut, Habr.
Dans la
partie précédente, nous avons examiné la possibilité de transmettre des signaux simples en utilisant GNU Radio. Nous allons maintenant aller plus loin et voir comment transmettre quelque chose de plus compliqué. Commençons par les signaux radio amateurs WSPR, puis créons un modem logiciel QAM fonctionnel.

Et comme dans le cas précédent, nous le ferons sans écrire une seule ligne de code, le programme sera également multi-plateforme et pourra fonctionner à la fois sous OSX / Linux et sous Windows. Je montrerai également comment déboguer un modem à l'aide de GNU Radio, sans aucun matériel.
Suite sous la coupe.
Pour ceux qui n'ont pas utilisé GNU Radio, il est recommandé de lire les parties
4 et
5 , qui décrivent les principes de travail avec le programme.
Wspr
Commençons par une plus simple, avec
WSPR - ce type de communication a été spécialement conçu pour les tests de propagation de signaux faibles, c'est-à-dire nous avons besoin d'un niveau de puissance d'appareils comme LimeSDR ne dépassant pas 100 mW. Le signal WSPR est transmis à très faible vitesse (2 minutes par message d'environ 30 octets) dans une bande très étroite, ce qui permet de le recevoir même en dessous du niveau de bruit. Transmettez un tel signal en utilisant GNU Radio.
Vous devez d'abord enregistrer le signal. Pour ce faire, prenez le programme
WSJT , définissez tous les paramètres nécessaires (alimentation, indicatif d'appel, emplacement, etc.). Spécifiez Virtual Audio Cable comme périphérique audio de sortie dans les paramètres et enregistrez le signal en WAV. Les pauses sur les bords doivent être coupées dans n'importe quel éditeur (par exemple, Cool Edit), par conséquent, nous devrions obtenir un fichier d'une durée d'environ 2 minutes.
Créez maintenant un graphique dans le GNU Radio Companion.

Cette méthode ne prétend pas être d'une efficacité maximale, mais elle est assez simple et directe. Le signal WSPR est initialement à une fréquence de 1500 Hz, le fichier wav enregistré a une fréquence d'échantillonnage de 22050 s / s. Tout d'abord, nous rééchantillonnons le signal 57/5 fois pour amener la fréquence d'échantillonnage aux 250 000 s / s requis. Ensuite, nous augmentons la fréquence de 10 KHz (le signal utile sera à la fréquence de 11,5 KHz), traduisons le signal sous la forme complexe requise par le récepteur et coupons l'excédent de filtre, laissant les fréquences 11-12 KHz.
Les signaux WSPR sont limités dans le temps et transmis toutes les minutes paires (0:00, 0:02, etc.). J'ai commencé le transfert vers GNU Radio manuellement, à l'œil nu, en déterminant l'intervalle par heure, toute personne qui veut peut ajouter un script en Python pour démarrer automatiquement le transfert.
Nous attendons le bon moment, allumons l'émetteur, le récepteur et vérifions le résultat.

Si vous le souhaitez, vous pouvez également ajouter la génération automatique d'un fichier WSPR au programme en fonction des données d'entrée (indicatif d'appel, emplacement, puissance de transmission), des exemples de génération WSPR pour Python peuvent être pris sur github.
Il est intéressant de noter qu'à 432 MHz, la dérive de fréquence est déjà assez perceptible, bien que le signal soit encore décodé. Mais à une fréquence de 1,3 GHz, la dérive devient si importante que le WSPR n'est plus accepté - un générateur de référence externe avec un signal plus stable est nécessaire pour le SDR (ou au moins une correction de fréquence logicielle pendant la transmission, bien que ce soit moins pratique).
Si le SDR vous permet de transmettre à basses fréquences, vous pouvez essayer la transmission sur la bande HF. Ainsi, avec HackRF, il a été possible de transmettre un signal à 1000 km à 14 MHz depuis une antenne de salle, ce qui peut être considéré comme un bon résultat. Bien que les hautes fréquences (433 MHz et 1,3 GHz) soient peut-être encore plus intéressantes pour les expériences, les signaux ne sont transmis qu'en ligne de visée directe, donc pour de telles expériences, vous avez besoin d'un deuxième participant du côté récepteur. Le deuxième plus de ces tests est que seuls les paresseux n'ont pas transmis à HF en wspr, mais les hautes fréquences sont beaucoup moins maîtrisées. Ainsi, avec des cartes comme LimeSDR ou USRP, vous pouvez réaliser des expériences assez intéressantes avec la réception et la transmission à ultra-hautes fréquences.
Modem QAM
Allons plus loin. WSPR est un format assez simple, faisons quelque chose de plus intéressant - un modem à part entière (enfin, presque). Avec
la modulation d'amplitude en quadrature, l'amplitude et la phase du signal changent simultanément, ce qui permet aux données d'être transmises à une vitesse plus élevée (mais la bande occupée est également plus grande).
Considérez la première partie - l'émetteur.

Comme vous pouvez le voir, nous lisons les données du fichier data.txt, puis avec une fréquence d'échantillonnage de 25 KHz, nous envoyons des données à l'encodeur de paquets, qui convertit le flux en un code 4 bits. Ce flux va au modulateur en quadrature, puis la fréquence d'échantillonnage est augmentée à une fréquence d'émetteur de 250 kHz, et le signal est décalé vers le haut de 80 kHz (de nombreux récepteurs ont un pic à fréquence nulle, ce qui interfère). Le composant Constellation Rect définit les paramètres de modulation - le nombre de caractères et le décalage de phase et d'amplitude.
La première partie est prête. Nous commençons le «transfert» et voyons notre signal.

Nous pouvons tester notre émetteur sans même avoir d'équipement - pour cela, il y a un bloc de modèle de canal spécial - un modèle de canal de communication. Là, vous pouvez régler le bruit, le décalage de fréquence, etc.
Voici à quoi ressemble notre signal avant et après la transmission. Soit dit en passant, comme vous pouvez le voir, toutes les "harmoniques" de l'émetteur en dessous de 120 dB sont bien inférieures au niveau de bruit.

Maintenant la réception. En fait, la même chose, mais dans l'ordre inverse.

Séparément, vous pouvez vous arrêter au dernier bloc UDP Sink. Il n'est pas clair pourquoi, mais dans GNU Radio il n'y a pas de composant pour visualiser les données texte. Par conséquent, nous envoyons simplement des données via UDP à n'importe quel port local (j'ai choisi 999).
Pour recevoir, nous écrivons un programme simple en Python.
import socket UDP_IP = "127.0.0.1" UDP_PORT = 999 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
Résultat: exécutez le script, exécutez GNU Radio et voyez les messages reçus dans la console.

Comme vous pouvez le voir, tout fonctionne et vous ne pouvez avoir ni récepteur ni antenne :)
Pour ceux qui veulent répéter les expériences, le fichier grc du projet est sous le spoiler. Il devrait fonctionner sur Linux et Windows.
qam_test.grc <?xml version='1.0' encoding='utf-8'?> <?grc format='1' created='3.7.11'?> <flow_graph> <timestamp>Mon May 27 21:52:42 2019</timestamp> <block> <key>options</key> <param> <key>author</key> <value></value> </param> <param> <key>window_size</key> <value></value> </param> <param> <key>category</key> <value>[GRC Hier Blocks]</value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>description</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(8, 8)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>generate_options</key> <value>qt_gui</value> </param> <param> <key>hier_block_src_path</key> <value>.:</value> </param> <param> <key>id</key> <value>top_block</value> </param> <param> <key>max_nouts</key> <value>0</value> </param> <param> <key>qt_qss_theme</key> <value></value> </param> <param> <key>realtime_scheduling</key> <value></value> </param> <param> <key>run_command</key> <value>{python} -u {filename}</value> </param> <param> <key>run_options</key> <value>prompt</value> </param> <param> <key>run</key> <value>True</value> </param> <param> <key>thread_safe_setters</key> <value></value> </param> <param> <key>title</key> <value></value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1144, 172)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>excess_bw</value> </param> <param> <key>value</key> <value>0.35</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1104, 436)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>nfilts</value> </param> <param> <key>value</key> <value>32</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1096, 588)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>nfilts_0</value> </param> <param> <key>value</key> <value>32</value> </param> </block> <block> <key>variable_constellation_rect</key> <param> <key>comment</key> <value></value> </param> <param> <key>const_points</key> <value>[0.707+0.707j, -0.707+0.707j, -0.707-0.707j, 0.707-0.707j]</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1104, 16)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>qpsk</value> </param> <param> <key>imag_sect</key> <value>2</value> </param> <param> <key>real_sect</key> <value>2</value> </param> <param> <key>rot_sym</key> <value>4</value> </param> <param> <key>soft_dec_lut</key> <value>None</value> </param> <param> <key>precision</key> <value>8</value> </param> <param> <key>sym_map</key> <value>[0, 1, 2, 3]</value> </param> <param> <key>w_imag_sect</key> <value>1</value> </param> <param> <key>w_real_sect</key> <value>1</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1104, 372)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>rrc_taps</value> </param> <param> <key>value</key> <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), 0.35, 45*nfilts)</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1112, 508)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>rrc_taps_0</value> </param> <param> <key>value</key> <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), 0.35, 45*nfilts)</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(168, 12)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>samp_rate</value> </param> <param> <key>value</key> <value>250000</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1144, 244)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>sps</value> </param> <param> <key>value</key> <value>4</value> </param> </block> <block> <key>variable</key> <param> <key>comment</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(1104, 308)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>timing_loop_bw</value> </param> <param> <key>value</key> <value>6.28/100.0</value> </param> </block> <block> <key>analog_sig_source_x</key> <param> <key>amp</key> <value>1</value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>freq</key> <value>80000</value> </param> <param> <key>_coordinate</key> <value>(664, 20)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>analog_sig_source_x_0</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>offset</key> <value>0</value> </param> <param> <key>type</key> <value>complex</value> </param> <param> <key>samp_rate</key> <value>samp_rate</value> </param> <param> <key>waveform</key> <value>analog.GR_COS_WAVE</value> </param> </block> <block> <key>analog_sig_source_x</key> <param> <key>amp</key> <value>1</value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>freq</key> <value>-80000</value> </param> <param> <key>_coordinate</key> <value>(48, 540)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>analog_sig_source_x_1</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>offset</key> <value>0</value> </param> <param> <key>type</key> <value>complex</value> </param> <param> <key>samp_rate</key> <value>samp_rate</value> </param> <param> <key>waveform</key> <value>analog.GR_COS_WAVE</value> </param> </block> <block> <key>blks2_packet_decoder</key> <param> <key>access_code</key> <value></value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> <value>(296, 676)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blks2_packet_decoder_0</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>type</key> <value>byte</value> </param> <param> <key>threshold</key> <value>-1</value> </param> </block> <block> <key>blks2_packet_encoder</key> <param> <key>access_code</key> <value></value> </param> <param> <key>bits_per_symbol</key> <value>4</value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> <value>(224, 76)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blks2_packet_encoder_0</value> </param> <param> <key>type</key> <value>byte</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>pad_for_usrp</key> <value>True</value> </param> <param> <key>payload_length</key> <value>0</value> </param> <param> <key>preamble</key> <value></value> </param> <param> <key>samples_per_symbol</key> <value>4</value> </param> </block> <block> <key>blocks_file_source</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>file</key> <value>D:\MyProjects\GNURadio\data.txt</value> </param> <param> <key>_coordinate</key> <value>(8, 92)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blocks_file_source_0</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>type</key> <value>byte</value> </param> <param> <key>repeat</key> <value>True</value> </param> <param> <key>vlen</key> <value>1</value> </param> </block> <block> <key>blocks_multiply_xx</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(920, 88)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blocks_multiply_xx_0</value> </param> <param> <key>type</key> <value>complex</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>num_inputs</key> <value>2</value> </param> <param> <key>vlen</key> <value>1</value> </param> </block> <block> <key>blocks_multiply_xx</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>_coordinate</key> <value>(224, 496)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blocks_multiply_xx_1</value> </param> <param> <key>type</key> <value>complex</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>num_inputs</key> <value>2</value> </param> <param> <key>vlen</key> <value>1</value> </param> </block> <block> <key>blocks_throttle</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> <value>(96, 196)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blocks_throttle_1</value> </param> <param> <key>ignoretag</key> <value>True</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>samples_per_second</key> <value>25000</value> </param> <param> <key>type</key> <value>byte</value> </param> <param> <key>vlen</key> <value>1</value> </param> </block> <block> <key>blocks_udp_sink</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>ipaddr</key> <value>127.0.0.1</value> </param> <param> <key>port</key> <value>999</value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> <value>(680, 660)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>blocks_udp_sink_0</value> </param> <param> <key>type</key> <value>byte</value> </param> <param> <key>psize</key> <value>64</value> </param> <param> <key>eof</key> <value>True</value> </param> <param> <key>vlen</key> <value>1</value> </param> </block> <block> <key>channels_channel_model</key> <param> <key>alias</key> <value></value> </param> <param> <key>block_tags</key> <value>False</value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>epsilon</key> <value>1.0</value> </param> <param> <key>freq_offset</key> <value>0.0</value> </param> <param> <key>_coordinate</key> <value>(504, 284)</value> </param> <param> <key>_rotation</key> <value>180</value> </param> <param> <key>id</key> <value>channels_channel_model_0</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>noise_voltage</key> <value>0.1</value> </param> <param> <key>seed</key> <value>0</value> </param> <param> <key>taps</key> <value>1.0 + 1.0j</value> </param> </block> <block> <key>digital_qam_demod</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>differential</key> <value>True</value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>excess_bw</key> <value>0.35</value> </param> <param> <key>freq_bw</key> <value>6.28/100.0</value> </param> <param> <key>_coordinate</key> <value>(672, 456)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>mod_code</key> <value>"gray"</value> </param> <param> <key>id</key> <value>digital_qam_demod_0</value> </param> <param> <key>log</key> <value>False</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>constellation_points</key> <value>4</value> </param> <param> <key>phase_bw</key> <value>6.28/100.0</value> </param> <param> <key>samples_per_symbol</key> <value>4</value> </param> <param> <key>timing_bw</key> <value>6.28/100.0</value> </param> <param> <key>verbose</key> <value>False</value> </param> </block> <block> <key>digital_qam_mod</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>differential</key> <value>True</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>excess_bw</key> <value>0.35</value> </param> <param> <key>_coordinate</key> <value>(384, 116)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>mod_code</key> <value>"gray"</value> </param> <param> <key>id</key> <value>digital_qam_mod_0</value> </param> <param> <key>log</key> <value>False</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>constellation_points</key> <value>4</value> </param> <param> <key>samples_per_symbol</key> <value>4</value> </param> <param> <key>verbose</key> <value>False</value> </param> </block> <block> <key>low_pass_filter</key> <param> <key>beta</key> <value>6.76</value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>cutoff_freq</key> <value>12000</value> </param> <param> <key>decim</key> <value>1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>type</key> <value>fir_filter_ccf</value> </param> <param> <key>_coordinate</key> <value>(320, 460)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>gain</key> <value>1</value> </param> <param> <key>id</key> <value>low_pass_filter_0</value> </param> <param> <key>interp</key> <value>1</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>samp_rate</key> <value>samp_rate</value> </param> <param> <key>width</key> <value>1000</value> </param> <param> <key>win</key> <value>firdes.WIN_HAMMING</value> </param> </block> <block> <key>qtgui_const_sink_x</key> <param> <key>autoscale</key> <value>False</value> </param> <param> <key>axislabels</key> <value>True</value> </param> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>_enabled</key> <value>1</value> </param> <param> <key>_coordinate</key> <value>(456, 20)</value> </param> <param> <key>gui_hint</key> <value></value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>grid</key> <value>False</value> </param> <param> <key>id</key> <value>qtgui_const_sink_x_0</value> </param> <param> <key>legend</key> <value>True</value> </param> <param> <key>alpha1</key> <value>1.0</value> </param> <param> <key>color1</key> <value>"blue"</value> </param> <param> <key>label1</key> <value></value> </param> <param> <key>marker1</key> <value>0</value> </param> <param> <key>style1</key> <value>0</value> </param> <param> <key>width1</key> <value>1</value> </param> <param> <key>alpha10</key> <value>1.0</value> </param> <param> <key>color10</key> <value>"red"</value> </param> <param> <key>label10</key> <value></value> </param> <param> <key>marker10</key> <value>0</value> </param> <param> <key>style10</key> <value>0</value> </param> <param> <key>width10</key> <value>1</value> </param> <param> <key>alpha2</key> <value>1.0</value> </param> <param> <key>color2</key> <value>"red"</value> </param> <param> <key>label2</key> <value></value> </param> <param> <key>marker2</key> <value>0</value> </param> <param> <key>style2</key> <value>0</value> </param> <param> <key>width2</key> <value>1</value> </param> <param> <key>alpha3</key> <value>1.0</value> </param> <param> <key>color3</key> <value>"red"</value> </param> <param> <key>label3</key> <value></value> </param> <param> <key>marker3</key> <value>0</value> </param> <param> <key>style3</key> <value>0</value> </param> <param> <key>width3</key> <value>1</value> </param> <param> <key>alpha4</key> <value>1.0</value> </param> <param> <key>color4</key> <value>"red"</value> </param> <param> <key>label4</key> <value></value> </param> <param> <key>marker4</key> <value>0</value> </param> <param> <key>style4</key> <value>0</value> </param> <param> <key>width4</key> <value>1</value> </param> <param> <key>alpha5</key> <value>1.0</value> </param> <param> <key>color5</key> <value>"red"</value> </param> <param> <key>label5</key> <value></value> </param> <param> <key>marker5</key> <value>0</value> </param> <param> <key>style5</key> <value>0</value> </param> <param> <key>width5</key> <value>1</value> </param> <param> <key>alpha6</key> <value>1.0</value> </param> <param> <key>color6</key> <value>"red"</value> </param> <param> <key>label6</key> <value></value> </param> <param> <key>marker6</key> <value>0</value> </param> <param> <key>style6</key> <value>0</value> </param> <param> <key>width6</key> <value>1</value> </param> <param> <key>alpha7</key> <value>1.0</value> </param> <param> <key>color7</key> <value>"red"</value> </param> <param> <key>label7</key> <value></value> </param> <param> <key>marker7</key> <value>0</value> </param> <param> <key>style7</key> <value>0</value> </param> <param> <key>width7</key> <value>1</value> </param> <param> <key>alpha8</key> <value>1.0</value> </param> <param> <key>color8</key> <value>"red"</value> </param> <param> <key>label8</key> <value></value> </param> <param> <key>marker8</key> <value>0</value> </param> <param> <key>style8</key> <value>0</value> </param> <param> <key>width8</key> <value>1</value> </param> <param> <key>alpha9</key> <value>1.0</value> </param> <param> <key>color9</key> <value>"red"</value> </param> <param> <key>label9</key> <value></value> </param> <param> <key>marker9</key> <value>0</value> </param> <param> <key>style9</key> <value>0</value> </param> <param> <key>width9</key> <value>1</value> </param> <param> <key>name</key> <value>""</value> </param> <param> <key>nconnections</key> <value>1</value> </param> <param> <key>size</key> <value>1024</value> </param> <param> <key>tr_chan</key> <value>0</value> </param> <param> <key>tr_level</key> <value>0.0</value> </param> <param> <key>tr_mode</key> <value>qtgui.TRIG_MODE_FREE</value> </param> <param> <key>tr_slope</key> <value>qtgui.TRIG_SLOPE_POS</value> </param> <param> <key>tr_tag</key> <value>""</value> </param> <param> <key>type</key> <value>complex</value> </param> <param> <key>update_time</key> <value>0.10</value> </param> <param> <key>xmax</key> <value>2</value> </param> <param> <key>xmin</key> <value>-2</value> </param> <param> <key>ymax</key> <value>2</value> </param> <param> <key>ymin</key> <value>-2</value> </param> </block> <block> <key>rational_resampler_xxx</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>decim</key> <value>1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>fbw</key> <value>0</value> </param> <param> <key>_coordinate</key> <value>(648, 148)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>rational_resampler_xxx_0</value> </param> <param> <key>interp</key> <value>10</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>taps</key> <value></value> </param> <param> <key>type</key> <value>ccc</value> </param> </block> <block> <key>rational_resampler_xxx</key> <param> <key>alias</key> <value></value> </param> <param> <key>comment</key> <value></value> </param> <param> <key>affinity</key> <value></value> </param> <param> <key>decim</key> <value>10</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> <key>fbw</key> <value>0</value> </param> <param> <key>_coordinate</key> <value>(480, 484)</value> </param> <param> <key>_rotation</key> <value>0</value> </param> <param> <key>id</key> <value>rational_resampler_xxx_0_0</value> </param> <param> <key>interp</key> <value>1</value> </param> <param> <key>maxoutbuf</key> <value>0</value> </param> <param> <key>minoutbuf</key> <value>0</value> </param> <param> <key>taps</key> <value></value> </param> <param> <key>type</key> <value>ccc</value> </param> </block> <connection> <source_block_id>analog_sig_source_x_0</source_block_id> <sink_block_id>blocks_multiply_xx_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>analog_sig_source_x_1</source_block_id> <sink_block_id>blocks_multiply_xx_1</sink_block_id> <source_key>0</source_key> <sink_key>1</sink_key> </connection> <connection> <source_block_id>blks2_packet_decoder_0</source_block_id> <sink_block_id>blocks_udp_sink_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>blks2_packet_encoder_0</source_block_id> <sink_block_id>digital_qam_mod_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>blocks_file_source_0</source_block_id> <sink_block_id>blocks_throttle_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>blocks_multiply_xx_0</source_block_id> <sink_block_id>channels_channel_model_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>blocks_multiply_xx_1</source_block_id> <sink_block_id>low_pass_filter_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>blocks_throttle_1</source_block_id> <sink_block_id>blks2_packet_encoder_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>channels_channel_model_0</source_block_id> <sink_block_id>blocks_multiply_xx_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>digital_qam_demod_0</source_block_id> <sink_block_id>blks2_packet_decoder_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>digital_qam_mod_0</source_block_id> <sink_block_id>qtgui_const_sink_x_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>digital_qam_mod_0</source_block_id> <sink_block_id>rational_resampler_xxx_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>low_pass_filter_0</source_block_id> <sink_block_id>rational_resampler_xxx_0_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>rational_resampler_xxx_0</source_block_id> <sink_block_id>blocks_multiply_xx_0</sink_block_id> <source_key>0</source_key> <sink_key>1</sink_key> </connection> <connection> <source_block_id>rational_resampler_xxx_0_0</source_block_id> <sink_block_id>digital_qam_demod_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> </flow_graph>
Un bon guide pour créer un modem plus sophistiqué se trouve
sur le site Web de GNU Radio , mais ils utilisent un bloc personnalisé pour la démodulation, qui n'était possible que sous Linux. Il n'y a aucun problème avec cela dans l'exemple ci-dessus.
Conclusion
Comme vous pouvez le voir, GNU Radio est un programme assez intéressant pour travailler avec des signaux de différentes manières, où vous pouvez faire beaucoup de choses intéressantes. Si le public ne se désintéresse pas (j'ai l'impression de me plonger dans des sujets étroits qui intéressent peu la plupart), vous pouvez essayer d'envisager de transmettre quelque chose de plus intéressant, par exemple une vidéo.