ส่งข้อมูลผ่านเสียงระหว่างคอมพิวเตอร์ 2 เครื่อง (ระยะทางใกล้มาก)


12

ฉันกำลังเขียนตัวอย่างเกี่ยวกับการส่งข้อมูลผ่านเสียงระหว่างคอมพิวเตอร์ 2 เครื่อง ข้อกำหนดบางประการ:

  • ระยะทางอยู่ใกล้มากนั่นคือคอมพิวเตอร์ 2 เครื่องนั้นอยู่ติดกัน

  • เสียงรบกวนน้อยมาก (ฉันไม่คิดว่าครูของฉันจะเปิดเพลงร็อคเป็นแหล่งเสียง)

  • ข้อผิดพลาดเป็นที่ยอมรับได้: ตัวอย่างเช่นถ้าฉันส่ง "การสื่อสารด้วยวิทยุ" ถ้าคอมพิวเตอร์อีกเครื่องได้รับ "RadiQ CommunEcation" ก็ไม่เป็นไร

  • ถ้าเป็นไปได้: ไม่มีส่วนหัว, ธง, checksum, .... เนื่องจากฉันต้องการตัวอย่างพื้นฐานที่แสดงให้เห็นถึงพื้นฐานของการส่งข้อมูลผ่านเสียง ไม่จำเป็นต้องแฟนซี

ฉันลองใช้การเปลี่ยนความถี่เสียงตามลิงค์นี้:

Lab 5 APRS (ระบบรายงานแพ็กเกจอัตโนมัติ)

และได้ผลลัพธ์บางส่วน: หน้า Github ของฉัน

แต่มันก็ไม่เพียงพอ ฉันไม่ทราบวิธีการกู้คืนนาฬิกาการซิงโครไนซ์ ... (ลิงก์มี Phase Locked Loop เป็นกลไกการกู้คืนเวลา แต่ดูเหมือนจะไม่เพียงพอ)

ดังนั้นฉันคิดว่าฉันควรหาวิธีที่ง่ายกว่า พบลิงค์ที่นี่:

ข้อมูลเสียงและกลับ Modulation / demodulation พร้อม source code

แต่ OP ไม่ได้ใช้วิธีการที่แนะนำในคำตอบดังนั้นฉันกลัวว่ามันอาจซับซ้อนมาก นอกจากนี้ฉันไม่เข้าใจวิธีการถอดรหัสที่แนะนำในคำตอบ:

ตัวถอดรหัสนั้นซับซ้อนกว่าเล็กน้อย แต่นี่เป็นโครงร่าง:

ตัวเลือก band-pass กรองสัญญาณตัวอย่างประมาณ 11Khz สิ่งนี้จะปรับปรุงประสิทธิภาพในสภาพแวดล้อมที่มีเสียงดัง ตัวกรอง FIR ค่อนข้างง่ายและมีแอปเพล็ตการออกแบบออนไลน์จำนวนน้อยที่จะสร้างตัวกรองสำหรับคุณ

เกณฑ์สัญญาณ ทุกค่าที่สูงกว่า 1/2 แอมพลิจูดสูงสุดคือ 1 ทุกค่าที่ต่ำกว่าคือ 0 ซึ่งถือว่าคุณสุ่มตัวอย่างสัญญาณทั้งหมดแล้ว หากเป็นแบบเรียลไทม์คุณจะเลือกเกณฑ์คงที่หรือทำการควบคุมการรับสัญญาณอัตโนมัติบางประเภทที่คุณติดตามระดับสัญญาณสูงสุดในบางช่วงเวลา

สแกนหาจุดเริ่มต้นหรือเส้นประ คุณอาจต้องการเห็นจำนวนอย่างน้อย 1 ในช่วงจุดของคุณเพื่อพิจารณาตัวอย่างจุด จากนั้นทำการสแกนต่อไปเพื่อดูว่านี่เป็นเส้นประหรือไม่ อย่าคาดหวังว่าสัญญาณที่สมบูรณ์แบบ - คุณจะเห็นว่ามีสักสองสามตัวที่อยู่ตรงกลางของ 1 และของคุณไม่กี่คนในช่วงกลางของ 0 ของคุณ หากมีเสียงรบกวนน้อยการแยกช่วงเวลา "เปิด" ออกจากช่วง "ปิด" ควรเป็นเรื่องง่าย

จากนั้นย้อนกลับกระบวนการข้างต้น หากคุณเห็นเส้นประผลักบิต 1 ไปยังบัฟเฟอร์ของคุณถ้าจุดกดศูนย์

ฉันไม่เข้าใจว่ามี 1 คนก่อนที่จะจัดประเภทเป็นจุด ... ดังนั้นจึงมีหลายสิ่งที่ฉันไม่เข้าใจในตอนนี้ กรุณาแนะนำให้ฉันวิธีง่ายๆในการส่งข้อมูลผ่านเสียงเพื่อให้ฉันสามารถเข้าใจกระบวนการ ขอบคุณมาก :)

UPDATE:

ฉันได้สร้างรหัส Matlab ซึ่งดูเหมือนว่าจะใช้งานได้บ้าง ฉันปรับสัญญาณโดยใช้ Amplitude shift keying (สุ่มตัวอย่างความถี่ 48000 Hz, F_on = 5,000 Hz, bit rate = 10 bits / s) จากนั้นเพิ่มด้วยส่วนหัวและลำดับท้าย (แน่นอนปรับด้วย) ส่วนหัวและลำดับท้ายถูกเลือกตามหลักกิจ (ใช่แล้วคือแฮ็ค):

header = [0 0 1 0 1 1 1 1   1 0 0 0 0 0 0 1   1 0 0 0 0 0 0 1   1 0 1 1 0 1 0 1];  
end_seq = [1 1 1 1 1 0 1 0 1  0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1     0 1 0 1 0 1 0 1    0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1  1 0 0 1 0 0 0 1];

จากนั้นฉันก็ส่งผ่านเสียงและบันทึกด้วยสมาร์ทโฟนของฉัน จากนั้นฉันก็ส่งเสียงที่บันทึกไว้กลับไปที่คอมพิวเตอร์ของฉันใช้โค้ดอีกชิ้นเพื่ออ่านเสียง จากนั้นฉันเชื่อมโยงสัญญาณที่ได้รับ (ยังไม่ demodulated) กับส่วนหัวมอดูเลตและลำดับตอนจบเพื่อค้นหาจุดเริ่มต้นและจุดสิ้นสุด หลังจากนั้นฉันจะรับสัญญาณที่เกี่ยวข้องเท่านั้น (ตั้งแต่ต้นจนจบตามที่พบในส่วนสหสัมพันธ์) จากนั้นฉันก็ทำการดีมอดูเลตและสุ่มตัวอย่างเพื่อค้นหาข้อมูลดิจิทัล นี่คือ 3 ไฟล์เสียง:

  • "DigitalCommunication_ask": ลิงค์ที่นี่มันส่งข้อความ "การสื่อสารแบบดิจิตอล" ไม่มีเสียงรบกวนแม้จะได้ยินเสียงพื้นหลังบ้างในตอนต้นและตอนท้าย อย่างไรก็ตามผลลัพธ์แสดงเฉพาะ "Digital Commincatio"

  • "HelloWorld_ask": เชื่อมโยงที่นี่โดยส่งข้อความ "Hello world" ปราศจากเสียงรบกวนเช่น "DigitalCommunication_ask" อย่างไรก็ตามผลลัพธ์สำหรับอันนี้ถูกต้อง

  • "HelloWorld_noise_ask": เชื่อมโยงที่นี่โดยส่งข้อความ "Hello world" อย่างไรก็ตามมีบางเสียงที่ฉันได้ทำ (ฉันเพิ่งพูดบางสิ่งสุ่ม "A, B, C, D, E, .... " ในระหว่างการส่ง) น่าเสียดายที่สิ่งนี้ล้มเหลว

นี่คือรหัสสำหรับผู้ส่ง (sender.m):

 clear
fs = 48000;
F_on = 5000;
bit_rate = 10;

