Get Prusa 3D Printer Status with Python¶
Still Unstable... need to revise more
Reference:
We can get current printer status with sending G-Code via serial communication.
For example:
- M105 : Could get Temperture status of the printer
- M114 : Could get X,Y,Z position and extrusion amount or position of the extruder
- M155 : Count output Temperature, fan status and position automatically
Connecting my Prusa Core One to my PC, I tried to get the printer status data.
First, import serial library and time library
In [111]:
import serial
import time
from datetime import datetime as dt
import serial.tools.list_ports as list_ports
Then, check the serial port path.
In [112]:
ports = list_ports.comports()
for port,desc,hwid in sorted(ports):
print(f"{port}: {desc} [{hwid}]")
/dev/cu.AnkerPowerConf: n/a [n/a] /dev/cu.Bluetooth-Incoming-Port: n/a [n/a] /dev/cu.debug-console: n/a [n/a] /dev/cu.usbmodem2101: Original Prusa COREONE [USB VID:PID=2C99:001F SER=13052-4742441644809810 LOCATION=2-1] /dev/cu.usbserial-5: FT232R USB UART [USB VID:PID=0403:6001 SER=A9085KFP LOCATION=0-1] /dev/cu.usbserial-A9085KFP: FT232R USB UART [USB VID:PID=0403:6001 SER=A9085KFP LOCATION=0-1]
I found "/dev/cu.usbmodem2101" is the serial port for my Prusa Core One. Then, open the serial port as baudrate 115200
In [113]:
prusa = serial.Serial('/dev/cu.usbmodem2101',115200,timeout=1)
time.sleep(2)
prusa.reset_input_buffer()
I asked ChatGPT as prompt:
I am connecting to the Prusa printer via USB serial. I want to obtain the results of the M114 command, which reports the x, y, z positions every second, and the M105 command, which reports the temperature status.
Then, he showed the code in the following three code.
- send_gcode: receive the g-code command (M114 or M105) and write it into serial, read the response.
- parse_temp, parse_position: Printer sometime send information like "busy: processing", those should be dropped here.
- main function: using try and while loop to get the data.
to debug and modified his code (his code just print the info from the printer, I wanted to save it), currently, I wrote the below code with modifying ChatGPT's suggested.
In [114]:
def send_gcode(command):
prusa.write((command + "\n").encode("utf-8"))
prusa.flush()
lines = []
while True:
line = prusa.readline().decode("utf-8").strip()
if not line:
break
if "busy: processing" in line:
print("Printer is busy:",line)
continue
lines.append(line)
if line == "ok" or line.startswith("ok "):
break
return lines
In [ ]:
def parse_temp(lines):
candidate = None
for line in lines:
if "busy: processing" in line:
continue
if line.startswith("echo:"):
continue
if "T:" in line and "B:" in line:
candidate = line
if candidate is not None:
return candidate.lstrip("ok ").strip()
print("No temp data is found:", lines)
return None
def parse_position(lines):
for line in lines:
if line.startswith("X:"):
return line.replace("ok ","")
return None
In [116]:
try:
while True:
ct = dt.now()
ct_str = ct.strftime('%Y/%m/%d-%H:%M:%S')
temp_lines = send_gcode("M105")
temp_data = parse_temp(temp_lines)
if temp_data is None:
print("No temp data is found:",temp_lines)
time.sleep(1.0)
continue
pos_lines = send_gcode("M114")
position_data = parse_position(pos_lines)
if position_data is None:
print("No position data is found", pos_lines)
time.sleep(1.0)
continue
writelines_temp = ct_str + " " + temp_data + "\n"
writelines_position = ct_str + " " + position_data + "\n"
with open("./printer_data_temp.txt","a") as f:
f.write(writelines_temp)
with open("./printer_data_position.txt","a") as f2:
f2.write(writelines_position)
#print(writelines)
time.sleep(1.0)
except KeyboardInterrupt:
print("Finish")
Finish
Then, close the serial port.
In [ ]:
# Serial Close
prusa.close()