maybe I've just been lucky so far, but I've had more damaged models due to USB flash drive defects than through loss of connection via USB. It is more convenient for me to send a file to print with one button, than to connect a card reader to my computer, go for a flash drive, aim at a small socket on the printer.... Of course, it's sporty. But I would like sports separately, and printing separately))
As mentioned by ahoeben
The usb support in UltiMaker Cura is very limited, and not even being actively maintained that I am aware of.
You will likely only progressively have more and more issues with it over time as operating systems rollout updates.
(there has already been multiple times where usb support is just simply broken entirely)
UltiMaker does not produce any active products that even have an accessible USB port that can be connected to a computer for the very reason of the issues. Because there is no reason to maintain it for their active products, updates or fixes for its functionality largely comes from community contributed bugfixes etc.
Would very much recommend reconsidering the use of printing via usb long term.
GregValiant 1,354
I'm an amateur and a hack at writing code but I've been doing it (poorly) for over 50 years. I don't remember how many apps I've written to communicate over the serial port with various devices. It was a lot. From ski racing timers to load cells to a 60 ton Baldwin Universal Test Machine. There were even some numerically controlled puppets in there.
They all had 1 thing in common...they were slow (especially the Baldwin).
The difference I see with 3D printers is that the data needs to flow at varying rates or you will get buffer under-runs or over-runs at the printer. Under-runs will cause blobs and over-runs will drop command lines. In addition there are thousands of combinations of 3D printers, PC's, USB ports, port drivers, and firmware.
The fact that it works for you is nice. It just doesn't work for everyone because really, it can't. There are just too many combinations of "stuff" to account for. I always had 1 PC talking to 1 specific device. I didn't appreciate that at first so I tried my hand at an app to be a print server and send gcode over the USB to my Ender. After about a week of fooling around with it, the entire project ended up in the toilet.
So I copy the gcode to an SD card, stick it in the printer, sit down with my "Greg's Toolbox" app that talks to the printer. I ask the printer to list the files on the SD and then I tell it which one to print. Nice. If the print needs some tuning, no problem, I click on a slider and run the speed up a couple of notches and hit a button to send M106 S255 to the printer. It says "ok" and keeps motoring along. The LCD is totally out of the loop except to resume after a pause. For that I have to hit the button, but that's the only thing I need it for. That's a good thing because it was really the clumsiness of using that button for everything that I didn't like.
Because I always leave the printer plugged into the PC - if I'm printing over-night I kill the internet connection so Microsoft can't send an update that will restart the PC and reboot the printer.
Another thing you might consider is that the "Power Loss Recovery" data is written to the SD card. If you don't have one in the slot then there is no chance to recover a print.
okay. Let printing via USB be worse than using a USB flash drive. Indeed, I won't be able to restore the print after a power failure. This is important for Ukraine. In summer, the power supply was stable, but in winter interruptions are very likely. But is it possible to make the printer's card reader defined in Windows as a USB drive and the slicer would write the G-code directly to the printer's flash drive? It would be nice to do without moving the flash drive between the computer and the printer, it's really inconvenient. Probably, this is not a task for the slicer, but for the printer firmware?
3 hours ago, Lommm said:But is it possible to make the printer's card reader defined in Windows as a USB drive and the slicer would write the G-code directly to the printer's flash drive?
Not really. That would require custom firmware on the printer to make it show up as a mass storage device, which would require you to get a serial connection to it anyway.
Depending on what firmware it uses, it might be possible to write a file onto a printer's SD card (although if your printer uses a flash drive instead, it will probably just use that). It does require you make a serial connection to the printer, except instead of printing over USB, you get it to write a file (i.e. the gcode) to the printer's memory device, then you can remotely tell it to print that file.
I'm 99% sure Cura doesn't support and I'm 99.99% sure it never will.
You gotta face facts here: USB printing is basically on life support.
It doesn't work as well as it used to (i.e. the first 3D printer I had only printed over USB) because it's limited by how fast it can send commands (which acting a serial device, isn't very fast), and printers are a heck of a lot faster (and more accurate, for curves and such) than they used to be. This can result in blobs on your model while it's waiting for more commands to come in.
And the printers were dumb back then, they didn't have the brainpower to run the show by themselves, just to keep an ear open for commands and then do them when they came in. Printers these days are smart enough to run the whole thing by themselves. And they can load from their own storage a lot faster than they can take commands over USB.
Is it possible? Where there's a will, there's a way. But for a situation as niche as yours, you can't rely on there being someone else out there to make that way happen.
- 2
Sorry, but there is still a solution..
I've heard about the Simplify3D program. I decided to take a look. I installed it, did not configure anything, pressed Ctrl+P and saw a miracle: I select the COM port with the desired printer, print directly, print from a USB flash drive, even write to a USB flash drive! The recording is slow, but it is there and it works!
I didn't like Simplify3D as a slicer. I just generate the G-code in Cura and use Simplify3D print manager to do whatever I want with it. So, all this is possible. No special printer firmware is needed. It's just not in Cura!
1 hour ago, Lommm said:I select the COM port with the desired printer, print directly, print from a USB flash drive, even write to a USB flash drive! The recording is slow, but it is there and it works!
That part's easy, if somewhat fiddly to do it manually. At least you found a solution you're happy with.
- 4 months later...
On 11/23/2023 at 7:27 AM, Lommm said:I have two 3D printers. I would like to run two copies of Cura for Windows separately for each of the printers and print to the two printers at the same time. But Cura automatically finds the com-port of the printer, so I can only use one printer. How do I manually specify the com-ports for each of the printers in Cura?
I know this is an old post, but the solution is to use an older version of Cura that allows you to set the com port of the printer. Version 15.04.6 is one version that lets you do this. You can do a Google search to find the download. Hope this helps.
1 hour ago, bjimenez51 said:15.04.6 is one version that lets you do this
Just know that that version is 9 years old.
- 1 month later...
#This file is USBPrinterOutputDeviceManager.py under C:\Program Files\UltiMaker Cura 5.7.1\share\cura\plugins\USBPrinting,you only have replace copy and paste all of the below code you can change to match you liking, for device location go to device manager and look at the comport it will show Port_#0002.Hub_#0001 that means 1-2 port_#0005.Hub_#0001 means 1-5 . if u use raspberry choose 都不用. 1-2 means 小台(small) 1-5 means 大台(big), change these to meet yours. so 1-2,1-5. these two need change. 小台,大台,都不用, depends on u.
# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import threading
import time
import serial.tools.list_ports
from os import environ
from re import search
import sys
from PyQt6.QtWidgets import QApplication, QMessageBox, QComboBox, QPushButton, QVBoxLayout, QWidget, QDialog
from PyQt6.QtCore import QObject, pyqtSignal
from UM.Platform import Platform
from UM.Signal import Signal, signalemitter
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from UM.i18n import i18nCatalog
from cura.PrinterOutput.PrinterOutputDevice import ConnectionState
from . import USBPrinterOutputDevice
i18n_catalog = i18nCatalog("cura")
base_list = []
combo_box = QComboBox()
@signalemitter
class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin):
"""Manager class that ensures that an USBPrinterOutput device is created for every connected USB printer."""
addUSBOutputDeviceSignal = Signal()
progressChanged = pyqtSignal()
def __init__(self, application, parent = None):
dialog = QDialog()
dialog.setWindowTitle("COM Port Selector")
layout = QVBoxLayout()
combo_box = QComboBox()
com_ports = serial.tools.list_ports.comports()
# Filter COM ports based on desired addresses
desired_addresses = ['1-2', '1-5']
filtered_com_ports = [("都不用", "")] # Add "都不用" option with empty port name
for port in com_ports:
if port.location == '1-2':
filtered_com_ports.append(('小台', port.device)) # Store both '小台' and actual port name
elif port.location == '1-5':
filtered_com_ports.append(('大台', port.device)) # Store both '大台' and actual port name
combo_box.addItems([item[0] for item in filtered_com_ports]) # Add '都不用', '小台', or '大台' to combo box
layout.addWidget(combo_box)
save_button = QPushButton("Save Selected COM Port")
save_button.clicked.connect(lambda: [base_list.append(filtered_com_ports[combo_box.currentIndex()][1]), dialog.accept()])# Get actual port name
layout.addWidget(save_button)
dialog.setLayout(layout)
dialog.exec()
if USBPrinterOutputDeviceManager.__instance is not None:
raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__)
super().__init__(parent = parent)
USBPrinterOutputDeviceManager.__instance = self
self._application = application
self._serial_port_list = []
self._usb_output_devices = {}
self._usb_output_devices_model = None
self._update_thread = threading.Thread(target = self._updateThread)
self._update_thread.daemon = True
self._check_updates = True
self._application.applicationShuttingDown.connect(self.stop)
# Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
self.addUSBOutputDeviceSignal.connect(self.addOutputDevice)
self._application.globalContainerStackChanged.connect(self.updateUSBPrinterOutputDevices)
# The method updates/reset the USB settings for all connected USB devices
def updateUSBPrinterOutputDevices(self):
for device in self._usb_output_devices.values():
if isinstance(device, USBPrinterOutputDevice.USBPrinterOutputDevice):
#device.resetDeviceSettings()
return
def start(self):
self._check_updates = True
self._update_thread.start()
def stop(self, store_data: bool = True):
self._check_updates = False
def _onConnectionStateChanged(self, serial_port):
if serial_port not in self._usb_output_devices:
return
changed_device = self._usb_output_devices[serial_port]
if changed_device.connectionState == ConnectionState.Connected:
self.getOutputDeviceManager().addOutputDevice(changed_device)
else:
self.getOutputDeviceManager().removeOutputDevice(serial_port)
def _updateThread(self):
while self._check_updates:
container_stack = self._application.getGlobalContainerStack()
if container_stack is None:
time.sleep(5)
continue
port_list = [] # Just an empty list; all USB devices will be removed.
if container_stack.getMetaDataEntry("supports_usb_connection"):
machine_file_formats = [file_type.strip() for file_type in container_stack.getMetaDataEntry("file_formats").split(";")]
if "text/x-gcode" in machine_file_formats:
# We only limit listing usb on windows is a fix for connecting tty/cu printers on MacOS and Linux
port_list = self.getSerialPortList(only_list_usb=Platform.isWindows())
self._addRemovePorts(port_list)
time.sleep(5)
def _addRemovePorts(self, serial_ports):
"""Helper to identify serial ports (and scan for them)"""
# First, find and add all new or changed keys
for serial_port in list(serial_ports):
if serial_port not in self._serial_port_list:
self.addUSBOutputDeviceSignal.emit(serial_port) # Hack to ensure its created in main thread
continue
self._serial_port_list = list(serial_ports)
for port, device in self._usb_output_devices.items():
if port not in self._serial_port_list:
device.close()
def addOutputDevice(self, serial_port):
"""Because the model needs to be created in the same thread as the QMLEngine, we use a signal."""
device = USBPrinterOutputDevice.USBPrinterOutputDevice(serial_port)
device.connectionStateChanged.connect(self._onConnectionStateChanged)
self._usb_output_devices[serial_port] = device
device.connect()
def getSerialPortList(self, only_list_usb=False, selected_port=None):
return base_list
__instance = None # type: USBPrinterOutputDeviceManager
@classmethod
def getInstance(cls, *args, **kwargs) -> "USBPrinterOutputDeviceManager":
return cls.__instance
# Define the main function
- 1
@albertage - please tell us the name of the python file you edited and where the file is in the cura folders.
Also should I delete the first of 2 posts above?
- 1
I’ll be editing one of the post up and update later on today, I’m out but I have confirm it to be working.you can delete one for me, thank you
edit:the above post is now completed, change to your liking. i may come and go to answer question
TLDR. start with choosen comport, will not reset any existing comport(a pain in the ass)
Recommended Posts
ahoeben 1,989
You can't (*). The USB printing functionality is severely underdeveloped in Cura. My best advice is not to use it, and to use OctoPrint instead. You can then use the OctoPrint Connection plugin from the Marketplace. An additional benefit is that you can then manage both printers in a single copy of Cura, and have them both printing at the same time. Cura does not handle two simultaneous copies of Cura particularly well.
*: You could check out the functionality of this plugin as well: https://marketplace.ultimaker.com/app/cura/plugins/DevPeeps/USBPrintingNG
I don't know if it will easily let you use different ports for different instances of Cura.
Edited by ahoebenLink to post
Share on other sites
GregValiant 1,354
There might be a way to do this. It's clumsy and I wouldn't do it myself, but you can try.
As you have found - if a Com Port is busy then Cura won't connect to it.
If "USB Printing" is in use by one instance of Cura then a second instance of the same version can't use it because the plugin is busy.
That is the key. If you use a different version of Cura, and if you time the connection to the printer just right, it will connect.
With one USB connected from the PC to a printer, start Cura 5.5.0. After a few minutes it should connect.
After the 1st connection is established - connect the second printer to the PC and start Cura 5.4.0. After a few minutes it should connect.
Here I've got 5.4.0 connected to an AnyCubic on Com 8 and 5.5.0 connected to my Ender on Com 9. Notice that the hot end temperature box is missing from the 5.5 instance. I don't know what's up with that and hitting "cancel" doesn't bring it back. I pre-heated by sending M104 and that worked fine.
I'm using a port emulator and a null modem cable as a virtual AnyCubic (which is in reality another PC). It appears you could actually print like this as my experiment worked. I will stress that I said "YOU" could print like this...I would never.
I agree wholeheartedly with AHoeben. Other than being a semi-interesting exercise it's just something I wouldn't do because USB Printing is glitchy with even a single printer hooked up.
So I went a different way. I wrote a "print server" app and it will control up to 10 printers at once. But it doesn't print over the USB ports. Instead, you select a file from the SD card in each printer and then tell the printer to print it. Switch to another printer and do the same thing. I can switch back and forth between printers and tune a print, pause, or abort from my laptop (which could look like an "decopus" if there were 10 USB cables connected). That all seems to work quite well because I'm not actually printing over the USB, just sending commands to control the different printers.
Take none of that as gospel. It could all just be the rantings of an old man. Seems to work though.
Time for more coffee.
Link to post
Share on other sites
Slashee_the_Cow 433
To summarise @GregValiant and quote the great Dr. Ian Malcolm: you were so preoccupied with whether or not you could that you didn't stop to think if you should.
Though I'm much the same, so don't take that as criticism, or I'd be a hypocrite.
But Slashee's Rules of Life #28: Only I am allowed to be a hypocrite.
Link to post
Share on other sites