% header = [0 0 1 0 1 1 1 1  1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1     1 1 1 1 1 1 1 1      1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1     1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1  1 1 1 1 1 1 1 1 ];
% header = [0 0 1 0 1 1 1 1  1 0 0 0 0 0 0 1   1 0 0 0 0 0 1   1 0 0 0 0 0 0 1   1 0 0 0 0 0 0 1     1 0 0 0 0 0 0 1      1 0 0 0 0 0 0 1    1 0 0 0 0 0 0 1  1 0 0 0 0 0 0 1    1 0 0 0 0 0 0 1  1 1 1 1 1 1 1 1 ];
header = [0 0 1 0 1 1 1 1   1 0 0 0 0 0 0 1   1 0 0 0 0 0 0 1   1 0 1 1 0 1 0 1];  

% end_seq = [1 0 0 1 0 1 0 0  1 0 1 1 0 0 0 1  0 0 0 0 1 0 0 1  1 0 0 0 1 0 0 1];
% end_seq = [1 0 0 1 0 1 0 0  1 0 1 1 0 0 0 1  0 0 0 0 1 0 0 1  1 0 0 0 1 0 0 1   0 1 0 0 1  1 0 0   1 1 0 1 1 0 0 1  ];
% end_seq = [0 0 0 1 0 0 0 1  0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0   1 1 0 0 1 1 0 0];
end_seq = [1 1 1 1 1 0 1 0 1  0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1     0 1 0 1 0 1 0 1    0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1  1 0 0 1 0 0 0 1];


num_of_samples_per_bit = round(fs / bit_rate);
modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);
% input_str = 'Ah';
input_str = 'Hello world';
ascii_list = double(input_str); % https://www.mathworks.com/matlabcentral/answers/298215-how-to-get-ascii-value-of-characters-stored-in-an-array
bit_stream = [];
for i = 1:numel(ascii_list)
    bit = de2bi(ascii_list(i), 8, 'left-msb');
    bit_stream = [bit_stream bit];
end
bit_stream = [header bit_stream  end_seq];
num_of_bits = numel(bit_stream);
bandlimited_and_modulated_signal = ask_modulate(bit_stream, fs, F_on, bit_rate);
sound(bandlimited_and_modulated_signal, fs);

สำหรับผู้รับ (receiver.m):

clear
fs = 48000;
F_on = 5000;
bit_rate = 10;

% header = [0 0 1 0 1 1 1 1  1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1     1 1 1 1 1 1 1 1      1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1     1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1  1 1 1 1 1 1 1 1 ];
% header = [0 0 1 0 1 1 1 1  1 0 0 0 0 0 0 1   1 0 0 0 0 0 1   1 0 0 0 0 0 0 1   1 0 0 0 0 0 0 1     1 0 0 0 0 0 0 1      1 0 0 0 0 0 0 1    1 0 0 0 0 0 0 1  1 0 0 0 0 0 0 1    1 0 0 0 0 0 0 1  1 1 1 1 1 1 1 1 ];
header = [0 0 1 0 1 1 1 1   1 0 0 0 0 0 0 1   1 0 0 0 0 0 0 1   1 0 1 1 0 1 0 1];  

% end_seq = [1 0 0 1 0 1 0 0  1 0 1 1 0 0 0 1  0 0 0 0 1 0 0 1  1 0 0 0 1 0 0 1];
% end_seq = [1 0 0 1 0 1 0 0  1 0 1 1 0 0 0 1  0 0 0 0 1 0 0 1  1 0 0 0 1 0 0 1   0 1 0 0 1  1 0 0   1 1 0 1 1 0 0 1  ];
% end_seq = [0 0 0 1 0 0 0 1  0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0   1 1 0 0 1 1 0 0];
end_seq = [1 1 1 1 1 0 1 0 1  0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1     0 1 0 1 0 1 0 1    0 1 0 1 0 1 0 1   0 1 0 1 0 1 0 1  1 0 0 1 0 0 0 1];


modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);

% recObj = audiorecorder(fs,8,1);
% time_to_record = 10; % In seconds
% recordblocking(recObj, time_to_record);
% received_signal = getaudiodata(recObj);

% [received_signal, fs] = audioread('SounddataTruong_Ask.m4a');
% [received_signal, fs] = audioread('HelloWorld_noise_ask.m4a');
% [received_signal, fs] = audioread('HelloWorld_ask.m4a');
[received_signal, fs] = audioread('DigitalCommunication_ask.m4a');
ereceived_signal = received_signal(:)';
num_of_samples_per_bit = round(fs / bit_rate);

modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);

y= xcorr(modulated_header, received_signal); % do cross correlation
[m,ind]=max(y); % location of largest correlation
headstart=length(received_signal)-ind+1;

z = xcorr(modulated_end_seq, received_signal);
[m,ind]=max(z); % location of largest correlation
end_index=length(received_signal)-ind+1; 

relevant_signal = received_signal(headstart + num_of_samples_per_bit * numel(header) : end_index - 1);
% relevant_signal = received_signal(headstart + num_of_samples_per_bit * numel(header): end);
demodulated_signal = ask_demodulate(relevant_signal, fs, F_on, bit_rate);
sampled_points_in_demodulated_signal = demodulated_signal(round(num_of_samples_per_bit / 2) :  num_of_samples_per_bit :end);
digital_output = (sampled_points_in_demodulated_signal > (max(sampled_points_in_demodulated_signal(:)) / 2));
% digital_output = (sampled_points_in_demodulated_signal > 0.05);

% Convert to characters 
total_num_of_bits = numel(digital_output);
total_num_of_characters = total_num_of_bits / 8;
first_idx = 0;
last_idx = 0;
output_str = '';
for i = 1:total_num_of_characters
    first_idx = last_idx + 1;
    last_idx = first_idx + 7;
    binary_repr = digital_output(first_idx:last_idx); 
    ascii_value = bi2de(binary_repr(:)', 'left-msb');  
    character = char(ascii_value);
    output_str = [output_str character];    
end
output_str

ASK รหัสการปรับ (ask_modulate):

function [bandlimited_and_modulated_signal] = ask_modulate(bit_stream, fs, F_on, bit_rate)
% Amplitude shift keying: Modulation
% Dang Manh Truong (dangmanhtruong@gmail.com)
num_of_bits = numel(bit_stream);
num_of_samples_per_bit = round(fs / bit_rate);
alpha = 0;
d_alpha = 2 * pi * F_on / fs;
A = 3;
analog_signal = [];
for i = 1 : num_of_bits
    bit = bit_stream(i);
    switch bit
        case 1
            for j = 1 : num_of_samples_per_bit
                analog_signal = [analog_signal A * cos(alpha)];
                alpha = alpha + d_alpha;

            end
        case 0
            for j = 1 : num_of_samples_per_bit
                analog_signal = [analog_signal 0];
                alpha = alpha + d_alpha;                
            end
    end    
end
filter_order = 15;
LP_filter = fir1(filter_order, (2*6000)/fs, 'low');
bandlimited_analog_signal = conv(analog_signal, LP_filter,'same');
% plot(abs(fft(bandlimited_analog_signal)))
% plot(bandlimited_analog_signal)
bandlimited_and_modulated_signal = bandlimited_analog_signal;

end

ASK demodulation (ask_demodulate.m) (โดยทั่วไปเป็นเพียงการตรวจจับซองจดหมายซึ่งฉันใช้การแปลง Hilbert)

function [demodulated_signal] = ask_demodulate(received_signal, fs, F_on, bit_rate)
% Amplitude shift keying: Demodulation
% Dang Manh Truong (dangmanhtruong@gmail.com)

demodulated_signal = abs(hilbert(received_signal));

end

โปรดบอกฉันว่าทำไมมันไม่ทำงาน ขอบคุณมาก


ในทางทฤษฎี (ในสภาพแวดล้อมที่ปราศจากเสียงรบกวน) สิ่งนี้จะเป็นเรื่องเล็กน้อยที่จะนำไปใช้ แต่ในทางปฏิบัติสิ่งนี้ยากกว่ามาก ยังขึ้นอยู่กับประเภทของข้อมูลที่คุณพยายามส่ง ข้อความนั้นยากที่จะส่งได้อย่างน่าเชื่อถือเพราะแม้แต่เสียงที่เล็กที่สุดก็ทำให้ข้อความนั้นไม่สามารถจดจำได้
dsp_user

@dsp_user ฉันกำลังพยายามส่งข้อความ ฉันสามารถอยู่กับข้อผิดพลาดบางอย่าง (เช่น "เสียง" -> "Apdio") :) นอกจากนี้ฉันไม่เข้าใจจริง ๆ ว่าสำหรับ Amplitude Shift Keying เช่นเมื่อคุณมี 1 คุณส่งคลื่นไซน์ 0 แล้วไม่มีอะไร แต่เป็นอย่างไร คุณรู้ 0 ตัวแรกไหม? ฉันหมายถึงในสภาพแวดล้อมที่ปราศจากเสียงรบกวน แต่ก่อนหน้า 1 จะมีจำนวนมากใช่ไหม แล้วคุณจะรู้ได้อย่างไร
Dang Manh Truong

