# Cellule 1 : Import des bibliothèques et définition des paramètres import numpy as np import matplotlib.pyplot as plt from IPython.display import Audio, display # Paramètres de simulation fs = 44100 # Fréquence d'échantillonnage (Hz) fc = 22000 # Fréquence porteuse (Hz) bit_duration = 0.1 # Durée d'un bit en secondes samples_per_bit = int(fs * bit_duration) A = 1.0 # Amplitude pour un bit '1' # Cellule 2 : Définition du message et conversion en trames binaires (version de base) message_base = "HELP les gars" print("Message original (base) :", message_base) def char_to_frame(c): """ Convertit un caractère en trame de 9 bits (8 bits ASCII + bit de parité pair). Pour la parité paire, si le nombre de '1' dans les 8 bits est impair, on ajoute '1', sinon '0'. """ ascii_val = ord(c) bin_str = format(ascii_val, '08b') parity_bit = '1' if bin_str.count('1') % 2 != 0 else '0' return bin_str + parity_bit # Conversion en trames frames_base = [char_to_frame(c) for c in message_base] print("Trames binaires avec parité (base) :") for frame in frames_base: print(frame) # Concaténation de toutes les trames pour obtenir la séquence complète bit_seq_base = ''.join(frames_base) print("Séquence binaire complète (base) :", bit_seq_base) # Cellule 3 : Modulation ASK def modulate_ask(bit_seq): """ Effectue la modulation ASK (On-Off Keying) d'une séquence de bits. Pour un '1', une sinusoïde est générée ; pour un '0', le signal est nul. Retourne le vecteur temps et le signal modulé. """ signal = np.array([]) t_total = np.array([]) for i, bit in enumerate(bit_seq): t = np.linspace(0, bit_duration, samples_per_bit, endpoint=False) segment = A * np.sin(2 * np.pi * fc * t) if bit == '1' else np.zeros_like(t) signal = np.concatenate((signal, segment)) t_total = np.concatenate((t_total, t + i * bit_duration)) return t_total, signal # Modulation de la séquence de base t_signal_base, modulated_signal_base = modulate_ask(bit_seq_base) # Cellule 4 : Visualisation du signal modulé (version de base) plt.figure(figsize=(12, 4)) plt.plot(t_signal_base, modulated_signal_base, label="Signal modulé ASK (base)") plt.xlabel("Temps (s)") plt.ylabel("Amplitude") plt.title("Signal modulé en ASK – Chaîne de base") plt.grid(True) plt.legend() plt.show() # Lecture audio du signal modulé print("Lecture du signal modulé (émission - base) :") display(Audio(modulated_signal_base, rate=fs)) # Cellule 5 : Démodulation du signal sans bruit def demodulate_signal(signal, samples_per_bit, threshold=0.3): """ Démodule un signal ASK en découpant le signal en segments correspondant à chaque bit. Retourne la séquence de bits détectée. """ num_bits = len(signal) // samples_per_bit recovered_bits = "" for i in range(num_bits): segment = signal[i * samples_per_bit:(i+1) * samples_per_bit] mean_amp = np.mean(np.abs(segment)) bit = '1' if mean_amp > threshold else '0' recovered_bits += bit return recovered_bits # Démodulation sur le signal de base (sans bruit) recovered_bit_seq_base = demodulate_signal(modulated_signal_base, samples_per_bit, threshold=0.2) print("Séquence binaire récupérée (base) :", recovered_bit_seq_base) # Cellule 6 : Reconstitution du message et détection d'erreur (parité) def frame_to_char(frame): """ Convertit une trame de 9 bits en caractère après vérification de la parité. Retourne le caractère et un flag d'erreur si la parité ne correspond pas. """ data_bits = frame[:8] parity_bit = frame[8] expected_parity = '1' if data_bits.count('1') % 2 != 0 else '0' error = (expected_parity != parity_bit) char = chr(int(data_bits, 2)) return char, error # Découpage de la séquence en trames de 9 bits frames_received_base = [recovered_bit_seq_base[i:i+9] for i in range(0, len(recovered_bit_seq_base), 9)] print("Trames récupérées (base) :", frames_received_base) recovered_message_base = "" errors_detected = False for frame in frames_received_base: if len(frame) < 9: continue char, error = frame_to_char(frame) if error: errors_detected = True recovered_message_base += "�" else: recovered_message_base += char print("Message reconstruit (base) :", recovered_message_base) if errors_detected: print("Attention : des erreurs ont été détectées via le bit de parité.") else: print("Transmission sans erreur détectée (base).") # Cellule 7 : Bilan de la transmission sans bruit (chaîne de base) print("=== Bilan de la transmission – Chaîne de base ===") print("Message original (base) :", message_base) print("Message reconstruit (base) :", recovered_message_base) if errors_detected: print("Des erreurs ont été détectées dans la transmission (vérification par parité).") else: print("La transmission s'est déroulée correctement.") # Cellule 8 : Calcul et ajout du CRC def compute_crc8(data, polynomial=0x07, initial=0): """ Calcule un CRC-8 pour une séquence d'octets. 'data' doit être un objet bytes ou bytearray. """ crc = initial for byte in data: crc ^= byte for _ in range(8): if crc & 0x80: crc = ((crc << 1) ^ polynomial) & 0xFF else: crc = (crc << 1) & 0xFF return crc def message_to_bits(message): """ Convertit une chaîne de caractères en une séquence binaire (8 bits par caractère). """ return ''.join(format(ord(c), '08b') for c in message) # Message à transmettre avec CRC message_crc = message_base print("Message original (CRC) :", message_crc) # Conversion du message en séquence binaire (sans parité par caractère) bit_seq_crc = message_to_bits(message_crc) # Calcul du CRC sur le message message_bytes = bytearray(message_crc, 'utf-8') crc_value = compute_crc8(message_bytes) print("CRC calculé (hex) :", hex(crc_value)) # Conversion du CRC en 8 bits crc_bits = format(crc_value, '08b') # Concaténation du CRC à la séquence de données bit_seq_crc_full = bit_seq_crc + crc_bits print("Séquence binaire complète avec CRC :", bit_seq_crc_full) # Cellule 9 : Modulation et visualisation du signal avec CRC t_signal_crc, modulated_signal_crc = modulate_ask(bit_seq_crc_full) plt.figure(figsize=(12, 4)) plt.plot(t_signal_crc, modulated_signal_crc, label="Signal modulé ASK (avec CRC)") plt.xlabel("Temps (s)") plt.ylabel("Amplitude") plt.title("Signal modulé en ASK – Message avec CRC") plt.grid(True) plt.legend() plt.show() print("Lecture du signal modulé (avec CRC) :") display(Audio(modulated_signal_crc, rate=fs)) # Cellule 10 : Démodulation et vérification du CRC recovered_bit_seq_crc = demodulate_signal(modulated_signal_crc, samples_per_bit, threshold=0.2) print("Séquence binaire récupérée (avec CRC) :", recovered_bit_seq_crc) # Extraction des bits de données et du CRC transmis data_bits = recovered_bit_seq_crc[:-8] crc_received_bits = recovered_bit_seq_crc[-8:] crc_received = int(crc_received_bits, 2) print("CRC reçu :", hex(crc_received)) def bits_to_message(bits): """ Reconstruit un message à partir d'une séquence binaire (8 bits par caractère). """ message = "" for i in range(0, len(bits), 8): byte = bits[i:i+8] if len(byte) < 8: continue message += chr(int(byte, 2)) return message recovered_message_crc = bits_to_message(data_bits) print("Message reconstruit (avec CRC) :", recovered_message_crc) # Recalcul du CRC sur le message reconstruit computed_crc = compute_crc8(bytearray(recovered_message_crc, 'utf-8')) print("CRC recomputé sur les données reçues :", hex(computed_crc)) if computed_crc == crc_received: print("Le CRC est correct. La transmission est validée.") else: print("Le CRC ne correspond pas. Erreur dans la transmission.") # Cellule 11 : Simulation de la réception avec bruit noise_amplitude = 0.24 # Intensité du bruit # Génération du bruit noise = noise_amplitude * np.random.normal(0, 1, len(modulated_signal_base)) received_signal_noise = modulated_signal_base + noise plt.figure(figsize=(12, 4)) plt.plot(t_signal_base, received_signal_noise, label="Signal reçu avec bruit", color='orange') plt.xlabel("Temps (s)") plt.ylabel("Amplitude") plt.title("Signal reçu en ASK avec ajout de bruit") plt.grid(True) plt.legend() plt.show() print("Lecture du signal reçu avec bruit :") display(Audio(received_signal_noise, rate=fs)) # Démodulation du signal bruité recovered_bit_seq_noise = demodulate_signal(received_signal_noise, samples_per_bit, threshold=0.2) print("Séquence binaire récupérée (avec bruit) :", recovered_bit_seq_noise) # Reconstitution du message à partir du signal bruité frames_received_noise = [recovered_bit_seq_noise[i:i+9] for i in range(0, len(recovered_bit_seq_noise), 9)] recovered_message_noise = "" errors_detected_noise = False for frame in frames_received_noise: if len(frame) < 9: continue char, error = frame_to_char(frame) if error: errors_detected_noise = True recovered_message_noise += "�" else: recovered_message_noise += char print("Message reconstruit (avec bruit) :", recovered_message_noise) if errors_detected_noise: print("Des erreurs ont été détectées dans la transmission avec bruit.") else: print("Aucune erreur détectée malgré la présence de bruit (seuil adapté).")