Как напрямую отправить G-код на принтер с терминала Linux?

Можно ли напрямую отправить G-код на последовательное соединение принтера с помощью pipes под Linux?

Пример:

echo M106 > /dev/ttyUSB0

Мой контроллер работает со скоростью 250000 бод, я попытался установить скорость передачи данных TTY на 250 Кбит / с с помощью:

stty -F /dev/ttyUSB0 250000

Но, к сожалению, эта конкретная скорость передачи данных в бодах, по-видимому, не поддерживается в Ubuntu, что приводит к ошибке:

stty: invalid argument ‘250000’

, 👍8


6 ответов


Лучший ответ:

7

Для прямого управления принтером низкого уровня с терминала, без специального программного обеспечения, я нашел следующее решение с полной благодарностью пользователю: http://stackexchange.com/users/6463673/meuh

Делитесь здесь, как это может быть полезно другим пользователям в сообществе 3d-печати, и я не смог найти "полное" решение для этого в другом месте.


Шаг 1) Создайте пользовательский скрипт на python, который позволяет вам задавать произвольные скорости передачи данных (сделайте исполняемый файл с помощью chmod u+x).

#!/usr/bin/python
# set nonstandard baudrate. Original Question: http://unix.stackexchange.com/a/327366/119298
import sys,array,fcntl

# from /usr/lib/python2.7/site-packages/serial/serialposix.py
# /usr/include/asm-generic/termbits.h for struct termios2
#  [2]c_cflag [9]c_ispeed [10]c_ospeed
def set_special_baudrate(fd, baudrate):
    TCGETS2 = 0x802C542A
    TCSETS2 = 0x402C542B
    BOTHER = 0o010000
    CBAUD = 0o010017
    buf = array.array('i', [0] * 64) # is 44 really
    fcntl.ioctl(fd, TCGETS2, buf)
    buf[2] &= ~CBAUD
    buf[2] |= BOTHER
    buf[9] = buf[10] = baudrate
    assert(fcntl.ioctl(fd, TCSETS2, buf)==0)
    fcntl.ioctl(fd, TCGETS2, buf)
    if buf[9]!=baudrate or buf[10]!=baudrate:
        print("failed. speed is %d %d" % (buf[9],buf[10]))
        sys.exit(1)

set_special_baudrate(0, int(sys.argv[1]))

Шаг 2) Запустите сценарий, чтобы установить скорость передачи данных.
./set_custom_baud_rate.py <> /dev/ttyUSB0 250000


Шаг 3) Теперь вы можете отслеживать вывод принтера в окне терминала просто с помощью:
tail -f /dev/ttyUSB0


Шаг 4) И, наконец, откройте новое окно терминала, и вы сможете напрямую отправить M или G-код на свой принтер; пример:
echo "M115" >> /dev/ttyUSB0


,

Могу я спросить вас, как возможно, чтобы этот скрипт работал? Я не понимаю, почему вы используете<>``, сначала я подумал, что это опечатка, но изменение сценария и прямое открытие серийного номера не изменяет его скорость., @gipi

<>` в unix открывает файл в режиме чтения+записи без усечения и создает файл, если он еще не существует. т. е. системный вызов: открыть(имя файла, O_RDWR|O_CREAT)`, @Mtl Dev

Например, кошка < foo.txt it will print the contents of foo.txt, or fail if foo.txt doesn't exist. Whereas cat <>foo.txt,также распечатает содержимое, если оно существует, но создаст файл, если он еще не существует., @Mtl Dev

Я знаю, что<>делает`, но я не понимаю, почему это работает для скорости передачи: вы устанавливаете скорость передачи дескриптора файла 0, т. Е. stdin` не для последовательного порта., @gipi

Насколько я понимаю, baudrate-это просто первый аргумент скрипта (т. Е. sys.argv[1]). Если бы вы изменили сценарий и жестко закодировали бодрейт и/или открытое устройство, используя эквивалент python. из " открыть(имя файла, O_RDWR|O_CREAT)`, то я тоже был бы удивлен, если бы это не сработало., @Mtl Dev

@gipi Аргумент "<>/dev/ttyUSB0" определяет стандартный ввод и вывод для сценария. Когда скрипт работает на stdin, он работает на /dev/ttyUSB0., @cmm

Это не сработало ни со мной, ни с этим парнем: https://3d-printery.ru/topics/10612/sending-g-code-through-usb-serial-doesnt-work-ender-3?noredirect=1&lq=1 Команда tail ничего не выводит Принтер, похоже, "ок" - это неизвестная команда, которая является его ответом, верно? Так почему же он получает свой собственный ответ в виде команды?, @K Mmmm


1

Эта страница форума настоятельно рекомендует вам использовать setserial для порта, а не stty , который предназначен для терминалов. Я бы дал фрагменты кода там попробовать. В качестве альтернативы, stackoverflow имеет аналогичное обсуждение, с несколько более сложными модификациями.

Вы уверены, что не можете общаться с вашим принтером со скоростью передачи данных ниже, чем максимальная пропускная способность принтера?

,

Я полагаю, что вы не можете снизить скорость Марлина без перекомпиляции прошивки., @Tom van der Zanden

