صنع مودم: نقل البيانات الرقمية عبر الأثير باستخدام OFDM وراديو GNU

مرحبا يا هابر.

يمكن اعتبار هذا النص استمرارًا لمقالة " نحلل صوت مودم الاتصال الهاتفي " ، الذي تناول طريقة إنشاء الاتصال بين أجهزة المودم. سنذهب اليوم إلى أبعد من ذلك ونرى عمليا كيف يتم نقل البيانات ، والتي سنقوم من أجلها بتنفيذ تطبيق مودم بسيط باستخدام OFDM وراديو GNU.

سننقل البيانات عن طريق الجو ، بالمعنى الحرفي للكلمة - سيكون مكبر الصوت والميكروفون كافيين للاستقبال والإرسال.

بالنسبة لأولئك المهتمين بكيفية عمل ذلك ، استمر تحت القطع.

لذا ، فإن مهمتنا هي جعل أبسط مودم قادر على إرسال البيانات من النقطة A إلى النقطة B. هناك العديد من الطرق لتعديل الإشارة الرقمية ، وسوف نستخدم OFDM ، وهي طريقة تستخدم على نطاق واسع في أنظمة الاتصالات الحديثة. في OFDM ، يتم تحويل إشارة تحويل فورييه الرقمية إلى العديد من الموجات الحاملة الفرعية المتوازية ، مما يضمن سرعة وكفاءة عالية لقناة الإرسال. يستخدم OFDM كثيرًا ، من التلفزيون الرقمي والراديو إلى LTE. قناتنا الصوتية أضيق بكثير وأكثر تواضعا من حيث المعلمات ، بحيث تكون السرعات أقل ، ولكن في الأساس ، لا يتغير الجوهر بشكل عام. بالمعنى الدقيق للكلمة ، فإن OFDM غير مخصص لنقل البيانات عبر الهواء ، على الرغم من أن الميكروفون ومكبر الصوت التقليديين سيكونان كافيين للمسافات الصغيرة.

OFDM في راديو جنو


يظهر الرسم البياني الأدنى لاختبار الاستقبال والإرسال أدناه:



شفرة المصدر لراديو جنو 3.8:

ofdm1.grc
options:
  parameters:
    author: ''
    category: '[GRC Hier Blocks]'
    cmake_opt: ''
    comment: ''
    copyright: ''
    description: ''
    gen_cmake: 'On'
    gen_linking: dynamic
    generate_options: qt_gui
    hier_block_src_path: '.:'
    id: ofdm_test_1
    max_nouts: '0'
    output_language: python
    placement: (0,0)
    qt_qss_theme: ''
    realtime_scheduling: ''
    run: 'True'
    run_command: '{python} -u {filename}'
    run_options: prompt
    sizing_mode: fixed
    thread_safe_setters: ''
    title: OFDM Test 1
    window_size: ''
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [8, 8]
    rotation: 0
    state: enabled

blocks:
- name: fft_len
  id: variable
  parameters:
    comment: ''
    value: '64'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [448, 12.0]
    rotation: 0
    state: enabled
- name: packet_len
  id: variable
  parameters:
    comment: ''
    value: '12'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [336, 12.0]
    rotation: 0
    state: enabled
- name: samp_rate
  id: variable
  parameters:
    comment: ''
    value: '2400'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [216, 12.0]
    rotation: 0
    state: enabled
- name: blocks_file_source_0
  id: blocks_file_source
  parameters:
    affinity: ''
    alias: ''
    begin_tag: pmt.PMT_NIL
    comment: ''
    file: D:\Temp\1\data2.txt
    length: '0'
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    repeat: 'True'
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [32, 128.0]
    rotation: 0
    state: enabled
- name: blocks_stream_to_tagged_stream_0
  id: blocks_stream_to_tagged_stream
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    len_tag_key: '"key"'
    maxoutbuf: '0'
    minoutbuf: '0'
    packet_len: packet_len
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [488, 156.0]
    rotation: 0
    state: enabled
- name: blocks_throttle_0
  id: blocks_throttle
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    ignoretag: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    samples_per_second: samp_rate
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [272, 168.0]
    rotation: 0
    state: enabled
- name: blocks_udp_sink_0
  id: blocks_udp_sink
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    eof: 'True'
    ipaddr: 127.0.0.1
    port: '40868'
    psize: '128'
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [424, 476.0]
    rotation: 180
    state: enabled
- name: channels_channel_model_0
  id: channels_channel_model
  parameters:
    affinity: ''
    alias: ''
    block_tags: 'True'
    comment: ''
    epsilon: '1.0'
    freq_offset: 0 * 1.0/fft_len
    maxoutbuf: '0'
    minoutbuf: '0'
    noise_voltage: '0.1'
    seed: '0'
    taps: 1.0 + 1.0j
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1112.0, 280]
    rotation: 270
    state: enabled
- name: digital_ofdm_rx_0
  id: digital_ofdm_rx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    cp_len: fft_len//4
    fft_len: fft_len
    header_mod: '"BPSK"'
    log: 'False'
    maxoutbuf: '0'
    minoutbuf: '0'
    occupied_carriers: ((-4,-3,-2,-1,1,2,3,4),)
    packet_len_key: '"key"'
    payload_mod: '"QPSK"'
    pilot_carriers: ((-6,-5,5,6),)
    pilot_symbols: ((-1,1,-1,1),)
    scramble_bits: 'False'
    sync_word1: None
    sync_word2: None
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [776, 428.0]
    rotation: 180
    state: enabled
- name: digital_ofdm_tx_0
  id: digital_ofdm_tx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    cp_len: fft_len//4
    fft_len: fft_len
    header_mod: '"BPSK"'
    log: 'False'
    maxoutbuf: '0'
    minoutbuf: '0'
    occupied_carriers: ((-4,-3,-2,-1,1,2,3,4),)
    packet_len_key: '"key"'
    payload_mod: '"QPSK"'
    pilot_carriers: ((-6,-5,5,6),)
    pilot_symbols: ((-1,1,-1,1),)
    rolloff: '0'
    scramble_bits: 'False'
    sync_word1: None
    sync_word2: None
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [776, 80.0]
    rotation: 0
    state: enabled
- name: qtgui_freq_sink_x_0
  id: qtgui_freq_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    autoscale: 'False'
    average: '1.0'
    axislabels: 'True'
    bw: samp_rate
    color1: '"blue"'
    color10: '"dark blue"'
    color2: '"red"'
    color3: '"green"'
    color4: '"black"'
    color5: '"cyan"'
    color6: '"magenta"'
    color7: '"yellow"'
    color8: '"dark red"'
    color9: '"dark green"'
    comment: ''
    ctrlpanel: 'False'
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    label: Relative Gain
    label1: Rx Spectrum
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: Rx Spectrum
    nconnections: '1'
    showports: 'True'
    tr_chan: '0'
    tr_level: '0.0'
    tr_mode: qtgui.TRIG_MODE_FREE
    tr_tag: '""'
    type: complex
    units: dB
    update_time: '0.10'
    width1: '1'
    width10: '1'
    width2: '1'
    width3: '1'
    width4: '1'
    width5: '1'
    width6: '1'
    width7: '1'
    width8: '1'
    width9: '1'
    wintype: firdes.WIN_BLACKMAN_hARRIS
    ymax: '10'
    ymin: '-140'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1232, 92.0]
    rotation: 0
    state: enabled

connections:
- [blocks_file_source_0, '0', blocks_throttle_0, '0']
- [blocks_stream_to_tagged_stream_0, '0', digital_ofdm_tx_0, '0']
- [blocks_throttle_0, '0', blocks_stream_to_tagged_stream_0, '0']
- [channels_channel_model_0, '0', digital_ofdm_rx_0, '0']
- [digital_ofdm_rx_0, '0', blocks_udp_sink_0, '0']
- [digital_ofdm_tx_0, '0', channels_channel_model_0, '0']
- [digital_ofdm_tx_0, '0', qtgui_freq_sink_x_0, '0']

metadata:
  file_format: 1