ฉันขอแนะนำให้คุณดูบางอย่างเช่นโมเด็ม 14.4 ที่ล้าสมัยสำหรับแนวคิด

@StanleyPawlukiewicz ฉันมีความคืบหน้า โปรดตรวจสอบการอัปเดต ขอบคุณมาก.
Dang Manh Truong

มีความคิดเห็นมากมาย คุณอาจต้องการดูลำดับบาร์เกอร์สำหรับคำนำของคุณเนื่องจากคุณใช้ preambles

คำตอบ:


8

ดังที่คุณได้รับรู้ส่วนที่ยากของการสื่อสารทางดิจิตอลคือผู้ให้บริการสัญลักษณ์และการซิงโครไนซ์เฟรมและการประมาณ / การปรับช่องสัญญาณ

ข่าวร้ายคือคุณไม่สามารถแก้ไขปัญหาเหล่านี้ได้ ข่าวดีก็คือว่าการใช้สิ่งเหล่านี้ไม่ยากตราบใดที่คุณ จำกัด ตัวเองให้แคบลง BPSK ฉันรู้เพราะฉันทำสิ่งนี้ด้วยตัวเองและให้นักเรียน (ระดับปริญญาตรี) ของฉัน (ดูhttp://ieeexplore.ieee.org/document/5739249/ )

คำแนะนำง่ายๆในการแก้ไขปัญหาการซิงโครไนซ์ของผู้ให้บริการคือใช้ AM DSB-LC เพื่อแปลงสัญญาณเบสแบนด์ของคุณ จากนั้นคุณสามารถใช้เครื่องตรวจจับซองจดหมายโดยไม่มีผู้ให้บริการและการซิงโครไนซ์เฟส สิ่งนี้จะทำให้คุณเสียค่าใช้จ่ายในเรื่องประสิทธิภาพการใช้พลังงาน แต่นั่นไม่ใช่สิ่งสำคัญสำหรับคุณ

อีกข้อเสนอแนะง่ายๆคือการ "ประมวลผลชุดข้อมูล" แทน "การประมวลผลแบบเรียลไทม์"; สิ่งที่หมายถึงคือเก็บสัญญาณที่ได้รับทั้งหมดและประมวลผลในภายหลัง การดำเนินการนี้ง่ายกว่าการสตรีมหรือการประมวลผลแบบเรียลไทม์

ข้อเสนอแนะที่สำคัญยิ่งของฉันคือการอ่านหนังสือเล่มนี้: Johnson, Sethares และ Klein, "การออกแบบตัวรับซอฟต์แวร์", Cambridge มันอธิบายในแง่ที่ชัดเจนมาก ๆ ทุกชิ้นส่วนของผู้รับและมีตัวอย่างรหัส Matlab มากมาย Steven Tretter มีหนังสือที่คล้ายกันเกี่ยวกับการใช้ระบบการสื่อสารบน DSP (ตอนนี้ฉันจำชื่อที่แน่นอนไม่ได้)

โชคดี; และโปรดถามคำถามใหม่ที่เฉพาะเจาะจงยิ่งขึ้นหากคุณมี


ฉันอ่านกระดาษของคุณแล้ว ดีแล้วทำต่อไป! คำถามหนึ่ง: ในกระดาษคุณพูดคุยเกี่ยวกับวิธีการต่าง ๆ ที่นักเรียนใช้ในการค้นหาการตอบกลับของช่องสัญญาณ (โดยใช้แรงกระตุ้นคลื่นไซน์, .. ) ฉันต้องการค้นหาการตอบกลับของช่องด้วยหรือไม่ :)
Dang Manh Truong

