Klipper3d / klipper

Klipper is a 3d-printer firmware
GNU General Public License v3.0
8.98k stars 5.17k forks source link

klippy: Allow to open existing tty #6482

Open cyberhuman opened 4 months ago

cyberhuman commented 4 months ago

This adds a possibility to run Klipper using an existing tty. In particular, I use it for multicolor print with Mosaic Palette 3 in connected mode (which means the Palette controls the printer/Klipper via a serial port).

There are a few issues when a real tty is used, which may be solved in the future by a willing persion:

  1. If the printer is disconnected from the Palette, the system sends SIGHUP to Klipper, which it doesn't handle and exits. Then it has to be re-started manually.
  2. On start, Klipper is waiting for the serial connection to be active (that is, the printer must be connected to the Palette). I didn't check but I think it's blocked by the startup banner.
  3. If Mainsail is used, the console is filled with "ok" replies to the commands the Palette gives to the printer. Eventually the page slows down and refreshes because there are too many lines.
JamesH1978 commented 4 months ago

Thank you for submitting a PR, pleas refer to point 3 in "What to expect in a review" in https://github.com/Klipper3d/klipper/blob/master/docs/CONTRIBUTING.md and provide a signed off by line.

Thanks James

Arksine commented 4 months ago

I suspect that its possible to use socat to link Klipper's pty to the Pallete. Presumably there would be no SIGHUP issues there, and no need to modify the systemd unit when you want to enable it.

cyberhuman commented 4 months ago

Hey @Arksine! I tried to use socat before implementing this but it didn't work well. I think it's because only one process can read from pty at the same time. I also did some experiments redirecting my console's output and it confirmed the theory.

ian-rosenberg commented 4 months ago

Hi there @cyberhuman, I came across this work and am very interested to help if possible!

cyberhuman commented 4 months ago

@ian-rosenberg thanks! I'm not actively working on it; the current implementation works well enough for me. But if you have ideas how to improve it, please share. Or you can implement your improvements on top of my work.

ian-rosenberg commented 4 months ago

@ian-rosenberg thanks! I'm not actively working on it; the current implementation works well enough for me. But if you have ideas how to improve it, please share. Or you can implement your improvements on top of my work.

Would love to know what you did besides this code change to get Connected Mode working on a P3P

cyberhuman commented 4 months ago

@ian-rosenberg I did nothing special. I just made sure the gadget serial driver (g_serial) is loaded on my RPi and that M105 probes from P3P appear on /dev/ttyGS0. Then I added -T /dev/ttyGS0 in the klipper systemd unit and it worked! I saw you mentioned PALETTE_CONNECT in the email notification, but no plugins are needed as the printer is controlled directly by P3P via the serial interface. (I also switched flush command to M400 in P2PP)

ian-rosenberg commented 4 months ago

@ian-rosenberg I did nothing special. I just made sure the gadget serial driver (g_serial) is loaded on my RPi and that M105 probes from P3P appear on /dev/ttyGS0. Then I added -T /dev/ttyGS0 in the klipper systemd unit and it worked! I saw you mentioned PALETTE_CONNECT in the email notification, but no plugins are needed as the printer is controlled directly by P3P via the serial interface. (I also switched flush command to M400 in P2PP)

Would it be possible to have a side conversation? When I add -T /dev/ttyGS0 anywhere in the KLIPPER_ARGS, and then start klipper, it never can connect to my MCU on the printer.

*EDIT: I have g_serial loaded prior to running klippy.py, on a service that is required by klipper's service

cyberhuman commented 4 months ago

@ian-rosenberg what board do you have? Does it have two serial ports? How is the MCU connected to it?

ian-rosenberg commented 4 months ago

@ian-rosenberg what board do you have? Does it have two serial ports? How is the MCU connected to it?

I'm running a BTT SKR Mini E3 V3, I only see the one microUSB on it. The raspberry pi running Klipper controls it, and the Palette is plugged into the raspberry pi. This sounds like I need a board w/ a second serial port?

cyberhuman commented 4 months ago

raspberry pi This sounds like I need a board w/ a second serial port?

Yes, which RPi do you have? E.g. I have Zero 2W and SKR Pico is connected via the serial on the RPi connector, while Palette is talking via another serial over USB.

ian-rosenberg commented 4 months ago

So, the board in your printer is talking directly to your pi over usb, as well as the palette over a 2nd one? I have a BTT-CB1 raspberry pi, it's a weak Pi4 CM.

cyberhuman commented 4 months ago

So, the board in your printer is talking directly to your pi over usb, as well as the palette over a 2nd one?

SKR is talking with Pi via UART: image

Palette is talking with Pi via USB.

For Pi4 CM, looking at the datasheet, it must be possible to configure it the same way, connect SKR directly to GPIO14/15 and connect Palette via USB.

ian-rosenberg commented 4 months ago

