Skip to content

Commit

Permalink
Merge pull request #13 from fchampalimaud/AS_olfactometer_example
Browse files Browse the repository at this point in the history
Add olfactometer end valve toggle example
  • Loading branch information
artursilva0 authored Aug 13, 2024
2 parents 56fa6b5 + 0069a32 commit eb60b00
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 2 deletions.
8 changes: 6 additions & 2 deletions docs/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
href: install_bonsai.md
- name: Install Harp
href: install_harp.md
- name: Bonsai/Harp Examples (12)
- name: Bonsai/Harp Examples (13)
items:
- name: Behavior Board (11)
items:
Expand All @@ -32,14 +32,18 @@
href: ../workflows/HarpExamples/BehaviorBoard/QuadratureEncoder/QuadratureEncoder.md
- name: Log Selected
href: ../workflows/HarpExamples/BehaviorBoard/LogSelected/LogSelected.md
- name: Olfactometer (1)
items:
- name: End Valve Toggle
href: ../workflows/HarpExamples/Olfactometer/EndValveToggle/EndValveToggle.md
- name: Syringe Pump (1)
items:
# - name: Toggle Single Steps
# href: ../workflows/HarpExamples/SyringePump/ToggleSingleSteps/ToggleSingleSteps.md
# - name: Toggle Multiple Steps
# href: ../workflows/HarpExamples/SyringePump/ToggleMicroSteps/ToggleMicroSteps.md
- name: Toggle Multiple Steps
href: ../workflows/HarpExamples/SyringePump/ToggleMultipleSteps/ToggleMultipleSteps.md
href: ../workflows/HarpExamples/SyringePump/ToggleMultipleSteps/ToggleMultipleSteps.md
- name: Reactive Examples (8)
items:
- name: Take
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core"
xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp"
xmlns:p1="clr-namespace:Harp.Olfactometer;assembly=Harp.Olfactometer"
xmlns:wie="clr-namespace:Bonsai.Windows.Input;assembly=Bonsai.Windows.Input"
xmlns="https://bonsai-rx.org/2018/workflow">
<Workflow>
<Nodes>
<Expression xsi:type="Annotation">
<Name>1</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="rx:BehaviorSubject" TypeArguments="harp:HarpMessage">
<rx:Name>Device Commands</rx:Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="p1:Device">
<harp:OperationMode>Active</harp:OperationMode>
<harp:OperationLed>On</harp:OperationLed>
<harp:DumpRegisters>true</harp:DumpRegisters>
<harp:VisualIndicators>On</harp:VisualIndicators>
<harp:Heartbeat>Disabled</harp:Heartbeat>
<harp:IgnoreErrors>false</harp:IgnoreErrors>
<harp:PortName>COM5</harp:PortName>
</Combinator>
</Expression>
<Expression xsi:type="rx:PublishSubject">
<Name>Device Events</Name>
</Expression>
<Expression xsi:type="Annotation">
<Name>1.1</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:Parse">
<harp:Register xsi:type="p1:Channel0ActualFlow" />
</Expression>
<Expression xsi:type="Annotation">
<Name>1.2</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:Parse">
<harp:Register xsi:type="p1:Channel3ActualFlow" />
</Expression>
<Expression xsi:type="Annotation">
<Name>1.3</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:Parse">
<harp:Register xsi:type="p1:Channel4ActualFlow" />
</Expression>
<Expression xsi:type="Annotation">
<Name>2</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="wie:KeyDown">
<wie:Filter>B</wie:Filter>
<wie:SuppressRepetitions>false</wie:SuppressRepetitions>
</Combinator>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateEnableFlowPayload">
<p1:EnableFlow>Enabled</p1:EnableFlow>
</harp:Payload>
</Expression>
<Expression xsi:type="Annotation">
<Name>3</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="wie:KeyDown">
<wie:Filter>E</wie:Filter>
<wie:SuppressRepetitions>false</wie:SuppressRepetitions>
</Combinator>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateEnableFlowPayload">
<p1:EnableFlow>Disabled</p1:EnableFlow>
</harp:Payload>
</Expression>
<Expression xsi:type="Annotation">
<Name>4</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateEnableValvePulsePayload">
<p1:EnableValvePulse>EndValve0</p1:EnableValvePulse>
</harp:Payload>
</Expression>
<Expression xsi:type="Annotation">
<Name>5</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateEndValve0PulseDurationPayload">
<p1:EndValve0PulseDuration>500</p1:EndValve0PulseDuration>
</harp:Payload>
</Expression>
<Expression xsi:type="Annotation">
<Name>6</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateChannel3RangePayload">
<p1:Channel3Range>FlowRate1000</p1:Channel3Range>
</harp:Payload>
</Expression>
<Expression xsi:type="Annotation">
<Name>7</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateChannelsTargetFlowPayload">
<p1:Channel0>80</p1:Channel0>
<p1:Channel1>0</p1:Channel1>
<p1:Channel2>0</p1:Channel2>
<p1:Channel3>800</p1:Channel3>
<p1:Channel4>720</p1:Channel4>
</harp:Payload>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Merge" />
</Expression>
<Expression xsi:type="MulticastSubject">
<Name>Device Commands</Name>
</Expression>
<Expression xsi:type="Annotation">
<Name>8</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>Device Events</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:SubscribeWhen" />
</Expression>
<Expression xsi:type="Annotation">
<Name>9</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="wie:KeyDown">
<wie:Filter>A</wie:Filter>
<wie:SuppressRepetitions>false</wie:SuppressRepetitions>
</Combinator>
</Expression>
<Expression xsi:type="Annotation">
<Name>9.1</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateOdorValveStatePayload">
<p1:OdorValveState>Valve0 Valve3</p1:OdorValveState>
</harp:Payload>
</Expression>
<Expression xsi:type="MulticastSubject">
<Name>Device Commands</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Delay">
<rx:DueTime>PT2S</rx:DueTime>
</Combinator>
</Expression>
<Expression xsi:type="Annotation">
<Name>9.2</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateEndValveStatePayload">
<p1:EndValveState>EndValve0</p1:EndValveState>
</harp:Payload>
</Expression>
<Expression xsi:type="MulticastSubject">
<Name>Device Commands</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Delay">
<rx:DueTime>PT1S</rx:DueTime>
</Combinator>
</Expression>
<Expression xsi:type="Annotation">
<Name>9.3</Name>
<Text><![CDATA[]]></Text>
</Expression>
<Expression xsi:type="p1:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
<harp:Payload xsi:type="p1:CreateOdorValveStatePayload">
<p1:OdorValveState>None</p1:OdorValveState>
</harp:Payload>
</Expression>
<Expression xsi:type="MulticastSubject">
<Name>Device Commands</Name>
</Expression>
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="1" To="2" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="5" Label="Source1" />
<Edge From="3" To="7" Label="Source1" />
<Edge From="3" To="9" Label="Source1" />
<Edge From="4" To="5" Label="Source2" />
<Edge From="6" To="7" Label="Source2" />
<Edge From="8" To="9" Label="Source2" />
<Edge From="10" To="11" Label="Source1" />
<Edge From="11" To="12" Label="Source1" />
<Edge From="12" To="24" Label="Source1" />
<Edge From="13" To="14" Label="Source1" />
<Edge From="14" To="15" Label="Source1" />
<Edge From="15" To="24" Label="Source2" />
<Edge From="16" To="17" Label="Source1" />
<Edge From="17" To="24" Label="Source3" />
<Edge From="18" To="19" Label="Source1" />
<Edge From="19" To="24" Label="Source4" />
<Edge From="20" To="21" Label="Source1" />
<Edge From="21" To="24" Label="Source5" />
<Edge From="22" To="23" Label="Source1" />
<Edge From="23" To="24" Label="Source6" />
<Edge From="24" To="25" Label="Source1" />
<Edge From="25" To="28" Label="Source1" />
<Edge From="26" To="27" Label="Source1" />
<Edge From="27" To="28" Label="Source2" />
<Edge From="29" To="30" Label="Source1" />
<Edge From="30" To="32" Label="Source1" />
<Edge From="31" To="32" Label="Source2" />
<Edge From="32" To="33" Label="Source1" />
<Edge From="33" To="34" Label="Source1" />
<Edge From="34" To="36" Label="Source1" />
<Edge From="35" To="36" Label="Source2" />
<Edge From="36" To="37" Label="Source1" />
<Edge From="37" To="38" Label="Source1" />
<Edge From="38" To="40" Label="Source1" />
<Edge From="39" To="40" Label="Source2" />
<Edge From="40" To="41" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# End Valve Toggle