@TomvanderZanden облом :-(, @Carl Witthoft

Я не смог заставить " setserial` работать на raspberry pi zero w. Но поскольку "stty-F /dev/ttyUSB0 500000" работает (а 250000-нет), я решил изменить скорость печати на своих принтерах. Я изменил скорость на 500000 в конфигурации Марлина.h после загрузки/распаковки конфигураций принтера и повторной компиляции/повторной загрузки. Сейчас отлично работает., @hellork


6

для этого вы можете использовать экран. Откройте окно терминала и введите screen /dev/ttyUSB0 115200 Общая форма-экранное серийное устройство baudrate Затем вы увидите все, что отправляет принтер. Все, что вы напечатаете, будет отправлено на принтер.

,

Спасибо! Хотя работает ли это при нестандартных скоростях передачи данных, например 250 тыс.? Я подозреваю, что нет (по крайней мере, в Ubuntu/Mint), но что можно было бы объединить приведенный выше сценарий с командой экран в соответствии с вашим предложением., @Mtl Dev


-2

Это рабочее решение:

вам нужно 2 терминала, один для входящих и другой для исходящих потоков

,

Из [справки]: **Укажите контекст для ссылок** Ссылки на внешние ресурсы приветствуются, но, пожалуйста, добавьте контекст вокруг ссылки, чтобы ваши коллеги-пользователи имели некоторое представление о том, что это такое и почему она там находится. Всегда цитируйте наиболее релевантную часть важной ссылки, если целевой сайт недоступен или постоянно отключается. *Без видео, в случае гниения ссылки, этот ответ не имеет никакого значения для будущего, пожалуйста, опишите, как видеопостер получил доступ к принтеру из Ubuntu, это был бы отличный ответ!*, @0scar


3

Я потратил несколько часов, пытаясь понять, почему мой Creality Ender Pro игнорировал меня, когда я отправил ему последовательные данные по USB из приложения Python. Поиск Google, пытающийся найти решение, которое не говорит о encode() и decode (), казалось, привел меня к этой теме.

Я установил Minicom в соответствии с видеосвязью, и все работало так, как должно, но я все еще не получил ответа в моей реализации Python, я мог подключиться и прочитать серийный номер, отправленный с принтера, но ничего не добавлял при отправке обратно на него.

После нескольких часов почесывания в затылке я понял, что принтер реагирует на ввод, получая каждую новую строку символа \n, которую я не смог добавить в конец каждой отправленной команды, поэтому принтер просто сидел и ждал, пока я закончу передачу конца моей строки, который так и не пришел.

self.serialPort = serial.Serial('/dev/ttyUSB0', 115200, exclusive = True)
lines = self.serialPort.read(self.serialPort.in_waiting).decode().splitlines(False)
line = line + "\n"
self.serialPort.write(line.encode())

Надеюсь, никто другой не так глуп, но, чтобы сэкономить время кому-то еще, как я, я хотел бы указать на это здесь.

,

Это своего рода ответ "я тоже", реагирующий на какой-то другой ответ. На какую ссылку вы ссылаетесь? Этот ответ можно было бы лучше опубликовать в качестве комментария к этому ответу., @0scar

я попытался передвинуть его, но там было написано: "у вас должно быть 50 представителей, чтобы прокомментировать"., @Jay Dee

Пожалуйста, сократите ответ и укажите, на какой ответ вы хотели бы ответить в комментарии, модераторы могут перенести его за вас., @0scar


4

Общепринятый ответ меня не устроил. Все, что поступало на последовательный порт, повторялось обратно на последовательный порт, посылая принтер в запутанный цикл. В этом ответе есть более подробная информация об этом: https://unix.stackexchange.com/questions/42964/unexpected-results-testing-serial-loopback-using-echo-and-cat

Ключ состоит в том , чтобы использовать подобную команду, чтобы предотвратить повторение определенных символов завершения строки: stty 115200-F /dev/ttyUSB0-echo-onlcr, где 115200-это ваша скорость передачи данных в бодах.

Вот что я сделал:

# 1. plug in printer
sudo chmod +777 /dev/ttyUSB0 # 2. allow access to printer USB permissions, add user to dialout or tty is better
stty 115200 -F /dev/ttyUSB0 -echo -onlcr # 3. set serial port baud rate, might be 250000 for you
cat -v < /dev/ttyUSB0 # 4. get printer output 

Затем в новом терминале:

   echo "M119" >> /dev/ttyUSB0

Это даст вам настоящую консоль.

,

Не могли бы вы, пожалуйста, поделиться тем, какой вкус и версию в Linux вы используете, чтобы это не сработало? (Во время публикации он работал с основными дистрибутивами - Ubuntu и Mint. Возможно, мы сможем определить, почему это не было успешным для вас. Я отмечаю, что ваше решение предназначено для скорости передачи 115200 бод, вы можете проверить, работает ли это для скорости передачи 250000 бод?, @Mtl Dev

Но принятый ответ также не работает для меня и на 250000, @K Mmmm

Принятый ответ работает при использовании " cat-v < /dev/ttyUSB0 вместо хвост -f /dev/ttyUSB` на 250000, хотя, @K Mmmm

Могу подтвердить, что предыдущий ответ работает на Ubuntu 18.04, а до этого IIRC Mint (версия неизвестна, форматирована). Не знаю, почему он выходит из строя 16.04. Большое спасибо за публикацию еще одного ответа, который работает для вас и других людей - всегда здорово иметь несколько рабочих ответов, чтобы помочь как можно большему количеству людей, ура!, @Mtl Dev

На самом деле это все еще повторяется на 250000. Поэтому, чтобы заставить stty прекратить повторение, похоже, что требуется 115200, @K Mmmm

250000 - это нестандартная скорость передачи данных в бодах. В моем случае 115200 работает со стандартными инструментами Linux, но для работы 250000 мне нужен был этот скрипт, опубликованный в моем ответе. На моих компьютерах 250000 работает с этим сценарием., @Mtl Dev

Спасибо, это было супер полезно, @user1529413