AD変換関連コード

AD変換お試しコード
```
import numpy as np
import matplotlib.pyplot as plt

# サンプリング周波数と時間範囲
sample_rate = 100  # Hz
duration = 1  # 秒
t_values = np.linspace(0, duration, sample_rate * duration)

# 実際のアナログ信号の関数
def analog_signal(t):
    return np.sin(t)

# AD変換関数
def adc_conversion(analog_value, full_scale_voltage, N):
    lsb_value = full_scale_voltage / (2**N - 1)
    digital_value = int(round(analog_value / lsb_value))
    return digital_value

# DA変換関数
def dac_conversion(digital_value, full_scale_voltage, N):
    lsb_value = full_scale_voltage / (2**N - 1)
    analog_value = digital_value * lsb_value
    return analog_value

# フルスケール電圧とビット数
full_scale_voltage = 5  # V
N = 5

# アナログ信号をサンプリングしてAD変換
digital_values = []
quantized_values = []
for t in t_values:
    analog_value = analog_signal(t)
    digital_value = adc_conversion(analog_value, full_scale_voltage, N)
    digital_values.append(digital_value)
    quantized_value = dac_conversion(digital_value, full_scale_voltage, N)
    quantized_values.append(quantized_value)

# AD変換後のデジタル値をDA変換してアナログ信号を再構築
reconstructed_analog_values = []
for digital_value in digital_values:
    analog_value = dac_conversion(digital_value, full_scale_voltage, N)
    reconstructed_analog_values.append(analog_value)

# グラフで結果を表示
plt.figure(figsize=(12, 10))

# 元のアナログ信号
plt.subplot(4, 1, 1)
plt.plot(t_values, analog_signal(t_values), label='Original Analog Signal', color='b')
plt.title('Original Analog Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

# AD変換 → DA変換後の再構築信号
plt.subplot(4, 1, 2)
plt.plot(t_values, reconstructed_analog_values, label='Reconstructed Analog Signal', color='r')
plt.title('Reconstructed Analog Signal from ADC/DAC')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

# 量子化した波形（デジタルコード）
plt.subplot(4, 1, 3)
plt.plot(t_values, quantized_values, label='Quantized Signal (Digital Codes)', color='g', marker='o', linestyle='None')
plt.title('Quantized Signal (Digital Codes)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

# 量子化前の波形
plt.subplot(4, 1, 4)
plt.step(t_values, analog_signal(t_values), where='post', label='Analog Signal (Before Quantization)', color='y')
plt.title('Analog Signal (Before Quantization)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/9bdac79e-8107-5439-b483-a75fc1de3505.png)


二部探索
```
# 定数
基準電圧 = 8.0
Vin = 3.7
N = 10  # Nの値を10に設定

# 初期化
基準電圧0 = 基準電圧 / 2  # ステップ0の基準電圧は基準電圧の半分
基準電圧値 = [基準電圧0]
D = []

# 計算ループ
for n in range(1, N + 1):
    if Vin < 基準電圧値[n - 1]:
        D.append(0)
        新基準電圧 = 基準電圧値[n - 1] - (基準電圧 / (2 ** (n + 1)))
    else:
        D.append(1)
        新基準電圧 = 基準電圧値[n - 1] + (基準電圧 / (2 ** (n + 1)))
    
    基準電圧値.append(新基準電圧)

# 結果表示
for i in range(N + 1):
    if i == 0:
        print(f"ステップ0: 基準電圧 = {基準電圧値[i]:.4f} V")
    else:
        print(f"ステップ{i}: D{i} = {D[i-1]}, 基準電圧 = {基準電圧値[i]:.4f} V")

```




AD変換関連パラメータ計算用


```

import numpy as np
import matplotlib.pyplot as plt

# Define input parameters
FSR = 5.0  # Full Scale Range in volts
RMS_noise_voltage = 0.001  # RMS noise voltage in volts
Peak_to_Peak_noise_voltage = 0.003  # Peak-to-Peak noise voltage in volts
SINAD_value = 70  # Signal-to-Noise and Distortion ratio in dB
THD_value = 0.01  # Total Harmonic Distortion as a ratio (not in dB)
signal_amplitude = 1.0  # Signal amplitude in volts
output_signal_amplitude = 1.0  # Output signal amplitude in volts
output_noise_level = 0.001  # Output noise level in volts

