BitsSharp

Control a CRS Bits# device. See typical usage in the class summary (and in the menu demos>hardware>BitsBox of PsychoPy’s Coder view).

Attributes

BitsSharp(*args, **kwargs)

A class to support functions of the Bits# (and most Display++ functions This device uses the CDC (serial port) connection to the Bits box.

BitsSharp.mode

Get/set the mode of the BitsSharp to one of: "bits++" "mono++" "color++" "status" "storage" "auto"

BitsSharp.isAwake()

Test whether we have an active connection on the virtual serial port

BitsSharp.getInfo()

Returns a python dictionary of info about the Bits Sharp box

BitsSharp.checkConfig([level, demoMode, logFile])

Checks whether there is a configuration for this device and whether it's correct

BitsSharp.gammaCorrectFile

Get / set the gamma correction file to be used (as stored on the device)

BitsSharp.temporalDithering

Temporal dithering can be set to True or False

BitsSharp.monitorEDID

Get / set the EDID file for the monitor.

BitsSharp.beep([freq, dur])

Make a beep of a given frequency and duration

BitsSharp.getVideoLine(lineN, nPixels[, ...])

Return the r,g,b values for a number of pixels on a particular video line

BitsSharp.start()

[Not currently implemented] Used to begin event collection by the device.

BitsSharp.stop()

[Not currently implemented] Used to stop event collection by the device.

Direct communications with the serial port:

BitsSharp.sendMessage(message[, autoLog])

Send a command to the device (does not wait for a reply or sleep())

BitsSharp.getResponse([length, timeout])

Read the latest response from the serial port

Control the CLUT (Bits++ mode only):

BitsSharp.setContrast(contrast[, LUTrange, ...])

Set the contrast of the LUT for 'bits++' mode only :Parameters:

BitsSharp.setGamma(newGamma)

Set the LUT to have the requested gamma value Currently also resets the LUT to be a linear contrast ramp spanning its full range.

BitsSharp.setLUT([newLUT, gammaCorrect, ...])

SetLUT is only really needed for bits++ mode of bits# to set the look-up table (256 values with 14bits each).

Details

class psychopy.hardware.crs.bits.BitsSharp(*args, **kwargs)[source]

A class to support functions of the Bits# (and most Display++ functions This device uses the CDC (serial port) connection to the Bits box. To use it you must have followed the instructions from CRS Ltd. to get your box into the CDC communication mode. Typical usage (also see demo in Coder view demos>hardware>BitsBox ):

from psychopy import visual
from psychopy.hardware import crs
# we need to be rendering to framebuffer
win = visual.Window([1024,768], useFBO=True)
bits = crs.BitsSharp(win, mode = 'mono++')
# You can continue using your window as normal and OpenGL shaders
# will convert the output as needed
print(bits.info)
if not bits.OK:
    print('failed to connect to Bits box')
    core.quit()
core.wait(0.1)
# now, you can change modes using
bits.mode = 'mono++' # 'color++', 'mono++', 'bits++', 'status'

Note that the firmware in Bits# boxes varies over time and some features of this class may not work for all firmware versions. Also Bits# boxes can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

RTBox commands that reset the key mapping have been found not to work one some firmware

Parameters:
  • win (a PsychoPy Window object, required) –

  • portName (str or int) – the (virtual) serial port to which the device is connected. If None then PsychoPy will search available serial ports and test communication (on OSX, the first match of /dev/tty.usbmodemfa* will be used and on linux /dev/ttyS0 will be used

  • mode ('bits++', 'color++', 'mono++', 'status') –

  • checkConfigLevel (int) –

    Allows you to specify how much checking of the device is done to ensure a valid identity look-up table. If you specify one level and it fails then the check will be escalated to the next level (e.g. if we check level 1 and find that it fails we try to find a new LUT):

    • 0 don’t check at all

    • 1 check that the graphics driver and OS version haven’t

      changed since last LUT calibration

    • 2 check that the current LUT calibration still provides

      identity (requires switch to status mode)

    • 3 search for a new identity look-up table (requires

      switch to status mode)

  • gammaCorrect (string) –

    G overning how gamma correction is performed: - ‘hardware’: use the gamma correction file stored on the

    hardware

    • ’FBO’: gamma correct using shaders when rendering the FBO to back buffer

    • ’bitsMode’: in bits++ mode there is a user-controlled LUT that we can use for gamma correction

  • noComms (bool) – If True then don’t try to communicate with the device at all (passive mode). This can be useful if you want to debug the system without actually having a Bits# connected.

RTBoxAddKeys(map)[source]

Add key mappings to an existing map. RTBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, triggers and CB6 IR input channels. The format for map is a list of tuples with each tuple containing the name of the RTBox button to be mapped and its source eg (‘btn1’,’Din1’) maps physical input Din1 to logical button btn1. RTBox has four logical buttons (btn1-4) and three auxiliary events (light, pulse and trigger) Buttons/events can be mapped to multiple physical inputs and stay mapped until reset.

Example:

bits.RTBoxSetKeys([('btn1','Din0),('btn2','Din1')])
bits.RTBoxAddKeys([('btn1','IRButtonA'),(('btn2','IRButtonB')])

Will link Din0 to button 1 and Din1 to button 2. Then adds IRButtonA and IRButtonB alongside the original mappings.

Now both hard wired and IR inputs will - emulating the same logical button press.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

RTBoxCalibrate(N=1)[source]

Used to assess error between host clock and Bits# button press time stamps.

Prints each sample provided and returns the mean error.

The clock willnever be completely in sync but the aim is that there should be that the difference between them should not grow over a serise of button presses.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

RTBoxClear()[source]

Flushes the serial input buffer. Its good to do this before and after data collection. This just calls flush() so is a wrapper for RTBox.

RTBoxDisable()[source]

Disables the detection of RTBox events. This is useful to stop the Bits# from reporting key presses When you no longer need them. Nad must be done before using any other data logging methods.

It undoes any button - input mappings.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

The ability to reset keys mappings has been found not to work on some Bits# firmware.

RTBoxEnable(mode=None, map=None)[source]

Sets up the RTBox with preset or bespoke mappings and enables event detection.

RTBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, tigers and CB6 IR input channels.

Mode is a list of strings. Preset mappings provided via mode:

  • CB6 for the CRS CB6 IR response box.

  • IO for a three button box connected to Din0-2

  • IO6 for a six button box connected to Din0-5

If mode = None or is not set then the value of self.RTBoxMode is used.

Bespoke Mappings over write preset ones.

The format for map is a list of tuples with each tuple containing the name of the RT Box button to be mapped and its source eg (‘btn1’,’Din0’) maps physical input Din0 to logical button btn1.

Note the lowest number button event is Btn1

RTBox has four logical buttons (btn1-4) and three auxiliary events (light, pulse and trigger) Buttons/events can be mapped to multiple physical inputs and stay mapped until reset.

Mode is a list of string or list of strings that contains keywords to determine present mappings and modes for RTBox.

  • If mode includes ‘Down’ button events will be detected when pressed.

  • If mode includes ‘Up’ button events will be detected when released.

You can detect both types of event but note that pulse, light and trigger events don’t have an ‘Up’ mode.

If Trigger is included in mode the trigger event will be mapped to the trigIn connector.

Example: .. code-block:: python

bits.RTBoxEnable(mode = [‘Down’]), map = [(‘btn1’,’Din0’), (‘btn2’,’Din1’)]

enables the RTBox emulation to detect Down events on buttons 1 and 2 where they are mapped to DIN0 and DIN1.

Example: .. code-block:: python

bits.RTBoxEnable(mode = [‘Down’,’CB6’])

enables the RTBox emulation to detect Down events on the standard CB6 IR response box keys.

If no key direction has been set (mode does not contain ‘Up’ or ‘Down’) the default is ‘Down’.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

The ability to reset keys mappings has been found not to work on some Bits# firmware.

RTBoxKeysPressed(N=1)[source]

Check to see if (at least) the appropriate number of RTBox style key presses have been made.

Example

bits.RTBoxKeysPressed(5)

will return false until 5 button presses have been recorded.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

RTBoxResetKeys()[source]

Resets the key mappings to no mapping. Has the effect of disabling RTBox input.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

The ability to reset keys mappings has been found not to work on some Bits# firmware.

RTBoxSetKeys(map)[source]

Set key mappings: first resets existing then adds new ones. Does not reset any event that is not in the new list. RTBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, triggers and CB6 IR input channels. The format for map is a list of tuples with each tuple containing the name of the RTBox button to be mapped and its source eg (‘btn1’,’Din1’) maps physical input Din1 to logical button btn1.

RTBox has four logical buttons (btn1-4) and three auxiliary events (light, pulse and trigger) Buttons/events can be mapped to multiple physical inputs and stay mapped until reset.

Example

bits.RTBoxSetKeys([(‘btn1’,’Din0),(‘light’,’Din9’)])

Will link Din0 to button 1 and Din9 to the the light input emulation.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

RTBoxWait()[source]

Waits until (at least) one of RTBox style key presses have been made Pauses program execution in mean time.

Example

res = bits.RTBoxWait()

will suspend all other activity until 1 button press has been recorded and will then return a dict / structure containing results.

Results can be accessed as follows:

structure

res.dir, res.button, res.time

or dictionary

res[‘dir’], res[‘button’], res[‘time’]

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

RTBoxWaitN(N=1)[source]

Waits until (at least) the appropriate number of RTBox style key presses have been made Pauses program execution in mean time.

Example

res = bits.RTBoxWaitN(5)

will suspend all other activity until 5 button presses have been recorded and will then return a list of Dicts containing the 5 results.

Results can be accessed as follows:

structure

res[0].dir, res[0].button, res[0].time

or dictionary

res[0][‘dir’], res[0][‘button’], res[0][‘time’]

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

_Goggles()

(private) Used to set control the goggles. Should not be needed by user if attached to a Window

_RTBoxDecodeResponse(msg, N=1)[source]

Helper function for decoding key presses in the RT response box format.

Not normally needed by user

_ResetClock()

(private) Used to reset Bits hardware clock. Should not be needed by user if attached to a Window since this will automatically draw the reset code as part of the screen refresh.

_drawLUTtoScreen()

(private) Used to set the LUT in ‘bits++’ mode. Should not be needed by user if attached to a Window since this will automatically draw the LUT as part of the screen refresh.

_drawTrigtoScreen(sendStr=None)

(private) Used to send a trigger pulse. Should not be needed by user if attached to a Window since this will automatically draw the trigger code as part of the screen refresh.

_extractStatusEvents()[source]

Interprets values from status log to pullout any events.

Should not be needed by user if start/stopStatusLog or pollStatus are used

Fills statusEvents with a list of dictionary like objects with the following entries source, input, direction, time.

source = the general source of the event - e.g. DIN for Digital input, IR for IT response box

input = the individual input in the source. direction = ‘up’ or ‘down’ time = time stamp.

Events are recorded relative to the four event flags

statusDINBase, initial values for ditgial ins. statusIRBase, initial values for CB6 IR box. statusTrigInBase, initial values for TrigIn. statusMode, direction(s) of events to be reported.

The data can be accessed as statusEvents[i][‘time’] or statusEvents[i].time

Also set status._nEvents to the number of events recorded

_getStatusLog()[source]

Read the log Queue

Should not be needed by user if start/stopStatusLog or pollStatus are used.

fills statusValues with a list of dictionary like objects with the following entries: sample, time, trigIn, DIN[10], DWORD, IR[6], ADC[6]

They can be accessed as statusValues[i][‘sample’] or statusValues[i].sample, statusValues[i].ADC[j]

Also sets status_nValues to the number of values recorded.

_inWaiting()[source]

Helper function to determine how many bytes are waiting on the serial port.

_protectTrigger()

If Goggles (or analog) outputs are used when the digital triggers are off we need to make a set of blank triggers first. But the user might have set up triggers in waiting for a later time. So this will protect them.

_restoreTrigger()

Restores the triggers to previous settings

_setHeaders(frameRate)

Sets up the TLock header codes and some flags that are common to operating all CRS devices

_setupShaders()

creates and stores the shader programs needed for mono++ and color++ modes

_statusBox()[source]

Should not normally be called by user Called in its own thread via self.statusBoxEnable() Reads the status reports from the Bits# for default 60 seconds or until self.statusBoxDisable() is called.

Note any non status reports are found on the buffer will cause an error.

args specifies the time over which to record status events. The minimum time is 10ms, less than this results in recording stopping after about 1 status report has been read.

Puts its results into a Queue.

This function is normally run in its own thread so actions can be asynchronous.

_statusDisable()[source]

Stop Bits# from recording data - and clears the buffer

Not normally needed by user

_statusEnable()[source]

Sets the Bits# to continuously send back its status until stopped. You get a lot a data by leaving this going.

Not normally needed by user

_statusLog(args=60)[source]

Should not normally be called by user Called in its own thread via self.startStatusLog() Reads the status reports from the Bits# for default 60 seconds or until self.stopStatusLog() is called. Ignores the last line as this is can be bogus. Note any non status reports are found on the buffer will cause an error.

args specifies the time over which to record status events. The minimum time is 10ms, less than this results in recording stopping after about 1 status report has been read.

Puts its results into a Queue.

This function is normally run in its own thread so actions can be asynchronous.

awaitResponse(multiline=False, timeout=None)

Repeatedly request responses until one arrives, or until a timeout is hit.

Parameters:
  • multiline (bool) – Look for additional lines after the first? WARNING: May be slow if there are none.

  • timeout – Time after which to give up waiting (by default is 10x pause length)

Returns:

The message eventually received

Return type:

str

beep(freq=800, dur=1)[source]

Make a beep of a given frequency and duration

checkConfig(level=1, demoMode=False, logFile='')[source]

Checks whether there is a configuration for this device and whether it’s correct

Parameters:

level (integer) –

  • 0: do nothing

  • 1: check that we have a config file and that the graphics

    card and operating system match that specified in the file. Then assume identity LUT is correct

  • 2: switch the box to status mode and check that the

    identity LUT is currently working

  • 3: force a fresh search for the identity LUT

clock()[source]

Reads the internal clock of the Bits box via the RTBox fortmat but note there will be a delay in reading the value back. The fortmat for the return values is the same as for button box presses. The return value for button will be 9 and the return value for event will be time. The return value for time will be the time of the clock at the moment of the request.

Example

res = bits.clock() print(res.time) print(res[‘time’])

close()
driverFor = []
flush()[source]

Flushes the serial input buffer Its good to do this before and after data collection, And generally quite often.

property gammaCorrectFile

Get / set the gamma correction file to be used (as stored on the device)

getAllRTBoxResponses()[source]

Read all of the RTBox style key presses on the input buffer. Returns a list of dict like objects with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-4 are the ‘btn1-btn4’ events, 5 and 6 are the ‘light’ and ‘pulse’ events, 7 is the ‘trigger’ event, 9 is a requested timestamp event (see Clock()).

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Values can be read as a structure eg:

res = getAllRTBoxResponses()
res[0].dir, res[0].button, res[0].time

or dictionary:

res[0]['dir'], res[0]['button'], res[0]['time']

Note even if only 1 key press was found a list of dict / objects is returned

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

getAllStatusBoxResponses()[source]

Read all of the statusBox style key presses on the input buffer. Returns a list of dict like objects with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-17 are the ‘btn1-btn17’ events.

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Values can be read as a structure eg:

res= getAllStatusBoxResponses()
res[0].dir, res[0].button, res[0].time

or dictionary:

res[0]['dir'], res[0]['button'], res[0]['time']

Note even if only 1 key press was found a list of dict / objects is returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getAllStatusEvents()[source]

Returns the whole status event list

Returns a list of dictionary like objects with the following entries source, input, direction, time.

source = the general source of the event - e.g. DIN for Digital input, IR for CB6 IR response box events

input = the individual input in the source. direction = ‘up’ or ‘down’ time = time stamp.

All sourses are numbered from zero. Din 0 … 9 IR 0 … 5 ADC 0 … 5

mode specifies which directions of events are captured. e.g ‘up’ will only report up events.

The data can be accessed as value[i][‘time’] or value[i].time

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
res=getAllStatusEvents()
print(bits.res[0].time)

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getAllStatusValues()[source]

Returns the whole status values list.

Returns a list of dict like objects with the following entries sample, time, trigIn, DIN[10], DWORD, IR[6], ADC[6] sample is the sample ID number. time is the time stamp. trigIn is the value of the trigger input. DIN is a list of 10 digital input values. DWORD represents the digital inputs as a single decimal value. IR is a list of 10 infra-red (IR) input values. ADC is a list of 6 analog input values. These can be accessed as value[i][‘sample’] or value[i].sample, values[i].ADC[j].

All sourses are numbered from zero. Din 0 … 9 IR 0 … 5 ADC 0 … 5

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
res=getAllStatusValues()
print(bits.res[0].time)

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getAnalog(N=0)[source]

Pulls out the values of the analog inputs for the Nth status entry.

Returns a dictionary with a list of 6 floats (ADC) and a time stamp (time).

All sourses are numbered from zero. ADC 0 … 5

Example

bits.pollStatus() res=bits.getAnalog() print(res[‘ADC’])

will poll the status display the values of the ADC inputs in the first status entry returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

static getAvailableDevices()

Get all available devices of this type.

Returns:

List of dictionaries containing the parameters needed to initialise each device.

Return type:

list[dict]

getDeviceProfile()

Generate a dictionary describing this device by finding the profile from getAvailableDevices which represents the same physical device as this object.

Returns:

Dictionary representing this device

Return type:

dict

getDigital(N=0)[source]

Pulls out the values of the digital inputs for the Nth status entry.

Returns a dictionary with a list of 10 ints that are 1 or 0 (DIN) and a time stamp (time)

ll sourses are numbered from zero. Din 0 … 9

Example

bits.pollStatus() res=bits.getAnalog() print(res[‘DIN’])

will poll the status display the value of the digital inputs in the first status entry returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also DBits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getDigitalWord(N=0)[source]

Pulls out the values of the digital inputs for the Nth status entry.

Returns a dictionary with a 10 bit word representing the binary values of those inputs (DWORD) and a time stamp (time).

Example

bits.pollStatus() res=bits.getAnalog() print(res[‘DWORD’])

will poll the status display the value of the digital inputs as a decimal number.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getIRBox(N=0)[source]

Pulls out the values of the CB6 IR response box inputs for the Nth status entry.

Returns a dictionary with a list of 6 ints that are 1 or 0 (IRBox) and a time stamp (time).

ll sourses are numbered from zero. IR 0 … 5

Example

bits.pollStatus() res=bits.getAnalog() print(res.[‘IRBox’])

will poll the status display the values of the IR box buttons in the first status entry returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getInfo()[source]

Returns a python dictionary of info about the Bits Sharp box

Example::

info=bits.getInfo print(info[‘ProductType’])

getJSON(asString=True)

Convert the output of getDeviceProfile to a JSON string.

Parameters:

asString (bool) – If True, then the output will be converted to a string, otherwise will simply be a JSON-friendly dict.

Returns:

JSON string (or JSON friendly dict) of getDeviceProfile.

Return type:

str or dict

getPackets()

Returns the number of packets available for trigger pulses.

getRTBoxResponse()[source]

checks for one RTBox style key presses on the input buffer then reads it. Returns a dict like object with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-4 are the ‘btn1-btn4’ events, 5 and 6 are the ‘light’ and ‘pulse’ events, 7 is the ‘trigger’ event, 9 is a requested timestamp event (see Clock()).

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Value can be read as a structure, eg:

res= getRTBoxResponse() res.dir, res.button, res.time

or dictionary

res[‘dir’], res[‘button’], res[‘time’]

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

getRTBoxResponses(N=1)[source]

checks for (at least) an appropriate number of RTBox style key presses on the input buffer then reads them. Returns a list of dict like objects with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-4 are the ‘btn1-btn4’ events, 5 and 6 are the ‘light’ and ‘pulse’ events, 7 is the ‘trigger’ event, 9 is a requested timestamp event (see Clock()).

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Values can be read as a list of structures eg:

res = getRTBoxResponses(3)
res[0].dir, res[0].button, res[0].time

or dictionaries:

res[0]['dir'], res[0]['button'], res[0]['time']

Note even if only 1 key press was requested a list of dict / objects is returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. Such variations may affect key mappings for RTBox commands.

getResponse(length=1, timeout=0.1)

Read the latest response from the serial port

Parameters:

length determines whether we expect:
  • 1: a single-line reply (use readline())

  • 2: a multiline reply (use readlines() which requires timeout)

  • -1: may not be any EOL character; just read whatever chars are

    there

getStatus(N=0)[source]

Pulls out the Nth entry in the statusValues list.

Returns a dict like object with the following entries sample, time, trigIn, DIN[10], DWORD, IR[6], ADC[6]

sample is the sample ID number. time is the time stamp. trigIn is the value of the trigger input. DIN is a list of 10 digital input values. DWORD represents the digital inputs as a single decimal value. IR is a list of 10 infra-red (IR) input values. ADC is a list of 6 analog input values. These can be accessed as value[‘sample’] or value.sample, values.ADC[j].

All sourses are numbered from zero. Din 0 … 9 IR 0 … 5 ADC 0 … 5

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
res=getStatus(20)
print(bits.res.time)

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getStatusBoxResponse()[source]

checks for one statusBox style key presses on the input buffer then reads it. Returns a dict like object with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-17 are the ‘btn1-btn17’ events.

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Value can be read as a structure, eg:

res= getRTBoxResponse() res.dir, res.button, res.time

or dictionary

res[‘dir’], res[‘button’], res[‘time’]

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getStatusBoxResponses(N=1)[source]

checks for (at least) an appropriate number of RTBox style key presses on the input buffer then reads them. Returns a list of dict like objects with three members ‘button’, ‘dir’ and ‘time’

‘button’ is a number from 1 to 9 to indicate the event that was detected. 1-4 are the ‘btn1-btn4’ events, 5 and 6 are the ‘light’ and ‘pulse’ events, 7 is the ‘trigger’ event, 9 is a requested timestamp event (see Clock()).

‘dir’ is the direction of the event eg ‘up’ or ‘down’, trigger is described as ‘on’ when low.

‘dir’ is set to ‘time’ if a requested timestamp event has been detected.

‘time’ is the timestamp associated with the event.

Values can be read as a list of structures eg:

res = getRTBoxResponses(3)
print(res[0].dir, res[0].button, res[0].time)

or dictionaries:

print(res[0]['dir'], res[0]['button'], res[0]['time'])

Note even if only 1 key press was requested a list of dict / objects is returned.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getStatusEvent(N=0)[source]

pulls out the Nth event from the status event list

Returns a dictionary like object with the following entries source, input, direction, time.

source = the general source of the event - e.g. DIN for Digital input, IR for IT response box.

input = the individual input in the source. direction = ‘up’ or ‘down’ time = time stamp.

All sourses are numbered from zero. Din 0 … 9 IR 0 … 5 ADC 0 … 5

mode specifies which directions of events are captured, e.g ‘up’ will only report up events.

The data can be accessed as value[‘time’] or value.time

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
res=getAllStatusEvents(20)
print(bits.res.time)

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getTrigIn(N=0)[source]

Pulls out the values of the trigger input for the Nth status entry.

Returns dictionary with a 0 or 1 (trigIn) and a time stamp (time)

Example

bits.pollStatus() res=bits.getAnalog() print(res[‘trigIn’])

will poll the status display the value of the trigger input.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

getVideoLine(lineN, nPixels, timeout=10.0, nAttempts=10)[source]

Return the r,g,b values for a number of pixels on a particular video line

Parameters:
  • lineN – the line number you want to read

  • nPixels – the number of pixels you want to read

  • nAttempts – the first time you call this function it has to get to status mode. In this case it sometimes takes a few attempts to make the call work

Returns:

an Nx3 numpy array of uint8 values

isAwake()[source]

Test whether we have an active connection on the virtual serial port

property isOpen
isSameDevice(other)

Determine whether this object represents the same physical device as a given other object.

Parameters:

other (SerialDevice, dict) – Other SerialDevice to compare against, or a dict of params (which must include port as a key)

Returns:

True if the two objects represent the same physical device

Return type:

bool

longName = ''
property mode

Get/set the mode of the BitsSharp to one of: “bits++” “mono++” “color++” “status” “storage” “auto”

property monitorEDID

Get / set the EDID file for the monitor. The edid files will be located in the EDID subdirectory of the flash disk. The file automatic.edid will be the file read from the connected monitor.

name = b'CRS Bits#'
pause()

Pause for a default period for this device

pollStatus(t=0.0001)[source]

Reads the status reports from the Bits# for the specified usually short time period t. The script will wait for this time to lapse so not ideal for time critical applications.

If t is less than 0.01 polling will continue until at least 1 data entry has been recorded.

If you don’t want to wait while this does its job use startStatusLog and stopStatusLog instead.

Fills the statusValues list with all the status values read during the time period.

Fills the statusEvents list with just those status values that are likely to be meaningful events.

the members statusValues and statusEvents will end up containing dict like objects of the following style: sample, time, trigIn, DIN[10], DWORD, IR[6], ADC[6]

They can be accessed as statusValues[i][‘sample’] or stautsValues[i].sample, statusValues[x].ADC[j].

Example:

bits.pollStatus()
print(bits.statusValues[0].IR[0])

will display the value of the IR InputA in the first sample recorded.

Note: Starts and stops logging for itself.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

primeClock()

Primes the clock to reset at the next screen flip - note only 1 clock reset signal will be issued but if the frame(s) after the reset frame is dropped the reset will be re-issued thus keeping timing good.

Resets continute to be issued on each video frame until the next win.flip so you need to have regular win.flips for this function to work properly.

Example:

bits.primeClock()
drawImage
while not response
    #do some processing
    bits.win.flip()

Will get a clock reset signal ready but won’t issue it until the first win.flip in the loop.

read(timeout=0.1)[source]

Get the current waiting characters from the serial port if there are any.

Mostly used internally but may be needed by user. Note the return message depends on what state the device is in and will need to be decoded. See the Bits# manual but also the other functions herein that do the decoding for you.

Example

message = bits.read()

reset()

Deprecated: This was used on the old Bits++ to power-cycle the box. It required the compiled dll, which only worked on windows and doesn’t work with Bits# or Display++.

resetClock()

Issues a clock reset code using 1 screen flip if the next frame(s) is dropped the reset will be re-issued thus keeping timing good.

Resets continue to be issued on each video frame until the next win.flip so you need to have regular win.flips for this function to work properly.

Example

bits.resetClock() drawImage() bits.win.flip()

Will issue clock resets while the image is being drawn then display the image and allow the clock to continue from the same frame.

Example

bits.resetClock() bits.RTBoxWait() bits.win.flip()

Will issue clock resets until a button is pressed.

sendAnalog(AOUT1=0, AOUT2=0)[source]

sends a single analog output pulse uses up 1 win flip. pulse will continue until next win flip called. Actions are always 1 frame behind the request.

May conflict with trigger and goggle settings.

Example

bits.sendAnalog(4.5,-2.0) bits.win.flip()

sendMessage(message, autoLog=True)

Send a command to the device (does not wait for a reply or sleep())

sendTrigger(triggers=0, onTime=0, duration=0, mask=65535)

Sends a single trigger using up 1 win.flip. The trigger will be sent on the following frame.

The triggers will continue until after the next win.flip.

Actions are always 1 frame after the request.

May do odd things if Goggles and Analog are also in use.

Example:

bits.sendTrigger(0b0000000010, 2.0, 4.0)
bits.win.flip()

Will send a 4ms puilse on DOUT1 2ms after the start of the frame. Due to the following win.flip() the pulse should last for 1 frame only.

Triggers will continue until stopTrigger is called.

setAnalog(AOUT1=0, AOUT2=0)[source]

Sets up Analog outputs in Bits# AOUT1 and AOUT2 are the two analog values required in volts. Analog commands are issued at the next win.flip() and actioned 1 video frame later.

Example

bits.set Analog(4.5,-2.2) bits.startAnalog() bits.win.flip()

setContrast(contrast, LUTrange=1.0, gammaCorrect=None)

Set the contrast of the LUT for ‘bits++’ mode only :Parameters:

contrastfloat in the range 0:1

The contrast for the range being set

LUTrangefloat or array

If a float is given then this is the fraction of the LUT to be used. If an array of floats is given, these will specify the start / stop points as fractions of the LUT. If an array of ints (0-255) is given these determine the start stop indices of the LUT

Examples

  • setContrast(1.0,0.5) to set the central 50% of the LUT so that a stimulus with

    contr=0.5 will actually be drawn with contrast 1.0

  • setContrast(1.0,[0.25,0.5])

  • or setContrast(1.0,[63,127]) to set the lower-middle quarter of the LUT

    (which might be useful in LUT animation paradigms)

setGamma(newGamma)

Set the LUT to have the requested gamma value Currently also resets the LUT to be a linear contrast ramp spanning its full range. May change this to read the current LUT, undo previous gamma and then apply new one?

setLUT(newLUT=None, gammaCorrect=False, LUTrange=1.0, contrast=None)[source]

SetLUT is only really needed for bits++ mode of bits# to set the look-up table (256 values with 14bits each). For the BitsPlusPlus device the default is to perform gamma correction here but on the BitsSharp it seems better to have the device perform that itself as the last step so gamma correction is off here by default. If no contrast has yet been set (it isn’t needed for other modes) then it will be set to 1 here.

setRTBoxMode(mode=['CB6', 'Down', 'Trigger'])[source]

Sets the RTBox mode data member - does not actually set the RTBox into this mode.

Example

bits.setRTBoxMode([‘CB6’,’Down’]) # set the mode bits.RTBoxEnable() # Enable RTBox emulation with # the preset mode.

sets the RTBox mode settings for a CRS CB6 button box. and for detection of ‘Down’ events only.

setStatusBoxMode(mode=['CB6', 'Down', 'Trigger', 'Analog'])[source]

Sets the statusBox mode data member - does not actually set the statusBox into this mode.

Example

bits.setStatusBoxMode([‘CB6’,’Down’]) # set the mode bits.statusBoxEnable() # Enable status Box emulation with # the preset mode.

sets the statusBox mode settings for a CRS CB6 button box. and for detection of ‘Down’ events only.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

setStatusBoxThreshold(threshold=None)[source]

Sets the threshold by which analog inputs must change to trigger a button press event. If None the threshold will be set very high so that no such events are triggered.

Can be used to change the threshold for analog events without having to re enable the status box system as a whole.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

setStatusEventParams(DINBase=1023, IRBase=63, TrigInBase=0, ADCBase=0, threshold=9999.99, mode=['up', 'down'])[source]

Sets the parameters used to determine if a status value represents a reportable event.

DIN_base = a 10 bit binary word specifying the expected starting values of the 10 digital input lines

IR_base = a 6 bit binary word specifying the expected starting values of the 6 CB6 IR buttons

Trig_base = the starting value of the Trigger input

mode = a list of event types to monitor can be ‘up’ or ‘down’ typically ‘down’ corresponds to a button press or when the input is being pulled down to zero volts.

Example:

bits.setStatusEventParams(DINBase=0b1111111111,
                          IRBase=0b111111,
                          TrigInBase=0,
                          ADCBase=0,
                          threshold = 3.4,
                          mode = ['down'])
bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
res=getAllStatusEvents(0)
print(bits.res.time)

This ill start the event extraction process as if DINs and IRs are all ‘1’, Trigger is ‘0’ ADCs = 0 with an ADC threshold for change of 3.4 volts, and will only register ‘down’ events. Here we display the time stamp of the first event.

Note that the firmware in Display++ units varies over time and some features of this class may not work for all firmware versions. Also Display++ units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

setTrigger(triggers=0, onTime=0, duration=0, mask=65535)[source]

Quick way to set up triggers.

Triggers is a binary word that determines which triggers will be turned on.

onTime specifies the start time of the trigger within the frame (in S with 100uS resolution)

Duration specifies how long the trigger will last. (in S with 100uS resolution).

Note that mask only protects the digital output lines set by other activities in the Bits. Not other triggers.

Example:

` bits.setTrigger(0b0000000010, 2.0, 4.0, 0b0111111111) bits.startTrigger() `

Will issue a 4ms long high-going pulse, 2ms after the start of each frame on DOUT1 while protecting the value of DOUT 9.

setTriggerList(triggerList=None, mask=65535)[source]

Overaload of Bits# and Display++ Sets up Trigger pulses via the list method while preserving the analog output settings.

Sets up Trigger pulses in Bist++ using the fine grained method that can control every trigger line at 100uS intervals.

TriggerList should contain 1 entry for every 100uS packet (see getPackets) the binary word in each entry specifies which trigger line will be active during that time slot.

Note that mask only protects the digital output lines set by other activities in the Bits. Not other triggers.

Example

packet = [0]*self._NumberPackets packet[0] = 0b0000000010 bits.setTriggerList(packet)

Will sens a 100us pulse on DOUT1 at the start of the frame.

Example 2:

packet = [0]*self._NumberPackets packet[10] = 0b0000000010 packet[20] = 0b0000000001 bits.setTriggerList(packet) bits.statrtTrigger()

Will sens a 100us pulse on DOUT1 1000us after the start of the frame and a second 100us pusle on DOUT0 2000us after the start of the frame.

Triggers will continue until stopTrigger is called.

start()[source]

[Not currently implemented] Used to begin event collection by the device.

Not really needed as other members now do this.

startAnalog()[source]

will start sending analog signals on the next win flip and continue until stopped.

Example

bits.set Analog(4.5,-2.2) bits.startAnalog() bits.win.flip()

startGoggles(left=0, right=1)

Starts CRS stereo goggles. Note if you are using FE-1 goggles you should start this before connecting the goggles.

Left is the state of the left shutter on the first frame to be presented 0, False or ‘closed’=closed; 1, True or ‘open’ = open,

right is the state of the right shutter on the first frame to be presented 0, False or ‘closed’=closed; 1, True or ‘open’ = open

Note you can set the goggles to be both open or both closed on the same frame.

The system will always toggle the state of each lens so as to not damage FE-1 goggles.

Example:

bits.startGoggles(0,1)
bits.win.flip()
while not response
    bits.win.flip()
    #do some processing
bits.stopGoggles()
bits.win.flip()

Starts toggling the goggles with the right eye open in sync with the first win.flip() within the loop. The open eye will alternate.

Example:

bits.startGoggles(1,1)
bits.win.flip()
while not response:
    bits.win.flip()
    #do some processing
bits.stopGoggles()
bits.win.flip()

Starts toggling the goggle with both eyes open in sync with the first win.flip() within the loop. Eyes will alternate between both open and both closed.

Note it is safe to leave the goggles toggling forever, ie to never call stopGoggles().

startStatusLog(t=60)[source]

Start logging data from the Bits#

Starts data logging in its own thread.

Will run for t seconds, defrault 60 or until stopStatusLog() is called.

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

startTrigger()

Start sending triggers on the next win flip and continue until stopped by stopTrigger Triggers start 1 frame after the frame on which the first trigger is sent.

Example:

bits.setTrigger(0b0000000010, 2.0, 4.0, 0b0111111111)
bits.startTrigger()
while imageOn:
    #do some processing
    continue
bits.stopTrigger()
bits.win.flip()
statusBoxAddKeys(map)[source]

Add key mappings to an existing map. statusBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, triggers and CB6 IR input channels. The format for map is a list of tuples with each tuple containing the name of the RTBox button to be mapped and its source eg (‘btn1’,’Din1’) maps physical input Din1 to logical button btn1. statusBox has 23 logical buttons (btn1-23). Unlike RTBox buttons/events can only be partially mapped to multiple physical inputs. That is a logical button can be mapped to more than 1 physical input but a physical input can onloy be mapped to 1 logical button. So, this function over write any existing mappings if the physical input is the same.

Example:

bits.RTBoxSetKeys([('btn1','Din0),('btn2','Din1')])
bits.RTBoxAddKeys([('btn1','IRButtonA'),(('btn2','IRButtonB')])

Will link Din0 to button 1 and Din1 to button 2. Then adds IRButtonA and IRButtonB alongside the original mappings.

Now both hard wired and IR inputs will emulate the same logical button press.

To match with the CRS hardware description inputs are labelled as follows.

TrigIn, Din0 … Din9, IRButtonA … IRButtonF, AnalogIn1 … AnalogIn6

Logical buttons are numbered from 1 to 23.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

statusBoxDisable()[source]

Disables the detection of statusBox events. This is useful to stop the Bits# from reporting key presses When you no longer need them. And must be done before using any other data logging methods.

It undoes any button - input mappings

statusBoxEnable(mode=None, map=None, threshold=None)[source]

Sets up the stautsBox with preset or bespoke mappings and enables event detection.

stautsBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, tigers and CB6 IR input channels.

mode is a list of strings. Preset mappings provided via mode:

  • CB6 for the CRS CB6 IR response box connected mapped to btn1-6

  • IO for a three button box connected to Din0-2 mapped to btn1-3

  • IO6 for a six button box connected to Din0-5 mapped to btn1-6

  • IO10 for a ten button box connected to Din0-9 mapped to btn1-10

  • Trigger maps the trigIn to btn17

  • Analog maps the 6 analog inputs on a Bits# to btn18-23

If CB6 and IOx are used together the Dins are mapped from btn7 onwards.

If mode = None or is not set then the value of self.statusBoxMode is used.

Bespoke Mappings overwrite preset ones.

The format for map is a list of tuples with each tuple containing the name of the button to be mapped and its source eg (‘btn1’,’Din0’) maps physical input Din0 to logical button btn1.

Note the lowest number button event is Btn1

statusBox has 23 logical buttons (btn1-123). Buttons/events can be mapped to multiple physical inputs and stay mapped until reset.

mode is a string or list of strings that contains keywords to determine present mappings and modes for statusBox.

If mode includes ‘Down’ button events will be detected when pressed. If mode includes ‘Up’ button events will be detected when released. You can detect both types of event noting that the event detector will look for transitions and ignorewhat it sees as the starting state.

To match with the CRS hardware description inputs are labelled as follows.

TrigIn, Din0 … Din9, IRButtonA … IRButtonF, AnalogIn1 … AnalogIn6

Logical buttons are numbered from 1 to 23.

threshold sets the threshold by which analog inputs must change to trigger a button press event. If None the threshold will be set very high so that no such events are triggered. Analog inputs must cycle up and down by threshold to be detected as separate events. So if only ‘Up’ events are detected the input must go up by threshold, then come down again and then go back up to register 2 up events.

Example:

bits.statusBoxEnable(mode = 'Down'), map = [('btn1','Din0'), ('btn2','Din1')]

enables the stautsBox to detect Down events on buttons 1 and 2 where they are mapped to DIN0 and DIN1.

Example:

bits.statusBoxEnable(mode = ['Down','CB6'])

enables the status Box emulation to detect Down events on the standard CB6 IR response box keys.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

statusBoxKeysPressed(N=1)[source]

Check to see if (at least) the appropriate number of RTBox style key presses have been made.

Example

bits.statusBoxKeysPressed(5)

will return false until 5 button presses have been recorded.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

statusBoxResetKeys()[source]
statusBoxSetKeys(map)[source]

Set key mappings: first resets existing then adds new ones. Does not reset any event that is not in the new list. statusBox events can be mapped to a number of physical events on Bits# They can be mapped to digital input lines, triggers and CB6 IR input channels. The format for map is a list of tuples with each tuple containing the name of the RTBox button to be mapped and its source eg (‘btn1’,’Din1’) maps physical input Din1 to logical button btn1.

statusBox has 17 logical buttons (btn1-17) Buttons/events can be mapped to multiple physical inputs and stay mapped until reset.

Example

bits.RTBoxSetKeys([(‘btn1’,’Din0),(‘btn2’,’IRButtonA’)])

Will link physical Din0 to logical button 1 and IRButtonA to button 2.

To match with the CRS hardware description inputs are labelled as follows.

TrigIn, Din0 … Din9, IRButtonA … IRButtonF, AnalogIn1 … AnalogIn6

Logical buttons are numbered from 1 to 23.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

statusBoxWait()[source]

Waits until (at least) one of RTBox style key presses have been made Pauses program execution in mean time.

Example

res = bits.statusBoxWait()

will suspend all other activity until 1 button press has been recorded and will then return a dict / structure containing results.

Results can be accessed as follows:

structure

res.dir, res.button, res.time

or dictionary

res[‘dir’], res[‘button’], res[‘time’]

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also DBits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

statusBoxWaitN(N=1)[source]

Waits until (at least) the appropriate number of RTBox style key presses have been made Pauses program execution in mean time.

Example

res = bits.statusBoxWaitN(5)

will suspend all other activity until 5 button presses have been recorded and will then return a list of Dicts containing the 5 results.

Results can be accessed as follows:

structure:

res[0].dir, res[0].button, res[0].time

or dictionary:

res[0]['dir'], res[0]['button'], res[0]['time']

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

stop()[source]

[Not currently implemented] Used to stop event collection by the device.

Not really needed as other members now do this.

stopAnalog()[source]

will stop sending analogs signals at the next win flip.

Example:

bits.set Analog(4.5,-2.2)
bits.startAnalog()
bits.win.flip()
while not response:
    #do some processing.
    bits.win.flip()
bits.stopAnalog()
bits.win.flip()
stopGoggles()[source]

Stop the stereo goggles from toggling

Example:

bits.startGoggles(0,1)
bits.win.flip()
while not response
    bits.win.flip()
    #do some processing
bits.stopGoggles()
bits.win.flip()

Starts toggling the goggles with the right eye open in sync with the first win.flip(0) within the loop. The open eye will alternate.

Note it is safer to leave the goggles toggling forever, ie to never call stopGoggles().

stopStatusLog()[source]
Stop logging data from the Bits#

and extracts the raw status values and significant events and puts them in statusValues and statusEvents.

statusValues will end up containing dict like objects of the following style: sample, time, trigIn, DIN[10], DWORD, IR[6], ADC[6]

They can be accessed as statusValues[i][‘sample’] or statusValues[i].sample, statusValues[x].ADC[j].

StatusEvents will end up containing dict like objects of the following style: source, input, direction, time

The data can be accessed as statusEvents[i][‘time’] or statusEvents[i].time

Waits for _statusLog to finish properly so can introduce a timing delay.

Example:

bits.startStatusLog()
while not event
    #do some processing
    continue
bits.stopStatusLog()
print(bits.statusValues[0].time)
print(bits.statusEvents[0].time)

Will display the time stamps of the first starus value recorded and the first meaningful event.

Note that the firmware in Bits# units varies over time and some features of this class may not work for all firmware versions. Also Bits# units can be configured in various ways via their config.xml file so this class makes certain assumptions about the configuration. In particular it is assumed that all digital inputs, triggers and analog inputs are reported as part of status updates. If some of these report are disabled in your config.xml file then ‘status’ and ‘event’ commands in this class may not work.

stopTrigger()[source]

Stop sending triggers at the next win flip.

Example:

bits.setTrigger(0b0000000010, 2.0, 4.0, 0b0111111111)
bits.startTrigger()
while imageOn:
    #do some processing
    continue
bits.stopTrigger()
bits.win.flip()
syncClocks(t)

Synchronise the Bits/RTBox Clock with the host clock Given by t.

property temporalDithering

Temporal dithering can be set to True or False

property win

The window that this box is attached to


Back to top