class pend: NP = 400 tmax = 5.0 # We digitize oscillations for 10 seconds looping = False xlabel = 'Seconds' ylabel = 'Volts' size = [100,100] scale = None delay = 0.0 def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.ph.select_adc(0) self.ph.set_adc_size(2) self.intro_msg() self.plot2d.setWorld(0, -5, self.tmax, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel) def exit(self): self.looping = False def set_tmax(self,w): d = self.scale.get() self.tmax = float(d) self.plot2d.setWorld(0, -5, self.tmax, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel) def clear(self,e): if self.looping == True: return self.plot2d.delete_lines() self.data.clear() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def calc_g(self,e): if self.data.points == []: return x = self.lentext.get() try: L = float(x) except: self.msgwin.msg('Set the length of the rod', 'red') return import phmath, math dat = [] for k in self.data.points: dat.append([k[0], k[1]]) res = phmath.fit_dsine(dat) fit = [] exp = [] for k in res[0]: fit.append([k[0],k[2]]) exp.append([k[0],k[3]]) self.data.traces.append(fit) self.col = self.data.get_col() self.plot2d.line(fit, self.col) self.col = self.data.get_col() self.plot2d.line(exp, self.col) D = res[1][4] T = 1.0 / res[1][1] r = 0.14 # radius of the rod R = 1.27 # radius of the ball density = 7.8 # density of iron m_rod = math.pi * r**2 * L * density m_ball = math.pi * 4 / 3 * R**3 * density # print m_rod,'',m_ball Lprime = ( (m_rod * L**2)/3 + (m_ball * 2/5 * R**2) + m_ball * \ (L+R)**2 ) / ( (m_rod * L)/2 + m_ball*(L+R) ) g = 4.0 * math.pi**2 * Lprime / (T * T) # print T, Lprime, g, D ss = 'T = %4.3f seconds. Length = %4.2f | g = %4.0f \ cm/sec2 | Damping factor = %4.3f\n'%(T,L,g,D) self.msgwin.showtext(ss) # g2 = 4.0 * math.pi**2 * L / (T * T) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def start(self,e): if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return if self.looping == False: # Same color if restarted self.col = self.data.get_col() self.msgwin.msg('Starting Pendulum Waveform digitization') self.looping = True v = self.ph.get_voltage_bip() # First reading is taken self.start_time = v[0] # Remember starting time self.data.points = [(0.0, v[1]/1000.0)] # initialize the list def accept_trace(self): self.data.traces.append(self.data.points) def update(self): if self.looping == False: return val = self.ph.get_voltage_bip() elapsed = val[0] - self.start_time self.data.points.append( (elapsed, val[1]/1000.0) ) self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) if elapsed >= self.tmax: self.msgwin.msg('Digitization done for %2.1f seconds'%elapsed) self.accept_trace() self.looping = False def refresh(self,e): if self.looping == True: return self.intro_msg() def intro_msg(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Connect DC motor output to Ch0, through an amplifier (gain = 100) and the '+\ 'Level Shifter.\nOscillate the pendulum and ') self.msgwin.showlink('Digitize', self.start) self.msgwin.showtext(' for ') if self.scale != None: self.scale.destroy() self.scale = Scale(None, command = self.set_tmax, \ from_ = 1, to=20, orient=HORIZONTAL, length=100, showvalue=1) self.scale.set(int(self.tmax)) self.msgwin.showwindow(self.scale) self.msgwin.showtext(' Seconds.\n') self.msgwin.showlink('Click Here', self.calc_g) self.msgwin.showtext(' to calculate period "T" by fitting the graph.\n Value of "g" is calculated '+\ 'assuming Length of the rod =') self.lentext = Entry(None, width = 4, fg = 'red') self.msgwin.showwindow(self.lentext) self.lentext.insert(END,'11.0') self.msgwin.showtext(' cm. and Bob diameter = 2.54 cm') self.msgwin.showlink('\nSave the latest trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to the text file') self.fntext = Entry(None, width =15, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'pend.dat') self.msgwin.showtext(' ') self.msgwin.showlink('Display all Traces', self.show_all) self.msgwin.showtext(' ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' ') self.msgwin.showlink('Xmgrace', self.analyze) self.msgwin.showtext(' ') self.msgwin.showlink('Refresh', self.refresh) self.msgwin.showtext('\n')
class osc: NP = 200 adc_delay = 20 delay_vals = [10,20,50,100,200,500,1000] looping = False xlabel = 'milli seconds' ylabel = 'Volts' adc_scale = None size = [100,100] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): #Phoenix handler set by the caller self.ph = fd self.ph.select_adc(0) self.ph.set_adc_size(1) self.plot2d.setWorld(0, 0, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) self.msg_intro() def exit(self): # Do cleanup here self.ph.disable_set() def update(self): pass def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_waveform(self,w): data = self.ph.read_block(self.NP, self.adc_delay, 0) self.data.points = [] for k in data: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) self.plot2d.line(self.data.points, self.data.get_col()) self.data.traces.append(self.data.points) def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) def duty_cycle(self,e): sum = 0.0 for k in range(100): t = self.ph.r2ftime(4,4) if t < 0: self.msgwin.showtext('\nTime out on CMP','red') return else: sum = sum + t hi = sum / 100 self.msgwin.showtext('\nHIGH = ' + '%4.1f'%(hi) + ' usec. ') sum = 0.0 for k in range(100): t = self.ph.f2rtime(4,4) if t < 0: self.msgwin.showtext('\nTime out on CMP','red') return else: sum = sum + t low = sum / 100 self.msgwin.showtext('LOW = ' + '%4.1f'%(low) + ' usec. ') ds = hi * 100 / (low + hi) self.msgwin.showtext('Duty Cycle = ' + '%4.1f'%(ds)+ ' %. ') def frequency(self,e): fr = self.ph.measure_frequency() self.msgwin.showtext('\nFrequency = ' + '%4.0f'%(fr) + ' Hz') def msg_intro(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Power the Astable Multivibrator circuit '+\ 'made using IC555 from the 5V Output socket. Connect the Output '+\ 'signal (pin number 3) to CH0.\n') self.msgwin.showlink('View Waveform', self.show_waveform) self.msgwin.showtext(' View the output of the circuit.\n') self.adc_scale = Scale(None, command = self.set_adc_delay, \ from_ = 0, to=6, orient=HORIZONTAL, length=100, showvalue=0) self.adc_scale.set(1) self.msgwin.showwindow(self.adc_scale) self.msgwin.showtext(' Change time scale if required.\n') self.msgwin.showlink('Save Last Trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'osc555.dat') self.msgwin.showtext(' ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' to remove all the plots.\n') self.msgwin.showtext('\nConnect 555 output to CMP and ') self.msgwin.showlink('Measure Duty Cycle', self.duty_cycle) self.msgwin.showtext('. Connect to CNTR and ') self.msgwin.showlink('Measure Frequency', self.frequency)
class sound: NP = 200 adc_delay = 10 delay_vals = [10,20,50,100,200,500,1000] looping = False xlabel = 'milli seconds' ylabel = 'Volts' adc_scale = None size = [100,100] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): #Phoenix handler set by the caller self.ph = fd self.ph.select_adc(0) self.ph.set_adc_size(1) self.ph.write_outputs(0) self.ph.set_pulse_width(13) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) self.msg_intro() def exit(self): # Do cleanup here self.ph.disable_set() def update(self): pass def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_waveform(self,w): self.ph.enable_pulse_high(3) data = self.ph.read_block(self.NP, self.adc_delay, 1) self.data.points = [] for k in data: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) self.plot2d.line(self.data.points, self.data.get_col()) self.data.traces.append(self.data.points) self.ph.write_outputs(0); def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) def ms_delay(self,e): self.ph.write_outputs(0) self.ph.set_pulse_width(13) self.ph.set_pulse_polarity(0) t = self.ph.pulse2rtime(3,3) if t < 0: self.msgwin.showtext('\nTime out on Input D3','red') return self.msgwin.showtext('%4.0f'%t) def refresh(self,e): self.msg_intro() def msg_intro(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Connect the Transmitter Piezo between Digital '+\ 'output D3 and Ground. Connect the Receiver Piezo between Ground '+\ 'and the Inverting Amplifier Input. Set a gain resistor of 100. '+\ 'Connect the Output of the amplifier to the level shifter and '+\ 'level shifter output to Ch0. If the Amplitude is less, use one '+\ 'more Inverting amplifier in series.') self.msgwin.showlink('View Waveform', self.show_waveform) self.msgwin.showtext(' View the output of the receiver piezo.\n') self.msgwin.showlink('Save Last Trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'sound.dat') self.msgwin.showtext(' ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' to remove all the plots.\n') self.msgwin.showtext('\nConnect the Inverting Amplifier Output '+\ 'to Digital Input D3 through a 1K Series resistance to.') self.msgwin.showlink('Measure Time Delay', self.ms_delay) self.msgwin.showtext(' or ') self.msgwin.showlink('Refresh', self.refresh) self.msgwin.showtext('\n')
class rodpend: NP = 400 tmax = 10.0 # We digitize oscillations for 10 seconds maxcount = 10 looping = False xlabel = 'Number' ylabel = 'g' size = [100,100] scale = None def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.ph.select_adc(0) self.ph.set_adc_size(2) self.intro_msg() self.plot2d.setWorld(0, -5, self.tmax, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel) def exit(self): self.looping = False def clear(self,e): self.plot2d.delete_lines() self.data.clear() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def start(self,e): x = self.lentext.get() try: self.length = float(x) except: self.msgwin.msg('Set the length of the Pendulum', 'red') return x = self.numtext.get() try: self.maxcount = int(x) except: self.maxcount = 10 self.tmax = self.maxcount if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return if self.looping == False: # Same color if restarted self.col = self.data.get_col() self.msgwin.msg('Starting Measurement of gravity using Rod Pendulum') self.count = 0 t = self.ph.pendulum_period(3) # Every alternate rising edge # t = self.ph.multi_r2rtime(3,1) if t < 0: self.msgwin.msg('Pendulum Period Timeout Error', 'red') return t = t/1000000.0 self.pisqr = math.pi ** 2 g = 4.0 * self.pisqr * 2.0 * self.length / (3.0 * t * t) self.msgwin.showtext('\nPeriod Gravity') self.msgwin.showtext('\n%6.5f\t%4.1f'%(t,g)) # print self.pisqr, self.length, t, g self.data.points = [(self.count, g)] self.plot2d.setWorld(0, 0, self.tmax, g*1.2) self.plot2d.mark_axes(self.xlabel,self.ylabel) self.looping = True def accept_trace(self): self.data.traces.append(self.data.points) def update(self): if self.looping == False: return t = self.ph.pendulum_period(3) # Every alternate rising edge if t < 0: self.msgwin.msg('Pendulum Period Timeout Error', 'red') self.looping = False return print t t = t/1000000.0 self.pisqr = math.pi ** 2 g = 4.0 * self.pisqr * 2.0 * self.length / (3.0 * t * t) self.data.points.append( (self.count, g) ) self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) self.msgwin.showtext('\n%6.5f\t%4.1f'%(t,g)) self.count = self.count + 1 if self.count >= self.maxcount: self.looping = False self.msgwin.msg('Measured gravity %d times'%self.count) self.accept_trace() time.sleep(t/2) # Always measure in the same direction def refresh(self,e): self.intro_msg() def intro_msg(self): # self.clear(None) self.msgwin.clear() self.msgwin.showtext('Connect the Light Barrier as shown in the '+\ 'photograph and set the pendulum oscillating. Phoenix will measure '+\ 'the Period of the pendulum and calculate the value of acceleration '+\ 'due to gravity. Measure the length of the pendulum and enter it '+\ 'The pendulum must be vertical in its resting position.\n') self.msgwin.showtext('Oscillate the Pendulum and ') self.msgwin.showlink('Click Here', self.start) self.msgwin.showtext(' to start the measurements.') self.msgwin.showtext(' Length = ') self.lentext = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.lentext) self.lentext.insert(END,'7.0') self.msgwin.showtext(' cm. Number of measurements = ') self.numtext = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.numtext) self.numtext.insert(END,str(self.maxcount)) self.msgwin.showlink('\nSave the latest trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =15, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'rodpend.dat') self.msgwin.showtext(' or ') self.msgwin.showlink('Analyze', self.analyze) self.msgwin.showtext(' data online using Xmgrace.\n') self.msgwin.showlink('Display all Traces', self.show_all) self.msgwin.showtext(' , ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' or ') self.msgwin.showlink('Refresh This Window', self.refresh) self.msgwin.showtext('\nCalculated g will be plotted.')
class pt100: NP = 400 delay = 0.03 # minimum delay between voltage reads tmax = 12.0 # Number of seconds for NP reads looping = False xlabel = 'Seconds' ylabel = 'Kelvin' gain = 11.0 # Assume PT100 output is amplified by 11 ccval = 1.0 # CCS nominal value is 1 mA maxtemp = 800.0 size = [100,100] del_scale = None np_scale = None def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.ph.select_adc(0) self.ph.set_adc_size(2) self.intro_msg() self.tmax = self.delay * self.NP self.plot2d.setWorld(0, 0, self.tmax, self.maxtemp) self.plot2d.mark_axes(self.xlabel,self.ylabel) def exit(self): self.looping = False def set_delay(self,w): if self.looping: return d = self.del_scale.get() self.delay = float(d)/1000.0 self.plot2d.setWorld(0, 0, self.NP * self.delay, self.maxtemp) self.plot2d.mark_axes(self.xlabel,self.ylabel) if len(self.data.points) < 2: return self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) def set_NP(self,w): d = self.np_scale.get() self.NP = d self.plot2d.setWorld(0, 0, self.NP * self.delay, self.maxtemp) self.plot2d.mark_axes(self.xlabel,self.ylabel) if len(self.data.points) < 2: return self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) def clear(self,e): self.plot2d.delete_lines() self.data.clear() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def start(self,e): if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return if self.looping == False: # Same color if restarted self.col = self.data.get_col() self.msgwin.msg('Started Temperature Recording') self.looping = True self.data.points = [] def stop(self,e): self.msgwin.msg('Stopped Recording') self.accept_trace() self.looping = False def accept_trace(self): self.data.traces.append(self.data.points) def update(self): if self.looping == False: return if self.delay > 0: time.sleep(self.delay) val = self.ph.get_voltage() if self.data.points == []: self.start_time = val[0] temp = self.mv2cel(val[1]) self.data.points.append( (val[0]-self.start_time, temp) ) if len(self.data.points) < 2: return self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) if len(self.data.points) >= self.NP: self.msgwin.msg('Temperature recording finished') self.accept_trace() self.looping = False def mv2cel(self,mv): self.offset = 0.0 mv = (mv - self.offset)/self.gain r = mv / self.ccval # Convert resistance to temperature for PT100 r0 = 100.0 A = 3.9083e-3 B = -5.7750e-7 c = 1 - r/r0 b4ac = math.sqrt( A*A - 4 * B * c) t = (-A + b4ac) / (2.0 * B) print t return t + 273 def calibrate(self,e): try: s = self.gaintext.get() self.gain = float(s) s = self.cctext.get() self.ccval = float(s) except: self.msgwin.msg('Error occured during calibration','red') def intro_msg(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Resistance of the PT100 sensor is a function '+\ 'of temperature. The sonsor is connected to a 1mA constant current '+\ 'source an the voltage across the sensor is measured after '+\ 'sufficient amplification.') self.msgwin.showlink('Start', self.start) self.msgwin.showtext(' Start Recording Temperature') self.msgwin.showlink('Stop', self.stop) self.msgwin.showtext(' Stop Recording Temperature') self.msgwin.showlink('Save the latest trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'pt100.dat') self.msgwin.showtext(' (You can change the filename)\n') self.msgwin.showlink('Analyze', self.analyze) self.msgwin.showtext(' Process the data using Xmgrace.\n') self.msgwin.showlink('Display all Traces', self.show_all) self.msgwin.showtext(' to see all the data collected and ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' Clear Everything ') self.msgwin.showtext('\nSet Maximum Number of Readings') if self.np_scale != None: self.np_scale.destroy() self.np_scale = Scale(None, command = self.set_NP, \ from_ = 10, to=1000, orient=HORIZONTAL, length=100, showvalue = 1) self.np_scale.set(self.NP) self.msgwin.showwindow(self.np_scale) self.msgwin.showtext(' and the Interval between readings ') if self.del_scale != None: self.del_scale.destroy() self.del_scale = Scale(None, command = self.set_delay, \ from_ = 30, to=1000, orient=HORIZONTAL, length=100, showvalue=1) self.del_scale.set(self.delay) self.msgwin.showwindow(self.del_scale) self.msgwin.showtext(' milli seconds.\n') self.msgwin.showtext('For calibration enter the amplifier gain ') self.gaintext = Entry(None, width =10, fg = 'red') self.msgwin.showwindow(self.gaintext) self.gaintext.insert(END,'11.0') self.msgwin.showtext(' and the CCS value') self.cctext = Entry(None, width =10, fg = 'red') self.msgwin.showwindow(self.cctext) self.cctext.insert(END,'1.0') self.msgwin.showtext('mA and ') self.msgwin.showlink('Click Here\n', self.calibrate)
class cap: NP = 200 adc_delay = 20 delay_vals = [10,20,50,100,200,500,1000] xlabel = 'milli seconds' ylabel = 'Volts' size = [100,100] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): #Phoenix handler 'ph' is set by the caller self.intro_msg() self.ph = fd try: self.ph.select_adc(0) self.ph.set_adc_size(2) except: self.msgwin.msg('Connection NOT Established','red') def exit(self): # Do cleanup here try: self.ph.disable_set() except: pass def update(self): pass def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def capture_trace(self): # Collect data and store in object 'data' # All conversion to be done here. setWorld according to 'trace' # xscale and yscale are specified # if axes are shown in different units phdata = self.ph.read_block(self.NP, self.adc_delay, 0) self.data.points = [] for k in phdata: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) #microsec -> millisec ; millivolts -> volts self.data.traces.append(self.data.points) last = self.data.points[-1][0] second = self.data.points[-2][0] xmax = last + (last-second) self.plot2d.setWorld(0, 0, xmax, 5) # Set scale factors self.plot2d.mark_axes(self.xlabel, self.ylabel) # axes & labels self.plot2d.line(self.data.points, self.data.get_col()) def discharge(self,w): self.ph.write_outputs(8) time.sleep(1) self.ph.enable_set_low(3) self.capture_trace() def charge(self,w): self.ph.write_outputs(0) time.sleep(1) self.ph.enable_set_high(3) self.capture_trace() def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, 0, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) def calc_cap(self,e): if self.data.points == []: return x = self.restext.get() try: R = float(x) except: self.msgwin.msg('Set the Resistance value', 'red') return import phmath, math dat = [] for k in self.data.points: dat.append([k[0], k[1]]) res = phmath.fit_exp(dat) fit = [] for k in res[0]: fit.append([k[0],k[2]]) self.data.traces.append(fit) self.col = self.data.get_col() self.plot2d.line(fit, self.col) RC = -1.0/res[1][1] C = RC/R # print res[1][1], RC, R, C ss = 'RC = %4.3f . C = %4.3f\n'%(RC,C) self.msgwin.showtext(ss) def refresh(self,e): self.intro_msg() def intro_msg(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Connect the Capacitor from CH0 to GND and '+\ 'Resistor from D3out to CH0. The Blue Texts are the Commands.\n') self.msgwin.showlink('Charge', self.charge) self.msgwin.showtext(' or ') self.msgwin.showlink('Discharge.', self.discharge) self.msgwin.showtext(' ') self.msgwin.showlink('Fit the Discharge Curve', self.calc_cap) self.msgwin.showtext(' and calculate the value of capacitance for R = ') self.restext = Entry(None, width = 4, fg = 'red') self.msgwin.showwindow(self.restext) self.restext.insert(END,'1.0') self.msgwin.showtext(' KOhm.\n') self.msgwin.showlink('Save Last Trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'cap.dat') self.msgwin.showtext(' ') self.msgwin.showlink('Clear Traces', self.clear) self.msgwin.showtext(' ') self.msgwin.showlink('Xmgrace', self.analyze) self.msgwin.showtext(' ') self.msgwin.showlink('Refresh', self.refresh) self.msgwin.showtext('\n') self.adc_scale = Scale(None, command = self.set_adc_delay, \ from_ = 0, to=6, orient=HORIZONTAL, length=100, showvalue=0) self.adc_scale.set(1) self.msgwin.showwindow(self.adc_scale) self.msgwin.showtext(' Change time scale according to RC time constant.\n')
class tran: NP = 200 adc_delay = 250 numchans = 2 xlabel = 'milli seconds' ylabel = 'Volts' size = [350.0, 272.0] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(im.size[0]) self.size[1] = float(im.size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = im.size[0], height = im.size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): self.ph = fd self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel, self.numchans) self.ph.add_channel(0) self.ph.add_channel(1) self.ph.del_channel(2) self.ph.del_channel(3) self.msg_intro() v = [] for i in range(100): x = 127.5 + 127.5 * math.sin(2.0*math.pi*i/100) x = int(x+0.5) v.append(x) self.ph.load_wavetable(v) res = self.ph.start_wave(20) s = 'DAC is set to generate %3.1f Hz Sine Wave'%(res) self.msgwin.msg(s) self.updating = True def exit(self): self.updating = False self.ph.stop_wave() for k in range(4): self.ph.del_channel(k) #-------------------------------------------------------------------- def update(self): if self.ph == None: return phdata = self.ph.multi_read_block(self.NP, self.adc_delay, 0) if phdata == None: return self.data.points = [] self.data.points2 = [] for pt in phdata: self.data.points.append( (pt[0]/1000.0, 5.0 - 2.0 * pt[1]/1000.0) ) self.data.points2.append((pt[0]/1000.0, 5.0 - 2.0 * pt[2]/1000.0) ) self.plot2d.delete_lines() self.plot2d.line(self.data.points, 'black') self.plot2d.line(self.data.points2, 'red') def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.traces = [] self.data.traces.append(self.data.points) self.data.traces.append(self.data.points2) self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) #-------------------------- Message routines ------------- def msg_intro(self): self.msgwin.clear() self.msgwin.showtext('In this experiment, the DAC socket (producing '+\ 'a 50 Hz signal) is connected one end of a coil (Other end to GND) '+\ 'through a series capacitor. The same is also connected to CH1 via '+\ 'a level shifter for monitoring the primary waveform. '+\ 'Another coil (Secondary) is connected between Ground '+\ 'and the input of another level shifter, and its output '+\ 'is connected to CH0. Now you should see the primary waveform '+\ 'as a sinewave and the secondary as a horizontal line. Keep the '+\ 'coils close and note changes in secondary waveform. Pack them '+\ 'with ferrite core to see the effect of increased magnetic coupling\n') self.msgwin.showlink('Save Traces', self.save_all) self.msgwin.showtext(' Saves both the voltage waveforms to text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'trans.dat') self.msgwin.showtext('\n\nTry changing the orientation of the coils, removing the ferrite '+\ 'etc. to study the effect of them')
class gravity: NP = 400 tmax = 10.0 # We digitize oscillations for 10 seconds maxcount = 10 looping = False xlabel = 'Number' ylabel = 'g' size = [100,100] scale = None def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.intro_msg() self.plot2d.setWorld(0, -5, self.tmax, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel) def exit(self): self.looping = False def update(self): pass def clear(self,e): self.plot2d.delete_lines() self.data.clear() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def attach(self,e): x = self.lentext.get() try: self.length = float(x) except: self.msgwin.msg('Set the Height', 'red') return if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return self.ph.write_outputs(1) self.msgwin.msg('Powered the Electromagnet') def measure(self,e): t = self.ph.clr2rtime(0,0) if t < 0: self.msgwin.msg('Timeout Error', 'red') return elif t < 20: self.msgwin.msg('Connection Error', 'red') return t = t + 4000.0 # 4 ms correction for magnetic retention t = t * 1.0e-6 # usec to sec print t, self.length g = 2.0 * self.length / t ** 2 self.msgwin.showtext('\n%7.6f\t%4.1f'%(t,g)) self.msgwin.msg('Done') def refresh(self,e): self.intro_msg() def intro_msg(self): self.msgwin.clear() self.msgwin.showtext('Connect the Electromagnet between Digital '+\ 'Output D0 and GND. '+\ 'Connect the loudspeaker between GND and the input of the inverting '+\ 'amplifier and set the gain resistor to 100 Ohms. '+\ ' Amplifier output goes to Digital Input D0 through a 1K resistor.\n') self.msgwin.showlink('Click Here', self.attach) self.msgwin.showtext(' to power the Electromagnet.') self.msgwin.showtext(' Height = ') self.lentext = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.lentext) self.lentext.insert(END,'30.0') self.msgwin.showtext(' cm.') self.msgwin.showlink('Click Here', self.measure) self.msgwin.showtext(' to Release the Ball from the magnet.')
class induction: NP = 200 adc_delay = 500 delay_vals = [200,500,1000] looping = False xlabel = 'milli seconds' ylabel = 'Volts' size = [100,100] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self,fd): self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) self.intro_msg() self.ph = fd try: self.ph.select_adc(0) self.ph.set_adc_size(2) except: self.msgwin.msg('Connection NOT Established','red') def exit(self): self.looping = False def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) #------------------------------------------------------------------ def start(self,e): if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return phdata = self.ph.read_block(self.NP, self.adc_delay, 1) if phdata == None: return self.data.points = [] for k in phdata: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) # scale & copy self.limit = 0.0 # Find the present signal level for p in self.data.points: if abs(p[1]) > self.limit: self.limit = abs(p[1]) + 0.1 self.looping = True self.msgwin.msg('Scanning for Waveform (amplitude > %4.3f V)'%self.limit) # print self.limit def get_peaks(self): vmin = 5.0 vmax = -5.0 t1 = t2 = 0 for p in self.data.points: if p[1] < vmin: vmin = p[1] t1 = p[0] if p[1] > vmax: vmax = p[1] t2 = p[0] # print vmin, vmax if t1 < t2: # First peak is first return (t1,vmin), (t2,vmax) else: return (t2,vmax),(t1,vmin) def accept_trace(self): # print self.data.points self.data.traces.append(self.data.points) self.msgwin.msg('Waveform Captured. Click on Scan CH0 to repeat') def update(self): if self.ph == None: return if self.looping != True: return try: data = self.ph.read_block(self.NP, self.adc_delay, 1) if data == None: return except: return self.data.points = [] for k in data: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) self.plot2d.delete_lines() self.plot2d.line(self.data.points,'black') for p in self.data.points: if abs(p[1]) > self.limit: self.peaks = self.get_peaks() tmax = self.NP * self.adc_delay / 1000.0 # micro to milli secs if self.peaks[0][0] > 0.2*tmax and self.peaks[1][0] < 0.8*tmax: self.looping = False self.accept_trace() break def intro_msg(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Connect the coil as shown in the figure.\n') self.msgwin.showlink('Click Here', self.start) self.msgwin.showtext(' to start scanning.\n'+\ 'Drop the magnet into the coil from some height, until a trace is captured.\n'+\ 'You can repeat the whole process to acquire several waveforms.\n') self.msgwin.showlink('Save', self.save) self.msgwin.showtext(' the latest trace or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'ind.dat') self.msgwin.showtext(' Send the data to ') self.msgwin.showlink('XmGrace', self.analyze) self.msgwin.showtext('\n') self.msgwin.showlink('View All', self.show_all) self.msgwin.showtext(' Traces captured so far. ') self.msgwin.showlink('Clear all Traces', self.clear)
class diode: NP = 500 looping = False xlabel = 'Volts' ylabel = 'mA' size = [100,100] dac_voltage = 0.0 adc_voltage = 0.0 step = 39.0 def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.ph.select_adc(0) self.ph.set_adc_size(2) self.plot2d.setWorld(0, 0, 5, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) self.intro_msg() def exit(self): self.looping = False def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def start(self,e): if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return if self.looping == False: # Same color if restarted in between self.col = self.data.get_col() self.msgwin.msg('Starting Diode IV measurement') self.data.points = [] self.looping = True self.dac_voltage = 0.0 def accept_trace(self): self.data.traces.append(self.data.points) def update(self): if self.ph == None: return if self.looping != True: return self.ph.set_voltage(self.dac_voltage) time.sleep(0.05) self.adc_voltage = self.ph.get_voltage()[1] # voltage and current converted into volts current = (self.dac_voltage - self.adc_voltage)/1000.0 self.data.points.append( (self.adc_voltage/1000.0, current)) if len(self.data.points) < 2: return self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col) self.dac_voltage = self.dac_voltage + self.step if self.dac_voltage > 5000: self.msgwin.msg('IV Plot Done') self.accept_trace() self.looping = False def intro_msg(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Make the connections as shown above. The '+\ 'software changes the DAC voltage from 0 to 5V in steps and '+\ 'measure the resulting voltage across the diode. The current is '+\ 'calculated from the voltages at DAC and CH0, both are known. '+\ 'Connect a 1 uF capacitor from CH0 to ground for better results.'+\ 'You can take multiple traces. The operations are:\n') self.msgwin.showlink('Start', self.start) self.msgwin.showtext(' Start making the IV plot\n') self.msgwin.showlink('Analyze', self.analyze) self.msgwin.showtext(' the data using Xmgrace.\n') self.msgwin.showlink('Save the latest trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a file named ') self.fntext = Entry(None, width =20, fg = 'blue') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'iv.dat') self.msgwin.showlink('Display all Traces', self.show_all) self.msgwin.showtext(' Shows the data collected so far\n') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' Clears all the data ')
class gm: NP = 400 countrate = 100.0 # Assume a 100 Hz count rate numtrials = 5 # 5 trials default duration = 1 # count for one second tube_voltage = 0.0 VMIN = 300.0 VOPT = 500.0 VMAX = 902.0 looping = False xlabel = 'Trial' ylabel = 'Count' size = [100,100] scale = None def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, p): self.ph = p self.ph.select_adc(0) self.ph.set_adc_size(2) self.plot2d.setWorld(0, 0, self.countrate, self.numtrials) self.plot2d.mark_axes(self.xlabel,self.ylabel) self.tube_voltage = self.ph.gm_set_voltage(self.VOPT) self.intro_msg() def exit(self): self.looping = False def clear(self,e): if self.looping == True: return self.plot2d.delete_lines() self.data.clear() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def analyze(self,e): self.data.analyze(self.xlabel, self.ylabel) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_all(self,e): self.plot2d.delete_lines() self.data.index = 0 for tr in self.data.traces: self.plot2d.line(tr,self.data.get_col()) #------------------------------------------------------------------ def start(self,e): x = self.durationtext.get() try: self.duration = int(x) except: self.msgwin.msg('Set the Duration of Counting', 'red') return x = self.trialstext.get() try: self.numtrials = int(x) except: self.numtrials = 5 if self.ph == None: self.msgwin.msg('Connection not made yet', 'red') return if self.looping == False: # Same color if restarted self.col = self.data.get_col() self.tube_voltage = self.ph.gm_set_voltage(self.tube_voltage) self.msgwin.msg('GM tube Counting Radiation.') self.msgwin.label.update() self.count = 0 gmc = self.ph.gm_get_count(self.duration) self.msgwin.showtext('\nCounts : %d '%(gmc)) self.data.points = [(self.count, gmc)] self.plot2d.setWorld(0, 0, self.numtrials, gmc * 1.5 + 5) self.xlabel = 'Trial' self.plot2d.mark_axes(self.xlabel,self.ylabel) self.count = self.count + 1 self.looping = True self.doing_gmchar = False def start_gmgraph(self,e): x = self.durationtext.get() try: self.duration = int(x) except: self.msgwin.msg('Set the Duration of Counting', 'red') return if self.looping == False: # Same color if restarted self.col = self.data.get_col() self.msgwin.msg('Drawing GM tube Characteristic (will take time)') self.msgwin.label.update() self.count = 0 self.tube_voltage = self.ph.gm_set_voltage(self.VOPT) gmc_max = self.ph.gm_get_count(self.duration) self.plot2d.setWorld(self.VMIN, 0, self.VMAX*1.1, gmc_max * 2 + 5) self.xlabel = 'Voltage' self.plot2d.mark_axes(self.xlabel,self.ylabel) self.tube_voltage = self.ph.gm_set_voltage(self.VMIN) gmc = self.ph.gm_get_count(self.duration) self.msgwin.showtext('\n(%4.0f,%d) '%(self.tube_voltage,gmc)) self.data.points = [(self.tube_voltage, gmc)] self.count = self.count + 1 self.looping = True self.doing_gmchar = True def accept_trace(self): self.data.traces.append(self.data.points) def update(self): if self.looping == False: return if self.doing_gmchar == True: if self.tube_voltage < 400: self.tube_voltage = self.ph.gm_set_voltage(self.tube_voltage + 20) else: self.tube_voltage = self.ph.gm_set_voltage(self.tube_voltage + 50) gmc = self.ph.gm_get_count(self.duration) self.data.points.append((self.tube_voltage, gmc)) self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col, smooth=False) self.msgwin.showtext('(%4.0f,%d) '%(self.tube_voltage,gmc)) self.count = self.count + 1 if self.tube_voltage > self.VMAX: self.looping = False self.msgwin.msg('GM Tube Characteristic Done.') # self.ph.gm_set_voltage(self.VOPT) self.set_tv(None) self.accept_trace() else: gmc = self.ph.gm_get_count(self.duration) self.data.points.append((self.count, gmc)) self.plot2d.delete_lines() self.plot2d.line(self.data.points, self.col, smooth=False) self.msgwin.showtext('%d '%(gmc)) self.count = self.count + 1 if self.count >= self.numtrials: self.looping = False self.msgwin.msg('Counting Over after %d trials'%self.numtrials) self.accept_trace() def set_tv(self, e): ss = self.tv_text.get() try: vset = float(ss) except: vset = 0 self.tube_voltage = self.ph.gm_set_voltage(vset) ss = '%5.0f'%self.tube_voltage self.gmtv_value.set(ss) def refresh(self,e): self.intro_msg() def intro_msg(self): self.msgwin.clear() self.msgwin.showtext('Connections: (1)Yellow - CNTR (2) Green - CH0 '+\ '(3) Blue - PWG (4) Black - GND (5) Red - 5V.\n','red') self.msgwin.showtext('Enter the Tube voltage ') self.tv_text = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.tv_text) self.tv_text.insert(END, '500') self.msgwin.showtext('Volts and ') self.msgwin.showlink('Click Here ', self.set_tv) self.msgwin.showtext(' to set it. Current Tube Voltage is ') self.gmtv_value = StringVar() self.gmtv_label = Label(None, width=5, textvariable = self.gmtv_value) self.msgwin.showwindow(self.gmtv_label) ss = '%5.0f'%self.tube_voltage self.gmtv_value.set(ss) self.msgwin.showtext('Volts\n') self.msgwin.showtext('Set the duration of Counting to') self.durationtext = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.durationtext) self.durationtext.insert(END,'1') self.msgwin.showtext('seconds and number of trials to') self.trialstext = Entry(None, width = 5, fg = 'red') self.msgwin.showwindow(self.trialstext) self.trialstext.insert(END,str(self.numtrials)) self.msgwin.showtext('.') self.msgwin.showlink('Click Here', self.start) self.msgwin.showtext(' to start counting. ') self.msgwin.showtext('For tube Characteristic ') self.msgwin.showlink('Click Here', self.start_gmgraph) self.msgwin.showtext('\n'); self.msgwin.showlink('Save the latest trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =15, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'gmcount.dat') self.msgwin.showtext(' or ') self.msgwin.showlink('Analyze', self.analyze) self.msgwin.showtext(' data online using Xmgrace.\n') self.msgwin.showtext('You can also do ') self.msgwin.showlink('Display all Traces', self.show_all) self.msgwin.showtext(' , ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' or ') self.msgwin.showlink('Refresh This Window', self.refresh) self.msgwin.showtext('\n')
class mono: NP = 200 adc_delay = 20 delay_vals = [10,20,50,100,200,500,1000] looping = False xlabel = 'milli seconds' ylabel = 'Volts' adc_scale = None size = [100,100] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(size[0]) self.size[1] = float(size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = size[0], height = size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): #Phoenix handler set by the caller self.ph = fd self.ph.select_adc(0) self.ph.set_adc_size(1) self.ph.set_pulse_width(1) self.plot2d.setWorld(0, 0, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) self.msg_intro() def exit(self): # Do cleanup here self.ph.disable_set() def update(self): pass def clear(self,e): self.data.clear() self.plot2d.delete_lines() def save(self,e): fname = self.fntext.get() if fname == None: return self.data.save(fname) self.msgwin.msg('Data saved to '+ fname) def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) def show_waveform(self,w): self.ph.enable_pulse_low(3) data = self.ph.read_block(self.NP, self.adc_delay, 0) self.data.points = [] for k in data: self.data.points.append( (k[0]/1000.0, k[1]/1000.0) ) self.plot2d.line(self.data.points, self.data.get_col()) self.data.traces.append(self.data.points) self.ph.write_outputs(8); def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel) def ms_delay(self,e): self.ph.write_outputs(8) self.ph.set_pulse_width(1) self.ph.set_pulse_polarity(1) t = self.ph.pulse2ftime(3,3) if t < 0: self.msgwin.showtext('\nTime out on Input D3','red') return self.msgwin.showtext('\nMonoshot Delay = ' + '%4.0f'%(t) + ' usec.') def refresh(self,e): self.msg_intro() def msg_intro(self): self.clear(None) self.msgwin.clear() self.msgwin.showtext('Power the Monostable Multivibrator circuit '+\ 'made using IC555 from the 5V Output socket. Connect the Trigger '+\ 'Input of 555 (pin number 2) to Digital Output D3.\n') self.msgwin.showlink('View Waveform', self.show_waveform) self.msgwin.showtext(' View the output of the circuit.\n') self.adc_scale = Scale(None, command = self.set_adc_delay, \ from_ = 0, to=6, orient=HORIZONTAL, length=100, showvalue=0) self.adc_scale.set(1) self.msgwin.showwindow(self.adc_scale) self.msgwin.showtext(' Change time scale if required.\n') self.msgwin.showlink('Save Last Trace', self.save) self.msgwin.showtext(' or ') self.msgwin.showlink('Save all Traces', self.save_all) self.msgwin.showtext(' to a text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'mono555.dat') self.msgwin.showtext(' ') self.msgwin.showlink('Clear all Traces', self.clear) self.msgwin.showtext(' to remove all the plots.\n') self.msgwin.showtext('\nConnect 555 output to Digital input D3. ') self.msgwin.showlink('Measure Time Delay', self.ms_delay) self.msgwin.showtext(' .To Refresh Text Window ') self.msgwin.showlink('Click Here', self.refresh)
class tran: NP = 200 adc_delay = 250 numchans = 2 xlabel = 'milli seconds' ylabel = 'Volts' size = [350.0, 272.0] def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg x = Image.open(abs_path(photograph)) im = x.resize(size) self.size[0] = float(im.size[0]) self.size[1] = float(im.size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = im.size[0], height = im.size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.data = Data() def enter(self, fd): self.ph = fd self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel, self.ylabel, self.numchans) self.ph.add_channel(0) self.ph.add_channel(1) self.ph.del_channel(2) self.ph.del_channel(3) self.msg_intro() v = [] for i in range(100): x = 127.5 + 127.5 * math.sin(2.0*math.pi*i/100) x = int(x+0.5) v.append(x) self.ph.load_wavetable(v) res = self.ph.start_wave(20) s = 'DAC is set to generate %3.1f Hz Sine Wave'%(res) self.msgwin.msg(s) self.updating = True def exit(self): self.updating = False self.ph.stop_wave() for k in range(4): self.ph.del_channel(k) #-------------------------------------------------------------------- def update(self): if self.ph == None: return phdata = self.ph.multi_read_block(self.NP, self.adc_delay, 0) if phdata == None: return self.data.points = [] self.data.points2 = [] for pt in phdata: self.data.points.append( (pt[0]/1000.0, 5.0 - 2.0 * pt[1]/1000.0) ) self.data.points2.append((pt[0]/1000.0, 5.0 - 2.0 * pt[2]/1000.0) ) self.plot2d.delete_lines() self.plot2d.line(self.data.points, 'black') self.plot2d.line(self.data.points2, 'red') def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.traces = [] self.data.traces.append(self.data.points) self.data.traces.append(self.data.points2) self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) #-------------------------- Message routines ------------- def msg_intro(self): self.msgwin.clear() self.msgwin.showtext('Primary Coil is connected to DAC (producing '+\ 'a 50 Hz signal) through a series capacitor. Primary is monitored by CH1. '+\ 'and secondary coil is monitored by CH0. The primary waveform will be seen as a'+\ 'sinewave. Watch the changes in the secondary waveform by changing the distance between '+\ 'coils and adding the ferrite core.\n') self.msgwin.showlink('Save Traces', self.save_all) self.msgwin.showtext(' Saves both the voltage waveforms to text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'trans.dat')
class explore: NP = 100 adc_delay = 10 delay_vals = [10,20,50,100,200,500,1000] numchans = 1 xlabel = 'milli seconds' ylabel = 'Volts' bw = ['black', 'white'] by = ['black', 'yellow'] br = ['black', 'red'] size = [350.0, 272.0] dotdx = 0.012 dotdy = 0.015 delta = 0.03 playing_tune = False # adc info [x, y, canvas_oval, status, color, coordinate data list] adcs = [[0.620, 0.717, None, 0, 'black', [] ],\ [0.620, 0.621, None, 0, 'red' , [] ],\ [0.620, 0.523, None, 0, 'green', [] ],\ [0.620, 0.432, None, 0, 'blue', [] ] ] #Digital have x,y,oval & value douts = [[0.21, 0.739, None, 0],\ [0.286, 0.739, None, 0],\ [0.360, 0.739, None, 0],\ [0.434, 0.739, None, 0]] dins = [[0.212, 0.836, None, 0],\ [0.285, 0.836, None, 0],\ [0.359, 0.836, None, 0],\ [0.433, 0.836, None, 0]] cmp = [0.508, 0.432, None, 0] digin_data = 0 # will force the first update cmp_stat = 0 # Comparator status ccs = [0.335, 0.246] led = [0.245, 0.339, None, 0] # x, y, oval & status dc5v = [0.333, 0.342, None, 0] # DAC, CNTR & PWG has x, y, oval, status & value fields dac = [0.434, 0.337, None, 0, 0.0] cntr = [0.333, 0.431, None, 0, 0.0] pwg = [0.433, 0.431, None, 0, 1000.0] # 1000 Hz ls_ins = [[0.841, 0.715, None, 0],\ [0.840, 0.620, None, 0]] ls_outs= [[0.701, 0.715],\ [0.701, 0.619]] ia_in = [[0.615, 0.245],\ [0.615, 0.33]] ia_out= [[0.838, 0.240],\ [0.838, 0.337]] ia_gb = [[0.689, 0.243],\ [0.689, 0.339]] ia_ge= [[0.763, 0.242],\ [0.763, 0.337]] nia_in = [0.916, 0.830] nia_out= [0.916, 0.620] nia_gb = [0.702, 0.833] nia_ge = [0.841, 0.833] gnds = [[0.911, 0.242],[0.940, 0.339], [0.508, 0.738], [0.508, 0.834]] adctl = [0.62,0.85] # Text display of ADC outputs dispadc = False adctext = [0,0,0,0] adcbox = [0,0,0,0] ph = None # The phoenix handler set by main program plot2d = None # The 2D plot window msgwin = None # The message window adc_scale = None def __init__(self, parent, size, plot, msg): self.parent = parent self.plot2d = plot self.msgwin = msg self.data = Data() x = Image.open(abs_path(photograph)) # Images are kept along with the python code im = x.resize(size) self.size[0] = float(im.size[0]) self.size[1] = float(im.size[1]) self.image = ImageTk.PhotoImage(im) self.canvas = Canvas(parent, width = im.size[0], height = im.size[1]) self.canvas.create_image(0,0,image = self.image, anchor = NW) self.adblock = self.canvas.create_rectangle(self.dotxy(self.adctl),fill='white') for k in self.douts: k[2] = self.canvas.create_oval(self.dotxy(k), outline="", fill = 'black') for k in self.dins: k[2] = self.canvas.create_oval(self.dotxy(k), outline="", fill = 'black') for k in self.adcs: k[2] = self.canvas.create_oval(self.dotxy(k), outline="", fill = 'black') for k in self.ls_ins: k[2] = self.canvas.create_oval(self.dotxy(k), outline="", fill = 'black') self.led[2] = self.canvas.create_oval(self.dotxy(self.led), outline="", fill = 'black') self.pwg[2] = self.canvas.create_oval(self.dotxy(self.pwg), outline="", fill = 'black') self.dac[2] = self.canvas.create_oval(self.dotxy(self.dac), outline="", fill = 'black') self.cntr[2] = self.canvas.create_oval(self.dotxy(self.cntr), outline="", fill = 'black') self.cmp[2] = self.canvas.create_oval(self.dotxy(self.cmp), outline="", fill = 'black') self.canvas.bind("<ButtonRelease-1>", self.mouse_click) self.canvas.pack() def enter(self, fd): # Called when entering this expt self.msg_intro() self.canvas.itemconfigure(self.led[2], fill = 'red') for adc in self.adcs: # initialize ADC data adc[3] = 0 self.canvas.itemconfigure(adc[2],fill = 'black') adc[5] = [] for xy in range(self.NP): adc[5].append( (0.0, 0.0) ) self.updating = True self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel,self.numchans) self.ph = fd try: self.ph.set_frequency(1000) for ch in range(4): self.ph.del_channel(ch) except: self.msgwin.msg('Connection NOT established', 'red') def exit(self): # Clear popup etc. here self.updating = False # if self.playing_tune == True: def set_adc_delay(self,w): d = self.adc_scale.get() self.adc_delay = self.delay_vals[d] if self.ph == None: return self.ph.set_adc_delay(self.adc_delay) self.plot2d.setWorld(0, -5, self.NP * self.adc_delay/1000.0, 5) self.plot2d.mark_axes(self.xlabel,self.ylabel,self.numchans) def calc_numchans(self): self.numchans = 0 for k in self.adcs: if k[3] == 1: self.numchans = self.numchans + 1 self.set_adc_delay(None) #-------------------------------------------------------------------- def w2s(self,x,y): #world to screen coordinates return x*self.size[0], y*self.size[1] def dotxy(self,socket): x1 = self.size[0] * (socket[0] - self.dotdx) y1 = self.size[1] * (socket[1] - self.dotdy) x2 = self.size[0] * (socket[0] + self.dotdx) y2 = self.size[1] * (socket[1] + self.dotdy) return(x1,y1,x2,y2) def set_pwg(self,w): freq = self.pwg_scale.get() f = float(freq) self.pwg[4] = self.ph.set_frequency(f) s = '%3.1f Hz'%(self.pwg[4]) self.pwg_label.config(text=s) def add_pwg(self): self.pwg_frame = Frame() self.pwg_scale = Scale(self.pwg_frame, command = self.set_pwg, from_ = 0,\ to=10000, orient=HORIZONTAL, length=100, showvalue=0) self.pwg_scale.set(self.pwg[4]) self.pwg_scale.pack(side=TOP) self.pwg_label = Label(self.pwg_frame) self.pwg_label.pack(side=TOP) xc = self.size[0] * self.pwg[0] + 10 yc = self.size[1] * self.pwg[1] + 10 self.canvas.create_window(int(xc), int(yc), \ anchor = NW, window = self.pwg_frame) def remove_pwg(self): self.canvas.itemconfigure(self.pwg[2], fill = 'black') self.pwg_label.destroy() self.pwg_scale.destroy() self.pwg_frame.destroy() #----------------------- DAC Control ------------------------ def set_dac(self,w): mv = self.dac_scale.get() self.dac[4] = float(mv) self.ph.set_voltage(self.dac[4]) s = '%4.0f mV'%(self.dac[4]) self.dac_label.config(text=s) def add_dac(self): self.dac_frame = Frame() self.dac_scale = Scale(self.dac_frame, command = self.set_dac, from_ = 0,\ to=5000, orient=HORIZONTAL, length=100, showvalue=0) self.dac_scale.set(self.dac[4]) self.dac_scale.pack(side=TOP) self.dac_label = Label(self.dac_frame) self.dac_label.pack(side=TOP) xc = self.size[0] * self.dac[0] + 10 yc = self.size[1] * self.dac[1] + 10 self.canvas.create_window(int(xc), int(yc), anchor = NE, \ window = self.dac_frame) self.canvas.itemconfigure(self.dac[2], fill = 'white') self.dac[3] = 1 def remove_dac(self): self.dac_label.destroy() self.dac_scale.destroy() self.dac_frame.destroy() self.canvas.itemconfigure(self.dac[2], fill = 'black') self.dac[3] = 0 #----------------------- CNTR Reading ------------------------ def get_cntr(self): self.cntr[4] = self.ph.measure_frequency() s = '%4.0f Hz'%(self.cntr[4]) self.cntr_value.set(s) def add_cntr(self): self.cntr_frame = Frame() self.cntr_value = StringVar() self.cntr_value.set('0.0 Hz') self.cntr_button = Button(self.cntr_frame, \ textvariable = self.cntr_value, command = self.get_cntr) self.cntr_button.pack(side=TOP) xc = self.size[0] * self.cntr[0] + 10 yc = self.size[1] * self.cntr[1] + 10 self.canvas.create_window(int(xc), int(yc), anchor = NE,\ window = self.cntr_frame) self.canvas.pack() self.get_cntr() def remove_cntr(self): self.cntr_button.destroy() self.cntr_frame.destroy() self.canvas.itemconfigure(self.cntr[2], fill = 'black') self.cntr[3] = 0 #------------------------------------------------------------- def selected(self, socket, e): if abs(e.x / self.size[0] - socket[0]) < 0.03 and \ abs(e.y / self.size[1] - socket[1]) < 0.03: return True return False def mouse_click(self, e): # Runs when user clicks on the Photograph self.msg_intro() if self.ph == None: self.msgwin.msg('Connection NOT established', 'red') return if self.selected(self.adctl,e): self.msg_adcdisp() if self.dispadc == False: self.dispadc = True self.canvas.itemconfigure(self.adblock,fill='yellow') for i in range(4): tl = self.w2s(0.65, self.adcs[i][1] - .03) rb = self.w2s(0.76, self.adcs[i][1] + .03) self.adcbox[i] = self.canvas.create_rectangle(tl[0], tl[1], rb[0], rb[1], fill = 'white') txy = self.w2s(0.655, self.adcs[i][1]) self.adctext[i] = self.canvas.create_text(txy, text = 'TEXT', fill = 'black', anchor = 'w') else: self.dispadc = False self.canvas.itemconfigure(self.adblock,fill='white') for i in range(4): self.canvas.delete(self.adcbox[i]) self.canvas.delete(self.adctext[i]) return for k in range(4): # ADC Inputs if self.selected(self.adcs[k], e): self.msg_adc() if self.adcs[k][3] == 0: # Not selected self.adcs[k][3] = 1 # Add trace self.calc_numchans() self.canvas.itemconfigure(self.adcs[k][2], fill = 'white') self.ph.add_channel(k) else: self.adcs[k][3] = 0 # Remove trace self.calc_numchans() self.canvas.itemconfigure(self.adcs[k][2], fill = 'black') self.ph.del_channel(k) for ls in self.ls_ins: # Level Shifters if self.selected(ls, e): self.msg_adc() ls[3] = ~ls[3] & 1 # Toggle status self.canvas.itemconfigure(ls[2],fill = self.bw[ls[3]] ) if self.selected(self.pwg, e): # PWG self.msg_pwg() if self.dac[3] == 1: # Either DAC or PWG at a time self.msgwin.msg('Remove DAC to use PWG','red') return if self.pwg[3] == 1: self.pwg[3] = 0 self.remove_pwg() else: self.add_pwg() self.pwg[3] = 1 self.canvas.itemconfigure(self.pwg[2], fill = self.bw[self.pwg[3]]) if self.selected(self.dac, e): # DAC self.msg_dac() if self.pwg[3] == 1: self.msgwin.msg( 'Remove PWG to use DAC','red') return if self.dac[3] == 1: self.dac[3] = 0 self.remove_dac() else: self.add_dac() self.dac[3] = 1 self.canvas.itemconfigure(self.dac[2], \ fill = self.bw[self.dac[3]]) if self.selected(self.cntr, e): # CNTR self.msg_cntr() if self.cntr[3] == 1: self.cntr[3] = 0 self.remove_cntr() else: self.cntr[3] = 1 self.add_cntr() self.canvas.itemconfigure(self.cntr[2],\ fill = self.bw[self.cntr[3]]) data = 0 # Digital Outputs for k in range(4): if self.selected(self.douts[k], e): self.douts[k][3] = (~self.douts[k][3]) & 1 # Toggle status self.msg_douts() self.canvas.itemconfigure(self.douts[k][2],\ fill = self.br[self.douts[k][3]] ) self.msgwin.showtext('\nYou just toggled D%d'%(k)) data = data | (self.douts[k][3] << k) self.ph.write_outputs(data) for k in range(4): # Digital Inputs if self.selected(self.dins[k], e): self.msg_dins() tp = self.ph.multi_r2rtime(k,99) if tp > 0: fr = 1.0e8/tp else: fr = 0.0 self.msgwin.showtext('\nFrequency = %5.2f Hz'%(fr)) if self.selected(self.cmp, e): self.msg_cmp() tp = self.ph.multi_r2rtime(4,99) if tp > 0: fr = 1.0e8/tp else: fr = 0.0 self.msgwin.showtext('\nFrequency = %5.2f Hz'%(fr)) # No action other than help message required for the following items if self.selected(self.ccs, e): self.msg_ccs() if self.selected(self.dc5v, e): self.msg_dc5v() for k in range(2): # Inverting Amps if self.selected(self.ia_in[k], e) or \ self.selected(self.ia_out[k], e) or \ self.selected(self.ia_gb[k], e) or \ self.selected(self.ia_ge[k], e): self.msg_ia() # Non Inverting amp if self.selected(self.nia_in, e) or \ self.selected(self.nia_out, e) or \ self.selected(self.nia_gb, e) or \ self.selected(self.nia_ge, e): self.msg_nia() for k in range(4): # GND Sockets if self.selected(self.gnds[k], e): self.msg_gnds() self.canvas.pack() #---------------------Panel Click action ends here----------------- def update(self): try: data = self.ph.read_inputs() & 15 # Digital Inputs except: self.msgwin.msg('Connection NOT established', 'red') if self.dispadc == True: for i in range(2): self.ph.select_adc(i) if self.ls_ins[i][3]: ss = '%4.2f V'%(self.ph.get_voltage_bip()[1]*0.001) else: ss = '%4.2f V'%(self.ph.get_voltage()[1]*0.001) self.canvas.itemconfigure(self.adctext[i],text = ss) for i in range(2,4): self.ph.select_adc(i) ss = '%4.2f V'%(self.ph.get_voltage()[1]*0.001) self.canvas.itemconfigure(self.adctext[i],text = ss) if data != self.digin_data: self.digin_data = data for k in range(4): self.canvas.itemconfigure(self.dins[k][2], \ fill = self.by[(data >> k) & 1]) self.canvas.pack() cs = ~self.ph.read_acomp() & 1 # returns 1 when socket if < 1.23 V if cs != self.cmp_stat: self.cmp_stat = cs self.canvas.itemconfigure(self.cmp[2], fill = self.by[cs]) self.canvas.pack() if self.updating == False: return have_work = False for k in self.adcs: if k[3] == 1: have_work = True if have_work == False: # No channels selected return try: self.phdata = self.ph.multi_read_block(self.NP, self.adc_delay, 0) if self.phdata == None: return except: return ch = 0; for k in range(4): # Copy data to traces adc = self.adcs[k] if self.adcs[k][3] == 1: # Active channel if k < 2: # CH0 or CH1 for xy in range(self.NP): if self.ls_ins[k][3] == 0: # No Level Shifter self.adcs[k][5][xy] = (self.phdata[xy][0]/1000.0,\ self.phdata[xy][ch+1]/1000.0 ) else: self.adcs[k][5][xy] = (self.phdata[xy][0]/1000.0, \ 5.0 - 2.0 * self.phdata[xy][ch+1]/1000.0 ) else: for xy in range(self.NP): self.adcs[k][5][xy] = (self.phdata[xy][0]/1000.0,\ self.phdata[xy][ch+1]/1000.0) ch = ch + 1 self.plot2d.delete_lines() for adc in self.adcs: if adc[3] == 1: # Active channel self.plot2d.line(adc[5], adc[4]) #----------------------------------------------------------------------- def start(self,e): self.updating = True def stop(self,e): self.updating = False def save_all(self,e): fname = self.fntext.get() if fname == None: return self.data.traces = [] for adc in self.adcs: if adc[3] == 1: # Active channel self.data.traces.append(adc[5]) self.data.save_all(fname) self.msgwin.msg('Data saved to '+ fname) #-------------------------- Message routines ------------- def msg_intro(self): self.msgwin.clear() self.msgwin.showtext('This section helps you to explore ' +\ 'the different building blocks of PHOENIX. ') self.msgwin.showtext('Click on the different Sockets ', 'blue') self.msgwin.showtext('shown in the Photograph to explore the system. '+\ 'Select "Connect" from the main before proceeding.\n'+\ 'From here you can use Phoenix as a test equipment also. The ADC '+\ 'inputs acts like CRO inputs. Digital Inputs can measure frequency '+\ 'of the 0-5V range signals etc.') def msg_ccs(self): self.msgwin.clear() self.msgwin.showtext('This socket gives a constant current of 1 mA ' +\ 'to load resistors upto 1KOhm. This feature is mainly used for ' +\ 'temperature measurements using RTD sensor elements.') def msg_cmp(self): self.msgwin.clear() self.msgwin.showtext('This is one of the Inputs of an Analog ' +\ 'Comparator. The other input is internally connected to around ' +\ '1.2 V. Connect the DAC output to CMP input and change the DAC ' +\ 'slider to see how it works. Similar to Digital Input Sockets ' +\ 'the CMP input also is used for time interval measurements. '+\ 'Clicking on CMP Socket will try to measure the '+\ 'frequency of the signal at the input. If nothing is connected '+\ 'the message will be displayed after the timeout and you will '+\ 'notice a delay.') def msg_dc5v(self): self.msgwin.clear() self.msgwin.showtext('Phoenix is powered by an unregulated 9V DC ' +\ 'supply which is regulated inside. The 5V DC output is available ' +\ 'on the Panel. This can only supply around 100 mA of current.') def msg_pwg(self): self.msgwin.clear() self.msgwin.showtext('The Programmable Waveform Generator ' +\ 'gives a square wave output. Frequency can be varied '+\ 'between 13 Hz and 10 KHz using the slider. ' +\ 'ou cannot set it to all the Using the set_frequency() '+\ 'function in the Phoenix library you can set it up to 4 MHz.'+\ 'The voltage level swings between 0 and 5V. To view this ' +\ 'waveform connect a wire from PWG to CH0 and click on CH0 to ' +\ 'add that channel to the plot window. Move the slider and ' +\ 'see the result. Frequency cannot be set to all the values '+\ 'between the limits due to the nature of the hardware.\n\n') self.msgwin.showtext('You can play a tune on PWG. Connect the '+\ 'Loudspeaker from PWG to Ground (with 100 Ohm series resisitor).\n'+\ 'Quit this and run /docs/phoenix/applications/TerminalProgs/jan.py') def msg_dac(self): self.msgwin.clear() self.msgwin.showtext('The DAC socket can be programmed to give ' +\ 'a DC voltage between 0 to 5V. The DAC us implemented using ' +\ 'Pulse Width Modulation technique. In fact the DAC socket is ' +\ 'the PWG socket output filtered. When in DAC mode the PWG will ' +\ 'show a 31.25 KHz squarewave whose duty cycle varies with the '+\ 'DAC voltage setting. Due to this reason, you can only use PWG '+\ 'or DAC at a time.') def msg_cntr(self): self.msgwin.clear() self.msgwin.showtext('Measures the frequency of the 5V signal ' +\ 'connected at the input. To test this feature, connect PWG output ' +\ 'to CNTR input using a cable and set PWG to some value. ' +\ 'CNTR can be updated by clicking on the currently displyed ' +\ 'frequency value.') def msg_douts(self): self.msgwin.clear() self.msgwin.showtext('The Digital Output Sockets can be made ' +\ '0V or 5V under software control. Under this program, clicking ' +\ 'on a socket will toggle the state. The output D0 alone is' +\ 'transistor buffered to drive upto 100 mA. The rest can drive ' +\ 'only upto 5 mA ') def msg_dins(self): self.msgwin.clear() self.msgwin.showtext('The voltage level at the Digital Input sockets ' +\ 'can be read through software. This program makes the socket hole ' +\ 'Yellow if it is conencted to 0V, floating inputs are 5 Volts. ' +\ 'Connect one socket to GND using a cable and watch the picture above. ' +\ 'The time between voltage level transitions at Digital Input'+\ 'Sockets can be measured with microsecond accuracy. '+\ 'Clicking on a Digital input Socket will try to measure the '+\ 'frequency of the signal at the input. If nothing is connected '+\ 'the message will be displayed after the timeout and you will '+\ 'notice a delay.') def msg_ls(self): self.msgwin.clear() self.msgwin.showtext('Level Shifting Amplifiers convert a -5V to 5V ' +\ 'range signal to a 0 to 5V range signal. A 5V DC value is added ' +\ 'to the input signal and the amplitude is reduced to half. With ' +\ 'the input connected to GND, the output will be nearly 2.5 Volts.') def msg_ia(self): self.msgwin.clear() self.msgwin.showtext(' ' +\ 'The variable gain Inverting Amplifiers are implemented using '+\ 'TL084 op-amps. ' +\ 'The Feedback Resistor (Rf)is fixed at 10 KOhms. The Input Resistor ' +\ '(Ri) can be changed by the user to adjust the gain. Remember that ' +\ 'TL084 Op-amps have around 2mV (multiply by the gain) offset. The '+\ 'Op-amps inside Phoenix are powered by a charge pump generating '+\ '+8V and -7V supplies from +5V. The output of these amplifiers ' +\ 'saturate at nearly 5V due to this reason.') def msg_nia(self): self.msgwin.clear() self.msgwin.showtext(' ' +\ 'The variable gain Non-Inverting Amplifiers are implemented using '+\ 'LM358 op-amp, which is good only for low frequencies. ' +\ 'The Feedback Resistor (Rf)is fixed at 10 KOhms. The Gain Selection '+\ ' Resistor (Rg) can be changed by the user to adjust the gain. '+\ 'Op-amps inside Phoenix are powered by a charge pump generating '+\ '+8V and -7V supplies from +5V. The output of these amplifiers ' +\ 'saturate at nearly 5V due to this reason.') def msg_gnds(self): self.msgwin.clear() self.msgwin.showtext('These sockets are at zero volts. ') def msg_adcdisp(self): self.msgwin.clear() self.msgwin.showtext('Clicking on the white square below the ADC Inputs '+\ 'starts the display of voltages at the Analog inputs CH0 to CH3. '+\ 'Click again to stop displaying the voltage valeus.') def msg_adc(self): self.msgwin.clear() self.msgwin.showtext('The voltage input at the ADC input channels can be ' +\ 'read through software. They can be read at regular time intervals and ' +\ 'plotted to get the input waveform. Four channels are available. Clicking '+\ 'on the sockets will Enable/Disable scanning. The ADC inputs must be '+\ 'between 0 to 5V. However, CH0 and CH1 can be used with the level shifting '+\ 'amplifiers to display a -5V to 5V range signal. To display the voltage '+\ 'at the Level Shifter Input Socket click on it. The functions available are:\n') self.msgwin.showlink('Stop Scanning', self.stop) self.msgwin.showtext(' To stop updating.\n') self.msgwin.showlink('Save Traces', self.save_all) self.msgwin.showtext(' to save the data to text file named ') self.fntext = Entry(None, width =20, fg = 'red') self.msgwin.showwindow(self.fntext) self.fntext.insert(END,'cro.dat') self.msgwin.showtext('\n') self.msgwin.showlink('Start Scanning', self.start) self.msgwin.showtext(' To start updating again') self.msgwin.showtext('\nAdjust the time axis using the slider ') if self.adc_scale != None: self.adc_scale.destroy() self.adc_scale = Scale(None, command = self.set_adc_delay, \ from_ = 0, to=6, orient=HORIZONTAL, length=100, showvalue=0) for i in range(len(self.delay_vals)): if self.delay_vals[i] == self.adc_delay: self.adc_scale.set(i) self.msgwin.showwindow(self.adc_scale) self.msgwin.showtext('. What your are changing is the time interval '+\ 'between digitizations.')