Como posso gerar sinais de frequência / pulso?


19

Estou procurando maneiras de usar o Raspberry Pi como um gerador de sinal. Atualmente, estou trabalhando para conectar um módulo AD9850 barato do ebay. Isso irá gerar frequências bastante precisas de até 40MHz (70MHz com o AD9851).

insira a descrição da imagem aqui

Eu acho que a saída de áudio também pode ser usada para formas de onda arbitrárias até uma frequência muito limitada.

há outras possibilidades?

Respostas:


13

Aqui está como eu conectei o módulo AD9850 e um programa Python simples para mostrar como definir a frequência para 1000Hz.

O AD9850 precisa rodar em 5V para funcionar corretamente com o cristal de 125MHz. Seria provavelmente ser ok para condutores 4 pinos GPIO diretamente para o módulo, uma vez que são apenas entradas, mas ligar através de um MCP23017 efetivamente transforma o módulo em outro I²C periférica e garante que as entradas RPI são seguros.

Nota importante sobre + 5V
O pino de + 5V no GPIO não pode realmente fornecer corrente suficiente para alimentar o AD9850. Você deve usar uma fonte externa de 5V.

RPi conectado ao módulo AD9850 via MCP23017

from functools import partial

import smbus

def main():
    addr = 0x20
    bus = smbus.SMBus(0) # or SMBus(1) on newer pis

    # Helper functions    
    wr_dir = partial(bus.write_byte_data, addr, 0x01)
    wr = partial(bus.write_byte_data, addr, 0x13)

    # Set Pins B0-B4 of the MCP23017 to output
    wr_dir(0xF0)

    # Names of the Pins
    RST = 1 << 0
    DATA = 1 << 1
    FQ = 1 << 2
    CLK = 1 << 3

    def send_bit(bit):
        # send a single bit
        wr(DATA * bit)
        wr(CLK | DATA * bit)

    def fq():
        wr(FQ)
        wr(0)

    def init():
        wr(RST)
        wr(0)
        wr(CLK)
        wr(0)
        wr(FQ)
        wr(0) 

    freq = 1000  
    init()
    dphase = int(0.5 + (freq << 32) / 125000000.0)
    for x in range(32):
        send_bit((dphase >> x) & 1)

    # Phase bits can all be 0
for x in range(8):
    send_bit(0)

    fq()

if __name__ == "__main__":
    main()

Esse é o seu próprio símbolo RPi GPIO?
Alex Chamberlain

1
@AlexChamberlain, sim, é. Tanto quanto eu posso dizer a RPF não lançou nada de muito útil além do próprio RPI :)
John La Rooy

Hmm, acho que isso pode ser uma pergunta boba, mas o que é um símbolo do GPIO?
Steven Lu

@StevenLu, o retângulo grande à direita do esquema. Os RPi antigos tinham 26 pinos, os mais novos têm 40 pinos. veja elinux.org/…
John La Rooy

Oh está bem. Parece muito natural. Eu acho que você não desenhou a versão de 40 pinos porque você só precisava de 3 desses pinos para o diagrama.
Steven Lu

11

Em teoria, você poderia conectar algum conversor D / A aos pinos GPIO, mas isso não é adequado para geração de sinal porque você não poderá controlá-lo com tempo preciso, principalmente porque o Linux não é um sistema operacional em tempo real.

Além disso, não há como isso funcionar em tais frequências altas.

Se 44 ​​kHz ou mais for suficiente, acho que a tomada de áudio pode ser a maneira mais simples de fazer isso.


4

John La Rooy tem uma boa solução, mas o circuito pode ser mais complicado do que alguns preferem. Isso descreve uma solução semelhante projetada por Tom Herbison usando apenas o AD9850, embora use 4 pinos de sinal GPIO em vez de 2 como a solução de John.

Tom se conecta ao GPIO assim: diagrama de ligação

Observe que ele roda o AD9850 em 3,3V em vez de 5V. De acordo com esta discussão , o AD9850 é classificado para funcionar em 3,3V ou 5V, mas algumas placas podem usar componentes que não suportam 5V por muito tempo, portanto, rodar em 3,3V pode realmente ser uma solução melhor, dependendo do seu sabor na placa AD9850 .

Minha placa AD9850 em particular tinha a maioria das etiquetas de pinos somente embaixo da placa, então tirei uma foto da parte de baixo antes de pressioná-la em uma placa de prototipagem. Os locais dos pinos acabaram sendo idênticos aos do quadro de Tom. No meu quadro, FQestá rotulado FU_UQ, CLKé W_CLKe RSTé RESET.

Tom fornece esse script Python 3 para controlar o gerador de funções. Aqui está uma cópia da v1.0, caso o link de download seja interrompido:

