Compare View
Commits (5)
-
…wake of the latest live-plot demo work
-
…Code runs, but lines do not appear!
Showing
7 changed files
Show diff stats
robots/little_john/telemetry/code/monitor/version1/colours.py
robots/little_john/telemetry/code/monitor/version1/getdata.py
0 → 100644
... | ... | @@ -0,0 +1,46 @@ |
1 | +# Functions to process data coming in from a serial data stream | |
2 | +# Written as a telemetry tool by: | |
3 | +# The UoN Robot Wars Project, 2018 | |
4 | + | |
5 | +import logging | |
6 | +import os | |
7 | +import time | |
8 | +import serial | |
9 | + | |
10 | + | |
11 | +def getData(starttime, datafeed, testseries, testseries2, fake=False): | |
12 | + """Check serial port for incoming data""" | |
13 | + # Note: 'elapsed' is time since last call of this function | |
14 | + # This works, but it might be better for performance to have two | |
15 | + # seperate functions, only one of which is run. | |
16 | + if fake: | |
17 | + timefromstart = (time.time()-starttime) | |
18 | + values = [timefromstart, 100*math.sin(timefromstart)] | |
19 | + # logging.info("Generated test data: " + str(values)) | |
20 | + testseries.addpoint(values) | |
21 | + testseries2.addpoint(values) | |
22 | + else: | |
23 | + try: | |
24 | + incoming = datafeed.readline() | |
25 | + except: | |
26 | + logging.error("Failed to read input data") | |
27 | + | |
28 | + try: | |
29 | + if os == 'Windows': | |
30 | + values = incoming.strip().split(b", ") | |
31 | + else: | |
32 | + values = incoming.strip() | |
33 | + values = values.split(b', ') | |
34 | + except: | |
35 | + logging.error("Failed to parse input data") | |
36 | + return | |
37 | + | |
38 | + try: | |
39 | + for n, value in enumerate(values): | |
40 | + values[n] = float(value) | |
41 | + except: | |
42 | + logging.error("Failed to convert input to float") | |
43 | + return | |
44 | + # logging.info("Recieved data: " + str(values)) | |
45 | + testseries.addpoint([time.time()-starttime] + values) | |
46 | + testseries2.addpoint(values) | ... | ... |
robots/little_john/telemetry/code/monitor/version1/main.py
... | ... | @@ -9,7 +9,6 @@ |
9 | 9 | |
10 | 10 | import math |
11 | 11 | import time |
12 | -#import serial | |
13 | 12 | |
14 | 13 | import pyglet |
15 | 14 | import numpy |
... | ... | @@ -23,6 +22,7 @@ from serialselect import selectserial |
23 | 22 | from colours import * |
24 | 23 | from series import Series |
25 | 24 | from plot import Plot |
25 | +from getdata import getData | |
26 | 26 | |
27 | 27 | logging.basicConfig(format='%(levelname)s:\t%(message)s', level=logging.DEBUG) |
28 | 28 | logging.info("Logging system active") |
... | ... | @@ -30,42 +30,40 @@ starttime = time.time() |
30 | 30 | |
31 | 31 | datafeed = selectserial() |
32 | 32 | |
33 | -if datafeed == None: | |
33 | +if datafeed is None: | |
34 | 34 | logging.critical("Failed to open serial port") |
35 | 35 | sys.exit() |
36 | - | |
37 | -if platform.system()=='Windows': | |
38 | - os='Windows' | |
36 | + | |
37 | +if platform.system() == 'Windows': | |
38 | + os = 'Windows' | |
39 | 39 | else: |
40 | - os='Other' | |
40 | + os = 'Other' | |
41 | 41 | logging.info('OS = ' + os) |
42 | 42 | |
43 | -testseries = Series(points=150, title="Sine wave demo", xname="Time (s)", yname="100sin(t)") | |
43 | + | |
44 | +testseries = Series(points=150, xauto=True, ylimits=(0, 1024), | |
45 | + title="Data from serial (time)", | |
46 | + xname="Time (s)", yname="ADC output") | |
47 | +testseries2 = Series(points=150, xlimits=(0, 1024), ylimits=(0, 1024), | |
48 | + title="Data from serial (xy)", | |
49 | + xname="ADC0 output", yname="ADC7 output") | |
50 | + | |
44 | 51 | plots = [] |
45 | 52 | plots.append(Plot(testseries)) |
53 | +plots.append(Plot(testseries2)) | |
54 | + | |
55 | + | |
56 | +def shrubbery(ni): | |
57 | + """ Yes I know these are absurd placeholder names. I'm leaving it like | |
58 | + that for the moment because I'm not sure if this is really the only | |
59 | + (or best) way to achive the desired result. clock.schedule_interval takes | |
60 | + a function, not the result of the function as its argument, so how can | |
61 | + you pass arguments to it? """ | |
62 | + getData(starttime, datafeed, testseries, testseries2) | |
63 | + | |
46 | 64 | |
47 | -def pollSerial(elapsed): | |
48 | - """Check serial port for incoming data""" | |
49 | - # Note: 'elapsed' is time since last call of this function | |
50 | - # This works, but it might be better for performance to have two seperate functions, only one of which is run. | |
51 | - if os=='Windows': | |
52 | - values = datafeed.readline().strip().split(b", ") | |
53 | - else: | |
54 | - values = datafeed.readline().strip() | |
55 | - values = values.split(b', ') | |
56 | - for n, value in enumerate(values): | |
57 | - values[n] = float(value) | |
58 | - #logging.info("Recieved data: " + str(values)) | |
59 | - testseries.addpoint(values) | |
60 | - | |
61 | -def fakePollSerial(elapsed): | |
62 | - """This function immitates the behaviour of pollSerial, for testing purposes""" | |
63 | - timefromstart = (time.time()-starttime) | |
64 | - values = [timefromstart, 100*math.sin(timefromstart)] | |
65 | - #logging.info("Generated test data: " + str(values)) | |
66 | - testseries.addpoint(values) | |
67 | - | |
68 | -# Pyglet looks after the main event loop, but this ensures that data keeps being read in | |
69 | -pyglet.clock.schedule_interval(fakePollSerial, 0.04) | |
65 | +# Pyglet looks after the main event loop, | |
66 | +# but this ensures that data keeps being read | |
67 | +pyglet.clock.schedule_interval(shrubbery, 0.01) | |
70 | 68 | |
71 | 69 | pyglet.app.run() | ... | ... |
robots/little_john/telemetry/code/monitor/version1/plot.py
... | ... | @@ -7,31 +7,38 @@ import numpy |
7 | 7 | import logging |
8 | 8 | from colours import * |
9 | 9 | |
10 | + | |
10 | 11 | class Plot(pyglet.window.Window): |
11 | 12 | def __init__(self, series): |
12 | 13 | """Setup a the details of a plot, and create a corresponding window""" |
13 | 14 | pyglet.window.Window.__init__(self, resizable=True) |
14 | 15 | self.set_icon(pyglet.image.load('32x32.png')) |
15 | - self.set_minimum_size(320,320) | |
16 | + self.set_minimum_size(320, 320) | |
16 | 17 | self.series = series |
17 | 18 | self.font = 'Arkhip' |
18 | - self.margins = (0.09, 0.08) # Fractions of window size | |
19 | + self.margins = (0.09, 0.08) # Fractions of window size | |
19 | 20 | self.lines = (10, 8) |
20 | - #self.resizable = True | |
21 | + # self.resizable = True | |
21 | 22 | self.set_caption(self.series.title) |
22 | 23 | |
23 | 24 | def on_resize(self, width, height): |
24 | 25 | """Handle a resize event from the pyglet event loop""" |
25 | 26 | try: |
26 | - self.bounds = ((int(self.width * self.margins[0]), int(self.width * (1 - self.margins[0]))), | |
27 | - (int(self.height * self.margins[1]), int(self.height * (1 - self.margins[1])))) | |
27 | + self.bounds = ((int(self.width * self.margins[0]), | |
28 | + int(self.width * (1 - self.margins[0]))), | |
29 | + (int(self.height * self.margins[1]), | |
30 | + int(self.height * (1 - self.margins[1])))) | |
28 | 31 | except Exception as e: |
29 | 32 | logging.critical(str(e)) |
30 | 33 | self.close() |
31 | 34 | logging.critical('Instance closed') |
32 | 35 | sys.exit() |
33 | - self.tag_size = min(self.height*self.margins[1]*0.3,self.width*self.margins[0]*0.3) | |
34 | - # This sometimes seems to throw an error ('AttributeError: 'Plot' object has no attribute 'margins') when started for a second time from the same instance. Interesting. Causes the plot windows to freeze | |
36 | + self.tag_size = min(self.height*self.margins[1]*0.3, | |
37 | + self.width*self.margins[0]*0.3) | |
38 | + # This sometimes seems to throw an error | |
39 | + # ('AttributeError: 'Plot' object has no attribute 'margins') | |
40 | + # when started for a second time from the same instance. | |
41 | + # Interesting. Causes the plot windows to freeze | |
35 | 42 | pyglet.window.Window.on_resize(self, width, height) |
36 | 43 | |
37 | 44 | def on_draw(self): |
... | ... | @@ -40,46 +47,60 @@ class Plot(pyglet.window.Window): |
40 | 47 | self.drawHeading() |
41 | 48 | self.drawAxis(0) |
42 | 49 | self.drawAxis(1) |
43 | - self.drawLine(self.series) | |
50 | + self.drawLines(self.series) | |
44 | 51 | |
45 | 52 | def drawBackground(self): |
46 | 53 | """Draw the graph background, currently a plain colour""" |
47 | - pyglet.image.SolidColorImagePattern(WHITE).create_image(self.width, self.height).blit(0, 0) | |
54 | + #whitepattern = pyglet.image.SolidColorImagePattern(WHITE) | |
55 | + #whitepattern.create_image(self.width, self.height).blit(0, 0) | |
56 | + pyglet.image.SolidColorImagePattern(RED).create_image(self.width, self.height).blit(0, 0) | |
48 | 57 | |
49 | 58 | def drawHeading(self): |
50 | - """Draw a title for the graph (duplicated in the window titlebar, if present""" | |
59 | + """Draw a title for the graph (duplicated in the window titlebar""" | |
51 | 60 | heading = pyglet.text.Label(self.series.title, color=BLACK, |
52 | - font_name=self.font, font_size=self.height*self.margins[0]*0.5, | |
53 | - x=self.width/2, y=self.height-(self.margins[1]), | |
54 | - anchor_x='center', anchor_y='top') | |
61 | + font_name=self.font, | |
62 | + font_size=self.height*self.margins[0]*0.5, | |
63 | + x=self.width/2, | |
64 | + y=self.height-(self.margins[1]), | |
65 | + anchor_x='center', anchor_y='top') | |
55 | 66 | heading.draw() |
56 | 67 | |
57 | - def drawLine(self, series): | |
58 | - xscale = float(self.series.xlimits[1]-self.series.xlimits[0])/(self.bounds[0][1]-self.bounds[0][0]) | |
59 | - yscale = float(self.series.ylimits[1]-self.series.ylimits[0])/(self.bounds[1][1]-self.bounds[1][0]) | |
68 | + def drawLines(self, series): | |
69 | + xscale = float(self.series.xlimits[1]-self.series.xlimits[0] / (self.bounds[0][1]-self.bounds[0][0])) | |
70 | + yscale = float(self.series.ylimits[1]-self.series.ylimits[0] / (self.bounds[1][1]-self.bounds[1][0])) | |
71 | + | |
60 | 72 | lmar = int(self.width * self.margins[0]) |
61 | 73 | rmar = int(self.width * self.margins[1]) |
62 | 74 | tmar = int(self.height * self.margins[0]) |
63 | 75 | bmar = int(self.height * self.margins[1]) |
64 | - | |
76 | + | |
65 | 77 | pyglet.gl.glLineWidth(2) |
66 | - | |
67 | - for n in range(len(series.data) - 1): | |
68 | - x1, y1 = series.data[n][0]-series.xlimits[0], series.data[n][1]-series.ylimits[0] | |
69 | - x2, y2 = series.data[n+1][0]-series.xlimits[0], series.data[n+1][1]-series.ylimits[0] | |
70 | - x1 = int((x1/xscale)+lmar) | |
71 | - y1 = int((y1/yscale)+bmar) | |
72 | - x2 = int((x2/xscale)+lmar) | |
73 | - y2 = int((y2/yscale)+bmar) | |
74 | - pyglet.graphics.draw(2, pyglet.gl.GL_LINES, | |
75 | - ('v2i', (x1, y1, x2, y2)), | |
76 | - ('c3B', (255, 0, 0, 255, 0, 0))) | |
77 | - pyglet.gl.glLineWidth(1) | |
78 | 78 | |
79 | + linecolours = [(255, 0, 0, 255, 0, 0), | |
80 | + (0, 220, 0, 0, 220, 0), | |
81 | + (0, 0, 255, 0, 0, 255)] | |
79 | 82 | |
83 | + try: | |
84 | + for m in range(len(series.data[0])-1): | |
85 | + for n in range(len(series.data) - 1): | |
86 | + x1 = series.data[n][0]-series.xlimits[0] | |
87 | + y1 = series.data[n][m+1]-series.ylimits[0] | |
88 | + x2 = series.data[n+1][0]-series.xlimits[0] | |
89 | + y2 = series.data[n+1][m+1]-series.ylimits[0] | |
90 | + x1 = int((x1/xscale)+lmar) | |
91 | + y1 = int((y1/yscale)+bmar) | |
92 | + x2 = int((x2/xscale)+lmar) | |
93 | + y2 = int((y2/yscale)+bmar) | |
94 | + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, | |
95 | + ('v2i', (x1, y1, x2, y2)), | |
96 | + ('c3B', linecolours[m])) | |
97 | + except: | |
98 | + logging.error("Failed to plot lines: corrupt/missing data?") | |
99 | + | |
100 | + pyglet.gl.glLineWidth(1) | |
80 | 101 | |
81 | - def drawAxis(self, axis): # axis=0 is x, 1 is y | |
82 | - """Draw the gridlines and labels for one axis, specified in the last argument""" | |
102 | + def drawAxis(self, axis): # axis=0 is x, 1 is y | |
103 | + """Draw gridlines & labels for one axis, specified as an argument""" | |
83 | 104 | limita = self.bounds[1-axis][1] |
84 | 105 | limitb = self.bounds[1-axis][0] |
85 | 106 | start = self.bounds[axis][0] |
... | ... | @@ -88,37 +109,49 @@ class Plot(pyglet.window.Window): |
88 | 109 | for pos in numpy.arange(start, stop+1, increment): |
89 | 110 | # Using fp arithmetic to avoid intermittent fencepost errors |
90 | 111 | pos = int(pos) |
91 | - if axis==0: # x axis, vertical lines | |
92 | - scale = float(self.series.xlimits[1]-self.series.xlimits[0])/(stop-start) | |
112 | + if axis == 0: # x axis, vertical lines | |
113 | + scale = float(self.series.xlimits[1]-self.series.xlimits[0]) | |
114 | + scale /= (stop-start) | |
93 | 115 | tagvalue = ((pos-start) * scale) + self.series.xlimits[0] |
94 | 116 | tagtext = str(int(tagvalue)) |
95 | - pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (pos, limita, pos, limitb)), | |
96 | - ('c3B', (0, 0, 0, 0, 0, 0))) | |
117 | + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, | |
118 | + ('v2i', (pos, limita, pos, limitb)), | |
119 | + ('c3B', (0, 0, 0, 0, 0, 0))) | |
97 | 120 | tag = pyglet.text.Label(tagtext, color=BLACK, |
98 | - font_name=self.font, font_size=self.tag_size, | |
121 | + font_name=self.font, | |
122 | + font_size=self.tag_size, | |
99 | 123 | x=pos, y=self.height*self.margins[1], |
100 | 124 | anchor_x='left', anchor_y='top') |
101 | 125 | axistitle = pyglet.text.Label(self.series.xname, color=BLACK, |
102 | - font_name=self.font, font_size=self.tag_size, | |
103 | - x=self.width/2, y=0, | |
104 | - anchor_x='center', anchor_y='bottom') | |
126 | + font_name=self.font, | |
127 | + font_size=self.tag_size, | |
128 | + x=self.width/2, y=0, | |
129 | + anchor_x='center', | |
130 | + anchor_y='bottom') | |
105 | 131 | axistitle.draw() |
106 | - if axis==1: # y axis, horizontal lines | |
107 | - scale = float(self.series.ylimits[1]-self.series.ylimits[0])/(stop-start) | |
132 | + if axis == 1: # y axis, horizontal lines | |
133 | + scale = float(self.series.ylimits[1]-self.series.ylimits[0]) | |
134 | + scale /= (stop-start) | |
108 | 135 | tagvalue = ((pos-start) * scale) + self.series.ylimits[0] |
109 | 136 | tagtext = str(int(tagvalue)) |
110 | - pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2i', (limita, pos, limitb, pos)), | |
111 | - ('c3B', (0, 0, 0, 0, 0, 0))) | |
137 | + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, | |
138 | + ('v2i', (limita, pos, limitb, pos)), | |
139 | + ('c3B', (0, 0, 0, 0, 0, 0))) | |
112 | 140 | tag = pyglet.text.Label(tagtext, color=BLACK, |
113 | - font_name=self.font, font_size=self.tag_size, | |
114 | - x=self.width*self.margins[0]*0.9, y=pos, | |
141 | + font_name=self.font, | |
142 | + font_size=self.tag_size, | |
143 | + x=self.width*self.margins[0]*0.9, | |
144 | + y=pos, | |
115 | 145 | anchor_x='right', anchor_y='center') |
116 | 146 | axistitle = pyglet.text.Label(self.series.yname, color=BLACK, |
117 | - font_name=self.font, font_size=self.tag_size, | |
118 | - x=0, y=self.height/2, | |
119 | - anchor_x='center', anchor_y='top') | |
120 | - pyglet.gl.glPushMatrix() # Set up a new context to avoid confusing the main one | |
121 | - # Tranformation to rotate label, and ensure it ends up in the right place | |
147 | + font_name=self.font, | |
148 | + font_size=self.tag_size, | |
149 | + x=0, y=self.height/2, | |
150 | + anchor_x='center', | |
151 | + anchor_y='top') | |
152 | + # Set up a new context to avoid confusing the main one | |
153 | + pyglet.gl.glPushMatrix() | |
154 | + # Tranformation to move label to the right place | |
122 | 155 | pyglet.gl.glTranslatef(self.height//2, self.height//2, 0.0) |
123 | 156 | pyglet.gl.glRotatef(90.0, 0.0, 0.0, 1.0) |
124 | 157 | # Draw the axis title using the rotated coordinate system | ... | ... |
robots/little_john/telemetry/code/monitor/version1/serialselect.py
... | ... | @@ -2,27 +2,29 @@ |
2 | 2 | # Written as a telemetry tool by: |
3 | 3 | # The UoN Robot Wars Project, 2018 |
4 | 4 | |
5 | + | |
5 | 6 | def selectserial(): |
6 | - """Cross-platform function to find appropriate serial ports, query the user if necessary, and open one of them""" | |
7 | + """Cross-platform function to find appropriate serial ports, query the | |
8 | + user if necessary, and open one of them""" | |
7 | 9 | import platform |
8 | 10 | import serial |
9 | 11 | import os |
10 | 12 | import easygui |
11 | 13 | import logging |
12 | - | |
14 | + | |
13 | 15 | devpatterns = ['ttyACM', 'ttyUSB', 'rfcomm'] |
14 | 16 | targetdevs = [] |
15 | - if platform.system()=='Windows': | |
17 | + if platform.system() == 'Windows': | |
16 | 18 | com_ports = ['COM%s' % (i + 1) for i in range(256)] |
17 | 19 | for port in com_ports: |
18 | 20 | try: |
19 | 21 | s = serial.Serial(port) |
20 | 22 | s.close() |
21 | 23 | targetdevs.append(port) |
22 | - # Temporarily broadened exception in attempt to make this work on uni PCs | |
23 | - except: # (OSError, serial.SerialException): | |
24 | + # Temporarily broadened exception to make this work on uni PCs | |
25 | + except: # (OSError, serial.SerialException): | |
24 | 26 | pass |
25 | - os='Windows' #may be useful | |
27 | + os = 'Windows' # may be useful | |
26 | 28 | else: |
27 | 29 | alldevs = os.listdir("/dev/") |
28 | 30 | targetdevs = [] |
... | ... | @@ -30,7 +32,7 @@ def selectserial(): |
30 | 32 | for pattern in devpatterns: |
31 | 33 | if pattern in dev: |
32 | 34 | targetdevs.append("/dev/" + dev) |
33 | - os='Other' #may be useful | |
35 | + os = 'Other' # may be useful | |
34 | 36 | |
35 | 37 | if len(targetdevs) == 0: |
36 | 38 | logging.info("No serial device found.") |
... | ... | @@ -42,22 +44,22 @@ def selectserial(): |
42 | 44 | message = "Please choose a serial port to recieve data through:" |
43 | 45 | title = "Found multiple serial ports!" |
44 | 46 | serialport = easygui.choicebox(message, title, targetdevs) |
45 | - if serialport == None: | |
47 | + if serialport is None: | |
46 | 48 | logging.info("User cancelled selection dialogue") |
47 | 49 | return None |
48 | 50 | else: |
49 | 51 | logging.info("Only found one likely serial device: " + targetdevs[0]) |
50 | 52 | serialport = targetdevs[0] |
51 | - | |
53 | + | |
52 | 54 | try: |
53 | 55 | datafeed = serial.Serial( |
54 | - port=serialport, | |
55 | - baudrate = 9600, | |
56 | - parity=serial.PARITY_NONE, | |
57 | - stopbits=serial.STOPBITS_ONE, | |
58 | - bytesize=serial.EIGHTBITS, | |
59 | - timeout=1 | |
60 | - ) | |
56 | + port=serialport, | |
57 | + baudrate=9600, | |
58 | + parity=serial.PARITY_NONE, | |
59 | + stopbits=serial.STOPBITS_ONE, | |
60 | + bytesize=serial.EIGHTBITS, | |
61 | + timeout=1 | |
62 | + ) | |
61 | 63 | |
62 | 64 | logging.info("Sucessfully opened " + serialport + " as data source!") |
63 | 65 | return datafeed | ... | ... |
robots/little_john/telemetry/code/monitor/version1/series.py
... | ... | @@ -4,8 +4,12 @@ |
4 | 4 | |
5 | 5 | import logging |
6 | 6 | |
7 | + | |
7 | 8 | class Series: |
8 | - def __init__(self, points=100, title="Series title", xname="x-axis name", yname="y-axis name"): | |
9 | + def __init__(self, points=100, xlimits=(0, 100), ylimits=(0, 100), | |
10 | + xauto=False, yauto=False, | |
11 | + title="Series title", | |
12 | + xname="x-axis name", yname="y-axis name"): | |
9 | 13 | """Set up an object to store a 2D data series""" |
10 | 14 | # Proposal: |
11 | 15 | # In order to neatly handle multiple lines on the same graph |
... | ... | @@ -20,28 +24,36 @@ class Series: |
20 | 24 | self.title = title |
21 | 25 | self.xname = xname |
22 | 26 | self.yname = yname |
23 | - self.xlimits = (0, 100) | |
24 | - self.ylimits = (-100, 100) | |
27 | + self.xlimits = xlimits | |
28 | + self.ylimits = ylimits | |
25 | 29 | self.data = [] |
26 | 30 | self.points = points |
27 | - | |
31 | + self.xauto = xauto | |
32 | + self.yauto = yauto | |
33 | + | |
28 | 34 | logging.info("Created series: " + title) |
29 | - | |
35 | + | |
30 | 36 | def addpoint(self, point): |
31 | 37 | """Add a point to the dataset, and remove the oldest, if necessary""" |
32 | 38 | self.data.append(point) |
33 | 39 | if len(self.data) > self.points: |
34 | 40 | del self.data[0] |
35 | - self.autoscale(0) | |
36 | - | |
37 | - def autoscale(self, axis): # axis=0 is x, 1 is y | |
41 | + try: | |
42 | + if self.xauto: | |
43 | + self.autoscale(0) | |
44 | + if self.yauto: | |
45 | + self.autoscale(1) | |
46 | + except: | |
47 | + logging.error("Series autoscale failed") | |
48 | + | |
49 | + def autoscale(self, axis): # axis=0 is x, 1 is y | |
38 | 50 | minval = self.data[0][axis] |
39 | 51 | maxval = self.data[0][axis] |
40 | 52 | for value in self.data: |
41 | 53 | if value[axis] < minval: |
42 | 54 | minval = value[axis] |
43 | 55 | if value[axis] > maxval: |
44 | - maxval = value[axis] | |
56 | + maxval = value[axis] | |
45 | 57 | if axis == 0: |
46 | 58 | self.xlimits = (minval, maxval) |
47 | 59 | else: | ... | ... |
robots/little_john/telemetry/code/robot/analogread_demo/analogread_demo.ino
... | ... | @@ -6,7 +6,6 @@ |
6 | 6 | * This code is under the GPL |
7 | 7 | */ |
8 | 8 | |
9 | -#include <math.h> | |
10 | 9 | #include <SoftwareSerial.h> |
11 | 10 | |
12 | 11 | SoftwareSerial Bluetooth(3, 2); // Rx, Tx |
... | ... | @@ -14,7 +13,6 @@ SoftwareSerial Bluetooth(3, 2); // Rx, Tx |
14 | 13 | void setup() { |
15 | 14 | Serial.begin(9600); |
16 | 15 | Bluetooth.begin(115200); |
17 | - //Bluetooth.print("Hello, wireless world!"); | |
18 | 16 | pinMode(13, OUTPUT); |
19 | 17 | } |
20 | 18 | |
... | ... | @@ -25,5 +23,5 @@ void loop() { |
25 | 23 | Bluetooth.print(a0value); |
26 | 24 | Bluetooth.print(", "); |
27 | 25 | Bluetooth.println(a7value); |
28 | - delay(500); | |
26 | + delay(180); | |
29 | 27 | } | ... | ... |