¿Cómo puedo generar señales de frecuencia / pulso?
19
Estoy buscando formas de usar Raspberry Pi como generador de señal. Actualmente estoy trabajando en conectar un módulo AD9850 económico de eBay. Esto generará frecuencias bastante precisas de hasta 40MHz (70MHz con el AD9851).
Supongo que la salida de audio también podría usarse para formas de onda arbitrarias hasta una frecuencia muy limitada.
Así es como conecté el módulo AD9850 y un simple programa Python para mostrar cómo configurar la frecuencia a 1000Hz.
El AD9850 necesita funcionar a 5V para funcionar correctamente con el cristal de 125MHz. Sería probablemente será aceptable para cablear 4 pines GPIO directamente al módulo ya que son sólo entradas, pero la conexión a través de un MCP23017 convierte efectivamente el módulo en otro I²C periférica y se asegura de las entradas RPI son seguros.
Nota importante sobre + 5V
El pin + 5V en el GPIO realmente no puede suministrar suficiente corriente para alimentar el AD9850. Debe usar un suministro externo de 5V.
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()
@AlexChamberlain, sí lo es. Por lo que puedo decir, el RPF no ha lanzado nada muy útil aparte del RPi en sí :)
John La Rooy
Hmm, supongo que esta podría ser una pregunta tonta, pero ¿qué es un símbolo GPIO?
Steven Lu
@StevenLu, el rectángulo grande a la derecha del esquema. Los viejos RPi tenían 26 pines, los más nuevos tienen 40 pines. ver elinux.org/…
John La Rooy
Ah, vale. Simplemente parece muy natural. Creo que no dibujó la versión de 40 pines porque de todos modos solo necesitaba 3 de esos pines para el diagrama.
Steven Lu
11
En teoría, podría conectar algunos convertidores D / A a pines GPIO, pero esto no es adecuado para la generación de señal porque no podrá conducirlo con una sincronización precisa, principalmente porque Linux no es un sistema operativo en tiempo real.
Además, no hay forma de que esto pueda funcionar a frecuencias tan altas.
Si 44 kHz más o menos es suficiente, creo que el conector de audio puede ser la forma más sencilla de hacerlo.
John La Rooy tiene una buena solución, pero el circuito puede ser más complicado de lo que algunos preferirían. Esto describe una solución similar diseñada por Tom Herbison usando solo el AD9850, aunque usa 4 pines de señal GPIO en lugar de 2 como la solución de John.
Tom se conecta a GPIO así:
Observe que ejecuta el AD9850 en 3.3V en lugar de 5V. Según esta discusión , el AD9850 está calificado para funcionar a 3.3V o 5V, pero algunas placas pueden usar componentes que no pueden manejar 5V por mucho tiempo, por lo que ejecutar a 3.3V puede ser una mejor solución, dependiendo de su sabor de placa AD9850 .
Mi placa AD9850 en particular tenía la mayoría de las etiquetas de clavijas solo debajo de la placa, así que tomé una foto de la parte inferior antes de presionarla en una placa de prototipos. Las ubicaciones de los pin terminaron siendo idénticas a las del tablero de Tom de todos modos. En mi pizarra, FQestá etiquetado FU_UQ, CLKes W_CLKy RSTes RESET.
Tom proporciona este script Python 3 para controlar el generador de funciones. Aquí hay una copia de v1.0 en caso de que el enlace de descarga se rompa:
# 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()
Dado que cualquier uso de los pines GPIO en el pi requiere ejecutarse como root, Tom describe dos métodos para lanzar su código python con privilegios de root. Su primer método es modificar el ícono de escritorio IDE de Python para que siempre se ejecute como root, pero eso me parece inseguro: no es necesario ejecutar todos los programas de la GUI de Python como root si no es necesario. El segundo método es ejecutar sudo idle3_desde un símbolo del sistema para iniciar el entorno de desarrollo integrado de Python 3 con privilegios de root siempre que necesite privilegios de root.
Tom no menciona la instalación de la biblioteca RPi.GPIO python 3, por lo que puede que ya esté disponible en algunas versiones de Pi OS, pero no estaba disponible en el Occidentalis v0.2 que estaba usando, así que corrí sudo apt-get install python3-rpi.gpio. Tenga en cuenta que Python 3 usa una ubicación diferente para RPi.GPIO, por sudo apt-get install python-rpi.gpiolo que solo hará que la biblioteca sea accesible para Python 2.
Una vez que el IDE de Python 3 esté abierto con privilegios de root, abra el archivo rpi_rfsiggen.py, luego elija Run -> Run Moduledel menú o presione F5.
Pude obtener una buena onda sinusoidal estable de 18kHZ a 1Vpp desde el pin de salida SinB (etiquetado ZOUT2en mi placa) en mi primer intento.
Si solo desea implementar un generador de funciones para audio y Lf rf, elija un módulo AD9833 barato de EBAY. Esto le dará ondas sinusoidales, cuadradas y triangulares, más fase variable. Aparentemente no es muy bueno después de 7 MHz ...
En teoría, podría conectar algunos convertidores D / A a pines GPIO, pero esto no es adecuado para la generación de señal porque no podrá conducirlo con una sincronización precisa, principalmente porque Linux no es un sistema operativo en tiempo real.
Además, no hay forma de que esto pueda funcionar a frecuencias tan altas.
Si 44 kHz más o menos es suficiente, creo que el conector de audio puede ser la forma más sencilla de hacerlo.
fuente
John La Rooy tiene una buena solución, pero el circuito puede ser más complicado de lo que algunos preferirían. Esto describe una solución similar diseñada por Tom Herbison usando solo el AD9850, aunque usa 4 pines de señal GPIO en lugar de 2 como la solución de John.
Tom se conecta a GPIO así:
Observe que ejecuta el AD9850 en 3.3V en lugar de 5V. Según esta discusión , el AD9850 está calificado para funcionar a 3.3V o 5V, pero algunas placas pueden usar componentes que no pueden manejar 5V por mucho tiempo, por lo que ejecutar a 3.3V puede ser una mejor solución, dependiendo de su sabor de placa AD9850 .
Mi placa AD9850 en particular tenía la mayoría de las etiquetas de clavijas solo debajo de la placa, así que tomé una foto de la parte inferior antes de presionarla en una placa de prototipos. Las ubicaciones de los pin terminaron siendo idénticas a las del tablero de Tom de todos modos. En mi pizarra,
FQ
está etiquetadoFU_UQ
,CLK
esW_CLK
yRST
esRESET
.Tom proporciona este script Python 3 para controlar el generador de funciones. Aquí hay una copia de v1.0 en caso de que el enlace de descarga se rompa:
Dado que cualquier uso de los pines GPIO en el pi requiere ejecutarse como root, Tom describe dos métodos para lanzar su código python con privilegios de root. Su primer método es modificar el ícono de escritorio IDE de Python para que siempre se ejecute como root, pero eso me parece inseguro: no es necesario ejecutar todos los programas de la GUI de Python como root si no es necesario. El segundo método es ejecutar
sudo idle3_
desde un símbolo del sistema para iniciar el entorno de desarrollo integrado de Python 3 con privilegios de root siempre que necesite privilegios de root.Tom no menciona la instalación de la biblioteca RPi.GPIO python 3, por lo que puede que ya esté disponible en algunas versiones de Pi OS, pero no estaba disponible en el Occidentalis v0.2 que estaba usando, así que corrí
sudo apt-get install python3-rpi.gpio
. Tenga en cuenta que Python 3 usa una ubicación diferente para RPi.GPIO, porsudo apt-get install python-rpi.gpio
lo que solo hará que la biblioteca sea accesible para Python 2.Una vez que el IDE de Python 3 esté abierto con privilegios de root, abra el archivo
rpi_rfsiggen.py
, luego elijaRun -> Run Module
del menú o presione F5.Pude obtener una buena onda sinusoidal estable de 18kHZ a 1Vpp desde el pin de salida SinB (etiquetado
ZOUT2
en mi placa) en mi primer intento.fuente
Si solo desea implementar un generador de funciones para audio y Lf rf, elija un módulo AD9833 barato de EBAY. Esto le dará ondas sinusoidales, cuadradas y triangulares, más fase variable. Aparentemente no es muy bueno después de 7 MHz ...
fuente