يتم استخدام ملف نص عادي كمصدر للبيانات (في حالتي ، يحتوي على السلسلة "Hello Habr !!") ، ثم يتم تقسيم البيانات إلى كتل يتم إرسالها إلى جهاز إرسال OFDM . OFDM هو نوع معقد نوعًا ما من التعديل ، في إعدادات التشفير OFDM تحتاج إلى تحديد الكثير من المعلمات غير الواضحة تمامًا.



يمكن العثور على تحليل أكثر تفصيلاً للقيم هنا . وبطبيعة الحال ، يجب أن تتطابق معلمات فدرة استقبال OFDM مع معلمات الإرسال.

يتم استخدام كتلة نموذج القناة لمحاكاة قناة الاتصال ، وكتلة بالوعة التردد QT GUIتستخدم لتصور الطيف. من الجدير أيضًا الانتباه إلى تردد أخذ العينات المنخفض (معدل العينة = 2400) ، ويتم ذلك بشكل خاص بحيث تشغل الإشارة نطاقًا صغيرًا من الطيف مناسب للإرسال عبر القناة الصوتية.

لسوء الحظ ، لم أجد وحدة مدمجة لعرض البيانات المستلمة في راديو GNU ، لذلك يجب علي استخدام UDP. يتم استخدام كتلة UDP Sink لإخراج البيانات ؛ يتم استخدام برنامج Python لاستقبال البيانات:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 40868

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((UDP_IP, UDP_PORT))
sock.settimeout(0.5)

while True:
    try:
        data, addr = sock.recvfrom(128) 
        print("Msg:", data, 'Hex:', ' '.join('{:02x}'.format(x) for x in data))
    except socket.timeout:
        pass

هذا يسمح لك بعرض البيانات المستلمة في وحدة التحكم ، وهو أمر مريح للغاية. ربما تكون هناك طريقة أسهل لإخراج راديو جنو ، إذا كان أي شخص يعرف ، اكتب في التعليقات.

إذا تم عمل كل شيء بشكل صحيح ، يمكننا تشغيل راديو جنو وكتابنا للاستقبال ، يجب أن تبدو النتيجة مثل هذا:



يبدو أنه يمكنك إغلاق الموضوع؟ لا ، كل شيء مثير للاهتمام بدأ للتو.

اذهب على الهواء


في المثال أعلاه ، كل شيء بسيط للغاية. لكن هناك "لكن" واحد - يعمل راديو جنو مع ما يسمى بـ "الإشارة المعقدة" ، والتي هي في الواقع زوج من الأرقام 90 درجة خارج المرحلة. هذا مناسب لمعالجة الكمبيوتر ، ولكن لا يمكننا فقط أخذ رقم معقد وبثه.

وهناك خياران. قد لا يقرأ مالكو مرسلات SDR (HackRF ، LimeSDR ، USRP ، وما إلى ذلك) المزيد ، ولكن ببساطة يأخذون وحدة جاهزة لراديو GNU ، حيث يتم كل شيء "تلقائيًا". لكن منذ سنقوم بإرسال إشارة باستخدام بطاقة صوت ، يجب أن نقوم بالتحويل بأنفسنا ، حيث نستخدم المخطط الانسيابي الموجود في أي مقال على DSP:



هنا OFDM هو جهاز الإرسال ، تردد ناقل Fc ، سنقوم بتعيينه على 4KHz بحيث تصل الإشارة إلى أقصى حساسية للسماعات والميكروفون. كما أن المخطط الانسيابي للرسم البياني للنقل معقد بشكل مماثل: من



أجل اختبار الراحة ، أستخدم WAV File Sink بحيث يمكن تسجيل الملف المحفوظ وتشغيله بشكل منفصل. يمكننا أيضًا فتح الملف ورؤية طيفه ، يمكننا التأكد من أن التردد المركزي هو حقا 4KHz:



استقبال


وأخيرًا ، الخطوة الأخيرة: إنشاء رسم تخطيطي لتلقي إشارة. هنا ، في الواقع ، كل شيء هو نفسه ، فقط بالترتيب العكسي.



نقوم بضرب الإشارة الأصلية من خلال الإشارات المرجعية المنقولة بالطور ، ثم بمساعدة LPF نقطع المكونات عالية التردد. الإخراج هو إشارة معقدة يمكن استخدامها لمزيد من المعالجة.

