chipweinberger/flutter_blue_plus

[Help]: Image Printing Issue with flutter_blue_plus and Thermal Printer

iOSyan opened this issue · 4 comments

Requirements

  • I've looked at the README 'Common Problems' section

Have you checked this problem on the example app?

No

FlutterBluePlus Version

1.32.12

Flutter Version

3.24.0

What OS?

Android

OS Version

Android 11

Bluetooth Module

Unknown BLE module

What is your problem?

An excellent library!
Currently, I have a thermal printer, and when I print an image using flutter_blue_plus, the printing is slow and the output is garbled. However, when using print_bluetooth_thermal, it works fine. I’m processing the images and commands using the esc_pos_utils_plus library. Could you please let me know what might be the cause?
When using flutter_blue_plus, I’m writing the image commands using splitWrite

Logs

D/[FBP-Android](29792): [FBP] onMethodCall: writeCharacteristic
D/[FBP-Android](29792): [FBP] onCharacteristicWrite:
D/[FBP-Android](29792): [FBP]   chr: fff2
D/[FBP-Android](29792): [FBP]   status: GATT_SUCCESS (0)
D/[FBP-Android](29792): [FBP] onMethodCall: writeCharacteristic
D/[FBP-Android](29792): [FBP] onCharacteristicWrite:
D/[FBP-Android](29792): [FBP]   chr: fff2
D/[FBP-Android](29792): [FBP]   status: GATT_SUCCESS (0)
.....

why are you building a custom printer app? just curious.

no, i dont know the answer. you're sending the wrong data probably.

from chatgpt


The data format for sending print commands to a BLE thermal printer typically depends on the specific printer model and manufacturer, but most BLE thermal printers use a variation of the ESC/POS (Epson Standard Code for Point of Sale) command set. The commands are usually sent in a binary format over Bluetooth's GATT (Generic Attribute Profile) protocol to a writable characteristic.

Here’s a general breakdown of how the data format is structured:

1. ESC/POS Commands:

  • Control Characters: ESC/POS uses specific control characters to start commands. For example, the escape character (ASCII 0x1B) is often used to denote the start of a command.
  • Text: Plain text can be sent to the printer as is, but special formatting (bold, underline, etc.) requires additional control sequences.
  • Images: Sending images to the printer typically involves converting the image into a monochrome bitmap and encoding it in a format the printer supports (e.g., using ESC * command).
  • Formatting Commands: Commands for things like line feeds, cutting paper, and setting text size are sent before the actual content.

2. GATT Communication:

  • BLE thermal printers expose a service (usually a custom service) with a writable characteristic.
  • Commands are sent to this characteristic, often in chunks of 20 bytes (depending on the MTU size supported by the printer).

Common ESC/POS Commands:

  • Print Text: ESC + @ (reset printer) followed by plain text.
  • Line Feed: LF (0x0A) to move to the next line.
  • Bold Text: ESC + E + n where n=1 to enable bold and n=0 to disable.
  • Set Font Size: ESC + ! + n where n determines the size.
  • Cut Paper: ESC + i or ESC + m.
  • Print Image: ESC * followed by the bitmap data.

Example Data Sequence:

Let’s say you want to send the text "Hello World" in bold to a BLE thermal printer:

  1. Enable Bold: Send ESC + E + 1 (0x1B 0x45 0x01).
  2. Send Text: Send the ASCII sequence for "Hello World" (0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64).
  3. Line Feed: Send LF (0x0A).
  4. Disable Bold: Send ESC + E + 0 (0x1B 0x45 0x00).

These commands need to be sent via the BLE writable characteristic. Many BLE libraries, such as those in iOS and Android, allow you to write data to a characteristic.

You should check the printer's documentation for the exact commands it supports, but ESC/POS is widely used for thermal printers.

Thank you very much for your reply!
The integration of this app with a printer is just one of its functions, which prints some patterns drawn by the user through the printer.

Regarding ESC/POS commands, I am using esc_pos_utils_plus to generate them. The generated commands work fine when printed using print_bluetooth_thermal, so the commands should be correct. However, print_bluetooth_thermal requires pairing with the printer during connection. I'm wondering if the issue is caused by different Bluetooth connection mechanisms?

The following is the command code generated by esc_pos_utils_plus:

 static Future<List<int>> changeToCommand(bytesImg) async {
    List<int> bytes = [];

    final profile = await CapabilityProfile.load();
    final generator = Generator(PaperSize.mm80, profile);

    bytes += generator.reset();

    img.Image? image = img.decodeImage(bytesImg);

    bytes += generator.image(image!);

    bytes += generator.feed(2);

    bytes += generator.cut();

    return bytes;
  }

cannot help you further.