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: 3,491
Last edited:

agraham

Expert
Licensed User
Longtime User
As I say in the comment to setCodePage
"You need to look at the printer documentation to establish which code pages are supported"
You then need to match the encoding used in WriteString to the printer code page so that the UTF16 characters used internally by B4X are correctly translated to the 8bit code page of the printer. IBM437 does not include the Euro character so it will be ignored by WriteString. UTF8 does include it but WiteString is translating it to a Chinese character as the code page selected on the printer is not UTF8 compatible.
 

lelelor

Active Member
Licensed User
As I say in the comment to setCodePage
"You need to look at the printer documentation to establish which code pages are supported"
You then need to match the encoding used in WriteString to the printer code page so that the UTF16 characters used internally by B4X are correctly translated to the 8bit code page of the printer. IBM437 does not include the Euro character so it will be ignored by WriteString. UTF8 does include it but WiteString is translating it to a Chinese character as the code page selected on the printer is not UTF8 compatible.

good morning, thanks 1000, it works!
 

Jannete

Member
I know it's an old thread, but trying to make the library work with the example, when connecting I get: "Error connecting. java.io.IOException: read failed, socket might closed or timeout, read ret: -1 ".

Does anyone know how to fix this error? Thank you very much!
 

agraham

Expert
Licensed User
Longtime User
If you look in the ExcPosPrinter class you will see that the communication with the printer uses the internal Serial library and AsyncStreams from the RandomAccessFile internal library. these libraries are well tested and proven over a long period of time so any problem will most probably be external to these. From the error it looks like the Bluetooth connection between the printer and your device is not working properly.
 

Jannete

Member
If you look in the ExcPosPrinter class you will see that the communication with the printer uses the internal Serial library and AsyncStreams from the RandomAccessFile internal library. these libraries are well tested and proven over a long period of time so any problem will most probably be external to these. From the error it looks like the Bluetooth connection between the printer and your device is not working properly.
First of all thank you for such a kind response.

Could it be the drivers? When I open the phone's Bluetooth menu and try to connect the device, I get this message: "An application is needed to use this device."
 

agraham

Expert
Licensed User
Longtime User
I get this message: "An application is needed to use this device."
I assume that by 'connect' you mean pair. That may be just a benign message stating the obvious, though I have never seen it myself. If you look at the example code it does ask the user to select a paired Bluetooth printer is paired and warns if not. If your Bluetooth does not 'just work' there is little that you can do apart from try another printer and/or device as the drivers are built in to your Android installation and are not accessible to you.
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
Hi there!

I am using this class for some printers and works.

However I got a Sunmi T2 mini Android PDV and something weird is happening.

Using the Demo app suplied with the class, I can print normally on the innerprinter.

When trying the same class on my app it simply does not work. I have tried everything, changing encoding, adding a sleep(100), printing everything as one big string, printing lines. Tryed testing in debug, release.

When I copy and paste part of the example to my code (the part where there is "reversed text" in the demo, most of the times it works.

I prepare my printing (POS Receipt) from a local Rest Server. I have the option to send very basic text, no ESCPOS, and even with that no way.

I receive the data from the server as ENCODED, since it can have lots of escpos commands thata can eventually cause problem in the http parsing. I always decode to play text string.

I can expect that before printing and seems normal text.

Then I started to break down the text in line and send one by one and that does not work either.

B4X:
Sub DecodePrint(dStr As String) As String
    If FAppManager.Server.ReportedAPI > 16 Then
        Try
            Dim su As StringUtils
            Dim Decoded() As Byte = su.DecodeBase64(dStr)
            Dim str As String = BytesToString(Decoded, 0, Decoded.Length, "UTF-8")
            Return str
        Catch
            Log(LastException.Message)
            Return dStr
        End Try
    Else
        Return dStr
    End If
End Sub

private Sub PrintLocalLIB(aStr As String, Param As TPrintParam)
    If FPrinter.IsInitialized Then
        Dim str As String = DecodePrint(aStr)
            
        If str <> "" Then
            FPrinter.Reset
            Dim Direto As Boolean = Param.Direto
        
            If (Param.DiretoFiltro <> "") And (Param.DiretoFiltro <> Null) Then
                If str.Contains(Param.DiretoFiltro) Then
                    Direto = True
                End If
            End If
            
            If Direto Then
                FPrinter.WriteString(str)
            Else   
                ToastMessageShow("Aguarde Impressão", False)       
'                FPrinter.CharacterFont = 0
'                FPrinter.LineSpacing = 15
                Dim paramnum () As String = Regex.Split(Chr(10), str)
                For Each n As String In paramnum
                    Dim Line As String = n.Replace(Chr(10), "").Replace(Chr(13), "")
                    If Param.RemoverLinhas And Line = "" Then
                    Else
                        
                        If Param.CortarEsquerda > 0 Then
                            
                            If Line.Length <= Param.CortarEsquerda Then
                                Line = ""
                            Else
                                Line = Line.SubString2(Param.CortarEsquerda, Line.Length)
                            End If
                            
                        End If

                        If Param.CortarDireita > 0 Then
                            
                            If Line.Length <= Param.CortarDireita Then
                            Else
                                Line = Line.SubString2(0, Param.CortarDireita-1)
                            End If
                                                    
                        End If
                        
                        FPrinter.WriteString(Line&CRLF)
'                        FPrinter.WriteString(Line)
                        
                        Sleep(50)
                    End If
                Next
            End If           
        End If
    End If
End Sub

I have added that Sleep because in one android POS it was necessary to work, but removing it makes no difference.

Any ideas?
 

agraham

Expert
Licensed User
Longtime User
When trying the same class on my app it simply does not work
You don't say in what way 'it does not work' :(
If the demo works there must something wrong with the way you are decoding the data and it is nothing to do with the class so I'm afraid you are on your own here.
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
You don't say in what way 'it does not work' :(
If the demo works there must something wrong with the way you are decoding the data and it is nothing to do with the class so I'm afraid you are on your own here.
thanks for the reply.

The decoding works. You class works in other printers in my app.

Trying to figure out from your experience what could be.

Using your demo directly it does print. Using the class (as a class) and doing what is in the attached code does not work for this sunmi. It does work with another type of bluetooth printer.
 

agraham

Expert
Licensed User
Longtime User
does not work for this sunmi.
Again, in what way 'does not work'? Blank lines? Garbage text? No response at all? Who knows!

I can only guess you are sending some data that upsets that printer. The class works with other printers. The class works in the demo with that printer. Your app doesn't work with the class and that printer. It's got to be the data you are sending to it.
 

walterf25

Expert
Licensed User
Longtime User
I just recently bought this BT printer and was hoping your code would work with 1D barcodes, unfortunately it doesn't, I have tried playing around and changing different parameters but I still can't get it to work.

When I try to print, I can only see the paper feeding, but no bar code is printer, text doesn't seem to work either.

The code to print an image works fine, unfortunately there's no documentation about what character sets are compatible with this printer, and I can't seem to find anything online, my fault I should have done more research about which printer to buy.

I'm not very familiar with this type of protocol, do you have any suggestions on what to try next to see if I can somehow get my printer to work, otherwise I would have to buy a different one, by the way do you have any suggestions on which printer to buy, I mainly am interested in printing 1D and 2D barcodes, I would like to integrate this into a web app I built a couple of years ago.

Thanks Agraham and great library by the way.

Walter
 

Xfood

Expert
Licensed User
I just recently bought this BT printer and was hoping your code would work with 1D barcodes, unfortunately it doesn't, I have tried playing around and changing different parameters but I still can't get it to work.

When I try to print, I can only see the paper feeding, but no bar code is printer, text doesn't seem to work either.

The code to print an image works fine, unfortunately there's no documentation about what character sets are compatible with this printer, and I can't seem to find anything online, my fault I should have done more research about which printer to buy.

I'm not very familiar with this type of protocol, do you have any suggestions on what to try next to see if I can somehow get my printer to work, otherwise I would have to buy a different one, by the way do you have any suggestions on which printer to buy, I mainly am interested in printing 1D and 2D barcodes, I would like to integrate this into a web app I built a couple of years ago.

Thanks Agraham and great library by the way.

Walter
create a barcode in png format at runtime, and then print the image
 

aeric

Expert
Licensed User
Longtime User
I just recently bought this BT printer and was hoping your code would work with 1D barcodes, unfortunately it doesn't, I have tried playing around and changing different parameters but I still can't get it to work.

When I try to print, I can only see the paper feeding, but no bar code is printer, text doesn't seem to work either.

The code to print an image works fine, unfortunately there's no documentation about what character sets are compatible with this printer, and I can't seem to find anything online, my fault I should have done more research about which printer to buy.

I'm not very familiar with this type of protocol, do you have any suggestions on what to try next to see if I can somehow get my printer to work, otherwise I would have to buy a different one, by the way do you have any suggestions on which printer to buy, I mainly am interested in printing 1D and 2D barcodes, I would like to integrate this into a web app I built a couple of years ago.

Thanks Agraham and great library by the way.

Walter
Just make sure you install the correct driver and try test print by usually pressing the feed button and power button when it is off. It usually print the barcode if it supports natively.

 

MR Kai

Member
Licensed User
Longtime User
hi
i have problem with print this report
attached image explain what mean
 

Attachments

  • flash1.png
    flash1.png
    166.7 KB · Views: 207
  • 111.png
    111.png
    219.5 KB · Views: 217

emexes

Expert
Licensed User
i have problem with print this report
attached image explain what mean

The problem might not be as obvious to others as it is to you.

Is it that the Print Time is a date?
Is it that the Sales Date is blank?
Is it that restaurant trading days often straddle midnight, ie not just a single date?
Is it that monetary amounts have between 1 and 5 decimal places?
Is it the incorrect total amount of sales by payment method? or
Is it that 0.36 was rounded to 0.3 ?
Is it the adjacent repetition of Revenue and Tips totals?
Is it that Gross Sales is an unexplained 22 higher than Total Sales?
Is it that Take Away QTY is 6.0 ? Could it ever be eg 6.3 ?
Is it the 0 guests and their associated average of 494.06 ?
Is it the mismatched sales totals by group vs profit center?
Is it the 0 void items totalling 2964.36 ?
 
Last edited:
Top