#!/usr/bin/env python import pyglet #import math #import time import serial import numpy from colours import * datafeed = serial.Serial( port='/dev/ttyUSB0', baudrate = 9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1 ) class Series: def __init__(self, points=100, title="Series title", xname="x-axis name", yname="y-axis name"): self.title = title self.xname = xname self.yname = yname self.data = [] self.points = points def addpoint(self, point): self.data.append(point) if len(self.data) > self.points: del self.data[0] class Plot(pyglet.window.Window): def __init__(self, series): """Setup a the details of a plot, and create a corresponding window""" pyglet.window.Window.__init__(self, resizable=True) self.series = series self.font = 'Arkhip' self.margins = (0.08, 0.08) # Fractions of window size self.lines = (12, 8) #self.resizable = True self.set_caption(self.series.title) def on_resize(self, width, height): self.bounds = ((int(self.width * self.margins[0]), int(self.width * (1 - self.margins[0]))), (int(self.height * self.margins[1]), int(self.height * (1 - self.margins[1])))) pyglet.window.Window.on_resize(self, width, height) def on_draw(self): """Draw all the components of the graph""" self.drawBackground() self.drawHeading() self.drawXAxis() self.drawYAxis() def drawBackground(self): """Draw the graph background, currently a plain colour""" pyglet.image.SolidColorImagePattern(WHITE).create_image(self.width, self.height).blit(0, 0) def drawHeading(self): """Draw a title for the graph (duplicated in the window titlebar, if present""" heading = pyglet.text.Label(self.series.title, color=BLACK, font_name=self.font, font_size=self.height*self.margins[0]*0.6, x=self.width/2, y=self.height, anchor_x='center', anchor_y='top') heading.draw() def drawXAxis(self): top = self.bounds[1][1] bot = self.bounds[1][0] start = self.bounds[0][0] stop = self.bounds[0][1] increment = float(stop-start)/self.lines[0] for x in numpy.arange(start, stop+1, increment): # Using fp arithmetic to avoid intermittent fencepost errors x = int(x) pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (x, top, x, bot)), ('c3B', (0, 0, 0, 0, 0, 0))) tag = pyglet.text.Label("123", color=BLACK, font_name=self.font, font_size=self.height*self.margins[0]*0.3, x=x, y=self.height*self.margins[0], anchor_x='center', anchor_y='top') tag.draw() axistitle = pyglet.text.Label(self.series.xname, color=BLACK, font_name=self.font, font_size=self.height*self.margins[0]*0.3, x=self.width/2, y=0, anchor_x='center', anchor_y='bottom') axistitle.draw() def drawYAxis(self): lef = self.bounds[0][0] rig = self.bounds[0][1] start = self.bounds[1][0] stop = self.bounds[1][1] increment = float(stop-start)/self.lines[1] for y in numpy.arange(start, stop+1, increment): # Using fp arithmetic to avoid intermittent fencepost errors y = int(y) pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (lef, y, rig, y)), ('c3B', (0, 0, 0, 0, 0, 0))) testseries = Series() plots = [] plots.append(Plot(testseries)) def pollSerial(elapsed): """Check serial port for incoming data""" # Note, elapsed is time since last call of this function values = datafeed.readline().strip().split(", ") testseries.addpoint(values) pyglet.clock.schedule_interval(pollSerial, 0.1) pyglet.app.run()