Block Check Character (BCC)

Discuss anything else that does not suite other forums.

Moderator: Rathinagiri

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Re: Block Check Character (BCC)

Post by Roberto Lopez » Mon Mar 13, 2017 12:44 am

edk wrote:
Fri Mar 10, 2017 10:06 am
<...>
In my opinion the binary sum of all bytes is nothing but the sum of the ASCII codes of each character in the string.
From a mathematical point of view, it does not matter if we add up the number of binary, hexadecimal or decimal notation. The sum should always be the same.
For example:
the sum in binary notation : 101 + 110 = 1011; decimal = 11
the sum in decimal notation: 5 + 6 = 11
I'm surprised the given example, because the sum of all bytes (from [STX] to [ETX]) results in a hexadecimal notation 0554, not 0054.
<...>
Maybe an error on the specific example. I'll try your suggestion with the others.
edk wrote:
Fri Mar 10, 2017 10:06 am
Manufacturer fiscal printer does not provide any libraries to operate the device?
Yes. It provides a nice OCX and other things, but, I like do my apps portable, so I prefer not to rely on an OCX control that could generate unexpected problems.

Many thanks for your help.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Post by Roberto Lopez » Mon Mar 13, 2017 12:47 am

mol wrote:
Sun Mar 12, 2017 6:21 am
I'm using such a function with communication with Polish fiscal printers to calculate CRC:

Code: Select all

function CalculateCRC
	param cString
	local nResult := 0xff
	local nChar
	local i
	local cRetValue
	for i:=1 to len(cString)
		nChar := asc(substr(cString,i,1))
		nResult := numxor(nResult, nChar)
	next i
	
	// conversion to required format - change hex to string
	nChar := nResult % 16
	if nChar > 9
		cRetValue := chr(55+nChar)
	else
		cRetValue := str(nChar,1)
	endif
	nChar := (nResult-nChar)/16
	if nChar > 9
		cRetValue := chr(55+nChar) + cRetValue
	else
		cRetValue := str(nChar,1) + cRetValue
	endif
 return cRetValue
Thanks Marek!

I'll check it ASAP.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

edk
Posts: 103
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 24 times
Been thanked: 44 times

Post by edk » Mon Mar 13, 2017 9:30 am

Roberto Lopez wrote:
Mon Mar 13, 2017 12:44 am
Yes. It provides a nice OCX and other things, but, I like do my apps portable, so I prefer not to rely on an OCX control that could generate unexpected problems.
I mean here the idea to see how libraries provided by the manufacturer calculate the BCC.

edk
Posts: 103
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 24 times
Been thanked: 44 times

Post by edk » Mon Mar 13, 2017 9:41 am

mol wrote:
Sun Mar 12, 2017 6:21 am
I'm using such a function with communication with Polish fiscal printers to calculate CRC:

Code: Select all

function CalculateCRC
	param cString
	local nResult := 0xff
	local nChar
	local i
	local cRetValue
	for i:=1 to len(cString)
		nChar := asc(substr(cString,i,1))
		nResult := numxor(nResult, nChar)
	next i
	
	// conversion to required format - change hex to string
	nChar := nResult % 16
	if nChar > 9
		cRetValue := chr(55+nChar)
	else
		cRetValue := str(nChar,1)
	endif
	nChar := (nResult-nChar)/16
	if nChar > 9
		cRetValue := chr(55+nChar) + cRetValue
	else
		cRetValue := str(nChar,1) + cRetValue
	endif
 return cRetValue
Marku, I calculate CRC for Posnet and Thermal protocol in this way:

Code: Select all

FUNCTION CalculateCRC( cSent, cProtocol)
Local k, xCRC

DO CASE
	CASE cProtocol='THERMAL'
		xCRC:=255

		FOR k:=3 TO LEN(TRIM(cSent))
			xCRC=NUMXOR( xCRC, ASC( SUBSTR ( cSent, k, 1) ) )
		NEXT

		xCRC:=NTOC( xCRC, 16, 2, '0')
		
	CASE cProtocol='POSNET'
		xCRC:=NTOC(HB_CrcCt( cSent ),16)
ENDCASE
RETURN xCRC
Edward.

User avatar
mol
Posts: 2742
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 91 times
Been thanked: 32 times
Contact:

Post by mol » Mon Mar 13, 2017 9:44 am

It's nice to have alternative :D :D :D
Thank you!

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Post by Roberto Lopez » Thu Mar 16, 2017 3:50 pm

edk wrote:
Mon Mar 13, 2017 9:30 am
Roberto Lopez wrote:
Mon Mar 13, 2017 12:44 am
Yes. It provides a nice OCX and other things, but, I like do my apps portable, so I prefer not to rely on an OCX control that could generate unexpected problems.
I mean here the idea to see how libraries provided by the manufacturer calculate the BCC.
Since the OCX methods, does not require the user to send any checksum to the printer, there is not any info about that.

I know that my attempt to not use a 'nice and easy' OCX could appear to be strange, but I always try to skip as much abstraction layers as possible. That way I (at least, theoretically) get more speed, control and stability.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Post by Roberto Lopez » Thu Mar 16, 2017 3:53 pm

And...

I hope to have some free time during weekend, to check your suggestions and compare with the results shown in the printer manual.

