New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added clocks and powersupply #4
Changes from 10 commits
e088258
3fa2ea1
8aa490b
09bf10d
484d218
0cc1ae4
ed0a7d6
8448be3
91ef6cc
e4f8b9d
d4345a2
9283bab
27c7e9f
5b4e726
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
""" | ||
Requests for the Code: | ||
the code should have an power Output on the Voltagesource VDD=5V /VAD=5V | ||
the code should build a Masterclock with a frequency inbetween 0.8 to 4 MHz, typical 2 MHz. The Voltagerange of the Clock | ||
shall be 0-4V | ||
The Sensor will be run in the Shutter Mode, so the SH-Clock and the ICG-Clock must be working as following: | ||
The SH is a squarewave with a high level of typical 4V and indicates the integration_time, due to the oscilloscope in the triggermode the integration must be at least 1µs. | ||
Tha Datasheet says, that the integrationtime in shuttermode must be at least 10µs. | ||
The ICG is a squarewave that indicates the 'read out time' of the sample, so it has to be 3694*integration_time*samples_per_element | ||
The integrationtime is started with the falling flank of the SH and and lasts till the next falling flank. | ||
The analog input of the sensor shall be read by the the osilloscope. | ||
The analog voltage signal shall be saved over the time and be integrated to get a digital signal. | ||
the algotithims still needs to be definded. | ||
|
||
""" | ||
|
||
import numpy as np | ||
import time | ||
import math | ||
from pslab.instrument.waveform_generator import PWMGenerator | ||
from pslab.instrument.oscilloscope import Oscilloscope | ||
from pslab.serial_handler import SerialHandler | ||
from pslab.instrument.logic_analyzer import LogicAnalyzer | ||
from pslab.instrument.power_supply import PowerSupply | ||
|
||
frequency_master_clock = 2e6 # no need to specify the variable type (float). frequency_master_clock = float(2e6) turns into frequency_master_clock = 2e6. Same for integration_time variable. Im Datentyp float werden reele Zahlen in Exponentialdarstellung geschrieben (also Gleitkommazahlen). float(2e6) turns 2e6 which is already a float into a float. In other words, it does nothing; However f.e. 280,7 would have also been linked to float instead of int | ||
integration_elements = 3694 # according to timing requests | ||
integration_time = 10e-6 # time in seconds | ||
oscillator_frequency = 128e6 #frequency of the oscilliator in Mhz | ||
microseconds_in_second = 1e6 | ||
min_voltage_output = 2.0 # defines the minimum voltage output of the sensor. The oscilloscope gets enabled by the trigger over that Voltage. range must be verified | ||
max_voltage_output = 4.0 # maximum voltage output of the sensor. must be verified | ||
samples_per_element = 2 | ||
read_out_time = integration_time*integration_elements | ||
|
||
class TCD1304(): | ||
def __init__( | ||
self, #Initializing; self is always first parameter of methods located inside a class and is not limited to the __init__ method but to most methods. A method is a function that belongs to a class | ||
min_masterclock_frequency = 0.8e6, # no need to specify the variable type (float). View comment in L37 | ||
max_masterclock_frequency = 4e6, # no need to specify the variable type (float). View comment in L37 | ||
frequency = frequency_master_clock, #default frequency of masterclock 2 MHz; # no need to specify the variable type (float). View comment in L37 | ||
min_voltagerange_clock: float = 0, #it says that min_voltagerange_clock should (!) be a float. Otherwise it would not turn into a float automatically. Output on float will be 0.0 V and on int 0 V. | ||
max_voltagerange_clock: float = 4, | ||
): | ||
|
||
self.min_masterclock_frequency = min_masterclock_frequency #initializing starts from here (? Not sure though) | ||
self.max_masterclock_frequency = max_masterclock_frequency | ||
self.frequency = frequency | ||
self.min_voltagerange_clock = min_voltagerange_clock | ||
self.max_voltagerange_clock = max_voltagerange_clock | ||
self.pwmgen = PWMGenerator() #once assigned in __init__ self.pwmgen can be used in other methods | ||
self.scope = Oscilloscope () | ||
self.ps = PowerSupply() | ||
|
||
def power_source (): # puts a voltage of 4V on PV1 | ||
ps = PowerSupply() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should use the |
||
ps.pv1 = 4 | ||
bessman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ps.pv1 | ||
freddiscr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As pointed out before, this line is unnecessary. |
||
|
||
def icg_clock (self): # on SQ3 starts and stops the reading of the sensor; this third clock is the slowest clock | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't put whitespace between the function name and the parentheses. |
||
self.pwmgen.set_state(sq3=True) | ||
time.sleep(read_out_time) | ||
self.pwmgen.set_state(sq3=False) | ||
|
||
def master_clock (self): # puts PWM with frequency of 2MHz on SQ1; masterclock is the fastest clock | ||
prescaler = int(math.log(oscillator_frequency / frequency_master_clock) / math.log(2)) # When setting a frequency by mapping the reference clock directly to a PWM output, only frequencies which are even factors of 128 MHz (the frequency of the PSLab's main oscillator) are available. The frequency is therefore not set by specifying the frequency itself, but by setting a prescaler. | ||
self.pwmgen.map_reference_clock(["SQ1"], prescaler) | ||
|
||
def sh_clock (self): # on SQ2 sets pulse for the integrationtime. Running the Sensor in shutter mode try with tint (min) = 10µs | ||
self.pwmgen.generate(["SQ2"], 1/integration_time, [0.5] ) | ||
|
||
def analog_signal_read (self, block:False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method should not take a |
||
self.scope.select_range('CH1', max_voltage_output) # voltagerange should be fitted to the sensors output for better resolution. sensor otput is between 2V-3V due to datasheet | ||
self.scope.configure_trigger(channel = 'CH1', voltage = min_voltage_output ) # starts recording , when voltage is over a certain level | ||
self.scope.capture(channels=1, samples=integration_elements*samples_per_element, timegap=integration_time/samples_per_element, block=False) | ||
icg_clock() | ||
bessman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
x, = self.scope.capture() # putting timestamps into numpy array (don't know, if that is necessary for our purpose) | ||
bessman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
y, = self.scope.fetch_data() # collecting the Voltage in nonblocking mode | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably want to return this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could just return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair point There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I corrected the "last" few things and committed it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first step to test the code is to check that you get some kind of output at all from the sensor. You have the sensor set up, right? What happens when you connect it to the PSLab and run this code? If you get some output, the next step is to compare it to a known reference. A fluorescent light source with a known spectrum, for example. The output should match the reference. As for the code, there are still a few errors (which I will address separately). Aside from the errors, there are some more things to do before the code can be merged:
from TCD1304 import TCD1304
spectrometer = TCD1304()
spectrometer.power_source()
spectrometer.master_clock()
spectrometer.sh_clock()
output = spectrometer.analog_signal_read() Is there any reason why the user should have to manually power the device and set up the clocks? Why not start them automatically when the object is created? It would be more user friendly like this: from TCD1304 import TCD1304
spectrometer = TCD1304()
output = spectrometer.read()
|
||
|
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No parentheses needed.