# 有効分解能 (Effective Number of Bits)
effective_resolution = FSR / (RMS_noise_voltage * np.sqrt(12))
print("Effective Resolution (bits):", effective_resolution)

# ノイズフリー分解能 (Noise-Free Resolution)
noise_free_resolution = FSR / Peak_to_Peak_noise_voltage
print("Noise-Free Resolution (bits):", noise_free_resolution)

# ノイズフリーカウント (Noise-Free Counts)
noise_free_counts = FSR / (2 * Peak_to_Peak_noise_voltage)
print("Noise-Free Counts:", noise_free_counts)

# ENOB (Effective Number of Bits)
ENOB = (SINAD_value - 1.76) / 6.02
print("ENOB (Effective Number of Bits):", ENOB)

# SNR (Signal-to-Noise Ratio)
SNR = 20 * np.log10(signal_amplitude / output_noise_level)
print("SNR (Signal-to-Noise Ratio):", SNR, "dB")

# THD (Total Harmonic Distortion)
THD = THD_value
print("THD (Total Harmonic Distortion):", THD)

# SINAD (Signal-to-Noise and Distortion Ratio)
SINAD = 20 * np.log10(output_signal_amplitude / np.sqrt(output_noise_level**2 + (THD * output_signal_amplitude)**2))
print("SINAD (Signal-to-Noise and Distortion Ratio):", SINAD, "dB")

# Additional metrics
OSR = 20  # Oversampling Ratio
num_bits = 10
SNR_osr = 6.02 * num_bits + 1.76 + 10 * np.log10(OSR)
print("SNR with OSR (dB):", SNR_osr)

# Plotting the results
labels = ['Effective Resolution', 'Noise-Free Resolution', 'Noise-Free Counts', 'ENOB', 'SNR', 'THD', 'SINAD', 'SNR with OSR']
values = [effective_resolution, noise_free_resolution, noise_free_counts, ENOB, SNR, THD, SINAD, SNR_osr]

plt.figure(figsize=(12, 7))
plt.bar(labels, values, color=['blue', 'green', 'red', 'purple', 'orange', 'brown', 'cyan', 'magenta'])
plt.ylabel('Value')
plt.title('ADC Performance Indices')
plt.xticks(rotation=45)
plt.grid(True)
plt.show()

# Additional calculations for quantization noise
quantization_noise_power = (FSR / (2 ** num_bits)) ** 2 / 12
thermal_noise_power = RMS_noise_voltage ** 2

print("Quantization Noise Power:", quantization_noise_power)
print("Thermal Noise Power:", thermal_noise_power)

# Effective SNR considering quantization and thermal noise
combined_noise_power = quantization_noise_power + thermal_noise_power
effective_SNR = 10 * np.log10((signal_amplitude ** 2) / combined_noise_power)
print("Effective SNR considering quantization and thermal noise:", effective_SNR, "dB")

import numpy as np
import matplotlib.pyplot as plt

# Parameters
t = np.linspace(0, 1, 1000)  # Time vector
f_sampling = 1000  # Sampling frequency
bits = 3  # Number of quantization bits

# Generate input signal (original sine wave)
input_signal = np.sin(2 * np.pi * t)

# Quantization process
quantized_signal = np.round(input_signal * (2**bits - 1)) / (2**bits - 1)

# Dithering (adding white noise)
dithered_signal = quantized_signal + np.random.uniform(-0.5/(2**bits), 0.5/(2**bits), size=len(t))

# Filters (example: 1 / (1 - z^(-1)))
filtered_signal = np.zeros_like(t)
for i in range(1, len(t)):
    filtered_signal[i] = dithered_signal[i] + dithered_signal[i-1]

# Plotting
plt.figure(figsize=(10, 6))