1
ขอบคุณสำหรับคำพูดที่ดีของคุณ :) สิ่งนี้คือคุณต้องการให้แน่ใจว่าคุณส่งผ่านคลื่นความถี่ที่การตอบสนองของช่องนั้นราบเรียบ มิฉะนั้นคุณจะต้องมีอีควอไลเซอร์ในเครื่องรับ หากคุณไม่ต้องการประเมินการตอบกลับของช่องสัญญาณสิ่งที่คุณทำได้คือใช้อัตราข้อมูลที่ต่ำมาก (เช่น 100 b / s) กับความถี่ที่อุปกรณ์เสียงทั้งหมดควรสบาย (พูด 5,000 Hz)
MBaz

1
@ DangManhTruong อีกสิ่งหนึ่ง: โปรดใช้พัลส์แบบ จำกัด แบนด์วิดท์เช่นสแควร์รูทโคไซน์ที่ยกขึ้นไม่ใช่พัลส์สแควร์ที่มีแบนด์วิดท์ขนาดใหญ่และมีแนวโน้มที่จะเกิดการบิดเบือน
MBaz

ฉันได้อ่านหนังสือการออกแบบตัวรับซอฟต์แวร์ตามที่คุณแนะนำ (จริง ๆ แล้วฉันอ่านส่วนใหญ่แล้วจดจ่ออยู่กับบทที่ 8: บิตกับสัญลักษณ์เป็นสัญญาณ) ดังนั้นฉันมีคำถาม คุณพูดอะไรบางอย่างเกี่ยวกับพัลส์ แต่ในตัวอย่างของหนังสือพวกเขาใช้หน้าต่างแฮมมิงเป็นจังหวะมันไม่เป็นไรถ้าฉันทำเช่นนั้น? และฉันก็เข้าใจถูกต้องก่อนอื่นคุณต้องปรับสัญญาณโดยใช้พูดถามจากนั้นคุณใช้การสร้างพัลส์ จากนั้นบนตัวรับสัญญาณคุณต้องสัมพันธ์กับสัญญาณพัลส์ก่อนเพื่อรับสัญญาณที่ได้รับการมอดูเลต จากนั้นคุณ demodulate ถูกต้องหรือไม่
Dang Manh Truong

และถ้าฉันต้องการส่งข้อมูลในรูปแบบแพ็คเก็ตโดยมีส่วนหัวที่จุดเริ่มต้นและจุดสิ้นสุดให้พูด 1 1 1 1 1 1 1 1 1 ดังนั้นฉันควรต่อท้ายด้วยข้อมูลแล้วปรับมันแล้วปรับรูปร่างแล้ว บนตัวรับสัญญาณฉันจะสัมพันธ์กับสัญญาณที่ได้รับกับรูปร่างของพัลส์ (สแควร์รูทยกโคไซน์, .. ) จากนั้นฉันต้อง demodulate สัญญาณหลังจากนั้นสัมพันธ์กับส่วนหัว ความเข้าใจของฉันถูกต้องหรือไม่
Dang Manh Truong

4

ในที่สุดฉันใช้ DTMF (สัญญาณโทนคู่หลายความถี่) DTMF ดั้งเดิมมี 16 สัญญาณแต่ละสัญญาณโดยใช้การรวมกันของ 2 ความถี่ แต่ที่นี่ฉันใช้ "1" (697 Hz และ 1209 Hz) และ "0" (941Hz และ 1336 Hz) เท่านั้น

