Closed Georges-Farkouh closed 4 years ago
The TLC5947 has 24 output so you can connect 20 LEDs and up to four motors. If you want to connect 20 LEDs and 10 motors you will have to chain to a second board, as explained here.
If you decide to chain, you will have to change the code and make sure N_OUTPUT
is set to the output you desire and that mapping is appropriate.
I have connected the 20 fibers to the output pins of TLC5947 (00 to 09 and 14 to 23), I am using the interactor option OptomotorSleepDepriverSystematic to deliver light pluses for optogenetics stimulation. We have to enter 1 or 2 for choosing opto or moto, and both options will send signal to only 10 of the 20 fibers. I would like to know how can I use all output for opto stimulation only.
The function controlling that is this one: https://github.com/gilestrolab/ethoscope/blob/fe74f69150779be4e3cff9b7eaf7695c62a21eb9/src/ethoscope/stimulators/sleep_depriver_stimulators.py#L348-L398
You will have to create a new class similar to that one and remapping the _roi_to_channel_opto
to include the mapping that you need. You have ROIs on the left and pin output on the right of that dictionary.
What is your LED trigger? If you are planning to use the same trigger then you can use the same _decide
function. If you need a different LED trigger then you will have to re-write the _decide function accordingly.
I work with Georges as an intern. We modified the function as you described, adding another class for our purposes and remapping the _roi_to_channel_opto
to associate each of the 20 pins to a LED. Our LED trigger is the same as the one used in OptomotorSleepDepriverSystematic
so we didn't modify that.
However for some unknown reason, the module works fine for any number of LEDs up to 19, but not for 20 LEDs. If we remove 1 LED from the _roi_to_channel_opto
mapping, the 19 remaining LEDs behave as expected; but if we include all 20, they light up once (sometimes twice) after the target acquisition and testing round, then stop working entirely.
Hi @ThHoler can you please post a copy of the code that works and one of the code that behaves weirdly? I suppose the hardware connection to the LED is the same in both cases.
Hello @ggilestro ,
Here's the class we created. For both ethoscopes we tried it with, the LEDs would flicker once or twice before shutting down if we kept all 20 LEDs mapped in the _roi_to_channel_opto
.
However, when changing the _roi_to_channel_opto
by unmapping one or more LEDs, the machine behave as expected.
For our first machine we had to remove at least 1 LED from the mapping (any LED works), for our second ethoscope we had to remove at least 2 LEDs. We used the same module with both ethoscope and didn't touch any of the hardware connections.
class OptogeneticsStimulationSystematic(OptomotorSleepDepriver):
_description = {"overview": "A stimulator to sleep deprive an animal using gear motors. See https://github.com/gilestrolab/ethoscope_hardware/tree/master/modules/gear_motor_sleep_depriver",
"arguments": [
{"type": "number", "min": 1, "max": 3600*12, "step":1, "name": "interval", "description": "The recurence of the stimulus","default":120},
{"type": "number", "min": 500, "max": 10000 , "step": 50, "name": "pulse_duration", "description": "For how long to deliver the stimulus(ms)", "default": 1000},
{"type": "number", "min": 0, "max": 3, "step": 1, "name": "stimulus_type", "description": "1 = opto, 2= moto", "default": 1},
{"type": "date_range", "name": "date_range",
"description": "A date and time range in which the device will perform (see http://tinyurl.com/jv7k826)",
"default": ""}
]}
_HardwareInterfaceClass = OptoMotor
_roi_to_channel_opto = {1:0, 2:1, 3:2, 4:3, 5:4, 6:5, 7:6, 8:7, 9:8, 10:9,
11:23, 12:22, 13:21, 14:20, 15:19, 16:18, 17:17, 18:16, 19:15, 20:14}
_roi_to_channel_moto = {}
def __init__(self,
hardware_connection,
interval=120, # s
pulse_duration = 1000, #ms
stimulus_type = 1, # 1 = opto, 2= moto, 3 = both
date_range=""
):
self._interval = interval *1000 # ms used internally
super(OptogeneticsStimulationSystematic, self).__init__(hardware_connection, 0,0,
pulse_duration, stimulus_type,
date_range)
self._t0 = 0
def _decide(self):
roi_id = self._tracker._roi.idx
try:
channel = self._roi_to_channel[roi_id]
except KeyError:
return HasInteractedVariable(False), {}
now = self._tracker.last_time_point + roi_id *100
if now - self._t0 > self._interval:
dic = {"channel": channel}
dic["duration"] = self._pulse_duration
self._t0 = now
return HasInteractedVariable(True), dic
return HasInteractedVariable(False), {}
Are you trying to keep all LEDs ON at once? Perhaps there is not enough current to do that.
Yes, we are trying to pulse all the 20 LEDs together, with 700ms stimulus duration and 1s recurrence.
It seems the issue was indeed a lack of power coming from the RPi to the TLC. We plugged the TLC to an external power supply at 5V/2A and now the module behaves as expected with all 20 LEDs pulsing together.
I thought so. If you don't want to use an external power supply you may be able to get enough current using one of these: https://amzn.to/2G2LIh8
Or alternatively, you may want to divide in two nonconcurrent pulses of 10 LED each. I'll close the issue now.
In the optomotor module there is a place to mount 20 LEDs, However on the Adafruit TLC 5947 only 10 outputs pins are used to drive the LEDs. I would like to know how we can connect 20 LEDs to 10 outputs pins of the TLC.