plt.subplot(411)
plt.plot(t, input_signal, label='Input Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(412)
plt.plot(t, quantized_signal, label='Quantized Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(413)
plt.plot(t, dithered_signal, label='Dithered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(414)
plt.plot(t, filtered_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.tight_layout()
plt.show()




import numpy as np
import matplotlib.pyplot as plt

# Parameters
t = np.linspace(0, 1, 1000)  # Time vector
f_sampling = 1000  # Sampling frequency
bits = 3  # Number of quantization bits

# Generate input signal (original sine wave)
input_signal = np.sin(2 * np.pi * t)

# Quantization process
quantized_signal = np.round(input_signal * (2**bits - 1)) / (2**bits - 1)

# Dithering (adding white noise)
dithered_signal = quantized_signal + np.random.uniform(-0.5/(2**bits), 0.5/(2**bits), size=len(t))

# Filters (example: 1 / (1 - z^(-1)))
filtered_signal = np.zeros_like(t)
for i in range(1, len(t)):
    filtered_signal[i] = dithered_signal[i] + dithered_signal[i-1]

# Plotting
plt.figure(figsize=(10, 6))

plt.subplot(411)
plt.plot(t, input_signal, label='Input Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(412)
plt.plot(t, quantized_signal, label='Quantized Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(413)
plt.plot(t, dithered_signal, label='Dithered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(414)
plt.plot(t, filtered_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()

plt.tight_layout()
plt.show()










https://qiita.com/qwer123123/items/f135d080a682d4f979c2


```


残渣電圧の確認コード

```
# 定数定義
full_scale_voltage = 5.0
Vin = 3.0
reference_voltage = full_scale_voltage / 2

# 関数定義：残差電圧を計算する関数
def calculate_residual_voltage(Vin, reference_voltage):
    if Vin > reference_voltage:
        D = 1
        residual_voltage = 2 * (Vin - reference_voltage)
    else:
        D = 0
        residual_voltage = 2 * Vin
    
    return D, residual_voltage

# 初期値
Vin_current = Vin
residual_voltage_current = Vin_current  # 最初はVinと同じでスタート

# ステップ数
N = 10  # 任意のステップ数

# Nステップまでの計算と表示
for step in range(N):
    D, residual_voltage_current = calculate_residual_voltage(residual_voltage_current, reference_voltage)
    print(f"D{step+1}の値: {D}")
    print(f"残差電圧{step+1}の値: {residual_voltage_current}")
```
    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/76869589-2b25-2f25-c541-d9b64da22d98.png)

    
2部探索その2
```
# 初期設定
Vin = 3.7
基準電圧 = 8.0

# ステップ数を指定
N = 3

# 初期の基準電圧
基準電圧_list = [基準電圧 / 2]

# Dのリスト
D_list = []

# ステップごとの計算
for i in range(1, N+1):
    D = 1 if Vin > 基準電圧_list[-1] else 0
    D_list.append(D)
    
    if D == 1:
        新基準電圧 = 基準電圧_list[-1] + 基準電圧 / (2 ** (i + 1))
    else:
        新基準電圧 = 基準電圧_list[-1] - 基準電圧 / (2 ** (i + 1))
    
    基準電圧_list.append(新基準電圧)

# 結果表示
for i in range(N):
    print(f"ステップ{i+1}: 基準電圧{i} = {基準電圧_list[i]}, D{i+1} = {D_list[i]}")
print(f"ステップ{N}後の基準電圧: 基準電圧{N} = {基準電圧_list[N]}")



```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/7492f95d-a1a2-bb82-7aed-8783cee26d73.png)

2部探索その3

```

# Define the parameters
reference_voltage = 8.0  # in volts
Vin = 3.7  # in volts

# Initialize the steps
Vx = [0] * 4
D = [0] * 3
Vx_expr = [""] * 4

# Step 1
Vx[0] = -Vin + reference_voltage / (2 ** 1)
Vx_expr[0] = f"-Vin + reference_voltage / (2 ** 1) = {-Vin} + {reference_voltage / (2 ** 1)}"
if Vx[0] > 0:
    D[0] = 0
    Vx[1] = Vx[0] - reference_voltage / (2 ** 2)
    Vx_expr[1] = f"Vx[0] - reference_voltage / (2 ** 2) = {Vx[0]} - {reference_voltage / (2 ** 2)}"
else:
    D[0] = 1
    Vx[1] = Vx[0] + reference_voltage / (2 ** 2)
    Vx_expr[1] = f"Vx[0] + reference_voltage / (2 ** 2) = {Vx[0]} + {reference_voltage / (2 ** 2)}"

# Step 2
if Vx[1] > 0:
    D[1] = 0
    Vx[2] = Vx[1] - reference_voltage / (2 ** 3)
    Vx_expr[2] = f"Vx[1] - reference_voltage / (2 ** 3) = {Vx[1]} - {reference_voltage / (2 ** 3)}"
else:
    D[1] = 1
    Vx[2] = Vx[1] + reference_voltage / (2 ** 3)
    Vx_expr[2] = f"Vx[1] + reference_voltage / (2 ** 3) = {Vx[1]} + {reference_voltage / (2 ** 3)}"

# Step 3
if Vx[2] > 0:
    D[2] = 0
    Vx[3] = Vx[2] - reference_voltage / (2 ** 4)
    Vx_expr[3] = f"Vx[2] - reference_voltage / (2 ** 4) = {Vx[2]} - {reference_voltage / (2 ** 4)}"
else:
    D[2] = 1
    Vx[3] = Vx[2] + reference_voltage / (2 ** 4)
    Vx_expr[3] = f"Vx[2] + reference_voltage / (2 ** 4) = {Vx[2]} + {reference_voltage / (2 ** 4)}"

# Print the results
print("Vx values:", Vx)
print("D values:", D)
print("Vx expressions:")
for i in range(4):
    print(f"Step {i}: {Vx_expr[i]}")





```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/d462981c-a4fa-438b-8cdc-6a8fbd0dbf71.png)





```

from sympy import symbols, Eq, solve

# Define the symbols
C, Vx1, Vx2, VREF = symbols('C Vx1 Vx2 VREF')
S1, S2, S3, S4 = symbols('S1 S2 S3 S4')

# Define S values for Q1 and Q2
S1_Q1 = S2_Q1 = S3_Q1 = 0
S4_Q1 = VREF

S1_Q2 = S2_Q2 = 0
S3_Q2 = S4_Q2 = VREF

# Define Q1 and Q2
Q1 = C * (Vx1 - S1_Q1) + C * (Vx1 - S2_Q1) + 2 * C * (Vx1 - S3_Q1) + (2**2) * C * (Vx1 - S4_Q1)
Q2 = C * (Vx2 - S1_Q2) + C * (Vx2 - S2_Q2) + 2 * C * (Vx2 - S3_Q2) + (2**2) * C * (Vx2 - S4_Q2)

# Define the equation Q1 = Q2
equation = Eq(Q1, Q2)

# Solve for Vx2 in terms of Vx1 and VREF
solution = solve(equation, Vx2)
solution



```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/c4114fe3-0a07-584a-cc45-a2d33d443efb.png)
新2部探索

```
import matplotlib.pyplot as plt

# Constants
reference_voltage = 8
Vin = 3.7
N = 30  # Set the value of N to 30

# Initialization
reference_voltage_0 = reference_voltage / 2  # Initial reference voltage at step 0 is half of reference voltage
reference_voltage_values = [reference_voltage_0]
D = []

# Calculation loop
for n in range(1, N + 1):
    if Vin < reference_voltage_values[n - 1]:
        D.append(0)
        new_reference_voltage = reference_voltage_values[n - 1] - (reference_voltage / (2 ** (n + 1)))
    else:
        D.append(1)
        new_reference_voltage = reference_voltage_values[n - 1] + (reference_voltage / (2 ** (n + 1)))
    
    reference_voltage_values.append(new_reference_voltage)

# Plotting the results
steps = range(N + 1)
plt.figure(figsize=(10, 6))

# Plot Reference Voltage
plt.plot(steps, reference_voltage_values, marker='o', linestyle='-', color='b', label='Reference Voltage')

# Plot D values
for i, txt in enumerate(D):
    plt.annotate(txt, (steps[i], reference_voltage_values[i]), textcoords="offset points", xytext=(0,10), ha='center')

plt.xticks(steps)
plt.xlabel('Steps')
plt.ylabel('Reference Voltage (V)')
plt.title('Reference Voltage over Steps with D Values')
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()


```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/6f39f15b-c277-3fa1-6ad7-348910ca528a.png)

２重み付け4ビットDAC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/b60de0d3-1260-f7b6-f4d3-8ae148fed2e8.png)


```
def calculate_D_N(N):
    power = 2 ** (N - 1)
    A = 7
    binary_A = bin(A)[2:].zfill(N)  # AをNビットの2進数に変換して桁を揃える
    trimmed_binary_A = binary_A[1:]      # 最初の文字を削除
    modified_binary_A = trimmed_binary_A + '0'  # 末尾に0を追加

    # 0を0と1をVに書き換える
    modified_binary_A = modified_binary_A.replace('0', '0').replace('1', 'V')

    print(f"A = {A}")
    print(f"Aの2進数表現（{N}ビット）: {binary_A}")
    print(f"2 ** (N - 1) = {power}")

    return modified_binary_A

# N=5の場合の実行例
N = 5
result = calculate_D_N(N)
print("Modified D_N:", result)


```



```
import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.signal import find_peaks

# パラメータ設定
f = 1  # 周波数
Fs = 100  # サンプリングレート
T = 1  # 収録終了時刻
Ts = 1 / Fs  # サンプリング周期
N = int(Fs * T)  # サンプル数

# 時間軸
t = np.linspace(0, T, N, endpoint=False)

# 入力信号
x = np.sin(2 * np.pi * f * t)

# NビットAD変換
num_bits = 2
quant_levels = 2 ** num_bits
x_min, x_max = -1, 1
x_q = np.round((x - x_min) / (x_max - x_min) * (quant_levels - 1)) * (x_max - x_min) / (quant_levels - 1) + x_min

# プロット
plt.figure(figsize=(10, 6))
plt.subplot(3, 1, 1)
plt.plot(t, x, label='Original Signal')
plt.title('Original Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

plt.subplot(3, 1, 2)
plt.plot(t, x_q, label='Quantized Signal', color='r')
plt.title('Quantized Signal (4-bit)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()

# FFT
X = fft(x_q)
X_mag = np.abs(X)[:N // 2] * 2 / N  # 振幅スペクトル
frequencies = np.fft.fftfreq(N, Ts)[:N // 2]

plt.subplot(3, 1, 3)
plt.plot(frequencies, X_mag, label='FFT of Quantized Signal')
plt.title('FFT of Quantized Signal')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()

# SNR, ENOB, SNDR計算
def calculate_snr(signal_power, noise_power):
    snr = 10 * np.log10(signal_power / noise_power)
    return snr

# ピークの検出
signal_peaks, _ = find_peaks(X_mag, height=0.1)
if len(signal_peaks) > 0:
    signal_freq = signal_peaks[0]
    signal_power = X_mag[signal_freq] ** 2
    noise_power = np.sum(X_mag ** 2) - signal_power
else:
    signal_power = 0
    noise_power = np.sum(X_mag ** 2)

snr = calculate_snr(signal_power, noise_power)
enob = (snr - 1.76) / 6.02
sndr = 10 * np.log10(signal_power / (signal_power + noise_power))

print(f"SNR: {snr:.2f} dB")
print(f"ENOB: {enob:.2f} bits")
print(f"SNDR: {sndr:.2f} dB")


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/e4baea1a-837b-2fa6-36b1-c82ad5487ebd.png)


```
import numpy as np
import matplotlib.pyplot as plt

# データのパラメータ
N = 2**9            # サンプル数
dt = 1/300e3        # サンプリング間隔
f1 = 18.164062e3    # 周波数

t = np.arange(0, N*dt, dt)  # 時間軸

# 信号を生成
f = np.sin(2*np.pi*f1*t) + 0.001 * np.random.randn(N)
#f=np.round(f,decimals=2)


# FFT
F = np.fft.fft(f)
freq = np.fft.fftfreq(N, dt)
freq_norm = freq/(1/dt)  # 正規化

# 振幅スペクトルを計算
Amp = np.abs(F)
# 縦軸をシグナル基準のdBに変換
max_index = np.argmax(Amp)
Amp_dB = 20*np.log10(Amp/Amp[max_index])

# パワースペクトルの計算
Pow = Amp ** 2
# 縦軸をシグナル基準のdBに変換
max_index = np.argmax(Pow)
Pow_dB = 10*np.log10(Pow/Pow[max_index])


noise = (np.average(Pow_dB[:max_index-1])+np.average(Pow_dB[max_index+1:]))/2
print("PSNR=", -noise)


# グラフ表示
plt.figure()
plt.subplot(131)
plt.plot(t, f, label='f(n)')
plt.xlabel("Time")
plt.ylabel("Signal")
plt.grid()
plt.subplot(132)
plt.plot(freq_norm[:int(N/2)], Pow_dB[:int(N/2)], label='|F(k)|')
plt.xlabel('f/fs')
plt.ylabel('Power')
plt.grid()
plt.subplot(133)
plt.plot(freq_norm[:int(N/2)], Amp_dB[:int(N/2)], label='|F(k)|')
plt.xlabel('f/fs')
plt.ylabel('Amp')
plt.grid()
plt.show()


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/0d7ae914-3c69-0975-a5f4-301c3b087841.png)




```

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft

# パラメータ設定
Fs = 1000  # サンプリング周波数 (Hz)
Fin = 50   # 入力信号の周波数 (Hz)
duration = 1  # 期間 (秒)
t = np.linspace(0, duration, int(Fs*duration), endpoint=False)  # 時間軸

# サイン波生成
amplitude = 1
signal = amplitude * np.sin(2 * np.pi * Fin * t)

# 8ビットAD変換
def adc_8bit(signal):
    quantized_signal = np.round((signal + 1) * (2**7)) / (2**7) - 1
    return quantized_signal

# 10ビットAD変換
def adc_10bit(signal):
    quantized_signal = np.round((signal + 1) * (2**9)) / (2**9) - 1
    return quantized_signal

# FFTによるパワースペクトル計算
def calculate_power_spectrum(signal, Fs):
    N = len(signal)
    yf = fft(signal)
    xf = np.fft.fftfreq(N, 1/Fs)[:N//2]
    power_spectrum = 2.0/N * np.abs(yf[:N//2])**2
    return xf, power_spectrum

# SNR計算
def calculate_snr(signal, Fs):
    xf, power_spectrum = calculate_power_spectrum(signal, Fs)
    signal_power = np.sum(power_spectrum[(xf >= Fin-1) & (xf <= Fin+1)])
    noise_power = np.sum(power_spectrum) - signal_power
    snr = 10 * np.log10(signal_power / noise_power)
    return snr

# SQNR計算
def calculate_sqnr(signal, quantized_signal):
    signal_power = np.mean(signal**2)
    quantization_noise_power = np.mean((signal - quantized_signal)**2)
    sqnr = 10 * np.log10(signal_power / quantization_noise_power)
    return sqnr

# SNDR計算
def calculate_sndr(signal, Fs):
    xf, power_spectrum = calculate_power_spectrum(signal, Fs)
    signal_power = np.sum(power_spectrum[(xf >= Fin-1) & (xf <= Fin+1)])
    total_noise_power = np.sum(power_spectrum) - signal_power
    sndr = 10 * np.log10(signal_power / total_noise_power)
    return sndr

# AD変換後の信号
adc_8bit_signal = adc_8bit(signal)
adc_10bit_signal = adc_10bit(signal)

# パワースペクトル計算
xf, power_spectrum_8bit = calculate_power_spectrum(adc_8bit_signal, Fs)
_, power_spectrum_10bit = calculate_power_spectrum(adc_10bit_signal, Fs)

# SNR計算
snr_8bit = calculate_snr(adc_8bit_signal, Fs)
snr_10bit = calculate_snr(adc_10bit_signal, Fs)

# SQNR計算
sqnr_8bit = calculate_sqnr(signal, adc_8bit_signal)
sqnr_10bit = calculate_sqnr(signal, adc_10bit_signal)

# SNDR計算
sndr_8bit = calculate_sndr(adc_8bit_signal, Fs)
sndr_10bit = calculate_sndr(adc_10bit_signal, Fs)

# 結果をコンソールに表示
print(f"8ビットAD変換のSN比 (SNR): {snr_8bit:.2f} dB")
print(f"10ビットAD変換のSN比 (SNR): {snr_10bit:.2f} dB")
print(f"8ビットAD変換の量子化雑音比 (SQNR): {sqnr_8bit:.2f} dB")
print(f"10ビットAD変換の量子化雑音比 (SQNR): {sqnr_10bit:.2f} dB")
print(f"8ビットAD変換の信号対歪雑音比 (SNDR): {sndr_8bit:.2f} dB")
print(f"10ビットAD変換の信号対歪雑音比 (SNDR): {sndr_10bit:.2f} dB")

# 結果表示
plt.figure(figsize=(14, 10))

# オリジナル信号とAD変換信号のプロット
plt.subplot(3, 1, 1)
plt.plot(t, signal, label='Original Signal')
plt.plot(t, adc_8bit_signal, label='8-bit ADC Signal', linestyle='--')
plt.plot(t, adc_10bit_signal, label='10-bit ADC Signal', linestyle='-.')
plt.legend()
plt.title('Original and ADC Converted Signals')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')

# 8ビットAD変換信号のパワースペクトル
plt.subplot(3, 1, 2)
plt.plot(xf, power_spectrum_8bit)
plt.title(f'Power Spectrum of 8-bit ADC Signal\n'
          f'SNR: {snr_8bit:.2f} dB, SQNR: {sqnr_8bit:.2f} dB, SNDR: {sndr_8bit:.2f} dB')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Power')

# 10ビットAD変換信号のパワースペクトル
plt.subplot(3, 1, 3)
plt.plot(xf, power_spectrum_10bit)
plt.title(f'Power Spectrum of 10-bit ADC Signal\n'
          f'SNR: {snr_10bit:.2f} dB, SQNR: {sqnr_10bit:.2f} dB, SNDR: {sndr_10bit:.2f} dB')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Power')

plt.tight_layout()
plt.show()


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/6a148107-dcb8-9766-721f-454fb8547b2f.png)

フルスケール電圧=8V
Vin=3.7とする
比較電圧=フルスケール電圧÷2とする
Vinが比較電圧よりも大きいときD1=1
Vin1=2×Vin-比較電圧
Vinが比較電圧よりも小さいとき D1=0
Vin1=2×Vin+比較電圧

Vin1が比較電圧よりも大きいときD2=1
Vin2=2×Vin1-比較電圧
Vin1が比較電圧よりも小さいとき D2=0
Vin2=2×Vin1+比較電圧

Vin2が比較電圧よりも大きいときD3=1
Vin3=2×Vin2-比較電圧
Vin2が比較電圧よりも小さいとき D3=0
Vin3=2×Vin2+比較電圧

```

def calculate_d_vin(vin, full_scale_voltage):
    # 比較電圧を計算
    comparison_voltage = full_scale_voltage / 2

    # D1を計算
    if vin > comparison_voltage:
        D1 = 1
        Vin1 = 2 * vin - comparison_voltage
    else:
        D1 = 0
        Vin1 = 2 * vin + comparison_voltage

    # D2を計算
    if Vin1 > comparison_voltage:
        D2 = 1
        Vin2 = 2 * Vin1 - comparison_voltage
    else:
        D2 = 0
        Vin2 = 2 * Vin1 + comparison_voltage

    # D3を計算
    if Vin2 > comparison_voltage:
        D3 = 1
        Vin3 = 2 * Vin2 - comparison_voltage
    else:
        D3 = 0
        Vin3 = 2 * Vin2 + comparison_voltage

    return D1, D2, D3, Vin1, Vin2, Vin3

# パラメータを設定
full_scale_voltage = 8
Vin = 3.7

# 計算の実行
D1, D2, D3, Vin1, Vin2, Vin3 = calculate_d_vin(Vin, full_scale_voltage)

# 結果の出力
print(f"D1: {D1}, D2: {D2}, D3: {D3}")
print(f"Vin1: {Vin1}, Vin2: {Vin2}, Vin3: {Vin3}")


```





```

# Define the VREF and N
VREF = 5.0  # Example value, you can change it as needed
N = 6  # Example value, you can change it as needed

# Calculate full scale voltage and VLSB
full_scale_voltage = 2 * VREF
VLSB = full_scale_voltage / (2**N - 1)

# Print the full scale voltage and VLSB
print(f"Full Scale Voltage: {full_scale_voltage} V")
print(f"VLSB: {VLSB} V")

# Generate and print all digital outputs
print("Digital Outputs:")
for i in range(2**N):
    print(f"Digital Output {i:0{N}b}: {i * VLSB:.6f} V")


```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/ee877048-d00e-1541-fb45-b3bc47bac463.png)

```



```
import numpy as np
import matplotlib.pyplot as plt

# Define the parameters
G = 10  # Gain of the operational amplifier
C0 = 1e-9  # Capacitance in farads
Cp = 0.5 * C0  # Cp value as a multiple of C0
VDAC = 1  # DAC reference voltage

# Time-related parameters for the input sine wave
t = np.linspace(0, 1, 1000)  # Time array from 0 to 1 second with 1000 points
frequency = 5  # Frequency of the input sine wave in Hz
Vin = 2 * np.sin(2 * np.pi * frequency * t)  # Sine wave input with amplitude 2V

# Define the transfer function for the amplifier circuit (Equation 8.68)
def Vout(Vin, VDAC, G, Cp, C0):
    return 2 * (Vin - VDAC / 2) / (1 + 1 / G * (2 + Cp / C0))

# Calculate the output voltage
Vout_signal = Vout(Vin, VDAC, G, Cp, C0)

# Plot the input and output signals
plt.figure(figsize=(10, 6))

# Plot input signal (Vin)
plt.subplot(2, 1, 1)
plt.plot(t, Vin, label='Input Signal (Vin)', color='b')
plt.title('Input Signal (Vin)')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid(True)

# Plot output signal (Vout)
plt.subplot(2, 1, 2)
plt.plot(t, Vout_signal, label='Output Signal (Vout)', color='r')
plt.title('Output Signal (Vout)')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid(True)

plt.tight_layout()
plt.show()


```
```

import numpy as np
import matplotlib.pyplot as plt

# Define parameters
Cs = 1e-9  # Sampling capacitor (in Farads)
Cf = 1e-9  # Feedback capacitor (in Farads)
Vref = 1  # Reference voltage (in Volts)

# Time settings for input signal
t = np.linspace(0, 1, 1000)  # Time from 0 to 1 second with 1000 samples
frequency = 5  # Frequency of the input sine wave in Hz
Vin = 2 * np.sin(2 * np.pi * frequency * t)  # Sine wave input (amplitude 2V)

# Discrete transfer function of analog integrator
def integrator_output(Vin, Vref, Cs, Cf):
    Vout = np.zeros_like(Vin)  # Initialize output array
    for k in range(1, len(Vin)):
        Vout[k] = (Cs / Cf) * (Vin[k-1] - Vref + Vout[k-1])  # Using the z-transform form
    return Vout

# Calculate output signal
Vout = integrator_output(Vin, Vref, Cs, Cf)

# Plotting the input and output signals
plt.figure(figsize=(10, 6))

# Plot input signal (Vin)
plt.subplot(2, 1, 1)
plt.plot(t, Vin, label='Input Signal (Vin)', color='b')
plt.title('Input Signal (Vin)')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid(True)

# Plot output signal (Vout)
plt.subplot(2, 1, 2)
plt.plot(t, Vout, label='Output Signal (Vout)', color='r')
plt.title('Output Signal (Vout)')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid(True)

plt.tight_layout()
plt.show()


```