## Summary
This example demonstrates how to configure the Harp Olfactometer to toggle the End valve using the [Harp Olfactometer](https://github.com/harp-tech/device.olfactometer) board (see hardware diagram below).

## Workflow

:::workflow
![Example](~/workflows/HarpExamples/Olfactometer/EndValveToggle/EndValveToggle.bonsai)
:::

## Details

1. Creates a subject node to send commands to the Olfactometer board and publishes all the events from the device. The PortName property in the Olfactometer node needs to be set to the COM device on the computer. To create the subject node, right-click on the Olfactometer node -> Create Source -> Behavior Subject, and name it accordingly.
1. Filters event messages associated with the Channel 0 flow rate.
2. Filters event messages associated with the Channel 3 flow rate.
3. Filters event messages associated with the Channel 4 flow rate.
2. Enables the Olfactometer flow by pressing the 'B' key.
3. Disables the Olfactometer flow by pressing the 'E' key.
4. Enables the End valve to be configured with hardware generated pulse.
5. Configures the value (in milliseconds) of the End valve pulse.
6. Selects the Channel 3 flow range (0-1000 ml/s).
7. Sets the target flow rate for all the channels of the olfactometer. If they are not used they are configure with zero value.
8. Ensures that command messages are sent only when the device is ready.
9. Sets the state of the different valves and End valve to perform a 500 ms odor delivery through the End valve after 'A' key press.
1. Odor valve 0 and valve 3 (used as auxiliary carrier) are enabled 2 seconds before the End valve toggle.
2. End valve is enabled and will execute the pre-configured pulse.
3. Odor valve 0 and valve 3 are disabled.


## Requirements

This example requires the following Bonsai package:
- Harp.Olfactometer (from nuget.org) - make sure to select 'Include prerelease'


## Schematics

The [Harp Olfactometer](https://github.com/harp-tech/device.olfactometer) supports up to 4 odor channels and 1 carrier line. When using an End valve, Channel 3 is used as an auxiliary carrier line.

In this example Channel 0 (odor line) is configured with a 80 ml/min flow rate, Channel 3 (auxiliary carrier) with 800 ml/min and Channel 4 (carrier line) with 720 ml/min. The sum of Channel 0 and Channel 4 flows should match the value of Channel 3 in order to maintain the same flow rate at the output, whether odor is being presented or not.

After 'A' key press the odor channel flow is enabled, goes through the correspondent vial, mixes with the auxiliary carrier line and is exhausted in the end valve during a time period before the End valve is toggled in order to stabilize the mixture. During this time, clean air is being delivered to the animal through the End valve. After that, the End valve toggles during 500 ms and the odorized air is delivered to the animal while the clean air is exhausted. Finally after the End valve toggling time, the Channel 0 and Channel 3 are disabled.

![Schematics](./EndValveToggle.png){ width=80% }


Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit eb60b00

Please sign in to comment.