الرسم البياني للاستقبال في راديو جنو هو كما يلي:



تجدر الإشارة إلى كتلة مصدر الصوت لتلقي البيانات من بطاقة الصوت ، يتم استخدام كتلة بالوعة التردد QT GUI لتصور الإشارة المستقبلة.

للاختبار ، قمت بتسجيل ملف WAV على هاتف ذكي ؛ عندما أحمله إلى ميكروفون الكمبيوتر ، يظهر نص تم فك ترميزه على الشاشة:



استنتاج


كما ترون ، فإن استقبال وإرسال الإشارات باستخدام راديو جنو مثير للاهتمام وواضح. OFDM لديه عدد كبير إلى حد ما من المعلمات ؛ أولئك الذين يرغبون في تجربة بشكل مستقل مع حجم كتلة FFT ، عدد شركات النقل ، تردد الإرسال ، إلخ.

شكرا لكم جميعا على اهتمامكم وتجاربكم الناجحة.

بالنسبة لأولئك الذين يرغبون ، المصدر تحت المفسد.

ofdm2.grc
options:
  parameters:
    author: ''
    category: Custom
    cmake_opt: ''
    comment: ''
    copyright: ''
    description: Transmit a pre-defined signal (a complex sine) as OFDM packets.
    gen_cmake: 'On'
    gen_linking: dynamic
    generate_options: qt_gui
    hier_block_src_path: '.:'
    id: ofdm_test_2
    max_nouts: '0'
    output_language: python
    placement: (0,0)
    qt_qss_theme: ''
    realtime_scheduling: ''
    run: 'True'
    run_command: '{python} -u {filename}'
    run_options: prompt
    sizing_mode: fixed
    thread_safe_setters: ''
    title: OFDM Test 2
    window_size: 1280, 1024
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [8, 12.0]
    rotation: 0
    state: enabled

blocks:
- name: audio_samp_rate
  id: variable
  parameters:
    comment: ''
    value: '24000'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [648, 20.0]
    rotation: 0
    state: true
- name: carrier_freq
  id: variable
  parameters:
    comment: ''
    value: '4000'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [792, 20.0]
    rotation: 0
    state: true
- name: fft_len
  id: variable
  parameters:
    comment: ''
    value: '64'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [448, 20.0]
    rotation: 0
    state: enabled
- name: len_tag_key
  id: variable
  parameters:
    comment: ''
    value: '"packet_len"'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [320, 20.0]
    rotation: 0
    state: enabled
- name: packet_len
  id: variable
  parameters:
    comment: ''
    value: '12'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [216, 20.0]
    rotation: 0
    state: enabled
- name: samp_rate
  id: variable
  parameters:
    comment: ''
    value: '2400'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [536, 20.0]
    rotation: 0
    state: enabled
- name: analog_sig_source_x_0
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: carrier_freq
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: audio_samp_rate
    type: float
    waveform: analog.GR_COS_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1080, 88.0]
    rotation: 0
    state: true
- name: analog_sig_source_x_0_0
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: carrier_freq
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: audio_samp_rate
    type: float
    waveform: analog.GR_SIN_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1080, 344.0]
    rotation: 0
    state: true
- name: analog_sig_source_x_0_0_0
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: carrier_freq
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: audio_samp_rate
    type: float
    waveform: analog.GR_SIN_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1376, 824.0]
    rotation: 180
    state: true
- name: analog_sig_source_x_0_1
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: carrier_freq
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: audio_samp_rate
    type: float
    waveform: analog.GR_COS_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1376, 672.0]
    rotation: 180
    state: true
- name: audio_sink_0
  id: audio_sink
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    device_name: ''
    num_inputs: '1'
    ok_to_block: 'True'
    samp_rate: audio_samp_rate
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1608, 224.0]
    rotation: 0
    state: disabled
- name: audio_source_0
  id: audio_source
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    device_name: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_outputs: '1'
    ok_to_block: 'True'
    samp_rate: audio_samp_rate
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1376, 584.0]
    rotation: 180
    state: enabled
- name: blocks_add_xx_0
  id: blocks_add_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1480, 264.0]
    rotation: 0
    state: true