โครงร่างของวิธีการทำงานของรหัส:

  • ผู้ส่งแปลงข้อความเป็นไบนารี่จากนั้นส่งสัญญาณ "0" / "1" DTMF (นี่คือเวลา 0.3s สำหรับช่วงเวลาโทนเสียงและ 0.1 วินาทีสำหรับช่วงเวลาเงียบระหว่างโทนเสียง) รหัสส่งจะนำมาจาก: https://sites.google.com/a/nd.edu/adsp-nik-kleber/home/advanced-digital-signal-processing/project-3-touch-tone เห็นได้ชัดว่าผู้เขียนใช้ตัวกรอง IIR ที่มีความเสถียรเล็กน้อยเพื่อใช้งานออสซิลเลเตอร์ดิจิตอล
  • ด้านผู้รับใช้ตัวกรองแบนด์วิดท์แคบที่มีคำสั่งและขันสูงเพื่อแยกส่วนประกอบความถี่ "0" และ "1" ตามลำดับ:

    filter_order = 1,000;

    one_band = [[((2696)/Fs) ((2698)/Fs)] [((21208)/Fs) ((21210)/Fs)]];
    
    one_dtmf_filter = fir1(filter_order, one_band);
    
    zero_band = [[((2940)/Fs) ((2942)/Fs)] [((21335)/Fs) ((21337)/Fs)]];
    
    zero_dtmf_filter = fir1(filter_order, zero_band);
    

หลังจากเสร็จสิ้นเราจะพบจุดเริ่มต้นและจุดสิ้นสุดของสัญญาณ "1" และ "0" แต่ละอัน รหัสจากhttps://github.com/codyaray/dtmf-signaling โดยทั่วไปจะพบช่วงเวลาเงียบซึ่งอย่างน้อย 10 ms และระยะเวลาโทนใด ๆ มากกว่า 100ms):

ป้อนคำอธิบายรูปภาพที่นี่

(จากบนลงล่าง: สัญญาณ Zero, สัญญาณหลังจากย้ายฟิลเตอร์เฉลี่ย, ความแตกต่างของสัญญาณหลังจากลบขีด จำกัด ด้านล่าง, สัญญาณหลังการกำหนดค่าใหม่)

  • ขั้นแรกผลลัพธ์จากขั้นตอนก่อนหน้านี้ถูกทำให้เป็นมาตรฐานจากนั้นผ่านตัวกรองค่าเฉลี่ยเคลื่อนที่ (ขนาดตัวกรองเท่ากับ 10ms * Fs) หากเราพล็อตผลลัพธ์เราจะเห็นว่ารูปร่างของ "0" และ "1" สามารถมองเห็นได้อย่างชัดเจน ดังนั้นฉันคิดว่ามันจะทำงานเป็นตัวตรวจจับซองจดหมายในกรณีนี้
  • จากนั้นสัญญาณทั้งหมดที่อยู่ต่ำกว่าเกณฑ์ที่กำหนดจะถูกตัดออก (ฉันเลือก 0.1)
  • ในที่สุดค้นหาช่วงเวลาทั้งหมดเหนือขีด จำกัด ที่มีช่วงเวลามากกว่า 100ms (โปรดทราบว่ารูปภาพไม่สามารถทำซ้ำได้จากโค้ดคุณจะต้องขุดไปรอบ ๆ เพื่อสร้าง)

จากนั้นเรารวบรวมบิตและแปลงกลับเป็นข้อความ :)

วิดีโอสาธิต: https://www.youtube.com/watch?v=vwQVmNnWa4sที่ฉันส่งข้อความ "Xin chao" ระหว่างแล็ปท็อปของฉันกับพีซีน้องชายของฉัน :)

P / S: แต่เดิมฉันทำสิ่งนี้เพราะครู Digital Communication ของฉันบอกว่าใครก็ตามที่ทำสิ่งนี้จะได้รับ A โดยไม่ต้องทำข้อสอบขั้นสุดท้าย แต่ฉันทำได้เพียงหลังจากทำข้อสอบ ดังนั้นที่นี่ไปทุกความพยายามของฉัน :(

P / S2: ฉันได้ C + :(


0

หากคุณต้องการห้องสมุดโอเพ่นซอร์สที่มีการซิงโครไนซ์ที่ดีมากฉันขอแนะนำhttps://github.com/jgaeddert/liquid-dspซึ่งใช้ลำดับเหตุการณ์เพื่อจัดแนวจากนั้นปรับอีควอไลเซอร์และกำจัดภาระ ฉันสร้างโมเด็มเสียงที่ทำงานได้ดีและทำงานได้ค่อนข้างดีดังนั้นหากไม่มีสิ่งอื่นวิธีการที่เป็นของเหลวก็น่าจะช่วยได้บ้าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.