A log file is a computer-generated data file that contains information about usage patterns, activities, and operations within an operating system, application, server, or another device.

Serial logs

The Raspberry Pi on the OT-2 uses a serial protocol to command the motor controller board. The OT-2 logs these commands in the form of G-codes. G-code is a common language for controlling things like 3D printers and CNC machines.

For example, you might give a machine the G-code command "G0 X10" to tell it to move 10 mm along its x-axis, or the G-code command "G28.2 Y" to tell it to home its y-axis.

The OT-2 uses G-code internally for controlling its gantry, pipettes, and modules.

  • The software running on the Raspberry Pi sends G-code to the motor controller board. The motor controller board then receives it, interprets it, and electrically drives the gantry and pipette motors accordingly.

  • It also sends G-code over a USB cable to modules, which interpret it and do their module things.

How to understand G-codes

Starting from:

M907 A0.1 B1.0 C0.05 X0.3 Y0.3 Z0.1 G4P0.005 G28.2B
  1. "M907 A0.1 B1.0 C0.05 X0.3 Y0.3 Z0.1M907" is code for “set the motors’ electrical current.” "A0.1 B1.0 C0.05 X0.3 Y0.3 Z0.1" specifies the new current for each axis (0.1 amps on the A-axis, 1.0 amps on the B-axis, and so on).

  2. "G4P0.005G4" is code for “dwell” (pause).P0.005 specifies that the dwell should be 0.005 seconds.

  3. "G28.2B G28.2" is code for “home.”B specifies that the home should be on the B-axis

So, in short, this line of G-code sets the motor currents, waits very briefly, and then homes the B-axis.

Example

Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'M400\r\n\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Read <- b'M400\n\no\r\nk\r\nok\r\nok\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'M18ZACB\r\n\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Read <- b'M18ZACB\r\no\r\nk\r\nok\r\nok\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'M400\r\n\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Read <- b'M400\ro\n\r\nk\r\nok\r\nok\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'G4P0.1\r\n\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Read <- b'G4P0.1\r\n\r\nok\r\nok\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'M400\r\n\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Read <- b'M400\r\n\n\rk\n\r\nok\r\nok\r\n'
Feb 17 21:40:05 blue-cloud opentrons-api-serial[237]: smoothie: Write -> b'M369R\r\n\r\n'

G-code references

Consult the OT-2’s Python source code to see what each G-code command means.

What the G-code is controlling

The relevant source code file

OT-2 gantry and pipettes

api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py

Magnetic Module

api/src/opentrons/drivers/mag_deck/driver.py

Temperature Module

api/src/opentrons/drivers/temp_deck/driver.py

Thermocycler Module

api/src/opentrons/drivers/thermocycler/driver.py

In these files, try Command+F searching for the first part of the command (like G0 or M907).

API Logs

Similar to serial logs, the OT-2 keeps a record of the API level commands. The commands are more intuitive to read. If you are using our Python API, they should be easier to understand.

How to understand API Commands

The messages that are printed on the API logs closely resemble the commands you would use when developing protocols with our Python API. Our API was designed to make writing protocols easy and accessible to everyone.

Not only do these logs resemble our Python API, but they also resemble the actions that are being performed by the OT-2 during a protocol.

Starting from:

Dec 14 20:20:55 falling-forest opentrons-api[233]: Updating working volume on pipette mount:RIGHT, tip volume: 300 ul
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.aspirate: {'volume': 50, 'location': Location(point=Point(x=63.88, y=42.74, z=5.550000000000001), labware=A1 of rez on 1), 'rate': 1.0}
  1. "Updating working volume on pipette mount:RIGHT, tip volume: 300 ul" is telling us the pipette on the right mount will be used in the following commands

  2. "InstrumentContext.aspirate" is telling us that the pipette is going to aspirating with this pipette

  3. "'volume': 50, 'location': Location(point=Point(x=63.88, y=42.74, z=5.550000000000001), labware=A1 of rez on 1), 'rate': 1.0" is telling us the volume, the location, and the rate of the aspirate step

So, in short, this line of logs says the pipette on the right mount is going to aspirate 50 μL of liquid from well A1 of the labware on slot 1.

Example

Below is a snippet of what the API log file would look like in an aspirate/dispense cycle.

Dec 14 20:20:55 falling-forest opentrons-api[233]: Updating working volume on pipette mount:RIGHT, tip volume: 300 ul
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.aspirate: {'volume': 50, 'location': Location(point=Point(x=63.88, y=42.74, z=5.550000000000001), labware=A1 of rez on 1), 'rate': 1.0}
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.dispense: {'volume': 50, 'location': Location(point=Point(x=146.88, y=74.24, z=1.42), labware=A1 of NEST 96 Well Plate 100 µL PCR Full Skirt on 2), 'rate': 1.0}
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.aspirate: {'volume': 50, 'location': Location(point=Point(x=63.88, y=42.74, z=5.550000000000001), labware=A1 of rez on 1), 'rate': 1.0}
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.dispense: {'volume': 50, 'location': Location(point=Point(x=155.88, y=74.24, z=1.42), labware=A2 of NEST 96 Well Plate 100 µL PCR Full Skirt on 2), 'rate': 1.0}
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.aspirate: {'volume': 50, 'location': Location(point=Point(x=63.88, y=42.74, z=5.550000000000001), labware=A1 of rez on 1), 'rate': 1.0}
Dec 14 20:20:55 falling-forest opentrons-api[233]: InstrumentContext.dispense: {'volume': 50, 'location': Location(point=Point(x=164.88, y=74.24, z=1.42), labware=A3 of NEST 96 Well Plate 100 µL PCR Full Skirt on 2), 'rate': 1.0}

Server Logs

On software versions 4.1+ you will be able to download a third log file referred to as the server log. These logs encompass both the built-in response logs (very useful for figuring out interaction patterns) and errors that bubble up to the server logging handlers.

How to understand Server Logs

Example:

Feb 11 17:57:56 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO:      - "GET /labware/calibrations HTTP/1.1" 200 OK
Feb 11 17:57:59 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO: - "GET /calibration/tip_length HTTP/1.1" 200 OK
Feb 11 17:57:59 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO: - "GET /labware/calibrations HTTP/1.1" 200 OK
Feb 11 17:57:59 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO: - "GET /pipettes HTTP/1.1" 200 OK
Feb 11 17:58:00 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO: - "GET /modules HTTP/1.1" 200 OK
Feb 11 17:58:01 CA9520E280A2E1B4A5E280A2CA94 uvicorn[239]: INFO: - "GET /sessions HTTP/1.1" 200 OK

Downloading logfiles via Operntrons app

  1. Make sure you are connected to your OT-2

  2. Scroll down in the main connection page

  3. Under Advanced Settings, you will see a DOWNLOAD button

  4. Select the DOWNLOAD button

  5. Follow the operating system specific on-screen directions to save the log files

Did this answer your question?