Thanks again.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Post by Roberto Lopez » Thu Mar 16, 2017 4:57 pm

Edward.
edk wrote:
Fri Mar 10, 2017 10:06 am
<..>
Example according to andyglezl
DecToHexa (BIntODEC (DecToBin (asciisum ("123"))))
is OK, but shorter is NTOC( AsciiSum ( cSent ), 16, 4, '0' )

Code: Select all

STX:=CHR(2)
ESC:=CHR(27)
FS:=CHR(28)
ETX:=CHR(3)
cSent:=STX+'1'+ESC+'*'+FS+'0000'+FS+'0000'+FS+'0004'+FS+'3'+FS+'83'+FS+'81'+FS+'2'+FS+'0'+FS+'0'+ETX

BCC:=NTOC( AsciiSum ( cSent ), 16, 4, '0' )  // => '0554'
I've applied your example to some different manual examples and I've found a pattern: Simply replacing the first two digits of the result generated by your code and replacing them by '00' I get the 'correct' answers:

Code: Select all

	STX := CHR(2)
	ESC := CHR(27)
	FS  := CHR(28)
	ETX := CHR(3)

	/*
	Manual Example: 
	[STX]1[ESC]*[FS]0000[FS]0000[FS]0004[FS]3[FS]83[FS]81[FS]2[FS]0[FS]0[ETX]0054
	*/

	cSent:=STX+'1'+ESC+'*'+FS+'0000'+FS+'0000'+FS+'0004'+FS+'3'+FS+'83'+FS+'81'+FS+'2'+FS+'0'+FS+'0'+ETX

	BCC := NTOC( AsciiSum ( cSent ), 16, 4, '0' )  


	/*
	Result: '0554' 
	According Manual: '0054'
	*/

	*-------------------------------------------------------------------------------*

	cSent:=STX+'1' + ESC+'*' + FS +'81' + ETX

	BCC :=	NTOC( AsciiSum ( cSent ), 16, 4, '0' )  

	/*	
	Result: '0100'
	According Manual: '0000'
	*/

	*-------------------------------------------------------------------------------*
	
	/*
	Manual Example: [STX]1[ESC]@[FS]82[ETX]0017
	*/

	cSent:=STX+'1' + ESC+'@' + FS +'82' + ETX

	BCC :=	NTOC( AsciiSum ( cSent ), 16, 4, '0' )  

	/*	
	Result: '0117'
	According Manual: '0017'
	*/

	*-------------------------------------------------------------------------------*

	/*
	Manual Example:
	[STX]1[ESC]@[FS]0000[FS]0000[FS]00000004[ETX]00E9
	*/

	cSent:=STX+'1' + ESC+'@' + FS +'0000' + FS + '0000' + FS + '00000004' + ETX

	BCC :=	NTOC( AsciiSum ( cSent ), 16, 4, '0' )  


	/*	
	Result: '03E9'
	According Manual: '00E9'
	*/

So... I've solved my problem! (I guess:) )

I'll check with the printer emulator to see what numbers makes she happy...

Thanks!
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

edk
Posts: 103
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 24 times
Been thanked: 44 times

Post by edk » Thu Mar 16, 2017 6:41 pm

Could it be nibble?

Roberto Lopez wrote:
Thu Mar 09, 2017 2:43 am
(...)
The description of BCC in the manual (translated from original Spanish) is as follows:
BCC = Four hexadecimales. Binary sum of all prior bytes
Roberto Lopez wrote:
Thu Mar 16, 2017 4:57 pm

Code: Select all

	(...)
	According Manual: '0000'

It seems to me that you wrong read on the description of the calculation of BCC.

The sum of the bytes can not give a result of zero unless all bytes are equal to 0. :roll:

Edward.

User avatar
Roberto Lopez
HMG Founder
Posts: 3880
Joined: Wed Jul 30, 2008 6:43 pm
Has thanked: 13 times
Been thanked: 107 times

Post by Roberto Lopez » Fri Mar 17, 2017 2:23 am

edk wrote:
Thu Mar 16, 2017 6:41 pm
Could it be nibble?

Roberto Lopez wrote:
Thu Mar 09, 2017 2:43 am
(...)
The description of BCC in the manual (translated from original Spanish) is as follows:
BCC = Four hexadecimales. Binary sum of all prior bytes
Roberto Lopez wrote:
Thu Mar 16, 2017 4:57 pm

Code: Select all

	(...)
	According Manual: '0000'

It seems to me that you wrong read on the description of the calculation of BCC.

The sum of the bytes can not give a result of zero unless all bytes are equal to 0. :roll:

Edward.
The printer is new and the technology (and API) are new too (these are the first thermal fiscal printers approved here) so could be errors in the manual.

Since the tools for developers include an emulator, I'll test with it to see what happens.

Regarding the translation I've made, it is correct from the Spanish manual to English.

The problem could be that the original technology is clearly not developed here, since some commands are named in English, other in Spanish and others with a mix between the two languages. ie: VAT is named sometimes as VAT and others as IVA (Spanish acronym for Value Added Tax: Impuesto al Valor Agregado).

My guess is that this is an 'imported' technology (US?, EU?) adapted with the changes required for the local taxes.
Regards/Saludos,

Roberto


(Veritas Filia Temporis)

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest