Come posso generare segnali frequenza / impulsi?


19

Sto cercando dei modi per utilizzare il Raspberry Pi come generatore di segnale. Attualmente sto lavorando per collegare un modulo AD9850 economico da ebay. Ciò genererà frequenze abbastanza precise fino a 40 MHz (70 MHz con AD9851).

inserisci qui la descrizione dell'immagine

Immagino che l'uscita audio possa essere utilizzata anche per forme d'onda arbitrarie fino a una frequenza molto limitata.

Ci sono altre possibilità?

Risposte:


13

Ecco come ho collegato il modulo AD9850 e un semplice programma Python per mostrare come impostare la frequenza su 1000Hz.

L'AD9850 deve funzionare a 5V per funzionare correttamente con il cristallo 125MHz. Sarebbe probabilmente ok cablare 4 pin GPIO direttamente al modulo poiché sono solo ingressi, ma connessione via MCP23017 trasforma efficacemente il modulo in un'altra I²C periferico e si assicura gli ingressi RPI sono sicuri.

Nota importante Informazioni su + 5 V
Il pin + 5 V sul GPIO non può realmente fornire abbastanza corrente per alimentare l'AD9850. È necessario utilizzare un'alimentazione esterna a 5 V.

RPi collegato al modulo AD9850 tramite 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()

È quello il tuo simbolo GPIO di RPi?
Alex Chamberlain,

1
@AlexChamberlain, sì, lo è. Per quanto ne so, l'RPF non ha rilasciato nulla di molto utile a parte l'RP stesso :)
John La Rooy,

Hmm, immagino che questa potrebbe essere una domanda sciocca, ma cos'è un simbolo GPIO?
Steven Lu

@StevenLu, il grande rettangolo a destra dello schema. Il vecchio RPi aveva 26 pin, i più recenti hanno 40 pin. vedi elinux.org/…
John La Rooy,

Oh ok. Sembra molto naturale. Suppongo che tu non abbia disegnato la versione a 40 pin perché hai solo bisogno di 3 di quei pin per lo schema.
Steven Lu,

11

In teoria potresti collegare alcuni convertitori D / A ai pin GPIO ma questo non è adatto per la generazione del segnale perché non sarai in grado di guidarlo con un tempismo preciso, principalmente perché Linux non è un sistema operativo in tempo reale.

Inoltre, non è possibile che funzioni a frequenze così elevate.

Se 44 ​​kHz o giù di lì sono sufficienti, penso che il jack audio possa essere il modo più semplice per farlo.


4

John La Rooy ha una buona soluzione ma il circuito potrebbe essere più complicato di quanto alcuni preferirebbero. Questo descrive una soluzione simile progettata da Tom Herbison usando solo l'AD9850, sebbene utilizzi 4 pin di segnale GPIO anziché 2 come la soluzione di John.

Tom si collega a GPIO in questo modo: schema di collegamento

Si noti che esegue AD9850 su 3,3 V invece che su 5 V. Secondo questa discussione , l'AD9850 è valutato per funzionare a 3,3 V o 5 V, ma alcune schede potrebbero utilizzare componenti non in grado di gestire a lungo 5 V, quindi funzionare a 3,3 V potrebbe effettivamente essere una soluzione migliore, a seconda del sapore della scheda AD9850 .

La mia particolare scheda AD9850 aveva la maggior parte delle etichette dei pin solo sotto la scheda, quindi ho fatto una foto della parte inferiore prima di premerla in una scheda di prototipazione. Le posizioni dei pin finirono per essere identiche a quelle sulla scheda di Tom comunque. Sulla mia lavagna, FQè etichettato FU_UQ, CLKè W_CLKed RSTè RESET.

Tom fornisce questo script Python 3 per il controllo del generatore di funzioni. Ecco una copia di v1.0 nel caso in cui il collegamento per il download si interrompa mai:

# 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()

Poiché qualsiasi utilizzo dei pin GPIO sul pi richiede l'esecuzione come root, Tom descrive due metodi per avviare il suo codice Python con i privilegi di root. Il suo primo metodo è quello di modificare l'icona del desktop IDE di Python in modo che venga sempre eseguita come root, ma ciò mi sembra non sicuro: non è necessario eseguire tutti i programmi della GUI di Python come root se non è necessario. Il secondo metodo consiste nell'eseguire sudo idle3_da un prompt dei comandi per avviare Python 3 Integrated Development Environment con i privilegi di root ogni volta che necessita di privilegi di root.

Tom non menziona l'installazione della libreria RPi.GPIO python 3, quindi potrebbe essere già disponibile su alcune versioni di Pi OS, ma non era disponibile su Occidentalis v0.2 che stavo usando, quindi ho corso sudo apt-get install python3-rpi.gpio. Nota che Python 3 utilizza una posizione diversa per RPi.GPIO, quindi sudo apt-get install python-rpi.gpiorenderà la libreria accessibile solo a Python 2.

Quando l'IDE di Python 3 è aperto con i privilegi di root, apri il file rpi_rfsiggen.py, quindi scegli Run -> Run Moduledal menu o premi F5.

Sono stato in grado di ottenere una bella onda sinusoidale 18kHZ stabile a 1Vpp dal pin di uscita SinB (etichettato ZOUT2sulla mia scheda) al mio primo tentativo.


3

Se vuoi solo implementare un generatore di funzioni per audio e Lf rf, prendi un modulo AD9833 economico da EBAY. Questo ti darà onde sinusoidali, quadrate e triangolari più fase variabile. Apparentemente non molto bene oltre 7 MHz ....

inserisci qui la descrizione dell'immagine


Ci deve essere una ragione per cui quei moduli sono molto più costosi dei moduli AD9850. Qualche idea sul perché?
John La Rooy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.