#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Ich möchte mit Hilfe von DSP und Python einen einfachen Empfänger für die Empfangsfrequenz 17,2 kHz erzeugt haben. 17,2 kHz ist die Frequenz vom Längstwellensender Grimeton. Empfangen werden soll diese direkt über den Mikrofoneingang der Soundkarte, an der für den Empfang eine Ferritantenne mit Kondensator als Parellelschwingkreis relativ breitbandig auf die Empfangsfrequenz abgestimmt. Das DSP-Eingangsfilter soll eine Mittenfrequenz von 17,2 kHz haben mit einer Bandbreite von 500 Hz für den Empfang von Morsezeichen. Nach dem Eingangsfilter soll die Frequenz auf 650 Hz heruntergemischt werden und von der Soundkarte ausgegeben werden, damit man die Morsezeichen hört. Das Skript läuft auf Ubuntu auf einem 10 Jahre alten Laptop mit eingebauter Soundkarte. """ import numpy as np import sounddevice as sd from scipy.signal import butter, lfilter import time # Parameter FS = 48000 # Abtastrate der Soundkarte CENTER_FREQ = 17200 # Empfangsfrequenz in Hz BANDWIDTH = 500 # Bandbreite in Hz IF_FREQ = 650 # Zieldurchmischungsfrequenz in Hz BLOCKSIZE = 1024 # Anzahl Samples pro Block THRESHOLD = 0.05 # Amplitude-Schwelle für Ton DIT_DURATION = 0.1 # Geschätzte Länge eines Punktes in Sekunden # Morse-Code-Tabelle MORSE_DICT = { ".-": "A", "-...": "B", "-.-.": "C", "-..": "D", ".": "E", "..-.": "F", "--.": "G", "....": "H", "..": "I", ".---": "J", "-.-": "K", ".-..": "L", "--": "M", "-.": "N", "---": "O", ".--.": "P", "--.-": "Q", ".-.": "R", "...": "S", "-": "T", "..-": "U", "...-": "V", ".--": "W", "-..-": "X", "-.--": "Y", "--..": "Z", "-----": "0", ".----": "1", "..---": "2", "...--": "3", "....-": "4", ".....": "5", "-....": "6", "--...": "7", "---..": "8", "----.": "9" } # Bandpass-Filter def bandpass_filter(data, lowcut, highcut, fs, order=4): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') return lfilter(b, a, data) # Tiefpass-Filter def lowpass_filter(data, cutoff, fs, order=4): nyq = 0.5 * fs norm_cutoff = cutoff / nyq b, a = butter(order, norm_cutoff, btype='low') return lfilter(b, a, data) # Morse-Code-Puffer morse_buffer = "" last_signal_time = None decoding_active = False def decode_morse(morse_code): words = morse_code.strip().split(" ") # Morsecode-Wörter trennen decoded_words = [] for word in words: letters = word.split(" ") decoded_word = "".join([MORSE_DICT.get(letter, "?") for letter in letters]) decoded_words.append(decoded_word) return " ".join(decoded_words) # Signalverarbeitung def callback(indata, outdata, frames, time, status): global morse_buffer, last_signal_time, decoding_active if status: print(status) mono_signal = indata[:, 0] filtered_signal = bandpass_filter(mono_signal, CENTER_FREQ - BANDWIDTH / 2, CENTER_FREQ + BANDWIDTH / 2, FS) t = np.arange(len(filtered_signal)) / FS mixed_signal = filtered_signal * np.cos(2 * np.pi * CENTER_FREQ * t) demodulated_signal = lowpass_filter(mixed_signal, IF_FREQ * 2, FS) signal = np.abs(demodulated_signal) avg_amplitude = np.mean(signal) if avg_amplitude > THRESHOLD: if not decoding_active: decoding_active = True last_signal_time = time.inputBufferAdcTime else: duration = time.inputBufferAdcTime - last_signal_time last_signal_time = time.inputBufferAdcTime if duration < DIT_DURATION * 1.5: morse_buffer += "." else: morse_buffer += "-" else: if decoding_active: decoding_active = False duration = time.inputBufferAdcTime - last_signal_time if duration > DIT_DURATION * 3: morse_buffer += " " elif duration > DIT_DURATION * 7: morse_buffer += " " if len(morse_buffer) > 0 and duration > DIT_DURATION * 10: print("Empfangener Morsecode:", morse_buffer) print("Dekodierter Text:", decode_morse(morse_buffer)) morse_buffer = "" outdata[:] = np.column_stack((demodulated_signal, demodulated_signal)) # Audio-Stream starten with sd.Stream(samplerate=FS, blocksize=BLOCKSIZE, channels=1, dtype='float32', callback=callback): print("Drücke Enter zum Beenden...") input()