Commands¶
Send commands to the dev-kit.
Example
>>> import microspec
>>> kit = microspec.Devkit()
If status=='TIMEOUT' it means the command timed out before a
response was received.
For applications that run a long time, such as data loggers and
free-running plot GUIs, there are occasional timeouts when
calling captureFrame(). These
applications should check the
status
attribute of responses to
captureFrame() and ignore the
data if the status is ‘TIMEOUT’.
A UserWarning is also issued when a timeout occurs,
identifying which command timed out. This is not an exception, so
it does not cause the application to terminate.
Notes
The Devkit attribute timeout
defaults to 2 seconds, which is usually long enough to send a
command, execute it on the dev-kit, and receive a response back
on the host computer running the application. It is rare to
observe a timeout when sending commands at the REPL or executing
a script that runs a few commands and exits. Users can observe
a timeout condition by setting a very short timeout such as 1ms.
-
class
microspec.commands.Devkit¶ Interface for dev-kit communication.
Every communication with the dev-kit consists of:
- a command sent to the dev-kit
- a response received from the dev-kit
Calling a
Devkitmethod sends the command. The method’s return value is the response.Example
Command
getBridgeLEDreturnsgetBridgeLED_response:>>> import microspec >>> kit = microspec.Devkit() >>> kit.getBridgeLED() getBridgeLED_response(status='OK', led_setting='GREEN')
Assign the response to variable
reply:>>> reply = kit.getBridgeLED()
Access each part of the response as attributes
statusandled_setting:>>> reply.status 'OK' >>> reply.led_setting 'GREEN'
-
autoExposure()¶ Auto-expose the spectrometer.
Tell dev-kit firmware to adjust spectrometer exposure time until peak signal strength hits the auto-expose target.
Returns: - status
- success
- iterations
Return type: autoExposure_responseSee also
setAutoExposeConfig()- configure auto-expose parameters
getExposure()- get the new exposure time after the auto-expose
Examples
>>> kit.autoExposure() # doctest: +SKIP autoExposure_response(status='OK', success='GAVE_UP', iterations=4)
-
captureFrame()¶ One-liner
Returns: - status (str) – Serial communication status, either ‘OK’, ‘ERROR’, or ‘TIMEOUT’.
- num_pixels (int) – The number of pixels in the frame (either 392 or 784 depending on pixel binning).
- pixels (list) – The 16-bit ADC counts at each pixel, starting with pixel 1 and ending with pixel 392 or 784 (depending on pixel binning).
- frame (dict) – Python dictionary where the key is the pixel number and the value is the 16-bit ADC counts at that pixel.
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
Capture a frame:
>>> reply = kit.captureFrame()
The frame is stored as a Python
listof numbers. Each number is the signal strength at that pixel in units of counts.The list starts with pixel 1. With pixel binning on, the frame has 392 pixels, so the list ends with pixel 392:
>>> print(reply) captureFrame_response(status='OK', num_pixels=392, pixels=[...], frame={...})
The list
pixelsis hard to read on its own (index 0 is pixel 1, index 1 is pixel 2, etc.):>>> print(reply.pixels) [..., ..., ...]
It is usually more convenient for applications to use the dict
framebecause it tags each pixel with its pixel number:>>> print(reply.frame) {1: ..., 2: ..., ..., 391: ..., 392: ...}
This is still hard to read in the REPL. Put each pixel on its own line:
>>> import pprint >>> pprint.pprint(reply.frame) {1: ..., 2: ..., ... 391: ..., 392: ...}
Alternatively, turn the
(pixel number, pixel value)pairs into a list oftuples:>>> frame = list(zip(range(1,reply.num_pixels+1), reply.pixels)) >>> pprint.pprint(frame) [(1, ...), (2, ...), ..., (391, ...), (392,...)]
Notes
If there is a timeout,
captureFrame()returnsstatus='TIMEOUT', and fills the reply with obviously bad data:num_pixels=0pixels=[]frame={}
Applications are protected from accidentally setting a
Devkit.timeoutthat is shorter than the exposure time (because this guarantees thatcaptureFrame()timeouts before a response is received).If the timeout is less than the exposure time,
captureFrame()uses aDevkit.timeoutthat is one second longer than the exposure time.If an application loops
captureFrame()for a long time (such as the data logging and plotting GUI examples above), there will likely be a timeout.In this case,
captureFrame()issues aUserWarningdescribing which command caused the timeout.This is only a warning because the timeout is hardware-dependent. It does not indicate a bug in the application code.The timeout
UserWarningprints to the console and can safely be ignored. If the timeouts are a frequent event, it indicates a problem with the host computer, its USB port, or the USB cable.
-
getAutoExposeConfig()¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
-
getBridgeLED(led_num: int = 0)¶ Read the state of the indicator LED on the Bridge PCB.
Examples
Setup – set the LED to a known state:
>>> import microspec as usp >>> kit = usp.Devkit() >>> kit.setBridgeLED(led_num=0, led_setting=usp.GREEN) setBridgeLED_response(status='OK')
Call
getBridgeLED:>>> kit.getBridgeLED() getBridgeLED_response(status='OK', led_setting='GREEN')
See also
-
getExposure()¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
getExposurereports exposure time in both units:>>> # Setup: set exposure time to 5ms >>> kit.setExposure(ms=5) setExposure_response(status='OK') >>> # Test: expect 5.0ms and 250 cycles >>> kit.getExposure() getExposure_response(status='OK', ms=5.0, cycles=250)
-
getSensorConfig()¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit() >>> kit.setSensorConfig() # restore default config setSensorConfig_response(status='OK')
Read the spectrometer’s pixel configuration:
>>> kit.getSensorConfig() getSensorConfig_response(status='OK', binning='BINNING_ON', gain='GAIN1X', row_bitmap='ALL_ROWS')
-
getSensorLED(led_num: int)¶ Read the state of an indicator LED on the Sensor PCB.
There are two indicator LEDS: led0 and led1.
Note
Application code should never call this method:
- led0 is OFF while commands execute, so the state returned
by
microspec.commands.Devkit.getSensorLED()is always OFF - led1 indicates the success of auto-expose, but this is
directly available from the
successattribute of the response tomicrospec.commands.Devkit.autoExposure()
Examples
Setup – set the LEDs to a known state:
>>> import microspec as usp >>> kit = usp.Devkit() >>> kit.setSensorLED(usp.GREEN, led_num=0) setSensorLED_response(status='OK') >>> kit.setSensorLED(usp.GREEN, led_num=1) setSensorLED_response(status='OK')
Call
getSensorLED:>>> kit.getSensorLED(0) # Expect OFF getSensorLED_response(status='OK', led_setting='OFF') >>> kit.getSensorLED(1) # Expect GREEN getSensorLED_response(status='OK', led_setting='GREEN')
See also
- led0 is OFF while commands execute, so the state returned
by
-
setAutoExposeConfig(max_tries: int = 12, start_pixel: int = 7, stop_pixel: int = 392, target: int = 46420, target_tolerance: int = 3277, max_exposure: int = 10000)¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
Configure auto-expose with …:
>>> kit.setAutoExposeConfig() setAutoExposeConfig_response(status='OK') >>> kit.getAutoExposeConfig() getAutoExposeConfig_response(status='OK', max_tries=12, start_pixel=7, stop_pixel=392, target=46420, target_tolerance=3277, max_exposure=10000)
Configure the dev-kit with the default auto-expose parameters:
>>> kit.setAutoExposeConfig() setAutoExposeConfig_response(status='OK') >>> kit.getAutoExposeConfig() getAutoExposeConfig_response(status='OK', max_tries=12, start_pixel=7, stop_pixel=392, target=46420, target_tolerance=3277, max_exposure=10000)
-
setBridgeLED(led_setting: int, led_num: int = 0)¶ Set the LED on the Bridge PCB to OFF, GREEN, or RED.
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
Call
setBridgeLEDwith optional parameterled_num:>>> kit.setBridgeLED(led_num=0, led_setting=usp.GREEN) setBridgeLED_response(status='OK')
Call
setBridgeLEDwithout optional parameterled_num:>>> kit.setBridgeLED(led_setting=usp.GREEN) setBridgeLED_response(status='OK')
Call
setBridgeLEDwith an invalid parameter value:>>> kit.setBridgeLED(led_num=1, led_setting=usp.GREEN) setBridgeLED_response(status='ERROR')
See also
-
setExposure(ms: float = None, cycles: int = None)¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit()
setExposureaccepts time in units of ms:>>> kit.setExposure(ms=5.0) setExposure_response(status='OK')
setExposureaccepts time in units of cycles:>>> kit.setExposure(cycles=250) setExposure_response(status='OK')
setExposurerequires an exposure time input>>> kit.setExposure() Traceback (most recent call last): ... TypeError: setExposure() missing 1 required argument: 'ms' or 'cycles'
Calling
setExposurewith bothmsandcyclesis not allowed:>>> kit.setExposure(ms=5.0, cycles=250) Traceback (most recent call last): ... TypeError: setExposure() got an unexpected keyword 'cycles' (requires 'ms' or 'cycles' but received both)
Exposure time must be within the allowed range:
>>> # Min exposure time in milliseconds: >>> usp.to_ms(usp.MIN_CYCLES) 0.02 >>> # Max exposure time in milliseconds: >>> usp.to_ms(usp.MAX_CYCLES) 1310.0 >>> # Try exceeding maximum exposure: >>> kit.setExposure(cycles=usp.MAX_CYCLES+1) Traceback (most recent call last): ... TypeError: Exposure time cannot be more than 65500 cycles.
>>> # Try exposure time below the minimum: >>> kit.setExposure(cycles=usp.MIN_CYCLES-1) Traceback (most recent call last): ... TypeError: Exposure time cannot be less than 1 cycles.
-
setSensorConfig(binning: int = 1, gain: int = 1, row_bitmap: int = 31)¶ One-liner
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit() #doctest: +SKIP
Configure the spectrometer with pixel binning off:
>>> kit.setSensorConfig(binning=usp.BINNING_OFF) #doctest: +SKIP setSensorConfig_response(status='OK') >>> kit.getSensorConfig() #doctest: +SKIP getSensorConfig_response(status='OK', binning='BINNING_OFF', gain='GAIN1X', row_bitmap='ALL_ROWS')
Configure the spectrometer with the default pixel configuration:
>>> kit.setSensorConfig() #doctest: +SKIP setSensorConfig_response(status='OK') >>> kit.getSensorConfig() #doctest: +SKIP getSensorConfig_response(status='OK', binning='BINNING_ON', gain='GAIN1X', row_bitmap='ALL_ROWS')
-
setSensorLED(led_setting: int, led_num: int)¶ Set the LEDs on the Sensor PCB to OFF, GREEN, or RED.
There are two indicator LEDS:
led0
- usually appears GREEN
- is OFF while a command is being executed
- only turns RED if there is a serious error in serial communication (this should never happen)
led1
- usually appears GREEN
- turns RED during auto-expose
- stays RED if auto-expose fails
- turns GREEN if auto-expose succeeds
Note
Application code should never call this method. The LEDs are controlled by firmware to indicate status. Controlling the LEDs from the application undermines the LEDs purpose as status indicators.
Examples
Setup:
>>> import microspec as usp >>> kit = usp.Devkit() #doctest: +SKIP
Turn led0 and led1 OFF:
>>> kit.setSensorLED(usp.OFF, 0) #doctest: +SKIP setSensorLED_response(status='OK') >>> kit.setSensorLED(usp.OFF, 1) #doctest: +SKIP setSensorLED_response(status='OK')
Turn led0 and led1 RED:
>>> kit.setSensorLED(usp.RED, 0) #doctest: +SKIP setSensorLED_response(status='OK') >>> kit.setSensorLED(usp.RED, 1) #doctest: +SKIP setSensorLED_response(status='OK')
Turn led0 and led1 GREEN:
>>> kit.setSensorLED(usp.GREEN, 0) #doctest: +SKIP setSensorLED_response(status='OK') >>> kit.setSensorLED(usp.GREEN, 1) #doctest: +SKIP setSensorLED_response(status='OK')