- name: blocks_complex_to_float_0
  id: blocks_complex_to_float
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1128, 256.0]
    rotation: 0
    state: true
- name: blocks_file_source_0
  id: blocks_file_source
  parameters:
    affinity: ''
    alias: ''
    begin_tag: pmt.PMT_NIL
    comment: ''
    file: D:\Temp\1\data2.txt
    length: '0'
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    repeat: 'True'
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [32, 224.0]
    rotation: 0
    state: enabled
- name: blocks_float_to_complex_0
  id: blocks_float_to_complex
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [744, 768.0]
    rotation: 180
    state: true
- name: blocks_multiply_xx_0
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1336, 176.0]
    rotation: 0
    state: true
- name: blocks_multiply_xx_0_0
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1336, 344.0]
    rotation: 0
    state: enabled
- name: blocks_multiply_xx_0_1
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1168, 696.0]
    rotation: 180
    state: true
- name: blocks_multiply_xx_0_1_0
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1176, 864.0]
    rotation: 180
    state: true
- name: blocks_null_sink_0
  id: blocks_null_sink
  parameters:
    affinity: ''
    alias: ''
    bus_structure_sink: '[[0,],]'
    comment: ''
    num_inputs: '1'
    type: float
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1608, 168.0]
    rotation: 0
    state: true
- name: blocks_stream_to_tagged_stream_0
  id: blocks_stream_to_tagged_stream
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    len_tag_key: '"key"'
    maxoutbuf: '0'
    minoutbuf: '0'
    packet_len: packet_len
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [424, 252.0]
    rotation: 0
    state: enabled
- name: blocks_throttle_0
  id: blocks_throttle
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    ignoretag: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    samples_per_second: samp_rate
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [248, 264.0]
    rotation: 0
    state: enabled
- name: blocks_udp_sink_0
  id: blocks_udp_sink
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    eof: 'True'
    ipaddr: 127.0.0.1
    port: '40868'
    psize: '128'
    type: byte
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [104, 748.0]
    rotation: 180
    state: enabled
- name: blocks_wavfile_sink_0
  id: blocks_wavfile_sink
  parameters:
    affinity: ''
    alias: ''
    bits_per_sample: '16'
    comment: ''
    file: D:\Temp\1\ofdm.wav
    nchan: '1'
    samp_rate: audio_samp_rate
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [1608, 308.0]
    rotation: 0
    state: disabled
- name: digital_ofdm_rx_0
  id: digital_ofdm_rx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    cp_len: fft_len//4
    fft_len: fft_len
    header_mod: '"BPSK"'
    log: 'False'
    maxoutbuf: '0'
    minoutbuf: '0'
    occupied_carriers: ((-4,-3,-2,-1,1,2,3,4),)
    packet_len_key: '"key"'
    payload_mod: '"QPSK"'
    pilot_carriers: ((-6,-5,5,6),)
    pilot_symbols: ((-1,1,-1,1),)
    scramble_bits: 'False'
    sync_word1: None
    sync_word2: None
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [440, 700.0]
    rotation: 180
    state: enabled
- name: digital_ofdm_tx_0
  id: digital_ofdm_tx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    cp_len: fft_len//4
    fft_len: fft_len
    header_mod: '"BPSK"'
    log: 'False'
    maxoutbuf: '0'
    minoutbuf: '0'
    occupied_carriers: ((-4,-3,-2,-1,1,2,3,4),)
    packet_len_key: '"key"'
    payload_mod: '"QPSK"'
    pilot_carriers: ((-6,-5,5,6),)
    pilot_symbols: ((-1,1,-1,1),)
    rolloff: '0'
    scramble_bits: 'False'
    sync_word1: None
    sync_word2: None
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [664, 176.0]
    rotation: 0
    state: enabled
- name: low_pass_filter_0
  id: low_pass_filter
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    cutoff_freq: carrier_freq
    decim: audio_samp_rate//samp_rate
    gain: '1'
    interp: '1'
    maxoutbuf: '0'
    minoutbuf: '0'
    samp_rate: audio_samp_rate
    type: fir_filter_fff
    width: '1000'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [960, 648.0]
    rotation: 180
    state: true
