B4A Class Bluetooth ESC/POS Printer Class

For the last couple of weeks I have been playing with an 80mm Bluetooth ESC/POS thermal printer I bought off eBay, new and delivered, for the ludicrously cheap price of £20. While the print quality, particularly of images with large areas of black (they are gray due to power supply or thermal dissipation limitations probably), is not great it is adequate. The printer itself seems to be a generic Chinese unit (no surprise there then!) which is re-badged by all and sundry and sold at a remarkably wide range of prices.

Here then is a Printer class that will connect by Bluetooth to the printer and enable access to most of the printer functions, including barcodes and image preparation and printing. The included demo shows the capabilities that are available. To run the demo you will need a paired Bluetooth printer that is switched on. The Printer class uses the BitmapCreator, RandomAccessFile and Serial libraries.

On my printer the only thing that doesn't seem to work properly is QR code generation. Small QR codes don't seem to be able to be decoded by scanners and larger ones look obviously wrong with part of the top of the code replicated at the bottom when printed.

The obvious capabilities missing (so far!) are user defined characters and non-volatile bit images. Also not implemented are some codes that are either duplicates of available commands or ones whose functions I don’t understand.

The class module is included as source code in the demo so you can add any missing capabilities you need. If you add a significant one then please post it for others to play with.

EDIT: Version 2 now posted includes support for creating custom characters. See post #5 for details
 

Attachments

  • BluetoothPrinter_v2.0.zip
    298.6 KB · Views: 2,951
Last edited:

vecino

Well-Known Member
Licensed User
Longtime User
Thank you, yes I see that it is well documented with comments.
Although my question was focused on why there are two different ways to print images, if it is more thought out by types of printers, by types of images that are better suited to one method or the other, etc.
Anyway, it's just out of curiosity.
Regards.
 

vecino

Well-Known Member
Licensed User
Longtime User
Hi, I have implemented this class on a trusted customer, for him to test it with his sales.
It prints tickets, delivery notes and invoices on a small portable bluetooth printer, and also prints the image of the customer's signature (the customer signs with his finger on the screen).
My customer tells me that between 20% and 30% of the images are printed deformed, as if they had been cut out like a puzzle and the different parts had been mixed up.
I attach a couple of examples, the original captured image is correct (I have superimposed it so that it can be seen next to the print).
However the print is a bit strange.

I was using the "PrintImage" print method and then decided to use "PrintImage2" to test, but the result is the same, the images are printed deformed.

I have been testing it too and it prints deformed 2 or 3 every 10 or so. Sometimes it prints many more perfectly, and other times it prints warped 4 or 5 in a row.

Any idea why this might happen?
Thank you very much.

test1.jpeg

test2.jpeg
 

vecino

Well-Known Member
Licensed User
Longtime User
Thank you for your response.
The images I am testing are always smaller than the width of the printer and I don't assign any size to it, I just load it like that:
bmp.Initialize( cDirImages, cSignImage )
Should I use "resize" and give it some size?

B4X:
Sub btnImage_Click
    Printer1.Reset
    Dim bmp As Bitmap
    ' Load an image to print and resize it to the maximum mage dimensions for the printer
    'bmp.InitializeResize(File.DirAssets, "F-35Brefuel.jpg", 576, 512, True) 'ignore
    'bmp.InitializeResize(File.DirAssets, "Avro_Lancaster.jpg", 576, 512, True) 'ignore

    bmp.Initialize(File.DirAssets,"test01.jpg")   '  <-------
    
    ' Convert the RGB image to one with luminance values
    Dim myimage As AnImage = Printer1.ImageToBWIMage(bmp)
    
    ' Choose thresholding the image or dithering it to get a black and white bit image
    'myimage = Printer1.ThresholdImage(myimage, 128)
    'myimage = Printer1.DitherImage1D(myimage, 128)
    myimage = Printer1.DitherImage2D(myimage, 128)
    
    ' Send the black and white bit image to the printer   
    myimage= Printer1.PackImage(myimage)   
    Printer1.WriteString(CRLF) ' nudge the printer to show the user something is happening
    Printer1.PrintImage(myimage)
    Printer1.WriteString(CRLF & "Ended" & CRLF)
