Post Go back to editing

AD5686 Signal Generation with DAQ - Reg.

Hello, 

I am working with Raspberry pi3b which is connected to AD5686 via SPI communication. It is connected to the Chip select 1. I am trying to generate a sine wave using the DAC commanded by the raspberry pi in the frequency range of about 1000Hz to 10000Hz, But I am not getting exact sine wave. The quantization delay is too high such that for higher frequencies like 10000Hz I get only 4 or five steps for one sine wave. I have also tried with different clock frequencies up to 49Mhz. But there is no use. Only lower frequencies like 300 or 400Hz were able to be achieved Because the sampling frequency is so much higher than the sine repetition  frequency. I will attach two samples of code which I have used. Please someone help me with this.

import spidev
import RPi.GPIO as GPIO
import time
import math

# Define GPIO pins
SYNC_PIN = 7
RESET_PIN = 22
POWER_PIN = 13

# Define SPI settings
spi = spidev.SpiDev()
spi.open(0, 1)  # SPI bus 0, device 1
spi.mode = 0b10
spi.max_speed_hz = 40000000  # 1 MHz

# Setup GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(SYNC_PIN, GPIO.OUT)
GPIO.setup(RESET_PIN, GPIO.OUT)
GPIO.setup(POWER_PIN, GPIO.OUT)

def power_up():
    GPIO.output(POWER_PIN, GPIO.HIGH)

def power_down():
    GPIO.output(POWER_PIN, GPIO.LOW)

def reset():
    GPIO.output(RESET_PIN, GPIO.LOW)
    time.sleep(0.00004)  # Minimum of 40 ns
    GPIO.output(RESET_PIN, GPIO.HIGH)

def write_and_update_dac_channel(channel, data):
    # Convert data to an integer
    data = int(data)

    # Construct the 24-bit command word for writing to and updating DAC channel
    command_word = (0b0011 << 20) | (channel << 16) | data

    # Send the command word over SPI
    GPIO.output(SYNC_PIN, GPIO.LOW)
    spi.xfer2([command_word >> 16, (command_word >> 8) & 0xFF, command_word & 0xFF])
    GPIO.output(SYNC_PIN, GPIO.HIGH)

def generate_sine_wave():
    SINE_DC_OFFSET = 32768
    SINE_AMPLITUDE = 32767

    SINE_WAVE_STEPS = 100
    STEP_DELAY_MICROS = 8.13

    sineWave = [0] * SINE_WAVE_STEPS

    for i in range(SINE_WAVE_STEPS):
        sineWave[i] = SINE_DC_OFFSET + SINE_AMPLITUDE * math.sin(i * 2 * math.pi / SINE_WAVE_STEPS)

    i = 0
    while True:
        write_and_update_dac_channel(0b0001, sineWave[i])
        i = (i + 1) % SINE_WAVE_STEPS
        #time.sleep(STEP_DELAY_MICROS / 1000000)  # Convert to seconds

def main():
    power_up()
    reset()  # Reset the DAC initially

    try:
        generate_sine_wave()
    except KeyboardInterrupt:
        power_down()
        GPIO.cleanup()

if __name__ == "__main__":
    main()

import spidev
import RPi.GPIO as GPIO
import time
import math

# Define GPIO pins
SYNC_PIN = 7
RESET_PIN = 22
POWER_PIN = 13

# Define SPI settings
spi = spidev.SpiDev()
spi.open(0, 1)  # SPI bus 0, device 1
spi.mode = 0b10
spi.max_speed_hz = 40000000  # 1 MHz

def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(SYNC_PIN, GPIO.OUT)
    GPIO.setup(RESET_PIN, GPIO.OUT)
    GPIO.setup(POWER_PIN, GPIO.OUT)

def power_up():
    GPIO.output(POWER_PIN, GPIO.HIGH)

def power_down():
    GPIO.output(POWER_PIN, GPIO.LOW)

def reset():
    GPIO.output(RESET_PIN, GPIO.LOW)
    time.sleep(0.00004)  # Minimum of 40 ns
    GPIO.output(RESET_PIN, GPIO.HIGH)

def write_and_update_dac_channel(channel, data):
    # Construct the 24-bit command word for writing to and updating DAC channel
    command_word = (0b0011 << 20) | (channel << 16) | data

    # Send the command word over SPI
    GPIO.output(SYNC_PIN, GPIO.LOW)
    spi.xfer2([command_word >> 16, (command_word >> 8) & 0xFF, command_word & 0xFF])
    GPIO.output(SYNC_PIN, GPIO.HIGH)

def generate_sine_wave(min_value, max_value, frequency, phase_shift):
    num_samples = 10000  # 50 seconds duration
    for i in range(360):
        # Calculate the sine wave value between 0 and 1
        sine_value = (math.sin(2 * math.pi * i))

        # Scale the sine value to the range between min_value and max_value
        scaled_value = sine_value * (max_value - min_value)

        # Shift the scaled value to the range between min_value and max_value
        shifted_value = scaled_value + min_value

        # Convert the sine value to 16-bit DAC input code
        input_code = int(shifted_value)

        # Write to and update DAC Channel A with the input code
        write_and_update_dac_channel(0b0001, input_code)
        time.sleep(0.001)

def main():
    setup()
    power_up()
    reset()  # Reset the DAC initially

    try:
        while True:
            generate_sine_wave(min_value=32768, max_value=65535, frequency=1230, phase_shift=0)
    except KeyboardInterrupt:
        power_down()
        GPIO.cleanup()

if __name__ == "__main__":
    main()


Thread Notes

Parents Reply Children
  • Hi, 

    I think the issue lies with how you control the SYNC pin. GPIO functions tend to have long latency. You can have the fastest SCLK available but still get low update rate results because of SYNC. I'm not an expert in coding but what I could advise is to have some sort of PWM or timing function for SYNC instead of the GPIO. You may want to check raspberry pi forums on how to set this up.