-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add USB connection support #8
Comments
Succesfully tested printing via USB on B21 (ref #4). Below is the summary of what I changed, tell me if you want a PR. Created separate transport classes for bluetooth and serial (based on pyserial library). You must create instance of either Transport classes...
from serial.tools.list_ports import comports
import serial
class BaseTransport(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self, length: int) -> bytes:
raise NotImplementedError
@abc.abstractmethod
def write(self, data: bytes):
raise NotImplementedError
class BluetoothTransport(BaseTransport):
def __init__(self, address: str):
self._sock = socket.socket(
socket.AF_BLUETOOTH,
socket.SOCK_STREAM,
socket.BTPROTO_RFCOMM,
)
self._sock.connect((address, 1))
def read(self, length: int) -> bytes:
return self._sock.recv(length)
def write(self, data: bytes):
return self._sock.send(data)
class SerialTransport(BaseTransport):
def __init__(self, port: str = "auto"):
port = port if port != "auto" else self._detect_port()
self._serial = serial.Serial(port=port, baudrate=115200, timeout=0.1)
def _detect_port(self):
all_ports = list(comports())
if len(all_ports) > 1:
raise RuntimeError("Too many serial ports")
return all_ports[0][0]
def read(self, length: int) -> bytes:
return self._serial.read(length)
def write(self, data: bytes):
return self._serial.write(data)
class PrinterClient:
def __init__(self, transport):
... Changed Print encoderdef naive_encoder(img: Image.Image):
img = ImageOps.invert(img.convert("L")).convert("1")
for y in range(img.height):
line_data = [img.getpixel((x, y)) for x in range(img.width)]
line_data = "".join("0" if pix == 0 else "1" for pix in line_data)
line_data = int(line_data, 2).to_bytes(math.ceil(img.width / 8), "big")
counts = (0, 0, 0) # It seems like you can always send zeros
header = struct.pack(">H3BB", y, *counts, 1)
pkt = niimbotpacket.NiimbotPacket(0x85, header + line_data)
yield pkt P.S. I also think |
@AndBondStyle Can you fork the repository and post code changes to support USB? |
@iROOT here you go. However I only tested it with Niimbot B21. Do you have B21 or D11? |
@AndBondStyle Thank you. |
@iROOT hmm... I've got the same problem when trying to print an image with wrong resolution. What resolution are you using? Also, I disabled some checksum-related code in image encoding function (originally it was here), but for my B21 it works fine. Would you care to take same wireshark / usbpcap captures of USB traffic? You need a windows machine and niimbot official app for that, and I can guide you through the process. |
@AndBondStyle I now used 8 pixels per millimeter and everything started to work out. Here is 30x20s with third party tape. There is some downward shift in the pattern, I think due to calibration. I got a dump via Wireshark. Here it captures before the Niimbot program starts and stops after it finishes. By the way, I noticed that the printer does not care for which original tape the NTAG is inserted. It still prints what is sent to it. |
@iROOT thank you for the capture. The problem with alignment was caused by me naively assuming that label length (aligned with printing direction) is always bigger than its height. This is the case for 30x15 and 80x50 labels, but clearly not for 30x20 labels. That means if you rotated your image originally by 90 degrees it would've probably printed fine. I'll try to point it out more clearly in the readme and add some extra args to CLI. Regarding the delay after P.S. Already updated the repo with more detailed readme |
D11 (and other devices maybe?) actually supports USB connection (as CDC ACM serial device, and uses same packet). But currently niimprint is hard-coded to use Bluetooth serial.
The text was updated successfully, but these errors were encountered: