def transmission(input_bits, qamNum=3): # qamNum = 3 payloadBits_per_OFDM = 512 mu = getModulation(qamNum) K = getCarriersNum(qamNum) # number of OFDM subcarriers log.info(f'K : {K}') CP = getCP(qamNum) # length of the cyclic prefix: 25% of the block P = Pilot_Carr[mu] # number of pilot carriers per OFDM block pilotValue = 3 + 3j # The known value each pilot transmits allCarriers = getAllCarriers( qamNum ) # indices of all subcarriers ([0, 1, ... K-1])# Pilots is every (K/P)th carrier. log.info(f'len(allCarriers) : {len(allCarriers)}') # For convenience of channel estimation, let's make the last carriers also be a pilot pilotCarriers = getPilotCarriers(qamNum) log.info(f'len(pilotCarriers) : {len(pilotCarriers)}') # data carriers are all remaining carriers dataCarriers = getDataCarriers(qamNum) log.info(f'len(dataCarriers) : {len(dataCarriers)}') carrier_plt = getCarrierPlot(qamNum) # carrier_plt.show() bit_num = getbit_num(qamNum) # mu = 4 # bits per symbol (i.e. 16QAM) # payloadBits_per_OFDM = dataBits_per_OFDM(qamNum) # number of payload bits per OFDM symbol if qamNum == 1: QAM = QAM64 elif qamNum == 2: QAM = QAM32 elif qamNum == 3: QAM = QAM16 mapping_table = QAM.mapping_table demapping_table = {v: k for k, v in mapping_table.items()} H_exact = np.fft.fft(channelResponse, K) plt.plot(allCarriers, abs(H_exact)) plt.xlabel('Subcarrier index') plt.ylabel('$|H(f)|$') plt.grid(True) plt.xlim(0, K - 1) log.info(f'payloadBits_per_OFDM : {payloadBits_per_OFDM}') # bits = np.random.binomial(n=1, p=0.5, size=(payloadBits_per_OFDM, )) bits = input_bits log.info(f"Bits count: {len(bits)}") old_bits = bits.copy() bits = padding.addPadding(bits, qamNum) CRC_polynomial = "1001" log.info(f'len(bits) : {len(bits)}') log.info(f"Before CRC length = {(len(bits))}") _, bits_with_crc = sender(''.join(bits.astype(str)), CRC_polynomial) bits_with_crc = np.array(list(bits_with_crc)).astype(np.uint8) log.info(f"After CRC length = {(len(bits_with_crc))}") # log.info(f'Padded Bits: {padded_bits}') log.info(f'bit_num : {bit_num}') log.info(f'Remainder: {(len(bits)+3)%bit_num}') def SP(bits): return bits.reshape((len(dataCarriers), bit_num)) bits_SP = SP(bits_with_crc) # log.info ("First 5 bit groups") # log.info (bits_SP[:5,:]) def Mapping(bits): return np.array([mapping_table[tuple(b)] for b in bits]) QAM = Mapping(bits_SP) def OFDM_symbol(QAM_payload): symbol = np.zeros(K, dtype=complex) # the overall K subcarriers symbol[pilotCarriers] = pilotValue # allocate the pilot subcarriers symbol[dataCarriers] = QAM_payload # allocate the pilot subcarriers return symbol OFDM_data = OFDM_symbol(QAM) log.info(f"Number of OFDM carriers in frequency domain: {len(OFDM_data)}") OFDM_time = np.fft.ifft(OFDM_data) log.info( f"Number of OFDM samples in time-domain before CP: {len(OFDM_time)}") OFDM_withCP = addCP(OFDM_time, qamNum) log.info( f"Number of OFDM samples in time domain with CP: {len(OFDM_withCP)}") OFDM_TX = OFDM_withCP OFDM_RX = channel(OFDM_TX) ####### rx_tx_plot = plots.recieved_transmitted_signal_plot(OFDM_TX, OFDM_RX) # rx_tx_plot.show() OFDM_RX_noCP = removeCP(OFDM_RX, qamNum) OFDM_demod = np.fft.fft(OFDM_RX_noCP) Hest = channelEstimate(OFDM_demod, qamNum, pilotValue) equalized_Hest = equalize(OFDM_demod, Hest) QAM_est = get_payload(equalized_Hest, qamNum) plt.plot(QAM_est.real, QAM_est.imag, 'bo') plt.grid(True) plt.xlabel('Real part') plt.ylabel('Imaginary Part') plt.title("Received constellation") PS_est, hardDecision = Demapping(QAM_est, qamNum) decision_mapping_plot = plots.decision_mapping_plot(QAM_est, hardDecision, show=False) bits_est = PS(PS_est) log.info("Bits est") log.info(len(bits_est)) log.info( f"Miscalculated Bits: {np.sum(abs(bits_with_crc-bits_est))}/{len(bits_with_crc)}" ) log.info( f"Obtained Bit error rate: {np.sum(abs(bits_with_crc-bits_est))/len(bits_with_crc)}" ) flag = False if reciever(''.join(bits_est.astype(str)), CRC_polynomial) == 0: log.info("No error in data, CRC check passed.") else: flag = True log.error("Error, CRC Check Failed") num_CRC_bits = len(CRC_polynomial) - 1 bits_est = bits_est[::-1][num_CRC_bits:][::-1] bits_est_wo_padding = padding.removePadding(bits_est, len(old_bits), qamNum) log.info( f"Miscalculated Bits: {np.sum(abs(old_bits-bits_est_wo_padding))}/{len(old_bits)}" ) log.info( f"Obtained Bit error rate: {np.sum(abs(old_bits-bits_est_wo_padding))/len(old_bits)}" ) return reception(bits_est_wo_padding, flag=flag)
OFDM_time = np.fft.ifft(OFDM_data) log.info(f"Number of OFDM samples in time-domain before CP: {len(OFDM_time)}") OFDM_withCP = addCP(OFDM_time, qamNum) log.info(f"Number of OFDM samples in time domain with CP: {len(OFDM_withCP)}") OFDM_TX = OFDM_withCP OFDM_RX = channel(OFDM_TX) ####### rx_tx_plot = plots.recieved_transmitted_signal_plot(OFDM_TX, OFDM_RX) # rx_tx_plot.show() OFDM_RX_noCP = removeCP(OFDM_RX, qamNum) OFDM_demod = np.fft.fft(OFDM_RX_noCP) Hest = channelEstimate(OFDM_demod, qamNum, pilotValue) equalized_Hest = equalize(OFDM_demod, Hest) QAM_est = get_payload(equalized_Hest, qamNum) plt.plot(QAM_est.real, QAM_est.imag, 'bo') plt.grid(True) plt.xlabel('Real part') plt.ylabel('Imaginary Part') plt.title("Received constellation") PS_est, hardDecision = Demapping(QAM_est, qamNum) decision_mapping_plot = plots.decision_mapping_plot(QAM_est, hardDecision, show=False)