kliment / Printrun

Pronterface, Pronsole, and Printcore - Pure Python 3d printing host software
GNU General Public License v3.0
2.38k stars 996 forks source link

checking if a print is done? #1192

Closed comes04 closed 3 years ago

comes04 commented 3 years ago

Hello, I would like to put in the project that I am developing a functionality that will terminate the script when a print ends. Is there a way to check if the printing has finished with printrun? Thank you very much as always in advance.

volconst commented 3 years ago

Try this

p = printcore()

def on_print_end():
  p.disconnect()

p.endcb = on_print_end
lunknowl commented 3 years ago

how do i check if single gcode is done sending to the machine?

volconst commented 3 years ago

@lunknowl printcore.sendcb event is called just before write. There is no event after the write, you can modify _send() to your needs.

lunknowl commented 3 years ago

from printrun.printcore import printcore from printrun import gcoder import sys import time

p = printcore() p.connect('COM16', 250000) while not p.online: time.sleep(0.1)

def recv_callback(line): if 'ok' in line: print("ok") p.disconnect()

p.send_now("G1 X10 Y10 Z0 F24000") time.sleep(0.7)

p.recvcb = recv_callback p.send_now("M119")

this is my code to check response "ok" but i cant check to make sure the printer is finish moving to X10 Y10, any recommendation how to do it?

volconst commented 3 years ago

You probably have a problem with threads - recv_callback is called in reading/receiving thread and the other code is called in main thread. Another problem may be is that the firmware could respond with an 'ok' before reaching the X,Y coordinates. I think this can be resolved by sending M114 command and waiting for its 'ok'

You have to be able to relate 'ok' to their respective commands. One strategy it to issue n commands in batch and wait till you get n 'ok's. Another strategy is to issue and wait for a single 'ok'.

E.g.:

ok_counter = 0
def count_oks(line):
  global ok_counter
  if 'ok' in line:
    ok_counter += 1

def wait_oks(target_count):
  while ok_counter < target_count:
    time.sleep(.1)

p.recvcb = count_oks

ok_counter=0
p.send_now("G1 X10 Y10 Z0 F24000")
wait_oks(1)

ok_counter=0
p.send_now("M114")
wait_oks(1)

Not sure if incrementing/reading ok_counter is thread safe or it needs explicit synchronization. You can also try this https://github.com/kliment/Printrun/blob/25720529febc493327718543139cac5242454320/printrun/gsync.py

lunknowl commented 3 years ago

how do i use the gsync.py? any example?

volconst commented 3 years ago

@lunknowl , you can see the main section in gsync at the bottom, which is executed when you run:

$ python3 gsync.py

Review the commands sent before running the script.

lunknowl commented 3 years ago

hi i use ok_counter = 0 def count_oks(line): global ok_counter if 'ok' in line: ok_counter += 1

def wait_oks(target_count): while ok_counter < target_count: time.sleep(.1)

p.recvcb = count_oks

ok_counter=0 p.send_now("G1 X100 Y10 Z0 F24000") wait_oks(1)

ok_counter=0 p.send_now("M114") wait_oks(1)

but the M114 is still processing fast, doesnt wait until robot get the the position (X100), i think the "ok" feedback is fast, it happen as soon as the robot moving, how can i fix it? im using marlin firmware and M400 code about 1s delay, too slow

volconst commented 3 years ago

Yes synchronization is slow, that's why it is avoided if possible. I would investigate why M400 has delay - I assume the delay is measured after the target position is reached. M114 wait for the moves to execute, at least in Marlin 1.1 branch https://github.com/MarlinFirmware/Marlin/blob/1314b31d97bba8cd74c6625c47176d4692f57790/Marlin/Marlin_main.cpp#L9322 and M114 synchronization code is just like M400 https://github.com/MarlinFirmware/Marlin/blob/1314b31d97bba8cd74c6625c47176d4692f57790/Marlin/Marlin_main.cpp#L10556