bitrate16/peripage-python

Image prints come out with lines

skorokithakis opened this issue · 34 comments

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?

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.

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

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.

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, it may be aliexpress description issue. This printer (and image size) looks like A6+

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.

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

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

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.

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

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

@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

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

@skorokithakis that looks fine

row_characters=48

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.

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

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).

@skorokithakis What do you mean by underruns?

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

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

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.

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

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.

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

def getDeviceHardware(self) -> bytes:

def getDeviceFirmware(self) -> bytes:

Or look in app if it is there

@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.

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.

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.

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

  • disconnect all bluetooth devices
  • Preciesly record timestamps of each event in test (manually or somehow automatically, or video of test itself)
  • Power off printer, kill app process
  • Enable bluetooth capture in developer options
  • Turn on printer
  • Open app
  • Connect printer
  • Print sample short (small height) image
  • Exit app, turn off printer, disable capture, export it

Later it can be analyzed with wireshark

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

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.

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?

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)

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