
Raspberry Oszilloskop
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry
Übliche
Oszilloskope im Elektronik-Labor können schnelle Änderungen bis in
den MHz-Bereich aufzeichnen und haben Empfindlichkeiten bis hinunter zu
wenigen mV. Solche Daten sind mit dem einfachen AD-Wandler für den
Raspberry natürlich nicht zu erreichen. Aber es ist eine interessante
Aufgabe, das Beste herauszuholen.
Grundlage des Oszilloskops ist der einfache AD-Wandler.
Allerdings muss die Messung möglichst schnell durchgeführt werden,
damit eine brauchbare zeitliche Auflösung entsteht. Das in Python
programmierte Oszilloskop hat 25 mal 10 Kästchen mit einer Auflösung
von einer Sekunde in x-Richtung und einem Volt in y-Richtung. In jeder
Sekunde werden 20 Einzelmessungen durchgeführt auf aufgezeichnet. Die
Null-Linie liegt in der Mitte. Damit wird der volle Messbereich von -5
V bis + 5V dargestellt. Die Anzeige erfolgt in Echtzeit, sodass
man beobachten kann, wie sich das Oszillogramm in 25 Sekunden aufbaut.
Für
die Ausgabe wird ein Canvas-Element mit einem Rechteck von 500 mal 200
Pixeln verwendet. Beim Start werden alle Hilfslinien und die grüne
Nulllinie eingezeichnet. Dann werden 500 Messwerte erfasst und
dargestellt. Für jeden Messpunkt wird eine AD-Wandlung mit 10.000
Vergleichen durchgeführt, was etwa 50 ms dauert. Das Oszillogramm wird
aus Linienelementen aufgebaut. Der jeweilige Anfangspunkt muss in
den globalen Variablen x1 und y1 geführt werden, damit er beim jeweils
folgenden Aufruf der Funktion scope(cv) bekannt ist.
Die
Funktion scope(cv) zeichnet 500 Linienelemente und ruft sich jeweils
mit einer Verzögerung von nur einer Millisekunde wieder auf. Fast die
gesamte Rechenzeit wird für die AD-Wandlung gebraucht. Damit ergibt
sich die erforderliche Verzögerung von 50 ms/Messpunkt. Nur am Ende der
Messung wartet das Programm 2000 ms, damit man genügend Zeit hat, das
gesamte Oszillogramm zu sehen. Der AD-Wandler kann kalibriert werden
indem man die konstanten Spannungen 0 V und 3,3 V misst.
Das Programm stammt aus dem Franzis-Lernpaket Raspberry Pi Maker Kit Elektronik.
Es wurde ursprünglich für den Raspberry Pi 2 entwickelt, läuft aber
auch auf dem Zero. Ein Test mit dem Raspberry Pi 3 zeigte dann, dass es
da noch glatter läuft, einfacher weil der Rpi3 noch schneller ist. Im
Moment ist mein Rpi3 allerdings meist mit einer anderen Aufgabe belegt:
Als Kurzwellensender für WSPR-Signale. Deshalb ist der Rpi2 weiterhin als Messlabor aktiv.
#Tk_ADC9_11oszi1.py Oszilloskop 1s/Skt, 1V/Skt
from Tkinter import *
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(9, GPIO.OUT)
GPIO.setup(11, GPIO.IN)
global x1
x1=0
global y1
def scope(cv):
global x1
global y1
if x1==0:
cv.create_rectangle(1, 1, 500, 200, fill="white")
for n in range (10):
cv.create_line(1, n*20, 500, n*20, fill = "grey")
for n in range (25):
cv.create_line( n*20, 1, n*20, 200, fill = "grey")
cv.create_line(1, 100, 500, 100, fill = "green")
while not GPIO.input(11):
GPIO.output(9, 1)
u1=0
u2=0
for i in range(10000):
if GPIO.input(11):
GPIO.output(9, 0)
u1=u1+1
else:
GPIO.output(9, 1)
u2=u2+1
GPIO.output(9, 0)
u=u1-u2
u=u*1000 #Endwert kalibrieren
u=u/100000
u=u+1 #Nullpunkt kalibrieren
u=u+100
y2=u
x2=x1+1
if x1>0:
cv.create_line(x1, 200-y1, x2, 200-y2, fill = "black")
y1=y2
x1=x1+1
if x1<500:
cv.after(1, scope, cv)
if x1>499:
x1=0
cv.after(2000, scope, cv)
root = Tk()
root.title("Oszilloskop GPIO 9/11")
cv = Canvas(root, width=502, height=202)
cv.pack()
cv.create_rectangle(1, 1, 500, 200, fill="white")
cv.create_line(1, 100, 500, 100, fill = "green")
w = Label(root, text="1V/Skt 1s/Skt")
w.pack()
scope(cv)
mainloop()
Verbesserungsvorschlag von Frank Behlich
Es
geht darum, die Systembelastung zu verringern. Falls jemand Problem mit
dem Oszilloskop beobachtet, sollte er diese Version testen, bei der
Linien nicht nur erzeugt sondern auch wieder gelöscht werden.
#Tk_ADC9_11oszi1.py Oszilloskop 1s/Skt, 1V/Skt
import Tkinter as tk
from random import randint
#import RPi.GPIO as GPIO
#GPIO.setwarnings(False)
#GPIO.setmode(GPIO.BCM)
#GPIO.setup(9, GPIO.OUT)
step_x = 5
def scope(cv, x, step_x, id):
def measure_point():
#while not GPIO.input(11):
# GPIO.output(9, 1)
#u1=0
#u2=0
#for i in range(10000):
#if GPIO.input(11):
#GPIO.output(9, 0)
#u1=u1+1
#else:
#GPIO.output(9, 1)
#u2=u2+1
#GPIO.output(9,0)
u1 = randint(0, 5000)
u2 = randint(0, 5000)
u = 200 - (((u1 - u2) * 1000 / 100000) + 100)
return u
if x < 500:
if id:
last_y = cv.coords(id)[-1]
else:
cv.delete("line_point")
last_y = 100
x += step_x
id = cv.create_line(x-step_x, last_y , x, measure_point(), fill = "black", tag="line_point", width=2)
else:
x = 0
id = None
cv.after(10, scope, cv, x, step_x, id)
root = tk.Tk()
root.title("Oszilloskop GPIO 9/11")
cv = tk.Canvas(root, width=500, height=200, bg="white")
cv.pack(padx=5, pady=5)
for n in xrange (10):
cv.create_line(1, n*20, 500, n*20, fill = "lightblue")
for n in xrange (25):
cv.create_line( n*20, 1, n*20, 200, fill = "lightblue")
cv.create_line(1, 100, 500, 100, fill = "lightgreen")
tk.Label(root, text="1V/Skt 1s/Skt").pack()
scope(cv, 0, step_x, None)
tk.mainloop()
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry