LED Zappelin’: An open source LED controller for arbitrary spectrum visual stimulation and optogenetics during 2-photon imaging

Graphical abstract


Hardware in context
Advances in fluorescence microscopy techniques and the development of genetically encoded biosensors [1,2] have allowed interrogating the structures and functions of biological systems at ever increasing depth [3,4]. In particular, twophoton (2P) imaging has enabled high temporal and spatial resolution imaging deep within intact tissues due to a low degree light scattering of the infrared laser [5].
And yet, combining 2P imaging with additional light stimulation -for example for visual stimulation or for driving optogenetic actuators -has remained challenging because the stimulation light can interfere with fluorescence detection. This can result in light artefacts in the image and/or may damage sensitive fluorescence detection equipment (e.g. photomultiplier tubes, PMTs). To circumvent these issues, stimulation lights are usually band-pass filtered so their wavelengths will not overlap with the fluorescence detection bands. However, for experimental designs requiring multiple chromatic stimulation or being restricted to a few choices of genetically encoded fluorescence indicators, light filtering is not necessarily sufficient. A temporal separation between light stimulation and fluorescence detection, for example during the scan-retrace, can thus ameliorate these problems [6].
Also, the ability to easily modify light stimulation is essential for the visual neuroscience field, which works on diverse retina models with even more diverse number of opsins and spectral sensitivities [7]. Traditional stimulator systems, despite offering high temporal resolution lack free access to their light source spectra, which are mostly built for the trichromatic primate vision [8]. A flexible and easily modified arbitrary spectrum system could then allow the study of multiple organism vision.
To limit flickering artefacts, the rate of interweaving stimulation and imaging epochs should ideally be substantially beyond the integration time of the to-be stimulated system. Accordingly, line-synchronisation (typically 500 -1,000 Hz) is usually preferred over frame-synchronisation (typically in the order of 10s of Hz). For this, both mechanical and electronic solutions are possible.
For example, some systems rely on an optical chopper and/or mechanical shutter with microsecond performance for rapid gating of a constant light source [9,10]. We listed below a few examples of the most used light stimulation strategies. These available systems tend to be bulky and/or expensive, can introduce mechanical vibrations, and rarely allow users to adapt the light source numbers or spectra to fit their experimental requirements. Alternatively, the problem can be readily solved electronically, for example through use of a microcontroller. Here, we present such a solution. Our system can line-synch up to 24 independent LED channels, and can be assembled from off-the-shelf components for substantially below $100. This provides for flexible options of spectrally diverse light stimulation during 2-photon scanning and comfortably provides sufficient power to drive standard optogenetics actuators such as CsChrimson [11]. Alongside, we also provide a custom 3D-printed casing, design suggestions for optically combining LED banks using Thorlabs parts, and an alternative 3D-printed LED holder and microscope chamber. For software control, we provide custom Arduino scripts to flexibly programme stimulation protocols.
We envision that this tool will find users requiring optogenetic or visual stimulation, for both animal and human research. Its low-cost and spectrum flexibility added to its accessible stimulation programming, makes it a favourable design compared to other available commercial solutions.

Overview
The challenge when combining 2P-microscopy and light stimulation centres around the potential spectral overlap of photodetector (e.g. photomultiplier) sensitivities and the stimulus light. Spectral separation is not always enough depending on the required excitation light, the available fluorescent probes or limitations in the microscope's optical design and its com-ponents (e.g. spectral filter imperfections or reflections). In this case, temporal separation between stimulation and fluorescence recording can be helpful in reducing crosstalk [6]. This requires time-precise control over the stimulus light, and a means to synchronise this control with a readout of the scan pattern.
High-efficiency LEDs, unlike conventional light sources, near instantly illuminate at full intensity when current is applied. They emit narrow-spectrum light and can be switched on and off within nanoseconds while providing high emission stability [12]. Similarly, even basic microcontrollers provide for suitable time resolution to control LED state in the microsecond range. We therefore built a microcontroller and LED-based stimulator system to interweave the laser excitation timing with LED illumination: By turning off the LEDs during the laser scanning period and turning them on during the mirror retrace period, a clean separation between stimulation and emission lights can be achieved while nevertheless delivering sufficient average light to stimulate photo-sensitive cells and commonly used optogenetic actuators.
For synchronisation with the imaging system, we use a ''blanking" signal from the scan-software: Most conventional 2Pimaging software solutions can send 5 V digital signal which runs synchronised to the fast scanning mirrors through their digital acquisition (DAQ) system. Such digital signal is for example frequently used to synchronise a Pockels cell for rapid regulation of laser power during the retrace period of a raster scan to avoid phototoxicity [13]. We use the same signal to synchronise the LED illumination with the retrace period ( Fig. 1d) [6,8]. This strategy works for both galvo-galvo and the substantially faster line rates of resonant scanning systems. Fig. 1. Stimulator design. a. A fully assembled stimulator. b. Rendering of the custom-printed circuit board which accommodates the microcontroller, the LED driver and up to 24 LED channels. c. Schematics illustrating the circuit that controls the LED output. The blanking input can be inverted by a switch before reaching the output enable pin on the LED driver (electronically switching off the LEDs) and sending the signal to the micro-controller. A second switch controls the blanking signal voltage as it needs to be adapted depending on the logic of the microcontroller used (3.3 V for ESP32, 5 V for Arduino). The microcontroller controls the LED driver through an SPI connection and sends a trigger signal output to an external DAQ-system. KiCAD schematic are available on the GitHub repository. d. Illustration of the raster scan method described. The ''blanking signal" is synchronous with the scanning logic, enabling the LEDs during the scanning mirrors retrace (black) and shutting them off during the acquisition (red), therefore providing temporal separation between stimulation and detection (schematic in (d) inspired from [6]).

Electronics
The stimulator consists of an ESP32 micro-controller (Adafruit ESP32 feather, built around the ESP32 system on a chip, Espressif), an LED driver (Adafruit TLC5947, built around the TLC5947 chip, Texas instruments), and common off-the shelf electronics components (Fig. 1b). Designed around a custom-built printed circuit board (PCB) (Fig. 1b), the stimulator assembly is intuitive and does not require previous electronics nor soldering experience (c.f. Supplementary video 1). The total cost for electronic parts is currently below $100.
The ESP32 is a low cost and relatively recent (released in Sept. 2016) type of microcontroller operating at 240 MHz (compared to 16 MHz for traditional micro-controller using the ATMega248 processor), which provides enough processing performance to control the light output in the kHz range. The microcontroller, through Serial Peripheral Interface (SPI), communicates with the LED driver, and allows for independent control of up to 24 LED channels, each with 12 bit resolution (4,096 ''grey levels"). As one example use-case, our visual stimulator for zebrafish retina experiments uses four spectrally distinct stimulus LEDs plus another set of 4 ''proxy"-LEDs which can be embedded in the 3D-printed chassis as a visual control for the experimenter (Fig. 1a).

LED control and linear modulation
One of the key features of the chosen LED driver is its blanking input (labelled O/E on the TLC5947 board for ''output enable"), which allows for the fast and simultaneous switching of all LEDs. When the blanking input is high, all 24 current outputs are forced off. When the blanking input is low, all constant current outputs are controlled by the grayscale Pulsewidth-modulation (PWM) timing controller which is reset during the blanking, thus providing a stable light output (Fig. 2a).
The blanking signal also serves as the stimulator's external clock: the stimulator counts the number of digital signal pulses (i.e. scan-lines) and from here computes the accurate timing to move through a pre-programmed stimulus sequence (c.f. 6.2).
For experiments in vision neuroscience, we use a custom movable-objective microscope (MOM)-type 2P system [14] controlled by ''ScanM" (developed by W. Denk, M. Müller and T. Euler). ScanM is configured to provide a HIGH signal during blanking which can be fed directly to the TLC5947 [6]. However, in our example optogenetics experiment, we use another software package (ScanImage [15]) on a custom-made 2P microscope (Independent NeuroScience Services), which instead provides a LOW signal during the retrace. We therefore incorporated a signal inverter which can be enabled through a jumper (Fig. 2b). When the jumper is close to the ESP32, the signal goes straight to the TLC5947, while when it is placed away from the microcontroller, the signal is inverted by passing a logical NOT gate (Fig. 2b).
This option thus offers the possibility for a single design to be easily adapted to different software systems. Another important feature to consider when using a constant-current sink LED driver like the TLC5947 is its ability to drive a near linear LED output. Indeed, an LED brightness modulated directly by a microcontroller does not necessarily scale linearly with pulse width but rather adopts a sigmoid dependency (Fig. 3). The use of an adequate LED driver therefore does not require further gamma correction from the experimenter.
Furthermore, the use of a dedicated constant current LED driver tends to improve LED stability over time as well as its life span. Such a driver ensures that the current drawn by the LED does not lead to thermal runaway which can cause irreversible damage. This is particularly important for short wavelength LEDs which tend to decay rapidly as they usually require higher power supply leading to higher thermal runaway. This characteristic thus necessitates regular recalibration or replacement. Fig. 2. The blanking signal controls LED illumination. a. Oscilloscope reading of the blanking signal (blue) efficiently switching off an LED (yellow). The blanking is operated here without noticeable delay. b. as a., shown for a 1 ms scanning cycle, the two possible configurations for the blanking signal input, with a LOW (top) and a HIGH (bottom) blanking signal input for an inverted and original signal input, respectively.

A trigger signal for synchronising stimulation protocols and image acquisition
The stimulator is equipped with an output trigger channel that can be connected to the 2P setup's DAQ-system to precisely time-align the light stimulation with imaging data. By default, this is a 5 V digital trigger-signal of 25 ms duration which starts as soon as a stimulus sequence begins via software control (see below) and is thereafter repeated with a pulse of exactly 1 Hz (1 trigger every 1,000 ms). These numbers are easily adjusted in the Arduino code provided. Due to the ESP32 0 s high processing speed, this trigger signal is reliable and precise within 0.1 ls (Fig. 8e) (see below).

LED Zappelin' without scan-synchronisation (optional)
Finally, our design can also be configured to work independent of an external blanking input, for example to function as a simple and time-precise LED controller. In this case, the ESP32 can be exchanged for a more economical Arduino Nano microcontroller. Since the Arduino Nano's internal logic runs on 5 V, while the ESP32 runs on 3.3 V, we incorporated a second jumper at the bottom of the PCB to adjust the voltage depending on the microcontroller choice. A dedicated Arduino script is also provided to run the stimulator in this configuration.  Readers interested in reproducing this system can use ready-to-order electronic design platform for open hardware projects:

Design files summary
https://kitspace.org/, a PCB repository where all boards and components for them can be put in a ''shopping cart" with one click.
Stimulator PCB (Fig. 1b): This custom PCB is the core of the stimulator, to which each component is soldered.
Potentiometer mount PCBs (Fig. 4): Optional PCBs that allow adding multi-turn trimmer potentiometers for fine tuning the LED supply current. We provide different versions for different numbers of LED channels (4, 8, 16 & 24).
3D-printed stimulator box (Fig. 5): Parts that fit and protect the electronics. The SCAD file is easily adaptable by the user. 3D-printed optical components (Fig. 6a): Parts used in combination with common optomechanical systems to hold LED, filter and dichroic mirrors in order to combine and collimate multiple spectral LEDs into a common light beam.
3D-printed optogenetics components (Fig. 6c-d): Parts that hold the sample and the stimulating LEDs. Chamber mounts are designed to fit a RC-40HP chamber (Thorlabs) and a 35 mm Petri dish lid. A 3D-printed mounting platform fits the mounts onto a standard M6 rigid platform (Fig. 9b).
Stimulator Software: Arduino codes that control the stimulator. Easily modifiable to generate custom stimuli. Calibration Manual: A Jupyter notebook (Python 3) with step by step instructions for intensity-calibrating the stimulator (an additional power-meter will be required).

Soldering the custom-designed PCB
The board is shown in Fig. 1b. For the microcontroller (left), two options are available for either the Arduino Nano (inner rows, no external line-synch option) or the ESP32 (outer rows, full stimulator). There is no need to solder more Japan Solderless Terminal (JST) pins beyond the number of LEDs required (here, we will show a version where 8 JST pins are connected: 4 for the stimulus LEDs, 4 for their proxy LEDs). On the right side of the board, the power plug and the 3-way JST header must be soldered into the respective sockets.
The jumper on the top (signal Inverter) allows the inversion of the 5 V digital ''Blanking" signals. For ScanImage users, the jumper should be placed in the upper position to switch off LEDs when the blanking signal is LOW. ScanM users should instead place it in the lower position to switch off LEDs when the blanking signal is HIGH.
The jumper at the bottom of the board (voltage divider) allows to set the voltage to 3.3 V (ESP32) or to 5 V (Arduino Nano). IMPORTANT: do not send 5 V signals to the ESP32. Since most devices deliver 5 V digital signal pulses, we selected 220 X and 470 X resistors to bring an expected 5 V blanking signal to a 3.3 V input. Depending on the voltage range of the blanking signal, these resistors may need to be adjusted according to Ohm's law: V1 + V2 = I*(R1 + R2).
The Adafruit TLC5947 LED driver is configured by default to a current output level of 15 mA per channel, which is safe for nearly any standard LED. However, it is possible to operate at different currents by replacing the on-board resistor with a new through hole resistor. The driver can deliver up to 30 mA per channel (described in detail on the manufacturer's datasheet: https://cdn-shop.adafruit.com/datasheets/tlc5947.pdf).

Mounting the potentiometers
To finely adjust each LED's peak power, we added multiple-turn trimmer potentiometers to our design. To mount them, one simple solution is to manufacture the appropriate custom PCB (we provide multiple options for different numbers of channels). These extra PCBs fit tightly into the 3D-printed box. LEDs should be connected to the potentiometer in series as shown in Fig. 4.

Printing the stimulator box
We used OpenSCAD (freely available at www.openscad.org) to design the stimulator enclosure. The tolerance of the printer can be adjusted in the ''USER Parameters" section of the script (tol = 0.1 mm by default, suitable for a reasonably wellcalibrated Prusa i3 MK3 or Ultimaker 2). Each component can be displayed/designed individually in the ''switches" section. Variables such as LED number (4 by default) and the potentiometer board dimensions can be adjusted in the ''component parameters" section.  Default STL files can also be found on the repository and printed directly (4 stimulation LEDs + 4 proxy LEDs). The PCB is mounted by adding 50 mm M3 screws from the top via fitting holes in the stacking parts. The potentiometer board is fitted to the ''back" part of the box, with trimmers fitting to their respective holes (Fig. 5b).

Mounting the proxy LEDs
The proxy LEDs provide convenient visualisation of the stimulus state for the experimenter. If this option is selected, 3 mm LEDs should be mounted at the back of the LED holder using 3 mm LED mounts and connected directly to their channel pins on the stimulator board (by default channels 5, 6, 7 & 8). As the LEDs are directly connected to an LED driver, no resistors are needed. Take note of their polarity (long LED leg should be connected to pin + ). For aesthetics, cuttings of Teflon sheet or white paper (e.g.) can be placed in the LED holder slot to diffuse the LED light.

Mounting the stimulating LEDs
Each stimulating LED must be connected to its respective channel, taking note of their polarity (long LED leg should be connected to the positive pin).
For our visual stimulation setup, we combined all LED light sources into one beam which is projected through the objective to our model retina. We therefore constructed an optical cage system using a mixture of Thorlabs parts and 3D-printed objects to hold all filters and dichroic mirrors (Fig. 6a). This LED cage system was used and described in another publication [8].
For the optogenetics experiment we 3D-designed arenas where the sample sits, surrounded by four LEDs (Fig. 6c-d). Rendering of the LED illumination system for the visual experiment. c. For optogenetics experiments, we designed a mounting platform that holds four 5 mm LEDs and can fit a RC-40HP chamber (SmartEphys, Warner Instrument). d. Same as c. but designed to fit a small petri dish (ø 35 mm) lid.

Connecting the stimulator to LEDs, the microscope's DAQ and a computer
The stimulator can be externally powered anywhere between 5 and 30 V via the power port. Since the TLC5947 is a constant current LED driver, the voltage selection is not critical, however it should be slightly higher than the LED forward voltage (cf. LED driver datasheet). If desired, multiple LEDs can be connected to the same channel, however in this case the voltage supply must be adjusted accordingly (cf. LED driver datasheet).
For the standard line-synched stimulator version with an ESP32, a line-synched 5 V digital blanking signal BNC must be fed into the stimulator from the microscope's DAQ (if the digital signal is different from 5 V, this can still be accepted provided the associated resistor is changed accordingly -see soldering paragraph). Note: Since for the default ESP32 version the blanking signal is used as the external clock, the stimulator will not execute any stimuli without it. If such line-synching is not required, consult the ''simple" non-synchronised version that can be used with a simple Arduino Nano.
If required, connect the output trigger channel to the microscope's DAQ. This signal generated by the stimulator by default sends a 3.3 V pulse (if ESP32 is used, 5 V for Arduino Nano) once at the start of the stimulus and then again, every 1,000 ms (1 Hz exactly). The trigger signal can for example be used to time-align acquired imaging data with the stimulus in postprocessing.
Finally, the board is connected to a computer via USB (micro USB for ESP32, mini USB for Arduino Nano). c. Select and install the library 4-Open the Arduino script (2 versions available on the repository: ''2Photon_LED_Stimulator" and ''Simple_LED_Stimulator", the second one being a simplified version of the first, independent of an external blanking signal input). 5-From the ''Tools" tab: a. For the ESP32: i. Select from ''Boards" the ''Adafruit ESP32 Feather". ii. From ''Upload Speed", select 921,600 (baud rate). iii. From ''Flash Frequency", select 80 Hz. iv. From ''Port", select the computer port to which the ESP32 is connected (if in doubt, unplug the board to see which ports are available, re-plug and observe which port is added). If the ESP is not recognised, check the driver installation (2a.), then check the micro USB cable (some USB cables do not work as not all their internal lines are connected).

Operation instructions
b. For the Arduino Nano i. Select from ''Boards" the ''Arduino Nano" ii. From ''Processor", select ''ATmega328P" (option ''Old Bootloader" for Arduino clones or older Arduino versions -if in doubt, try both) iii. From ''Port", select the computer port to which the Arduino is connected. If an Arduino clone is used, check that the proper driver is installed on the computer (consult its datasheet) and check the mini USB cable.
6-Compile and upload the code (clicking on the sideways arrow button on the top left). 7-The stimulator is ready to be used.

Operating the stimulator
The code is organised in five parts:

Stimulus parameters
The code is designed to iteratively loop a pre-programmed stimulus sequence after an initial one-off optional preadaptation period.
-The number of loops is determined by ''nLoops". The stimulus will stop after finishing the n th loop.
-IMPORTANT, the number of entries within the arrays must be the same and manually entered in ''nArrayEntries" (including the pre-adaptation at position 1, see below). -The ''Scan_Logic" parameter corresponds to the x-mirror scan period in ms (i.e. = 2.0 if line speed is 2 ms per line and scan rate is 500 Hz). This value must be changed if a different scan logic is used. This value defines the tempo of the entire stimulus (each time a blanking signal is counted, the code advances by an internal time-counter of Scan_Logic in milliseconds). -The ''array_LED#" arrays correspond to the stimulus sequence for each LED number. Here the number of arrays must be adjusted to the number of stimulating LEDs. All array positions will be read in synchrony, based on the timing array detailed below. IMPORTANT: The first entry is not part of the to-be-looped stimulus sequence, but instead defines the LED's brightness for the preadaptation period. Note also that the first trigger output will start with the second entry (=the first entry of the stimulation sequence). The value entered at each position is the light intensity where 0 corresponds to no light and 100 to maximal light intensity. The value entered must range between 0 and 100. -The ''array_Time" array corresponds to the duration of each entry in ms; the first entry being the pre-adaptation that will only be played at the start of the stimulus, the sequence will then loop starting at the second position. . . .the resultant stimulus will start with 5 s of both LEDs being set to 50% intensity (preadaptation) and will thereafter switch back and forth every 3 s between 100% and 0% power for the two LEDs in antiphase, for 3 repetitions (Fig. 7). Alongside, it will output one trigger signal every 1 s (fixed to this interval by default) once the looped portion of the stimulus starts (e.g. for later aligning the stimulus to imaging data). Throughout, the LEDs will be line-synched to a 1 ms scan logic.

Microcontroller board selection
Select if an ESP32 or an Arduino Nano is used.

Internal definitions
This is the main definition part of the code which can be modified to: -Add more LEDs than the 4 main and 4 proxy defined by default. (Global variables, the LED pins correspond to the pin number on the TLC5947). -Adjust the trigger duration (25 ms by default).
-Adjust the trigger interval (1,000 ms by default).

Internal methods
This is the main core of the code and should not be structurally changed (apart from adding more LEDs, as required).

Main loop
This is where the serial user controls are defined. By default, when the serial monitor is open (magnifying glass on the top right corner in the Arduino IDE) and the baud rate at the bottom right of the window has been changed to 115,200. In this configuration, a manual command followed by pressing ''enter" will trigger a stimulus: By default: -When ''a + ENTER" is entered in the serial monitor, the stimulator will play the sequence with intensity scaled relative to the predefine ''max1_LED#" powers (see below) -When ''b + ENTER" is entered, the same stimulus sequence will be played, but this time at the intensities defined by ''max2_LED#" powers (see below) -If ''0 + ENTER" is entered during a stimulus sequence, all LEDs will be turned off and all loop counters will be reset. -Further commands can easily be programmed by the user from the ''Main Loop" part of the Arduino code.
It is important to note that the stimulation will only be played if a blanking signal is sent to the board.

Calibrating the stimulator
Stimulating LEDs can be approximately brought into a desired intensity regime by adding a serial resistor to limit the current they receive (c.f. 5.2). They can also be further calibrated within the code: The TLC5947 is a 12-bit PWM grayscale driver, meaning that it offers up to 4,096 grey levels to adjust each LED power.
In the Arduino code there is a second tab called ''LED_values" which hard-codes the maximum power an LED can get. Those values range from 0 (no current) to 4,095 (max current, 15 mA by default with potentiometer tuned all the way down, c.f. 5.1).
In the default script we defined two distinct max values (max1 & max2) that can be called individually. The purpose here is to have the opportunity to use the same stimulus sequence at two different regimes of light intensities. More can be added manually by the user.
For the calibration, we suggest setting the max_LED# value to 4,095 (full power) and use successively a spectrometer and a power meter to adjust the LED brightness by finely turning the trimmer potentiometer at the back of the stimulator. As the LED output is linear relative to the values entered here (Fig. 3), any max_LED# value will be proportional to the LED power set up for the 4,095 value. The LED value (0-100%) entered in the stimulus sequence is linearly mapped to 0-max_LED#.
For a clear calibration procedure, we provide an easy step by step Jupyter notebook manual that can be found in our GitHub repository.

Visual stimulation experiment:
For colour vision experiments we recorded light-driven calcium signals under 2-photon from retinal bipolar cells in vivo in the tetrachromatic larval zebrafish [16]. We used a transgenic line expressing a genetically encoded biosensors for calcium at the bipolar cell synaptic terminals level (ctbp2:SyGCaMP6) [17] within the inner plexiform layer (IPL) (Fig. 8b).
Following established protocols [14], we used a Sutter-MOM microscope where light stimulation is displayed through the objective directly onto the fish retina along with the laser excitation. Fluorescence is also collected through the objective (Fig. 8a) as well as from below the stage (not shown).
We presented full field steps of red, green, blue and UV light to the fish eye (respectively 567, 480, 420 and 365 nm), and recorded evoked calcium signals as a readout of synaptic activity (Fig. 8c). We observed spectrally different tunings from distinct bipolar cell terminals (Fig. 8d) without detectable stimulus artefact across the scan.
In comparison to previous experiments performed on the same setup with a stimulator relying only on a basic microcontroller without LED driver [16], LED-Zappelin' completely (rather than ''mostly") eliminated the light-artefact on the sides of the scan. This is mostly due to the ESP32 processing power which also allows faster scanning rates compared to the performance achieved with traditional ATMega328 microcontrollers. Additionally, the use of an adequate LED driver providing linear 12-bit LED output (as opposed to, typically, 8-bit) has dramatically enriched possibilities in experimental design.

Optogenetics experiment
In addition to colour vision experiments, our LED Zappelin' is well suited for optogenetic manipulation during 2-photon imaging. Here we illustrate this application from optogenetic circuit mapping in Drosophila larvae. Specifically, we recorded brain-wide calcium signals under 2P in response to optogenetic stimulation of all olfactory sensory neurons (OSNs). To this end, we expressed the red-shifted channel rhodopsin CsChrimson [11] in OSNs and the genetically encoded calcium indicator GCaMP6s pan-neuronally (elav-Gal4;UAS-GCaMP6s/LexAOp-CsChrimson;Orco-LexA). We used first instar larvae that were fed from hatching on yeast paste supplemented with 0.4 mM all-trans retinal. Dissected larval heads with intact olfactory sensory organs (dorsal organs) and an exposed central brain (Fig. 9a) were immobilised in 3% low-melting-point agarose in physiological saline [18] 15) and placed under the microscope in a 3D-printed chamber mount, itself placed on a 3D-printed stand fixed on a rigid stand (Fig. 9b, see also Fig. 6d). Red light stimulation was delivered from four sides of the recording chamber and GCaMP6s fluorescence intensity was collected by two detectors, one through the objective lens and a sub-stage PMT (not shown).
We presented full field illumination steps of 615 nm light lasting 0.5 s and an inter-stimulus interval of either 3 s (Fig. 9c) or 10 s (Fig. 9d). We observed robust stimulus-evoked activity in the primary olfactory sensory centres of the larval brain, the antennal lobes (AL, red outlines in Fig. 9c & d). As in our colour vision experiments (Fig. 8), we detected no light artefact at the sides of the scan, indicating near perfect time-synchronisation between the LEDs and the scan-lines. This continued being the case also during resonant scans (not shown). Drawing of the larval zebrafish retina highlighting the IPL. c. 2 photon scan field of the IPL with regions-of-interest marked by red circles. The 64x32 pixel image was obtained by at 1 ms scan rate. d. Ca 2+ traces (mean traces in black, n = 5 trials in grey) in response to consecutive red, green, blue and UV On/Off flashes. e. Trigger timing recorded by the DAQ highlighting its accuracy over time with a precision of 0.1 ms. t(n + 1) = t(n) + T, where ''t" is the recorded trigger time and ''T" the trigger period.

Human and animal rights
All procedures were performed in accordance with the UK Animals (Scientific Procedures) act 1986 and approved by the animal welfare committee of the University of Sussex

Authors contribution
MJYZ conceived and implemented the stimulator with input from AMC, PB and TB. MJYZ performed the vision experiment on larval zebrafish. SP and LLPG performed the optogenetics experiments on Drosophila. MJYZ wrote the manuscript with help from TB and inputs from all authors.

Declaration of interest
AMC has a consultancy company providing services for Open Science: Chagas Science Consultancy, registered in the UK 12,299,826  (Fig. 6d) is placed in a 3Dprinted holder (c.f. 3), screwed onto a rigid stand (ThorLabs). c-d. Standard deviation projections of 2 photon scan fields of the larval brain with antennal lobes marked by red circles (left) and Ca 2+ traces in response to red flashes (right). c. Stimulation duration = 0.5 s, inter-stimulus interval = 3 s, image dimensions = 256 Â 230, scan rate (lines) = 1,081 Hz, frame rate = 4.7 Hz. d. Stimulation duration = 0.5 s, inter-stimulus interval = 10 s, image dimensions = 256 Â 170, scan rate (lines) = 1,077 Hz, frame rate = 6.34 Hz. Middle panel is a heatmap of pixel intensities showing high GCaMP6 fluorescence in the antennal lobe following optogenetic stimulation; obtained by subtracting a pre-stimulus from a during-stimulus image (median filter, kernel size = 2).