Я работаю над проектом Raspberry Pi, в котором я перешел от использования HiFi DAC HAT на базе I2C (PCM5122) к ЦАП на основе SPI (Boost 8568). Моя цель — вывести аналоговые сигналы из обработанных данных ЭЭГ с ЦАП, но я сталкиваюсь со значительными различиями в качестве выходного сигнала. Когда я проверяю выходы осциллографом, выход нового ЦАП SPI искажается по сравнению с чистым сигналом, вырабатываемым I2C DAC HAT. Изображение выходного сигнала HiFi DACИзображение выходного сигнала BOOST DAC 8568
Я попробовал снизить как частоту дискретизации сигнала, так и максимальную скорость, чтобы посмотреть, помогло ли это решить проблему, однако проблема все еще там. Я начинаю задаваться вопросом, связано ли это с тактовым компонентом повышающего ЦАП или необходимо изменить другие параметры SPI, чтобы обеспечить такой же чистый выходной сигнал, как предыдущий ЦАП и интерфейс i2C.
import spidev
import numpy as np
import time
import RPi.GPIO as GPIO
from scipy.io import wavfile
# Define DAC channels and their corresponding addresses (assuming 8 channels)
CHANNELS = {
'A': 0b0000, # Channel A address
'B': 0b0001, # Channel B address
'C': 0b0010, # Channel C address
'D': 0b0011, # Channel D address
'E': 0b0100, # Channel E address
'F': 0b0101, # Channel F address
'G': 0b0110, # Channel G address
'H': 0b0111, # Channel H address
}
# LDAC GPIO pin (adjust as needed)
LDAC_PIN = 17
def initialize_ldac():
GPIO.setmode(GPIO.BCM)
GPIO.setup(LDAC_PIN, GPIO.OUT)
GPIO.output(LDAC_PIN, GPIO.HIGH) # Default to inactive state
def trigger_ldac():
GPIO.output(LDAC_PIN, GPIO.LOW)
time.sleep(0.001)
GPIO.output(LDAC_PIN, GPIO.HIGH)
CHANNEL_MAP = {
"A": 0,
"B": 1,
"C": 2,
"D": 3,
"E": 4,
"F": 5,
"G": 6,
"H": 7
}
def build_command(channel, data):
if isinstance(channel, str):
channel = CHANNEL_MAP[channel.upper()] # Map channel to integer
data = int(data) & 0xFFFF # Ensure data is a 16-bit value
command = 0b0011 12) & 0x0F) # Upper nibble of data
lsb = (data >> 4) & 0xFF # Middle 8 bits of data
return [msb, lsb]
def send_to_dac(spi, channel, value):
command = build_command(channel, value)
spi.xfer2(command)
def update_channels_with_ldac(spi, channel_values):
for channel, value in channel_values.items():
send_to_dac(spi, channel, value)
trigger_ldac()
def set_all_channels_to_zero(spi):
channel_values = {channel: 0 for channel in CHANNELS}
update_channels_with_ldac(spi, channel_values)
def load_wav_file(file_path, desired_duration_seconds):
# Load WAV file and normalize the signal
sample_rate, signal = wavfile.read(file_path)
if signal.ndim > 1: # Handle multi-channel audio (stereo)
signal = signal[:, 0] # Use only the first channel
max_amplitude = np.max(np.abs(signal))
normalized_signal = signal / max_amplitude
# Determine how many samples fit within the desired duration
num_samples = int(sample_rate * desired_duration_seconds)
if len(normalized_signal) > num_samples:
normalized_signal = normalized_signal[:num_samples]
else:
# Repeat the signal to fit the desired duration
repeated_signal = np.tile(normalized_signal, int(np.ceil(num_samples / len(normalized_signal))))
normalized_signal = repeated_signal[:num_samples]
# Clip and convert to 16-bit integers
normalized_signal = np.clip(normalized_signal * 32767, -32768, 32767).astype(int)
return normalized_signal, sample_rate
def play_wav_file(spi, wav_file, target_channel, desired_duration_seconds):
audio_data, sample_rate = load_wav_file(wav_file, desired_duration_seconds)
num_samples = len(audio_data)
sample_interval = 1 / sample_rate # Time interval between samples
start_time = time.time() # Record the start time
for i, value in enumerate(audio_data):
# Send data to the DAC
channel_values = {channel: 0 for channel in CHANNELS}
channel_values[target_channel] = value
update_channels_with_ldac(spi, channel_values)
# Ensure proper timing
elapsed_time = time.time() - start_time
expected_time = (i + 1) * sample_interval
if elapsed_time < expected_time:
time.sleep(expected_time - elapsed_time)
# Stop playback if exceeded the desired duration
if elapsed_time >= desired_duration_seconds:
break
if __name__ == "__main__":
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 500000
spi.mode = 0b00
initialize_ldac()
try:
target_channel = input("Enter the target channel (A, B, C, D, E, F, G, H): ").strip().upper()
if target_channel not in CHANNELS:
raise ValueError("Invalid channel.")
wav_file = 'wav file dest here'
desired_duration_seconds = 7
play_wav_file(spi, wav_file, target_channel, desired_duration_seconds)
finally:
set_all_channels_to_zero(spi)
spi.close()
GPIO.cleanup()
Подробнее здесь: https://stackoverflow.com/questions/792 ... ed-signals
SPIDEV на Raspberry Pi для TI DAC8568, создающего искаженные сигналы ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение