Ich schreibe ein Beispiel für die Übertragung von Daten zwischen zwei Computern. Einige Anforderungen:
Die Entfernung ist sehr gering, dh die beiden Computer liegen im Grunde genommen nebeneinander
Sehr wenig Lärm (Ich glaube nicht, dass mein Lehrer einen Rocksong als Geräuschquelle einschalten würde)
Fehler ist akzeptabel: Wenn ich beispielsweise "Funkkommunikation" sende, ist dies auch in Ordnung, wenn der andere Computer "RadiQ-Kommunikation" empfängt.
Wenn möglich: Kein Header, Flag, Prüfsumme, ..., da ich nur ein sehr einfaches Beispiel möchte, das die Grundlagen der Übertragung von Daten durch Ton demonstriert. Kein Grund zur Fantasie.
Ich habe versucht, Audio Frequency Shift Keying wie folgt zu verwenden:
Lab 5 APRS (Automatic Package Reporting System)
und habe ein paar Ergebnisse: Meine Github Seite
aber es ist nicht genug. Ich weiß nicht, wie man Taktwiederherstellung, Synchronisation usw. durchführt (die Verbindung hat einen Phasenregelkreis als Zeitwiederherstellungsmechanismus, aber es hat anscheinend nicht gereicht).
Ich denke, ich sollte einen einfacheren Ansatz finden. Fand einen Link hier:
Daten zu Audio und zurück. Modulation / Demodulation mit Quellcode
Das OP hat die in der Antwort vorgeschlagene Methode jedoch nicht implementiert, sodass ich befürchte, dass sie sehr komplex sein könnte. Außerdem verstehe ich die in der Antwort vorgeschlagene Decodierungsmethode nicht klar:
Der Decoder ist etwas komplizierter, aber hier ein Überblick:
Optional kann das abgetastete Signal mit einem Bandpassfilter um 11 kHz gefiltert werden. Dies verbessert die Leistung in einer lauten Umgebung. FIR-Filter sind recht einfach und es gibt einige Online-Design-Applets, die den Filter für Sie generieren.
Schwelle das Signal ein. Jeder Wert über 1/2 Maximalamplitude ist 1, jeder Wert unter 0. Dies setzt voraus, dass Sie das gesamte Signal abgetastet haben. Wenn dies in Echtzeit geschieht, wählen Sie entweder einen festen Schwellenwert oder führen eine Art automatische Verstärkungsregelung durch, bei der Sie den maximalen Signalpegel über einen längeren Zeitraum verfolgen.
Nach Punkt- oder Strichanfang scannen. Sie möchten wahrscheinlich mindestens eine bestimmte Anzahl von Einsen in Ihrer Punktperiode sehen, um die Abtastwerte als Punkt zu betrachten. Scannen Sie dann weiter, um festzustellen, ob dies ein Strich ist. Erwarten Sie kein perfektes Signal - Sie werden einige Nullen in der Mitte Ihrer Einsen und einige Einsen in der Mitte Ihrer Nullen sehen. Wenn es wenig Rauschen gibt, sollte es ziemlich einfach sein, die "Ein" -Perioden von den "Aus" -Perioden zu unterscheiden.
Kehren Sie dann den obigen Vorgang um. Wenn Sie einen Strich sehen, drücken Sie ein 1-Bit in Ihren Puffer, wenn ein Punkt eine Null drückt.
Ich verstehe nicht, wie viele Einsen es sind, bevor ich es als Punkt klassifiziere. Es gibt also viele Dinge, die ich momentan nicht verstehe. Bitte schlagen Sie mir eine einfache Methode zur Übertragung von Daten durch Ton vor, damit ich den Vorgang nachvollziehen kann. Vielen Dank :)
AKTUALISIEREN:
Ich habe Matlab-Code erstellt, der (etwas) funktionsfähig zu sein scheint. Ich moduliere das Signal zuerst mit Amplitude-Shift-Keying (Abtastfrequenz 48000 Hz, F_on = 5000 Hz, Bitrate = 10 Bits / s) und füge es dann mit einem Header und einer Endsequenz hinzu (moduliere sie natürlich auch). Der Header und die Endsequenz wurden ad-hoc ausgewählt (ja, es war ein Hack):
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];
Dann übertrage ich sie per Ton und nehme sie mit meinem Smartphone auf. Anschließend sende ich das aufgezeichnete Audio an meinen Computer zurück und verwende einen anderen Code, um das Audio zu lesen. Dann korreliere ich das empfangene Signal (noch nicht demoduliert) mit dem modulierten Header und der Endsequenz, um den Anfang und das Ende herauszufinden. Danach nehme ich nur noch das relevante Signal (vom Anfang bis zum Ende, wie im Korrelationsteil zu finden). Dann demoduliere ich und taste ab, um die digitalen Daten zu finden. Hier sind 3 Audiodateien:
"DigitalCommunication_ask": Link hier sendet es den Text "Digital communication". Relativ geräuschlos, obwohl Sie am Anfang und am Ende Hintergrundgeräusche hören können. Das Ergebnis zeigte jedoch nur "Digital Commincatio"
"HelloWorld_ask": Link hier sendet es den Text "Hello world". Rauschfrei wie "DigitalCommunication_ask". Das Ergebnis für dieses war jedoch korrekt
"HelloWorld_noise_ask": Link hier sendet es den Text "Hello world". Es gibt jedoch ein Geräusch, das ich gemacht habe (ich sagte nur ein paar zufällige Sachen "A, B, C, D, E, ...." während der Übertragung). Dieser ist leider gescheitert
Hier ist der Code für den Absender (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);
Für den Empfänger (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 Modulationscode (ask_modulate):
function [bandlimited_and_modulated_signal] = ask_modulate(bit_stream, fs, F_on, bit_rate)
% Amplitude shift keying: Modulation
% Dang Manh Truong ([email protected])
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) (Grundsätzlich ist es nur die Hüllkurvenerkennung, für die ich die Hilbert-Transformation verwendet habe)
function [demodulated_signal] = ask_demodulate(received_signal, fs, F_on, bit_rate)
% Amplitude shift keying: Demodulation
% Dang Manh Truong ([email protected])
demodulated_signal = abs(hilbert(received_signal));
end
Bitte sagen Sie mir, warum es nicht funktioniert? Vielen Dank
quelle
Antworten:
Wie Sie erkannt haben, ist der schwierige Teil der digitalen Kommunikation die Träger-, Symbol- und Rahmensynchronisation sowie die Kanalschätzung / -entzerrung.
Die schlechte Nachricht ist, dass Sie diese Probleme nicht umgehen können. Die gute Nachricht ist, dass die Implementierung nicht allzu schwierig ist, solange Sie sich auf Schmalband-BPSK beschränken. Ich weiß, weil ich das selbst getan habe, und meine (Studenten-) Studenten auch (siehe http://ieeexplore.ieee.org/document/5739249/ )
Ein einfacher Vorschlag, um das Problem der Trägersynchronisation zu umgehen, ist die Verwendung von AM DSB-LC zur Aufwärtskonvertierung Ihres Basisbandsignals. Dann können Sie einen Hüllkurvendetektor ohne Träger- und Phasensynchronisation verwenden. Dies kostet Sie Energieeffizienz, hat aber in Ihrem Fall keine Priorität.
Ein weiterer einfacher Vorschlag ist die "Stapelverarbeitung" anstelle der "Echtzeitverarbeitung". Das heißt, Sie speichern das gesamte empfangene Signal und verarbeiten es anschließend. Dies ist viel einfacher zu implementieren als Streaming oder Echtzeitverarbeitung.
Mein größerer Vorschlag ist, dieses Buch zu lesen: Johnson, Sethares und Klein, "Software receiver design", Cambridge. Es erklärt in sehr klaren Worten jedes einzelne Stück des Empfängers und enthält viele Beispiele für Matlab-Code. Es gibt ein ähnliches Buch von Steven Tretter über die Implementierung eines Kommunikationssystems auf einem DSP (ich kann mich momentan nicht an den genauen Titel erinnern).
Viel Glück; und stellen Sie bitte neue, spezifischere Fragen, wenn Sie sie haben.
quelle
Am Ende habe ich DTMF (Dual Tone Multi Frequency Signaling) verwendet. Der ursprüngliche DTMF verfügt über 16 Signale, die jeweils eine Kombination von 2 Frequenzen verwenden. Aber hier habe ich nur "1" (697 Hz und 1209 Hz) und "0" (941 Hz und 1336 Hz) verwendet
Ein Überblick über die Funktionsweise des Codes:
Die Empfängerseite verwendet zuerst zwei lächerlich hochgeordnete und lächerlich enge Bandpassfilter, um die Frequenzkomponenten "0" bzw. "1" zu extrahieren:
filter_order = 1000;
Danach finden wir den Anfang und das Ende jedes "1" - und "0" -Signals. Der Code stammt von https://github.com/codyaray/dtmf-signaling . Grundsätzlich findet es die Ruheperiode, die mindestens 10 ms und jede Tonperiode mehr als 100 ms beträgt):
(Von oben nach unten: Nullsignal, Signal nach dem Filter für den gleitenden Durchschnitt, Differenz des Signals nach dem Entfernen der unter dem Schwellenwert liegenden Signale, Signal nach dem Schwellenwert)
Dann setzen wir die Bits zusammen und wandeln sie wieder in Text um :)
Videodemo: https://www.youtube.com/watch?v=vwQVmNnWa4s , wo ich den Text "Xin chao" zwischen meinem Laptop und dem PC meines Bruders sende :)
P / S: Ursprünglich tat ich dies, weil mein Lehrer für digitale Kommunikation sagte, dass jeder, der dies tat, ein A bekommen würde, ohne die Abschlussprüfung machen zu müssen, aber ich konnte dies erst nach der Prüfung tun. Also hier geht alle meine Bemühungen :(
P / S2: Ich habe ein C + :(
quelle
Wenn Sie eine Open-Source-Bibliothek mit sehr guter Synchronisation wünschen, empfehle ich https://github.com/jgaeddert/liquid-dsp, die msequences zum Ausrichten verwendet, dann eine Entzerrung vornimmt und die Nutzdaten demoduliert. Ich habe ein Audiomodem gebaut, das oben läuft und recht gut funktioniert. Daher sollten die Methoden von liquid eine Hilfe sein, wenn nichts anderes
quelle