Pioreactor / pioreactor

Hardware and software for accessible, extensible, and scalable bioreactors. Built on Raspberry Pi.
https://pioreactor.com
MIT License
100 stars 9 forks source link

LED design #35

Closed CamDavidsonPilon closed 3 years ago

CamDavidsonPilon commented 3 years ago

In total, we may have 6 LEDs driven by the Rpi at variable intensities. What are some use cases for using LEDs?

Use cases

Non-conditional lighting

  1. Turbidity and cell density - this is almost universal, i.e. one LED spot is for the IR LED. There may be circumstances where we want to turn off the IR LED, for example, if we turn on a bubbler or something. OD Readings will need to be timed then, too - that's fine.

  2. Growing algae: 1 or more LEDs may be used as a light source for algae. It could be white light, red, blue or a mixture of them.

  3. UV light used for fluorescence. It will be a quick pulse of UV light with a specific-wavelength PD at 90°. This could happen at 1 minute intervals, or less.

  4. UV light as mutagensis: Keeping the UV light off for long periods of time, and then flashing for N seconds.

  5. Ratiometric turbidity measurements, like in the GLI2 methods.

Conditional lighting

  1. Let's say we are doing directed evolution of algae, and want to ween algae off a light source. This involves conditionally turning LEDs on and off.

  2. For algae culture, as cell density increases, we need to match light intensity.

Potential interfaces (not mutually exclusive)

Action-based

Like pump actions, lighting could be actions. This way they can be imported into other jobs. Ex: od_reading imports actions.ir_led.LED and turns it on (it's probably a thread). Ex: algae directed evolution turns on/off actions.white_led, and flashes actions.uv_led. It's up the the code/author to turn on/off LEDs (supports conditional).

Job based, with an exposed API

Possibly there exists a "LEDController" class/job which listens to changes over MQTT. This fits the "long-running" idea of background jobs. By default, all are off, and other jobs/actions turn LEDs on or off. Or the default is defined in a config.ini which could support the following section. However, I do take on some latency by putting MQTT between jobs and controlling LEDs, which could make schedualing more difficult. EDIT: the latency, on the same network, of a publish and leader hears is sub-30 milliseconds, around 10milliseconds.

Static lighting (static is the wrong word)

Ex syntax (non-conditional, doesn't have any quantities)

# different LED tracks, each column represents one second. * means on, - means off. 
# suppose our pattern is 20seconds
1:-******************* # blue LED
2:-******************* # red LED
3:-******************* # IR LED
4:*------------------- # UV light for fl. measurement
5:-------------------- # not used
6:-------------------- # not used

Pros:

Cons:

job/algorithm based, like dosing

After refactoring io_controlling to dosing_control, the code feels cleaner and less of a garbage dump. At the same time, I am struggling with how to empower users with some simple like "I want LED light in proportion to OD for growing algae". What if there exists an LEDControl with accompanying LEDAlgorithms? The would make creating the algae script very straightforward, and can easily accommodate all other LED situations above: similar to how pumps are exposed as actions and are used in the DosingAlgos, we expose LED operations as actions (so jobs like od_reading can use them) and expose them as LEDAlgos.

CamDavidsonPilon commented 3 years ago

I initally coded up the job/algorithm based, like dosing option, and it feels good. The only problem is that we are spawning N more threads now if using LEDControl