# RPi RF Signal Generator v1.0

# Copyright (C) 2013 Tom Herbison MI0IOU
# Email (hidden to discourage spammers - see original rpi_rfsiggen.py file)
# Web <http://www.asliceofraspberrypi.co.uk>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# import GUI module
from tkinter import *

# import GPIO module
import RPi.GPIO as GPIO

# setup GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

# Define GPIO pins
W_CLK = 15
FQ_UD = 16
DATA = 18
RESET = 22

# setup IO bits
GPIO.setup(W_CLK, GPIO.OUT)
GPIO.setup(FQ_UD, GPIO.OUT)
GPIO.setup(DATA, GPIO.OUT)
GPIO.setup(RESET, GPIO.OUT)

# initialize everything to zero
GPIO.output(W_CLK, False)
GPIO.output(FQ_UD, False)
GPIO.output(DATA, False)
GPIO.output(RESET, False)

# Function to send a pulse to GPIO pin
def pulseHigh(pin):
    GPIO.output(pin, True)
    GPIO.output(pin, True)
    GPIO.output(pin, False)
    return

# Function to send a byte to AD9850 module
def tfr_byte(data):
    for i in range (0,8):
        GPIO.output(DATA, data & 0x01)
        pulseHigh(W_CLK)
        data=data>>1
    return

# Function to send frequency (assumes 125MHz xtal) to AD9850 module
def sendFrequency(frequency):
    freq=int(frequency*4294967296/125000000)
    for b in range (0,4):
        tfr_byte(freq & 0xFF)
        freq=freq>>8
    tfr_byte(0x00)
    pulseHigh(FQ_UD)
    return


# Class definition for RPiRFSigGen application
class RPiRFSigGen:
        # Build Graphical User Interface
        def __init__(self, master):
                frame = Frame(master, bd=10)
                frame.pack(fill=BOTH,expand=1)
                # set output frequency
                frequencylabel = Label(frame, text='Frequency (Hz)', pady=10)
                frequencylabel.grid(row=0, column=0)
                self.frequency = StringVar()
                frequencyentry = Entry(frame, textvariable=self.frequency, width=10)
                frequencyentry.grid(row=0, column=1)
                # Start button
                startbutton = Button(frame, text='Start', command=self.start)
                startbutton.grid(row=1, column=0)
                # Stop button
                stopbutton = Button(frame, text='Stop', command=self.stop)
                stopbutton.grid(row=1, column=1)


        # start the DDS module
        def start(self):
                frequency = int(self.frequency.get())
                pulseHigh(RESET)
                pulseHigh(W_CLK)
                pulseHigh(FQ_UD)
                sendFrequency(frequency)

        # stop the DDS module
        def stop(self):
                pulseHigh(RESET)

# Assign TK to root
root = Tk()

# Set main window title
root.wm_title('RPi RFSigGen')

# Create instance of class RPiRFSigGen
app = RPiRFSigGen(root)

# Start main loop and wait for input from GUI
root.mainloop()

Como qualquer uso dos pinos GPIO no pi exige a execução como root, Tom descreve dois métodos para iniciar seu código python com privilégios de root. Seu primeiro método é modificar o ícone da área de trabalho do Python IDE para sempre ser executado como root, mas isso me parece inseguro - você não deseja executar todos os programas da GUI python como root, se não precisar. O segundo método é executar a sudo idle3_partir de um prompt de comando para iniciar o Python 3 Integrated Development Environment com privilégios de root sempre que necessário.

Tom não menciona a instalação da biblioteca RPi.GPIO python 3, portanto ela já pode estar disponível em algumas versões do Pi OS, mas não estava disponível no Occidentalis v0.2 que eu estava usando, então eu executei sudo apt-get install python3-rpi.gpio. Observe que o Python 3 usa um local diferente para o RPi.GPIO sudo apt-get install python-rpi.gpio, tornando a biblioteca acessível apenas ao Python 2.

Quando o IDE do Python 3 for aberto com privilégios de root, abra o arquivo rpi_rfsiggen.pye escolha Run -> Run Moduleno menu ou pressione F5.

Consegui obter uma boa onda senoidal estável de 18kHZ a 1Vpp a partir do pino de saída SinB (rotulado ZOUT2na minha placa) na minha primeira tentativa.


3

Se você deseja apenas implementar um gerador de funções para áudio e Lf rf, compre um módulo AD9833 barato do EBAY. Isso fornecerá ondas senoidal, quadrada e triangular, além de fase variável. Aparentemente, não muito bom passado 7 MHz ....

insira a descrição da imagem aqui


Deve haver uma razão para esses módulos serem muito mais caros que os módulos AD9850. Alguma idéia do porquê?
John La Rooy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.