Alright, so I have the pi wired correctly, but in the manual for the BTT-CB1 Raspberry Pi, it says that ttyS0 gets set for UART0.

Tried that, and now when I go into Mainsail, the Klippy.py constantly loops through connecting, getting a connection, and resetting.

This segment repeats quite a bit in my Moonraker log:

2024-02-17 05:51:28,284 [klippy_connection.py:_do_connect()] - Klippy Connection Established
2024-02-17 05:51:30,635 [app.py:log_request()] - 404 GET /machine/device_power/devices (127.0.0.1) [No User] 4.39ms
2024-02-17 05:51:31,039 [file_manager.py:get_file_list()] - Updating File List <gcodes>...
2024-02-17 05:51:31,429 [klippy_connection.py:_request_initial_subscriptions()] - Webhooks Subscribed
2024-02-17 05:51:31,433 [klippy_connection.py:_request_initial_subscriptions()] - GCode Output Subscribed
2024-02-17 05:51:31,680 [job_state.py:_handle_started()] - Job state initialized: standby
2024-02-17 05:51:31,946 [klippy_connection.py:_check_ready()] - Klippy ready
2024-02-17 05:51:32,442 [data_store.py:_init_sensors()] - Configuring available sensors: ['heater_bed', 'extruder']
2024-02-17 05:51:37,242 [klippy_connection.py:_on_connection_closed()] - Klippy Connection Removed

In Klippy.log:

Read g-code
Traceback (most recent call last):
  File "/home/biqu/klipper/klippy/gcode.py", line 400, in _process_data
    data = str(os.read(self.fd, 4096).decode())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x84 in position 4: invalid start byte

Any ideas?

cyberhuman commented 4 months ago

@ian-rosenberg it's hard to tell what's wrong with the setup. I have two guesses:

  1. your Pi has something else on ttyS0. For example, a Linux serial console. You'll need to configure the kernel command line to either disable the serial console or use a different tty.
  2. your OS has some driver interfering with the UART driver. I can vaguely remember something about disabling the bluetooth (?) serial module by loading some DT overlay.
ian-rosenberg commented 4 months ago

I've got UART connected, the mcu is detected. However, how do I go about loading ttyGS0? Because when I start klipper it cannot find that device, and ls on /dev doesn't show it.

cyberhuman commented 4 months ago

@ian-rosenberg run sudo modprobe g_serial. Then check the output of dmesg. If you don't have ttyGS0 created, there must be some error and it should be visible the kernel logs.

ian-rosenberg commented 4 months ago

Okay, probably the last comment from me, but certain Raspi models are NOT capable of gadget serial, but I'm trying a specialized CM4 which may or may not work.

ian-rosenberg commented 4 months ago

Sorry to keep bringing this up, but I borrowed a Raspberry Pi 4B, I got UART connected and ttyAMA0 shows up.

What should my printer.cfg have for the printer's serial? I see a few potential options:

crw-rw---- 1 root dialout 204, 64 Feb 24 17:26 ttyAMA0 crw-rw---- 1 root dialout 240, 0 Feb 24 14:14 ttyGS0 crw------- 1 root root 5, 3 Feb 24 14:14 ttyprintk crw-rw---- 1 root dialout 188, 0 Feb 24 14:14 ttyUSB0

What should I set as the -T parameter in the klippy environment args?

cyberhuman commented 4 months ago

It should be -T /dev/ttyGS0. And in printer.cfg, /dev/ttyAMA0.

github-actions[bot] commented 3 months ago

Thank you for your contribution to Klipper. Unfortunately, a reviewer has not assigned themselves to this GitHub Pull Request. All Pull Requests are reviewed before merging, and a reviewer will need to volunteer. Further information is available at: https://www.klipper3d.org/CONTRIBUTING.html

There are some steps that you can take now:

  1. Perform a self-review of your Pull Request by following the steps at: https://www.klipper3d.org/CONTRIBUTING.html#what-to-expect-in-a-review If you have completed a self-review, be sure to state the results of that self-review explicitly in the Pull Request comments. A reviewer is more likely to participate if the bulk of a review has already been completed.
  2. Consider opening a topic on the Klipper Discourse server to discuss this work. The Discourse server is a good place to discuss development ideas and to engage users interested in testing. Reviewers are more likely to prioritize Pull Requests with an active community of users.
  3. Consider helping out reviewers by reviewing other Klipper Pull Requests. Taking the time to perform a careful and detailed review of others work is appreciated. Regular contributors are more likely to prioritize the contributions of other regular contributors.

Unfortunately, if a reviewer does not assign themselves to this GitHub Pull Request then it will be automatically closed. If this happens, then it is a good idea to move further discussion to the Klipper Discourse server. Reviewers can reach out on that forum to let you know if they are interested and when they are available.

Best regards, ~ Your friendly GitIssueBot

PS: I'm just an automated script, not a human being.