How to Make an Oscilloscope in Python
Oscilloscopes are used to measure the intervals of different kinds of waves and electrical signals. Their readings help provide researchers within insight into the frequency and strength of waves emitted from electrical devices and other sources. For the hardware in an oscilloscope to work, it needs to be connected to a software program that interprets the readings and displays them in a graph.
Instructions
-
-
1
Open a code editing application or use a text editing application such as TextEdit in Mac OS X or Notepad in Microsoft Windows. Create a new document to house the script of the Python oscilloscope.
-
2
Define the parameters that will be used in the script, as well as the two Python libraries needed for the script by using the following code:
import os, sys
import Image
import serial
import pygame
import timefrom pyBusPirateLite.UART import *
from pyBusPirateLite.BitBang import * -
-
3
Define the data rate and use the print function to enable the program to graph the inputs made by the oscilloscope:
DATA_RATE = 5720.0 #measures/second (estimated experimenticaly)
DEFAULT_TIME_SCALE = RES_X / DATA_RATE #default time in seconds to make one window fill
pygame.init()
bp = UART(BUS_PIRATE_DEV,115200)
print "Entering binmode: ",
if bp.BBmode():
print "OK."
else:
print "failed."
sys.exit() -
4
Define the parameters for the application window by using the pygame.display function:
window = pygame.display.set_mode((RES_X, RES_Y))
background = (0,0,0)
line = (0,255,0)
trig_color = (100,100,0) -
5
Create the script for the oscilloscope itself by defining the parameters that will be written on the graph and providing arguments for the x and y-axis:
bp.port.write("\x15")
while 1:
plot = {}
voltage = {}
maxv = 0
minv = 100
time_scale = DEFAULT_TIME_SCALE * time_div
prev_voltage = 0
measure = 0;
if(trig_mode != NO_SYNC):
for k in range(1,2000):
prev_voltage = voltage
measure = bp.response(2, True)
voltage = ord(measure[0]) << 8
voltage = voltage + ord(measure[1])
voltage = (voltage/1024.0) * 6.6
#rising slope
if((voltage >= trigger_level) and (prev_voltage < (voltage * TRIG_CAL)) and (trig_mode == RISING_SLOPE)):
break
if((voltage < trigger_level) and (voltage > 0.01) and (prev_voltage > voltage/TRIG_CAL) and (trig_mode == FALLING_SLOPE)):
break
for i in range(RES_X):
for k in range(time_div - 1):
#ignoring (time_div-1) samples to achieve proper time resolution
bp.response(2, True)
measure = bp.response(2, True)
voltage = ord(measure[0]) << 8
voltage = voltage + ord(measure[1])
voltage = (voltage/1024.0) * 6.6
plot[i] = voltage
for i in range(1,RES_X):
if plot[i] > maxv:
maxv = plot[i]
if plot[i] < minv:
minv = plot[i]
y = (RES_Y) - plot[i]*(RES_Y/MAX_VOLTAGE) - OFFSET
x = i
px = i-1;
py = (RES_Y) - plot[i-1]*(RES_Y/MAX_VOLTAGE) - OFFSET
pygame.draw.line(window, line, (px, py), (x, y))
trig_y = RES_Y - trigger_level * (RES_Y/MAX_VOLTAGE)
pygame.draw.line(window, trig_color, (0, trig_y), (RES_X, trig_y)) -
6
Finalize the oscilloscope by defining the parameters for the oscilloscope's graphical user interface:
##GUI)
font = pygame.font.Font(None, 19)
text_max_voltage = font.render("Max: %f V" % maxv, 1, (255, 255, 255))
text_min_voltage = font.render("Min: %f V" % minv, 1, (255, 255, 255))
text_time_scale = font.render("Timescale: %f s" % time_scale, 1, (255, 255, 255))
text_maxv_Rect = text_max_voltage.get_rect()
text_minv_Rect = text_min_voltage.get_rect()
text_time_scale_Rect = text_time_scale.get_rect()
text_maxv_Rect.x = 10
text_maxv_Rect.y = 10
text_minv_Rect.x = 10
text_minv_Rect.y = 30
text_time_scale_Rect.x = 10
text_time_scale_Rect.y = 50
window.blit(text_max_voltage, text_maxv_Rect)
window.blit(text_min_voltage, text_minv_Rect)
window.blit(text_time_scale, text_time_scale_Rect)
-
1