Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/api/pylabrobot.cole_parmer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.. currentmodule:: pylabrobot.cole_parmer

pylabrobot.cole_parmer package
==============================

.. currentmodule:: pylabrobot.cole_parmer.genogrinder

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

GenoGrinder
GenoGrinderError

.. currentmodule:: pylabrobot.cole_parmer.masterflex

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

Masterflex
1 change: 1 addition & 0 deletions docs/api/pylabrobot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Manufacturers
pylabrobot.big_bear
pylabrobot.brooks
pylabrobot.byonoy
pylabrobot.cole_parmer
pylabrobot.curiox
pylabrobot.hamilton
pylabrobot.high_res
Expand Down
234 changes: 234 additions & 0 deletions docs/user_guide/cole_parmer/genogrinder/hello-world.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "gg-title",
"metadata": {},
"source": "# Cole-Parmer GenoGrinder (fka SPEX GenoGrinder)\n\nThe GenoGrinder is a high-throughput plate shaker and homogenizer. It clamps a microplate (or a stack of plates, or a set of vials in a plate-format holder) between two platens and shakes it vertically for a fixed time at a fixed speed, grinding or mixing the contents of every well at once.\n\nProduct page: [Cole-Parmer SamplePrep HG-600-230 Geno/Grinder 2010](https://www.coleparmer.com/i/cole-parmer-sampleprep-hg-600-230-geno-grinder-2010-tissue-homogenizer-and-cell-lyser-230-vac-50-hz/0457684)\n\n| Property | Value |\n|---|---|\n| Communication | Serial, ASCII line protocol |\n| Serial settings | 9600 baud, 8 data bits, no parity, 1 stop bit |\n| Line terminator | carriage return (`\\r`) |\n| Duration range | 1--999 s |\n| Speed range | 1--9999 rpm |\n| Clamp | motorized (open/close) or fixed, depending on model |\n\n```{warning}\nThis driver has NOT been tested against hardware in PyLabRobot. `setup()` logs a\nwarning to that effect. If you verify it on your machine, please open a PR to\nremove the warning.\n```"
},
{
"cell_type": "markdown",
"id": "gg-physical",
"metadata": {},
"source": [
"## Physical setup\n",
"\n",
"Connect the GenoGrinder's serial port to your computer, typically through a USB-to-serial adapter, and note the port name (`/dev/ttyUSB*` on Linux, `/dev/tty.usbserial-*` on macOS, `COM*` on Windows).\n",
"\n",
"Make sure the instrument's serial parameters match the driver defaults (9600 baud, 8 data bits, no parity, 1 stop bit), and that the safety lid is closed -- the machine will not run with it open."
]
},
{
"cell_type": "markdown",
"id": "gg-connect-md",
"metadata": {},
"source": "## Connect\n\n`setup()` opens the serial port and runs the instrument's power-on routine, which homes the mechanism and readies the clamp. Its reply doubles as a communication check, so a successful `setup()` means the machine is talking and ready to run.\n\nSome GenoGrinder models have a fixed clamp that you tighten by hand instead of a motorized one. On those, pass `use_clamp_commands=False`: `open_clamp()` and `close_clamp()` then do nothing, so the same protocol code runs on either machine."
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-connect",
"metadata": {},
"outputs": [],
"source": [
"from pylabrobot.cole_parmer import GenoGrinder\n",
"\n",
"grinder = GenoGrinder(port=\"/dev/ttyUSB0\") # replace with your port\n",
"await grinder.setup()"
]
},
{
"cell_type": "markdown",
"id": "gg-clampstate-md",
"metadata": {},
"source": "## Check the clamp\n\n`request_clamp_state()` reports whether the clamp is `\"open\"`, `\"closed\"`, or `\"unknown\"`."
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-clampstate",
"metadata": {},
"outputs": [],
"source": "print(\"Clamp:\", await grinder.request_clamp_state())"
},
{
"cell_type": "markdown",
"id": "gg-open-md",
"metadata": {},
"source": [
"## Open the clamp\n",
"\n",
"`open_clamp()` reads the current position and only moves if the clamp is not already open, so it is safe to call repeatedly."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-open",
"metadata": {},
"outputs": [],
"source": [
"await grinder.open_clamp()"
]
},
{
"cell_type": "markdown",
"id": "gg-load-md",
"metadata": {},
"source": [
"## Load a plate\n",
"\n",
"Place your plate (or plate stack) in the clamp now, centered on the platen, and close the safety lid."
]
},
{
"cell_type": "markdown",
"id": "gg-close-md",
"metadata": {},
"source": [
"## Close the clamp\n",
"\n",
"`close_clamp()` clamps the plate down. Like `open_clamp()`, it checks the current position first."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-close",
"metadata": {},
"outputs": [],
"source": [
"await grinder.close_clamp()"
]
},
{
"cell_type": "markdown",
"id": "gg-shake-md",
"metadata": {},
"source": [
"## Shake\n",
"\n",
"`shake()` uploads the run parameters, starts the run, then polls the instrument until it reports the run is complete -- so the call returns when the plate has actually finished shaking.\n",
"\n",
"`duration` is in seconds (1--999) and `speed` in rpm (1--9999). Start gentle and work up: hard grinding at high rpm can crack plates and unseat seals."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-shake",
"metadata": {},
"outputs": [],
"source": [
"await grinder.shake(duration=30, speed=1500)"
]
},
{
"cell_type": "markdown",
"id": "gg-status-md",
"metadata": {},
"source": "## Read the status\n\n`request_status()` returns the instrument's raw status line -- `Standby` when idle, or one of the transient run states (`Running Sample`, `Locking`, `Mixing`, `Unlocking`, `Run Complete`) during a run. Useful when driving the machine from another task while a run is going."
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-status",
"metadata": {},
"outputs": [],
"source": "print(\"Status:\", await grinder.request_status())"
},
{
"cell_type": "markdown",
"id": "gg-stopshaking-md",
"metadata": {},
"source": [
"## Abort a run\n",
"\n",
"`stop_shaking()` stops a run in progress. Because `shake()` blocks until the run finishes, call this from a separate task (or after interrupting the cell) when you need to cut a run short."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-stopshaking",
"metadata": {},
"outputs": [],
"source": [
"await grinder.stop_shaking()"
]
},
{
"cell_type": "markdown",
"id": "gg-home-md",
"metadata": {},
"source": [
"## Home the clamp\n",
"\n",
"`home_clamp()` returns the clamp to its reference position. Use it to recover a known state after an aborted run."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-home",
"metadata": {},
"outputs": [],
"source": [
"await grinder.home_clamp()"
]
},
{
"cell_type": "markdown",
"id": "gg-unload-md",
"metadata": {},
"source": [
"## Unload the plate\n",
"\n",
"Open the clamp again and take the plate out."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-unload",
"metadata": {},
"outputs": [],
"source": [
"await grinder.open_clamp()"
]
},
{
"cell_type": "markdown",
"id": "gg-teardown-md",
"metadata": {},
"source": [
"## Teardown\n",
"\n",
"`stop()` halts any run still in progress and closes the serial connection."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "gg-teardown",
"metadata": {},
"outputs": [],
"source": [
"await grinder.stop()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
7 changes: 7 additions & 0 deletions docs/user_guide/cole_parmer/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Cole-Parmer

```{toctree}
:maxdepth: 1

genogrinder/hello-world
```
1 change: 1 addition & 0 deletions docs/user_guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ azenta/index
big_bear/index
brooks/index
byonoy/index
cole_parmer/index
curiox/index
hamilton/index
high_res/index
Expand Down
1 change: 1 addition & 0 deletions pylabrobot/cole_parmer/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .genogrinder import GenoGrinder, GenoGrinderError
from .masterflex import Masterflex
Loading
Loading