End Sub
 

agraham

Expert
Licensed User
Longtime User
I don't know. It's four years since I wrote this class module. The fact that sometimes it prints OK and not others, together with the fact that you are not checking image sizes indicates to me that you are probably doing something wrong. You need to check your printer manual and look at the class code to see if you can see why it's going wrong.
 

vecino

Well-Known Member
Licensed User
Longtime User
Thank you, just one more question.
Theoretically, it should print any image without the need to resize it (If it is smaller than the maximum width of the printer).
It's just that now I have done some tests resizing the image to 576x512 and they print fine, but if I leave them at their original size (which is smaller) then it prints deformed.
That is, apparently images smaller than 576x512 usually print badly, but if they are resized to 576x512 they print well.
That is the only difference, the tests I have done with your example, not with my code.
It doesn't seem to have any logic.
 

agraham

Expert
Licensed User
Longtime User
Theoretically, it should print any image without the need to resize it
it may be in theory, but as you have found in practice it may not. Many of these printers come from China and are renowned for crappy software not conforming to the full ESC/POS spec.
 

vecino

Well-Known Member
Licensed User
Longtime User
That's what I thought, that it was a printer failure.
Thank you very much again.
I like your Cray-1
 

agraham

Expert
Licensed User
Longtime User
I like your Cray-1
Serial number 1, used by Cray as a loan machine until customers got their own. I met it at Daresbury laboratory, it was loaned to them after the European weather forecasting bureau got their machine, where it was used to analyse data from the beamlines of the proton synchrotron there. Pre LAN days (1976) I designed a high speed serial interface card that networked PDP 11s on the beam lines to a set of central PDP 11s and then on to two Interdata 32 super-minis. The Interdatas sent the data to an IBM 370 mainframe for archiving and that fed the Cray 1. Your phone is probably more powerful than all those machines put together nowadays.
 

vecino

Well-Known Member
Licensed User
Longtime User
Nice story 😲
I think we are of similar ages, I knew about PDP-11s and punch cards. In some banks I was looking at IBM mainframes and some vector Teradata. But I hardly used them.
What a time those were!!!
 

vecino

Well-Known Member
Licensed User
Longtime User
Hello, I just want to clarify that the problems I have suffered from "sloppy" images and slow connections, was all due to a batch of faulty printers.
As soon as I received some new printers I tested them and this Agraham class worked perfectly.
Let's see if I can find the time and implement it in my application :rolleyes:
Regards.
 

Kiumbe

Member
Licensed User
Hello Members, about Bluetooth ESC/POS Printer Class, am very happy. I struggled finding help on using some other class but didn't manage anything for my app, after finding this class as provided by @agraham , my coding is smooth, am able to print barcodes, images and custom text for my thermal receipt printer, no failures at all. Thank you so much @agraham , I will definitely support further developments by the provider.👋👋👋
 

timwil

Active Member
Licensed User
Longtime User
Thank you @agraham for your hard work on this class.

I just stumbled over this today. I have been using these small cheap Chinese bluetooth printers for years now but never had to print any images. Now I have to print a logo and this class works perfectly.

Having resized some images the reason I think there is deformation is that the image has to be padded out if it is too small. The format that this printer takes is a very strange one and very very picky. Give it wat it needs and it will print right.

EDIT:

I tried the class with a RONGTA printer than only printed nonsense instead of an image and a Sunmi V2s that prints properly. The more expensive units appear to be of better quality (who could possibly guess that!)
 

vecino

Well-Known Member
Licensed User
Longtime User
Hi, a question, is it possible to connect to the printer with "wait for" instead of "'Sub Printer1_Connected( Success As Boolean )"
Something like this:
B4X:
Wait For (printer1.Connect) complete (success as boolean)
Thank you very much.
 

timwil

Active Member
Licensed User
Longtime User
Why do you want to use a Wait For?

This sub is only executed when the printer actually connects or times out
 
Top