- name: low_pass_filter_0_0
  id: low_pass_filter
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    cutoff_freq: carrier_freq
    decim: audio_samp_rate//samp_rate
    gain: '1'
    interp: '1'
    maxoutbuf: '0'
    minoutbuf: '0'
    samp_rate: audio_samp_rate
    type: fir_filter_fff
    width: '1000'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [960, 816.0]
    rotation: 180
    state: true
- name: qtgui_freq_sink_x_0
  id: qtgui_freq_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    autoscale: 'False'
    average: '1.0'
    axislabels: 'True'
    bw: samp_rate
    color1: '"blue"'
    color10: '"dark blue"'
    color2: '"red"'
    color3: '"green"'
    color4: '"black"'
    color5: '"cyan"'
    color6: '"magenta"'
    color7: '"yellow"'
    color8: '"dark red"'
    color9: '"dark green"'
    comment: ''
    ctrlpanel: 'False'
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    label: Relative Gain
    label1: Rx Spectrum
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: Rx Spectrum
    nconnections: '1'
    showports: 'True'
    tr_chan: '0'
    tr_level: '0.0'
    tr_mode: qtgui.TRIG_MODE_FREE
    tr_tag: '""'
    type: complex
    units: dB
    update_time: '0.10'
    width1: '1'
    width10: '1'
    width2: '1'
    width3: '1'
    width4: '1'
    width5: '1'
    width6: '1'
    width7: '1'
    width8: '1'
    width9: '1'
    wintype: firdes.WIN_BLACKMAN_hARRIS
    ymax: '10'
    ymin: '-140'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [728, 612.0]
    rotation: 0
    state: enabled
- name: rational_resampler_xxx_0
  id: rational_resampler_xxx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    decim: '1'
    fbw: '0'
    interp: audio_samp_rate//samp_rate
    maxoutbuf: '0'
    minoutbuf: '0'
    taps: ''
    type: ccf
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [912, 236.0]
    rotation: 0
    state: true

connections:
- [analog_sig_source_x_0, '0', blocks_multiply_xx_0, '0']
- [analog_sig_source_x_0_0, '0', blocks_multiply_xx_0_0, '1']
- [analog_sig_source_x_0_0_0, '0', blocks_multiply_xx_0_1_0, '1']
- [analog_sig_source_x_0_1, '0', blocks_multiply_xx_0_1, '1']
- [audio_source_0, '0', blocks_multiply_xx_0_1, '0']
- [audio_source_0, '0', blocks_multiply_xx_0_1_0, '0']
- [blocks_add_xx_0, '0', audio_sink_0, '0']
- [blocks_add_xx_0, '0', blocks_null_sink_0, '0']
- [blocks_add_xx_0, '0', blocks_wavfile_sink_0, '0']
- [blocks_complex_to_float_0, '0', blocks_multiply_xx_0, '1']
- [blocks_complex_to_float_0, '1', blocks_multiply_xx_0_0, '0']
- [blocks_file_source_0, '0', blocks_throttle_0, '0']
- [blocks_float_to_complex_0, '0', digital_ofdm_rx_0, '0']
- [blocks_float_to_complex_0, '0', qtgui_freq_sink_x_0, '0']
- [blocks_multiply_xx_0, '0', blocks_add_xx_0, '0']
- [blocks_multiply_xx_0_0, '0', blocks_add_xx_0, '1']
- [blocks_multiply_xx_0_1, '0', low_pass_filter_0, '0']
- [blocks_multiply_xx_0_1_0, '0', low_pass_filter_0_0, '0']
- [blocks_stream_to_tagged_stream_0, '0', digital_ofdm_tx_0, '0']
- [blocks_throttle_0, '0', blocks_stream_to_tagged_stream_0, '0']
- [digital_ofdm_rx_0, '0', blocks_udp_sink_0, '0']
- [digital_ofdm_tx_0, '0', rational_resampler_xxx_0, '0']
- [low_pass_filter_0, '0', blocks_float_to_complex_0, '0']
- [low_pass_filter_0_0, '0', blocks_float_to_complex_0, '1']
- [rational_resampler_xxx_0, '0', blocks_complex_to_float_0, '0']

metadata:
  file_format: 1


All Articles