bitrate16 / peripage-python

Python module and documentation for direct printing on Peripage thermal printers via bluetooth
GNU General Public License v3.0
77 stars 10 forks source link

Image prints come out with lines #17

Open skorokithakis opened 10 months ago

skorokithakis commented 10 months ago

Printing an image via this project results in the image having lots of horizontal lines, as if there were buffer underruns while printing. Printing via the app presents no such problem. Is it an issue with my Bluetooth adapter perhaps?

skorokithakis commented 10 months ago

I tried on another computer with a different adapter, and there are still lines on the output. Image prints are fairly unusable because of this. In contrast, images from the official app basically come out perfect.

bitrate16 commented 10 months ago

@skorokithakis, could you please provide information about your device, model and library version?

skorokithakis commented 10 months ago

Sorry, I completely forgot: I have a PeriPage A6, I'm running v1.1 from PyPI. I'm running the script both on my desktop and my laptop, with the same results.

skorokithakis commented 10 months ago

image

The top one is from the app, the bottom one from the script. The size is a bit odd, because it's a 384px image, which I thought was the native resolution of the printer (and thus would be full width).

skorokithakis commented 10 months ago

This is my printer: https://www.aliexpress.com/item/1005005789432494.html?spm=a2g0o.order_list.order_list_main.22.3fa51802ABmgnU

bitrate16 commented 10 months ago

@skorokithakis, it may be aliexpress description issue. This printer (and image size) looks like A6+

skorokithakis commented 10 months ago

Ah, you are correct, @bitrate16. I've set it to A6p and now the size is more reasonable, though I still get a few lines:

image

Oddly, the lines only appear to be printed at the top of the image.

skorokithakis commented 10 months ago

I tried a different image and that one didn't have any lines, so this seems intermittent. Odd, though, hm.

bitrate16 commented 10 months ago

@skorokithakis Try setting concentration to 0 and make a test print. Maybe it is overheating

rkolbaskin commented 10 months ago

I have the same issue. It seems to be caused by underflow as slower to print darker rows are less prone to produce white lines. Reducing concentration ends up producing more of them. These lines are not missing rows. Images with a lot of white lines also end up being stretched. Printer seems overfeed the tape by 1 row when it doesn't have data to print.

Comparing logs between PC and phone app - phone sends data in 122 byte packets and my PC for some reason sends 47 bytes per packet.

Also it looks like they changed the hardware. PCB in my A6+ has different MCU and Bluetooth controller. Maybe they cheaped out on stepper motor too.

skorokithakis commented 10 months ago

I agree with @rkolbaskin, it does seem like an underflow issue. I'll try reducing the delay to see if it helps.

skorokithakis commented 10 months ago

A delay of 0.005 still had two lines. A delay of 0.002 had no lines.

bitrate16 commented 10 months ago

@rkolbaskin If they've changed hardware/protocol/something else, you cold try to determine bytes per row used in printer by printing out continuous sequence of '0123456789abcdef'. Bytes per row then can be calculated based on number of characters in a row when using unsafe writeASCII

Also, delay is very experimental value that may vary from Bluetooth adapter and printer hardware. In my case default delay produces expected images on low concentration. If printing with high, image can be stuck/cut/broken because i couldn't find any indicators for overheat/complete/other printing states and overheating is unpredictable

skorokithakis commented 10 months ago

Seems to be 48 for me (as in, it printed 48 characters in a line before wrapping).

bitrate16 commented 10 months ago

@skorokithakis that looks fine https://github.com/bitrate16/peripage-python/blob/b2d2a9b2c6fcb3c01a2a3753b31e4205011a24e6/peripage/__init__.py#L55

skorokithakis commented 10 months ago

If printing with high, image can be stuck/cut/broken because i couldn't find any indicators for overheat/complete/other printing states and overheating is unpredictable

Hm, it sounds like delay might need to be adjusted with the concentration, then, though I can see how that can be finicky.

bitrate16 commented 10 months ago

We can sniff bluetooth packets sent during printing through app and check if there are status telemetry. Especially when printing long pure black image. Later I will check if it is possible to print very long black image with app

skorokithakis commented 10 months ago

I printed a black banner with the script, with concentration 2, and it turned out fine. It looks like black images are ok, but gray is a challenge (because of underruns).

bitrate16 commented 10 months ago

@skorokithakis What do you mean by underruns?

skorokithakis commented 10 months ago

