Attachment 'wobbulator2.6.3o.py'
Download 1 #!/usr/bin/env python3
2 # RPi Wobbulator v2.63
3 # 2016-11-13 RR, mod for Orange Pi
4 # Copyright (C) 2013-2014 Tom Herbison MI0IOU
5 # Email tom@asliceofraspberrypi.co.uk
6 # Web <http://www.asliceofraspberrypi.co.uk>
7
8 # Special thanks to Tony Abbey for his efforts developing v2 of the software...
9 # Edits by Tony Abbey for 10 speed up and continuous looping until STOP button
10 # ADC now runs at either 60 sps 14 bits or 240 SPS and 12 bits in one-shot mode
11 # to prevent glitches. Also added initialisation of frequency scan values,
12 # "Fast" option, optional screen clear every sweep plus code suggested by
13 # Fred LaPlante for a "scope-like" trace
14 # Also Fred for horizontal frequency scale, and Tony for vertical scale
15 # Now programmable display size and scales, stored in parameter file by Fred
16 # MHz, kHz i/p etc by Dick Bronsdijk
17 # Display tweaks by various and Tony added vertical text on Y scale
18 # V 2.6 Addition of Y scale in dB and bias average of 2 readings - Tony
19 # Version 2.61 scale updates when dBm clicked
20
21 # Please see "README.txt" for a description of this software
22 # and for details of the version change log
23
24 # If you wish to make changes to this software and would like your
25 # changes to be incorporated into a future release please visit,
26 # <https://github.com/mi0iou/RPi_Wobbulator> and 'fork' the repository
27
28 # This program is free software: you can redistribute it and/or modify
29 # it under the terms of the GNU General Public License as published by
30 # the Free Software Foundation, either version 3 of the License, or
31 # (at your option) any later version.
32
33 # This program is distributed in the hope that it will be useful,
34 # but WITHOUT ANY WARRANTY; without even the implied warranty of
35 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 # GNU General Public License for more details.
37
38 # You should have received a copy of the GNU General Public License
39 # along with this program. If not, see <http://www.gnu.org/licenses/>.
40
41 # import GUI module
42 from tkinter import *
43
44 import time, sys
45 print("start pgm") # debug
46
47 # ---- get user preferences or set defaults ----
48 # for param file persistence, import faster cPickle if available
49 try:
50 import cPickle as pickle
51 except:
52 import pickle
53
54 params = {}
55 try:
56 # user parameters
57 paramFN = 'wobParam.pkl'
58 paramFile = open(paramFN,"rb")
59 params = pickle.load(paramFile)
60 #print (params)
61 paramFile.close()
62 except IOError:
63 # default parameters
64 params['chrtHt'] = 500
65 params['chrtWid'] = 500
66 params['xDivs'] = 10
67 params['yDivs'] = 10
68 params['canvFg'] = 'black'
69 params['canvBg'] = 'cyan'
70 params['fBegin'] = 1000000
71 params['fEnd'] = 31000000
72 params['fIntvl'] = 100000
73 params['vgain'] = 132
74 params['vchan'] = 0
75 params['colour'] = 'blue'
76 params['bias'] = 0
77 params['fast'] = 0
78 params['cls'] = 0
79 params['grid'] = 1
80 params['dB'] = 0
81 # ---- end of user param support ----
82
83 # ---- for app menus and associated displays ----
84 from tkinter import messagebox
85 from tkinter import colorchooser
86
87 def notDone():
88 messagebox.showerror('Not implemented', 'Not yet available')
89
90 def getForegroundColor():
91 fgColor = colorchooser.askcolor(params['canvFg'], title='Foreground Color')
92 if fgColor[1] != 'None':
93 params['canvFg'] = fgColor[1]
94 app.canvFg = fgColor[1]
95 #print (params['canvFg'])
96
97 def getBackgroundColor():
98 bgColor = colorchooser.askcolor(params['canvBg'], title='Background Color')
99 if bgColor[1] != 'None':
100 params['canvBg'] = bgColor[1]
101 app.canvBg = bgColor[1]
102 #print (params['canvBg'])
103
104 def getChartWidth():
105 chrtWid = simpledialog.askinteger('Chart Width', '300 to 1000',initialvalue=params['chrtWid'],minvalue=300,maxvalue=1000)
106 if chrtWid != 'None':
107 params['chrtWid'] = chrtWid
108 app.chrtWid = chrtWid
109 #print (chrtWid)
110
111 def getChartHeight():
112 chrtHt = simpledialog.askinteger('Chart Height', '300 to 1000',initialvalue=params['chrtHt'],minvalue=300,maxvalue=1000)
113 if chrtHt != 'None':
114 params['chrtHt'] = chrtHt
115 app.chrtHt = chrtHt
116 #print (chrtHt)
117
118 def getXdivisions():
119 xDivs = simpledialog.askinteger('X-divisions', '10-50',initialvalue=params['xDivs'],minvalue=10,maxvalue=50)
120 if xDivs != 'None':
121 params['xDivs'] = xDivs
122 app.xDivs = xDivs
123 #print (xDivs)
124 def getYdivisions():
125 yDivs = simpledialog.askinteger('Y-divisions', '10-50',initialvalue=params['yDivs'],minvalue=10,maxvalue=50)
126 if yDivs != 'None':
127 params['yDivs'] = yDivs
128 app.yDivs = yDivs
129 #print (yDivs)
130
131 def makemenu(win):
132 top = Menu(win)
133 win.config(menu=top) # set its menu option
134
135 file = Menu(top, tearoff=0)
136 top.add_cascade(label='File', menu=file, underline=0)
137 file.add_command(label='Exit', command=root.destroy, underline=1, accelerator='Ctrl+Q')
138
139 opt = Menu(top, tearoff=0)
140 top.add_cascade(label='Options', menu=opt, underline=0)
141 opt.add_command(label='Background', command=getBackgroundColor, underline=0)
142 opt.add_command(label='Foreground', command=getForegroundColor, underline=0)
143 opt.add_separator()
144 opt.add_command(label='Chart Width', command=getChartWidth, underline=6)
145 opt.add_command(label='Chart Height', command=getChartHeight, underline=6)
146 opt.add_separator()
147 opt.add_command(label='X-divisions', command=getXdivisions, underline=0)
148 opt.add_command(label='Y-divisions', command=getYdivisions, underline=0)
149
150 help = Menu(top, tearoff=0)
151 top.add_cascade(label='Help', menu=help, underline=0)
152 help.add_command(label='About Wobbulator', command=notDone, underline=1)
153 # ---- end of menu support ----
154
155 # ---- RaspBerry Pi IO support ----
156 #import quick2wire i2c module
157 #import quick2wire.i2c as i2c
158 # for orange pi Lite, pyA20 library
159 from pyA20 import i2c
160
161 # import GPIO module
162 # import RPi.GPIO as GPIO
163 from pyA20.gpio import gpio
164 from pyA20.gpio import port
165 from pyA20.gpio import connector
166
167 # setup GPIO
168 #GPIO.setmode(GPIO.BOARD)
169 #GPIO.setwarnings(False)
170 gpio.init() #Initialize module. Always called first
171
172 # Define GPIO pins
173 #W_CLK = 15
174 W_CLK = port.PA3
175 #FQ_UD = 16
176 FQ_UD = port.PC4
177 #DATA = 18
178 DATA = port.PC7
179 #RESET = 22
180 RESET =port.PA2
181
182 # setup IO bits
183 #GPIO.setup(W_CLK, GPIO.OUT)
184 #GPIO.setup(FQ_UD, GPIO.OUT)
185 #GPIO.setup(DATA, GPIO.OUT)
186 #GPIO.setup(RESET, GPIO.OUT)
187 gpio.setcfg(W_CLK, gpio.OUTPUT)
188 gpio.setcfg(FQ_UD, gpio.OUTPUT)
189 gpio.setcfg(DATA, gpio.OUTPUT)
190 gpio.setcfg(RESET, gpio.OUTPUT)
191
192 # initialize everything to zero
193 #GPIO.output(W_CLK, False)
194 #GPIO.output(FQ_UD, False)
195 #GPIO.output(DATA, False)
196 #GPIO.output(RESET, False)
197 gpio.output(W_CLK, 0)
198 gpio.output(FQ_UD, 0)
199 gpio.output(DATA, 0)
200 gpio.output(RESET, 0)
201
202
203 #define address for ADC chip, Arduino mini
204 adc_address = 0x05
205
206 # setup i2c bus
207 #bus = i2c.I2CMaster()
208 i2c.init("/dev/i2c-0")
209 i2c.open(adc_address)
210
211 # Function to send a pulse to GPIO pin
212 def pulseHigh(pin):
213 #GPIO.output(pin, True)
214 #GPIO.output(pin, False)
215 gpio.output(pin, 1)
216 gpio.output(pin, 0)
217 return
218 # ---- end of RaspBerry Pi IO support ----
219
220 # ---- application specific stuff starts here ----
221 # Function to send a byte to AD9850 module
222 def tfr_byte(data):
223 for i in range (0,8):
224 #GPIO.output(DATA, data & 0x01)
225 gpio.output(DATA, data & 0x01)
226 pulseHigh(W_CLK)
227 data=data>>1
228 return
229
230 # Function to send frequency (assumes 125MHz xtal) to AD9850 module
231 def sendFrequency(frequency):
232 freq=int(frequency*4294967296/125000000)
233 for b in range (0,4):
234 tfr_byte(freq & 0xFF)
235 freq=freq>>8
236 tfr_byte(0x00)
237 pulseHigh(FQ_UD)
238 return
239
240 # Function to set address for ADC - not used ***
241 def changechannel(address, adcConfig):
242 bus.transaction(i2c.writing_bytes(address, adcConfig))
243 return
244
245 # Function to get reading from ADC (12 bit mode)
246 #def getadcreading(address, adcConfig): # << changed afa
247 # bus.transaction(i2c.writing_bytes(address, adcConfig)) # << added afa
248 # m, l ,s = bus.transaction(i2c.reading(address,3))[0]
249 # while (s & 128):
250 # m, l, s = bus.transaction(i2c.reading(address,3))[0]
251 # # shift bits to product result
252 # t = (m << 8) | l
253 # check if positive or negative number and invert if needed
254 # if (m > 128):
255 # t = ~(0x02000 - t)
256 # if root.fast:
257 # return (t * 0.001) # 1mV per DN in 12 bit mode
258 # else:
259 # return (t * 0.00025) # 0.25mV per DN in 14 bit mode
260
261 # Function to get reading from Arduino ADC
262 def getadcreading(address):
263 # channel 1 = box
264 # channel 3 = local signal
265 #bus.transaction(i2c.writing_bytes(0x05, 0x03))
266 i2c.write([0x05, 0x03]) #Write 0x03 to register 0x05
267 time.sleep(.001)
268 avhigh, avlow = i2c.read(2)
269 #while (s & 128):
270 # h, m, l, s = bus.transaction(i2c.reading(address,4))[0]
271 # shift bits to product result
272 t = (avhigh << 8) | avlow
273 # Uref = 3.32 V / 1023 (10 Bit) = 308 -> scale in Volt
274 return (t / 308)
275
276 # Function to convert frequency f to Hz and return as int value
277 # e.g.: 10 MHz, 14.1m, 1k, 3.67 Mhz, 1.2 khz
278 def fconv(f):
279 f = f.upper()
280 if f.find("K") > 0:
281 return (int(float(f[:f.find("K")]) * 1000))
282 elif f.find("M") > 0:
283 return (int(float(f[:f.find("M")]) * 1000000))
284 else:
285 return (int(float(f)))
286
287 # Class definition for WobbyPi application
288 class WobbyPi():
289
290 # Build Graphical User Interface
291 #def __init__(self, master):
292 def __init__(self, master, params):
293 print("tk init") # debug
294 frame = Frame(master, bd=10)
295 frame.pack(fill=BOTH,expand=1)
296
297 self.chrtHt = 0
298
299 # setup working parameters
300 # system values
301 self.mrgnLeft = 56 #<-changed ta
302 self.mrgnRight = 20
303 self.mrgnTop = 10
304 self.mrgnBotm = 30
305 # user values
306 self.canvFg = params['canvFg']
307 self.canvBg = params['canvBg']
308 self.chrtHt = int(params['chrtHt'])
309 self.chrtWid = int(params['chrtWid'])
310 self.xDivs = params['xDivs']
311 self.yDivs = params['yDivs']
312 self.fBegin = params['fBegin']
313 self.fEnd = params['fEnd']
314 self.fIntvl = params['fIntvl']
315
316 # setup canvas to display results
317 global canvas
318 self.canvHt = self.mrgnTop + self.chrtHt + self.mrgnBotm
319 self.canvWid = self.mrgnLeft + self.chrtWid + self.mrgnRight
320 canvas = Canvas(frame, width=self.canvWid, height=self.canvHt, bg=self.canvBg)
321 canvas.grid(row=0, column=0, columnspan=6, rowspan=10)
322 ampdivlabel = Label(frame, text='10dB/div')
323 ampdivlabel.grid(row=0, column=6)
324
325 # choose channel
326 channelframe = LabelFrame(frame, text='Ch', labelanchor='n')
327 self.channel = IntVar()
328 g1 = Radiobutton(channelframe, text='1', variable=self.channel, value=0)
329 g1.grid(row=0)
330 if int(params['vchan']) == 0:
331 g1.select()
332 g2 = Radiobutton(channelframe, text='2', variable=self.channel, value=1)
333 g2.grid(row=1)
334 if int(params['vchan']) == 1:
335 g2.select()
336 g3 = Radiobutton(channelframe, text='3', variable=self.channel, value=2)
337 g3.grid(row=2)
338 if int(params['vchan']) == 2:
339 g3.select()
340 g4 = Radiobutton(channelframe, text='4', variable=self.channel, value=3)
341 g4.grid(row=3)
342 if int(params['vchan']) == 3:
343 g4.select()
344 channelframe.grid(row=1, column=6)
345
346 # choose input gain - values changed from 3.75 SPS 18 bit to 60 SPS 14 bit, one shot mode
347 gainframe = LabelFrame(frame, text='Gain', labelanchor='n')
348 self.gainval = IntVar()
349 g1 = Radiobutton(gainframe, text='1', variable=self.gainval, value=132, command = self.dispScales)
350 g1.grid(row=0)
351 if int(params['vgain']) == 132:
352 g1.select()
353 g2 = Radiobutton(gainframe, text='2', variable=self.gainval, value=133, command = self.dispScales)
354 g2.grid(row=1)
355 if int(params['vgain']) == 133:
356 g2.select()
357 g3 = Radiobutton(gainframe, text='4', variable=self.gainval, value=134, command = self.dispScales)
358 g3.grid(row=2)
359 if int(params['vgain']) == 134:
360 g3.select()
361 g4 = Radiobutton(gainframe, text='8', variable=self.gainval, value=135, command = self.dispScales)
362 g4.grid(row=3)
363 if int(params['vgain']) == 135:
364 g4.select()
365 gainframe.grid(row=2, column=6)
366
367 # choose a colour
368 colourframe = LabelFrame(frame, text='Colour', labelanchor='n')
369 self.colour = StringVar()
370 c1 = Radiobutton(colourframe, fg='blue', text='[B]', variable=self.colour, value='blue')
371 c1.grid(row=0)
372 if params['colour'] == 'blue':
373 c1.select()
374 c2 = Radiobutton(colourframe, fg='red', text='[R]', variable=self.colour, value='red')
375 c2.grid(row=1)
376 if params['colour'] == 'red':
377 c2.select()
378 c3 = Radiobutton(colourframe, fg='green', text='[G]', variable=self.colour, value='green')
379 c3.grid(row=2)
380 if params['colour'] == 'green':
381 c3.select()
382 c4 = Radiobutton(colourframe, fg='magenta', text='[M]', variable=self.colour, value='magenta')
383 c4.grid(row=3)
384 if params['colour'] == 'magenta':
385 c4.select()
386 c5 = Radiobutton(colourframe, fg='yellow', text='[Y]', variable=self.colour, value='yellow')
387 c5.grid(row=4)
388 if params['colour'] == 'yellow':
389 c5.select()
390 colourframe.grid(row=3, column=6)
391
392 # remove bias
393 self.bias = IntVar()
394 biascheck = Checkbutton(frame, text="Bias", variable=self.bias, onvalue=1, offvalue=0)
395 biascheck.grid(row=5, column=6)
396 if int(params['bias']) == 1:
397 biascheck.select()
398
399 # fast flag
400 self.fast = IntVar()
401 fastcheck = Checkbutton(frame, text="Fast", variable=self.fast, onvalue=1, offvalue=0)
402 fastcheck.grid(row=6, column=6)
403 if int(params['fast']) == 1: #<< changed FL
404 fastcheck.select()
405
406 # CLS check button to clear the screen every sweep
407 self.cls = IntVar()
408 clearbutton = Checkbutton(frame, text='CLS', variable=self.cls, onvalue=1, offvalue=0)
409 clearbutton.grid(row=7, column=6)
410 if int(params['cls']) == 1: #<< changed FL
411 clearbutton.select()
412
413 # dBm check button to change Y scale to dB #<< New button afa
414 self.dB = IntVar()
415 dBbutton = Checkbutton(frame, text='dBm', variable=self.dB, onvalue=1, offvalue=0, command = self.dispScales)
416 dBbutton.grid(row=8, column=6)
417 if int(params['dB']) == 1:
418 dBbutton.select()
419 #if self.dB == 1:
420 # biascheck.select()
421
422 # Button to start a single sweep #<< New button db
423 self.sweepbutton = Button(frame, text='Sweep', height = 1, width = 3, relief=RAISED, command=self.onesweep)
424 self.sweepbutton.grid(row=9, column=6)
425
426 # RUN button to start the sweep
427 self.runbutton = Button(frame, text='RUN', height = 1, width = 3, relief=RAISED, command=self.loopsweep)
428 self.runbutton.grid(row=10, column=6)
429
430 # STOP button to stop continuous sweep
431 self.stopbutton = Button(frame, text='STOP', height = 1, width = 3, relief=SUNKEN, command=self.stop)
432 self.stopbutton.grid(row=11, column=6)
433
434 # start frequency for sweep
435 fstartlabel = Label(frame, text='Start Freq (Hz)')
436 fstartlabel.grid(row=10, column=0)
437 self.fstart = StringVar()
438 fstartentry = Entry(frame, textvariable=self.fstart, width=10)
439 fstartentry.grid(row=10, column=1)
440 fstartentry.insert(0,self.fBegin)
441
442 # stop frequency for sweep
443 fstoplabel = Label(frame, text='Stop Freq (Hz)')
444 fstoplabel.grid(row=10, column=2)
445 self.fstop = StringVar()
446 fstopentry = Entry(frame, textvariable=self.fstop, width=10)
447 fstopentry.grid(row=10, column=3)
448 fstopentry.insert(0,self.fEnd)
449
450 # increment for sweep
451 fsteplabel = Label(frame, text='Step (Hz)')
452 fsteplabel.grid(row=10, column=4)
453 self.fstep = StringVar()
454 fstepentry = Entry(frame, textvariable=self.fstep, width=8)
455 fstepentry.grid(row=10, column=5)
456 fstepentry.insert(0,self.fIntvl)
457
458 # user description space #<< new addition FL
459 descLabel = Label(frame, text='Description')
460 descLabel.grid(row=11, column=0)
461 descEntry = Entry(frame, width=57) #<< changed db
462 descEntry.grid(row=11, column=1, columnspan=5)
463
464 # display a grid
465 self.grid = IntVar()
466 gridcheck = Checkbutton(frame, text="Grid", variable=self.grid, onvalue=1, offvalue=0, command=self.checkgrid)
467 gridcheck.grid(row=4, column=6)
468 if int(params['grid']) == 1:
469 gridcheck.select()
470 self.checkgrid()
471 self.dispScales()
472
473
474 # clear the screen
475 def clearscreen(self):
476 chart = canvas.create_rectangle(self.mrgnLeft, self.mrgnTop,
477 self.mrgnLeft+self.chrtWid, self.mrgnTop+self.chrtHt,
478 fill=self.canvBg, outline=self.canvFg)
479 self.checkgrid()
480
481 # display grid
482 def checkgrid(self):
483 checked = self.grid.get()
484 if checked == 1:
485 colour=self.canvFg
486 else:
487 colour=self.canvBg
488 for x in range(self.mrgnLeft, self.mrgnLeft+self.chrtWid+1, int(self.chrtWid/self.xDivs)):
489 canvas.create_line(x, self.mrgnTop, x, self.mrgnTop+self.chrtHt, fill=colour)
490 for y in range(self.mrgnTop, self.chrtHt+self.mrgnBotm, int(self.chrtHt/self.yDivs)):
491 canvas.create_line(self.mrgnLeft, y, self.chrtWid+self.mrgnLeft, y, fill=colour)
492
493 # display horizontal axis labels
494 def dispScales(self):
495 startF = float(fconv(self.fstart.get()))
496 stopF = float(fconv(self.fstop.get()))
497 if stopF > 1000000:
498 f0 = round((startF/1000000.0),1)
499 fN = round(stopF/1000000.0,1)
500 fDesc = 'MHz'
501 elif stopF > 1000:
502 f0 = round(startF/1000.0,1)
503 fN = round(stopF/1000.0,1)
504 fDesc = 'kHz'
505 else:
506 f0 = round(startF/1.0,1)
507 fN = round(stopF/1.0,1)
508 fDesc = 'Hz'
509
510 canvas.create_rectangle(0, self.mrgnTop+self.chrtHt+1,
511 self.canvWid+self.mrgnLeft, self.canvHt,
512 fill=self.canvBg, outline=self.canvBg) #remove old X scale
513
514 fStep = (fN-f0)/self.xDivs
515 fLbls = ''
516 f = f0
517 hWhere = (self.mrgnLeft/2)+18 #<- changed ta
518 while f < fN:
519 #hLbl = canvas.create_text(hWhere,self.canvHt-20, text='{0:10s}'.format(' ')) #<- commmented out not needed? - ta
520 hLbl = canvas.create_text(hWhere,self.canvHt-20, text="{0:10.2f}".format(f))
521 f = f + fStep
522 hWhere = hWhere+self.chrtWid/self.xDivs
523 #hLbl = canvas.create_text(hWhere,self.canvHt-20, text='{0:10s}'.format(' ')) #<- commmented out not needed? - ta
524 hLbl = canvas.create_text(hWhere,self.canvHt-20, text='{0:10.2f}'.format(fN))
525 hWhere = ((self.mrgnLeft+self.chrtWid+self.mrgnRight) - len(fDesc)) / 2
526 hLbl = canvas.create_text(hWhere, self.canvHt-5, text=fDesc)
527
528 # display vertical axis labels << new function
529
530 canvas.create_rectangle(0, 0, self.mrgnLeft-1, self.canvHt-self.mrgnBotm,
531 fill=self.canvBg, outline=self.canvBg) #remove old Y scale <<moved and changed by ta
532
533 gain = pow(2,(self.gainval.get()-132))
534
535 if self.dB.get() == 1:
536 #self.yDivs = 25 # << with this commented out you should set the menu Ydivs to something which suits the dB scale
537 # cant make the next line work - get AttributeError: type object 'WobbyPi' has no attribute 'biascheck'
538 # self.biascheck.select() # remove bias if in dB mode else display is incorrect
539 startV = float(-80)
540 stopV = float(20)
541 v0 = startV
542 vN = startV + 100/gain
543 vDesc = 'dBm'
544 vStep = (vN-v0)/self.yDivs
545 vLbls = ''
546 v = vN
547 vWhere = (self.mrgnBotm)/2 - 5
548 while v > v0:
549 vLbl = canvas.create_text(self.mrgnLeft-30, vWhere, text='{0:10.1f}'.format(v))
550 v = v - vStep
551 vWhere = vWhere+self.chrtHt/self.yDivs
552 vLbl = canvas.create_text(self.mrgnLeft-30, vWhere, text='{0:10.1f}'.format(v0))
553
554
555 else:
556 startV = float(0)
557 stopV = float(2.5)
558 v0 = startV
559 vN = stopV/gain
560 vDesc = 'Volts'
561 vStep = (vN-v0)/self.yDivs
562 vLbls = ''
563 v = vN
564 vWhere = (self.mrgnBotm)/2 - 5
565 while v > v0:
566 vLbl = canvas.create_text(self.mrgnLeft-30, vWhere, text='{0:10.3f}'.format(v))
567 v = v - vStep
568 vWhere = vWhere+self.chrtHt/self.yDivs
569 vLbl = canvas.create_text(self.mrgnLeft-30, vWhere, text='{0:10.3f}'.format(v0))
570
571 vWhere = (self.chrtHt) / 2 - 6 #<< changed ta
572 vLbl = canvas.create_text(8, vWhere, text="\n".join(vDesc))#<- changed to give vertical text - ta
573
574 # start frequency sweep
575 def sweep(self):
576 print("sweep") # debug
577 pulseHigh(RESET)
578 root.fast = int(self.fast.get())
579 address = int(self.gainval.get())-4*root.fast # change to fast value if fast flag
580 channel = int(self.channel.get())
581 chip = adc_address
582 address = (address + (32 * channel))
583 # changechannel(chip, address) #trigger adc <<removed afa
584 startfreq = fconv(self.fstart.get())
585 stopfreq = fconv(self.fstop.get())
586 span = (stopfreq-startfreq)
587 step = fconv(self.fstep.get())
588 # If a value has changed, only then refresh scales. This to avoid slowdown between sweeps #<< added db
589 if self.oldstartfreq != startfreq or self.oldstopfreq != stopfreq or self.oldspan != span or self.oldstep != step:
590 self.dispScales()
591 self.oldstartfreq = startfreq
592 self.oldstopfreq = stopfreq
593 self.oldspan = span
594 self.oldstep = step
595 colour = str(self.colour.get())
596 removebias = self.bias.get()
597 bias = (getadcreading(chip) + getadcreading(chip))/2 #<< changed afa
598 if int(self.cls.get()):
599 self.clearscreen()
600 root.fast = int(self.fast.get())
601 print('bias [V] ', bias)
602 tstart = time.time()
603 for frequency in range((startfreq - step), (stopfreq + step), step):
604 pulseHigh(RESET)
605 pulseHigh(W_CLK)
606 pulseHigh(FQ_UD)
607 sendFrequency(frequency)
608 # changechannel(chip, address) #trigger adc << removed afa
609 reading = getadcreading(chip) #includes triggering adc << added afa
610 #x = int(self.chrtWid * ((frequency - startfreq) / span)) + self.mrgnLeft
611 #y = int(self.chrtHt + self.mrgnTop - ((reading - (bias * removebias)) * self.chrtHt/2.5))
612 x = int(500 * ((frequency - startfreq) / span)) + self.mrgnLeft
613 # AD8307 span 0.3 - 2.1 V, *185 = 10 dB/div, +15 = offset
614 y = int(500 + 25 - (reading * 185))
615 if frequency > startfreq:
616 canvas.create_line(oldx, oldy, x, y, fill=colour)
617 canvas.update_idletasks() # new code to look like oscilloscope
618 oldx = x
619 oldy = y
620 #if frequency == stopfreq: #<< changed db
621 # pulseHigh(RESET)
622 # root.after(100, self.runsweep)
623 tend = time.time()
624 print('Dauer (s) ', tend-tstart)
625
626 # continuous sweep
627 def runsweep(self):
628 if not root.stopflag:
629 if root.oneflag:
630 root.stopflag = True
631 self.sweep()
632 else:
633 # change relief of button to show selected button
634 self.runbutton.config(relief=RAISED)
635 self.sweepbutton.config(relief=RAISED)
636 self.stopbutton.config(relief=SUNKEN)
637
638 # initialize parameters for first sweep
639 def startsweep(self): #<< new function db
640 self.stopbutton.config(relief=RAISED)
641 # Initial data to check when Scales need refresh
642 self.oldstartfreq = 0
643 self.oldstopfreq = 0
644 self.oldspan = 0
645 self.oldstep = 0
646 # ---------------------------------------------
647 root.stopflag = False
648 self.runsweep()
649
650 # start single sweep
651 def onesweep(self): #<< new function db
652 self.sweepbutton.config(relief=SUNKEN)
653 root.oneflag = True
654 self.startsweep()
655
656 # start sweep after clearing stop flag to prevent need for dubble click run button
657 def loopsweep(self): #<< changed db
658 self.runbutton.config(relief=SUNKEN)
659 root.oneflag = False
660 self.startsweep()
661
662 # set stop flag
663 def stop(self):
664 # change relief of button to show selected button #<< added db
665 self.stopbutton.config(relief=SUNKEN)
666 self.dispScales()
667 root.stopflag = True
668
669 # Assign TK to root
670 root = Tk()
671
672 # Set main window title and menubar
673 root.wm_title('RPi Wobbulator v2.6.3RR-OPi, use "scrot -s -d 4" for window shot')
674 makemenu(root)
675
676 # Create instance of class WobbyPi
677 app = WobbyPi(root, params)
678
679 # initialise start and stopflags
680 root.startflag = 0
681 root.stopflag = 0
682 root.oneflag = 0
683 root.fast = 0
684
685 print("start mainloop") # debug
686 # Start main loop and wait for input from GUI
687 root.mainloop()
688
689 # When program stops, save user parameters
690 paramFile = open(paramFN, "wb")
691 params['chrtHt'] = app.chrtHt
692 params['chrtWid'] = app.chrtWid
693 params['canvFg'] = app.canvFg
694 params['canvBg'] = app.canvBg
695 params['fBegin'] = str(app.fstart.get())
696 params['fEnd'] = str(app.fstop.get())
697 params['fIntvl'] = str(app.fstep.get())
698 params['vgain'] = str(app.gainval.get())
699 params['vchan'] = str(app.channel.get())
700 params['colour'] = app.colour.get()
701 params['bias'] = str(app.bias.get())
702 params['fast'] = str(app.fast.get())
703 params['cls'] = str(app.cls.get())
704 params['grid'] = str(app.grid.get())
705 params['dB'] = str(app.dB.get())
706 #print (params)
707 params = pickle.dump(params, paramFile)
708 paramFile.close()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.