{ "cells": [ { "cell_type": "markdown", "id": "866f6f49", "metadata": {}, "source": [ "# Hamilton Heater Shaker" ] }, { "cell_type": "markdown", "id": "d2087a07", "metadata": {}, "source": [ "The Hamilton Heater Shaker can be used both through a control box (the `HamiltonHeaterShakerBox`, which supports up to 8 heater shakers), or directly plugged into a Hamilton STAR liquid handler (supporting up to 2 heater shakers).\n", "\n", "When using the box, a USB B cable is plugged into one of the heater shakers and connected to the host computer. This heater shaker is connected via a serial port to the control box. Other heater shakers are also plugged into the control box using serial cables, but not plugged into the computer. The first heater shakers serves as a gateway.\n", "\n", "When using the Hamilton STAR, the heater shaker is connected to the STAR via a serial cable. The STAR is connected to the host computer via a USB A cable. This is no different from using the STAR as a standalone liquid handler. The heater shaker is then controlled through the STAR.\n", "\n", "In either case, `HamiltonHeaterShakerBackend` will be the backend and `HeaterShaker` will be the frontend. Depending on the interface you use, pass a different argument to `HamiltonHeaterShakerBackend`.\n", "\n", "As multiple heater shakers can be controlled through one USB connection to the computer (the STAR cable when using the STAR, or a cable to HHS 1 when using the control box), the `index` of a specific heater shaker needs to be specified. Note that this also requires turing a DIP switch on the bottom of the HHS module." ] }, { "cell_type": "code", "execution_count": null, "id": "000202e0", "metadata": {}, "outputs": [], "source": [ "# Setting up a backend with the HamiltonHeaterShakerBox\n", "from pylabrobot.heating_shaking import HamiltonHeaterShakerBackend, HamiltonHeaterShakerBox\n", "\n", "hhs_box = HamiltonHeaterShakerBox()\n", "backend = HamiltonHeaterShakerBackend(index=1, interface=hhs_box)" ] }, { "cell_type": "code", "execution_count": null, "id": "eb133716", "metadata": {}, "outputs": [], "source": [ "# Alternative: setting up a backend with a STAR\n", "from pylabrobot.liquid_handling import LiquidHandler, STAR\n", "from pylabrobot.resources import STARDeck\n", "from pylabrobot.heating_shaking import HamiltonHeaterShakerBackend\n", "\n", "star_backend = STAR()\n", "lh = LiquidHandler(backend=star_backend, deck=STARDeck())\n", "\n", "backend = HamiltonHeaterShakerBackend(index=1, interface=star_backend)" ] }, { "cell_type": "code", "execution_count": null, "id": "819863d9", "metadata": {}, "outputs": [], "source": [ "from pylabrobot.heating_shaking import HeaterShaker\n", "from pylabrobot.resources.coordinate import Coordinate\n", "\n", "hs = HeaterShaker(\n", " name=\"Hamilton HeatShaker\",\n", " backend=backend,\n", " size_x=146.2,\n", " size_y=103.8,\n", " size_z=74.11,\n", " child_location=Coordinate(x=9.66, y=9.22, z=74.11),\n", ")" ] }, { "cell_type": "markdown", "id": "29806703", "metadata": {}, "source": [ "Note that for the HHS Box, you will need to call `setup` before calling `HeaterShaker.setup`. When using a `STAR`, just use `star.setup()` or, more likely, `lh.setup()`. This is opening the USB connection to the device you are using as an interface.\n", "\n", "Note that setup should only be called ONCE:\n", "- when using a STAR as a liquid handler, just call `lh.setup()`. Do not call it again when using the heater shaker.\n", "- when using multiple heater shakers with the control box, call `setup` once for the control box, and then call `HeaterShaker.setup` for each heater shaker. Do not call `setup` again for the control box." ] }, { "cell_type": "code", "execution_count": null, "id": "76173726", "metadata": {}, "outputs": [], "source": [ "# when using the HamiltonHeaterShakerBox, you need to call setup() on the box\n", "await hhs_box.setup()" ] }, { "cell_type": "code", "execution_count": null, "id": "1cc6afa9", "metadata": {}, "outputs": [], "source": [ "# Alternative: when using the STAR, you need to call setup() on lh\n", "await lh.setup()" ] }, { "cell_type": "markdown", "id": "70115dff", "metadata": {}, "source": [ "After calling `setup` on your interface, call `HeaterShaker.setup` for each module. This will initialize the module itself." ] }, { "cell_type": "code", "execution_count": 3, "id": "c6d38f82", "metadata": {}, "outputs": [], "source": [ "await hs.setup()" ] }, { "cell_type": "markdown", "id": "5e201ecb", "metadata": {}, "source": [ "## Temperature" ] }, { "cell_type": "code", "execution_count": 4, "id": "2f544e4a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "26.3" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "await hs.get_temperature() # middle temperature" ] }, { "cell_type": "markdown", "id": "6cadda38", "metadata": {}, "source": [ "The HHS also supports reading the edge temperature:" ] }, { "cell_type": "code", "execution_count": 5, "id": "81e0743c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "26.4" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "await hs.backend.get_edge_temperature()" ] }, { "cell_type": "code", "execution_count": 6, "id": "f076c7bd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'T1TAid0004er00'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "await hs.set_temperature(37)" ] }, { "cell_type": "code", "execution_count": 7, "id": "cf85de20", "metadata": {}, "outputs": [], "source": [ "await hs.wait_for_temperature()" ] }, { "cell_type": "code", "execution_count": 8, "id": "a4d8e655", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "36.6" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "await hs.get_temperature()" ] }, { "cell_type": "markdown", "id": "d1b72d26", "metadata": {}, "source": [ "## Shaking" ] }, { "cell_type": "code", "execution_count": 9, "id": "17646f3d", "metadata": {}, "outputs": [], "source": [ "await hs.lock_plate()" ] }, { "cell_type": "code", "execution_count": 10, "id": "49b330b7", "metadata": {}, "outputs": [], "source": [ "await hs.shake(\n", " speed=100,\n", " direction=0,\n", " acceleration=1000,\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "a0d8ab2d", "metadata": {}, "outputs": [], "source": [ "await hs.unlock_plate()" ] }, { "cell_type": "code", "execution_count": 12, "id": "71d8a964", "metadata": {}, "outputs": [], "source": [ "await hs.stop_shaking()" ] }, { "cell_type": "markdown", "id": "a6ee0951", "metadata": {}, "source": [ "## Using multiple heater shakers\n", "\n", "When using multiple heater shakers, you can use the `HamiltonHeaterShakerBackend` class to control them. This class will automatically handle the communication with the control box and the individual heater shakers.\n", "\n", "As above, initialize the `HamiltonHeaterShakerBox` class. Then, initialize as many `HamiltonHeaterShakerBackend` classes as you want to control, specifying the index for each. Note that each `HamiltonHeaterShakerBackend` gets the same instance of the `HamiltonHeaterShakerBox`: this is because there is a single USB connection, managed by that instance." ] }, { "cell_type": "code", "execution_count": null, "id": "9745da8f", "metadata": {}, "outputs": [], "source": [ "hhs_box = HamiltonHeaterShakerBox()\n", "\n", "# HS1\n", "backend1 = HamiltonHeaterShakerBackend(index=1, interface=hhs_box)\n", "hs1 = HeaterShaker(\n", " name=\"Hamilton HeatShaker\",\n", " backend=backend,\n", " size_x=146.2,\n", " size_y=103.8,\n", " size_z=74.11,\n", " child_location=Coordinate(x=9.66, y=9.22, z=74.11),\n", ")\n", "\n", "# HS2\n", "backend2 = HamiltonHeaterShakerBackend(index=2, interface=hhs_box)\n", "hs2 = HeaterShaker(\n", " name=\"Hamilton HeatShaker\",\n", " backend=backend,\n", " size_x=146.2,\n", " size_y=103.8,\n", " size_z=74.11,\n", " child_location=Coordinate(x=9.66, y=9.22, z=74.11),\n", ")" ] }, { "cell_type": "markdown", "id": "e26cc8dc", "metadata": {}, "source": [ "For setup, call `setup` on the `HamiltonHeaterShakerBox` instance. This will setup the USB connection to the control box. Then, call `setup` on each `HamiltonHeaterShakerBackend` instance. This will setup the individual heater shakers." ] }, { "cell_type": "code", "execution_count": null, "id": "7ff193b0", "metadata": {}, "outputs": [], "source": [ "await hhs_box.setup()\n", "\n", "for hs in [hs1, hs2]:\n", " await hs.setup()" ] } ], "metadata": { "kernelspec": { "display_name": "env", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.15" } }, "nbformat": 4, "nbformat_minor": 5 }