Sorry, underflow, buffer underruns. The same issue that @rkolbaskin described above.

bitrate16 commented 10 months ago

In fact this printer works the following way:

  1. client connects, performs reset (many 0 values row)
  2. client sends info about next data block: how many rows of data to be sent (max 0xffff)
  3. client iterates over each row and sends row width (max 0xffff pixels) + row bytes encoding each 8 pixels
  4. printer receives each row and each row is stored in internal buffer (average capacity - 60 lines)
  5. if printer overheats and stops, buffer may overflow and excessive first entered data is dropped, these lines are not printed and paper does not move (so no white lines). Example: buffer size = 4, rows: A, B, C, D, E, F; rows F & E are dropped and not printed, but consumed as existing

So there could not be white lines if printer didn't receive anything. If no row data received after step 2 or iteration on step 3, printer just waits for data and does nothing.

Possible problem is - client sends rows too fast (too low delay) and printer can not properly print it and has to drop lines. Another untested possible thing - buffer is not aligned to packets and row header may be unaligned, so partially cut off. In this case printer receives partial header and consumes row data as header, so image gets corrupted

skorokithakis commented 10 months ago

But then why does the problem go away entirely if I set the delay to a very low value? I can test setting the delay to 0.1, I predict the problem will be even greater then.

rkolbaskin commented 10 months ago

@skorokithakis increasing delay results in white line inserted after every row.

skorokithakis commented 10 months ago

Yes, but it's not just that:

signal-2023-09-06-023847

0.1 leads to a line after every row, but 0.02 leads to some lines being burnt as well.

bitrate16 commented 10 months ago

But then why does the problem go away entirely if I set the delay to a very low value? I can test setting the delay to 0.1, I predict the problem will be even greater then.

Maybe they've really changed something in hardware. Try to request device info https://github.com/bitrate16/peripage-python/blob/b2d2a9b2c6fcb3c01a2a3753b31e4205011a24e6/peripage/__init__.py#L315 https://github.com/bitrate16/peripage-python/blob/b2d2a9b2c6fcb3c01a2a3753b31e4205011a24e6/peripage/__init__.py#L290

Or look in app if it is there

rkolbaskin commented 10 months ago

@bitrate16 Hardware: "v3.38.21_AY", firmware: "V1.12_304dpi" Also I did open it. It doesn't match your photos. It now has some obscure MCU I can't acquire documentation for (marked mh1902t) instead of glorious f103 derivative and Bouffalo Lab SoC for bluetooth.

bitrate16 commented 10 months ago

What will happen with delay 1 or 10? If it feeds paper with constant speed, this should produce just white

Also, i can later implemented deleted row mode to check what happens when each row is submitted with very large or varying delay.

rkolbaskin commented 10 months ago

It only inserts one white row regardless of delay size. Honestly, it looks like a firmware bug. I don't have high hopes for them fixing it considering the app isn't affected as much by it.

bitrate16 commented 10 months ago

@rkolbaskin I can try to reverse app communication again to check if something has changes. You can you do the following test from app:

Later it can be analyzed with wireshark

bitrate16 commented 10 months ago

Current workaround: allow commandline config of delay to manually set it to 0.001. Possibly will cause problems for long images, like data loss

rkolbaskin commented 10 months ago

Current workaround: allow commandline config of delay to manually set it to 0.001 Will cause problems for long images, like data loss

I already tried removing time.sleep completely and it still produces white lines on bright images.

I also already captured bluetooth logs and at the first glance they don't look any different from what your script does (except it sends more than 0xFF rows per print command). I might do another one for you later.

bitrate16 commented 10 months ago

Current workaround: allow commandline config of delay to manually set it to 0.001 Will cause problems for long images, like data loss

I already tried removing time.sleep completely and it still produces white lines on bright images.

I also already captured bluetooth logs and at the first glance they don't look any different from what your script does (except it sends more than 0xFF rows per print command). I might do another one for you later.

Do row size of app match one in library?

rkolbaskin commented 10 months ago

Here are print commands from the logs First image: 1d 76 30 00 48 00 9b 03 Second: 1d 76 30 00 48 00 01 04 Third: 1d 76 30 00 48 00 7a 03 So it looks like it is still 576 pixels wide. (also it looks like you have an error in the comments. Row counts are definitely little-endian)

rkolbaskin commented 10 months ago

Just tried printing with official app from two rooms away. It ended up making white lines as well.