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.
  • [get | view] (2016-12-28 11:05:00, 11.0 KB) [[attachment:Orange-pi-lite_panel-additions_364.png]]
  • [get | view] (2016-12-23 13:26:00, 168.1 KB) [[attachment:OrangePi_Lite_DSC06813.jpg]]
  • [get | view] (2017-03-08 09:01:00, 46.7 KB) [[attachment:OrangePi_housing_DSC06921.jpg]]
  • [get | view] (2016-12-28 09:54:00, 22.3 KB) [[attachment:Orange_pi_tkinter-test.png]]
  • [get | view] (2017-01-05 10:26:00, 206.3 KB) [[attachment:Wobbulator_OrangePiLiteXFCE.jpg]]
  • [get | view] (2017-01-05 06:32:00, 26.0 KB) [[attachment:wobbulator2.6.3o.py]]
  • [get | view] (2017-01-05 12:47:00, 2.8 KB) [[attachment:wobbulator_orangePi_patch.txt]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.