I'm programming a low level communication with an Epson tm-t88iv thermal printer on a Linux device, which receives only hexadecimal packages. I have read the manual trying to understand how the checksum is built but i can't manage to recreate it.
the manual says that the checksum are 4 bytes representing the 2 bytes sum of all the data in the package sent.
I have currently four working examples I found by listening to a port on a windows computer with a different program. the last 4 hexadecimals are the checksum (03 marks the end of the data and is included in the checksum calculation, according to the manual).
02 AC 00 01 1C 00 00 03 30 30 43 45
02 AC 00 00 1C 80 80 1C 00 00 1C 00 00 1C 03 30 32 32 31
02 AD 07 01 1C 00 00 1C 31 30 03 30 31 35 33
02 AD 00 00 1C 80 80 1C 00 00 1C 00 00 1C 03 30 32 32 32
I have read somewhere that there is a sum32 algorithm but i can't find any example of it or how to program it.
Wow, this is a bad algorithm! If someone else finds himself trying to understand Epson's terrible low-level communication manual, this is how the check-sum is done:
The checksum base is 30 30 30 30
Sum in hexadecimals all of the data package (for example, 02+89+00+00+1C+80+80+1C+00+01+1C+09+0C+1C+03 = 214)
Then separate the result digit by digit, if its a letter add 1 to the value (for example B2 would be 2|1|4).
sum it to the checksum base number by number starting from right to left (this would be a checksum of 30 32 31 34).
Note: It works perfectly, but for some reason the examples I posted above don't seem to match so much. They are all the printers response, but slightly after it got a hardware problem and had to be reformatted by technical support, so maybe it got fixed.
I hope it helps somebody somewhere.
Related
I was reading in the CANopen device number EL6751-0010, of course, using the SDO reading command, which I did as follows:
603 | 40 7A 60 00 00 00 00 00
and gave me the following error:
583 | 80 7A 60 00 00 00 02 06
I realized that this object does not exist.
What should I do to find all the objects of an Object Dictionary?
Finally, I can write and read code in the right place.
I'm struggling with an old radiation sensor and his communication protocol.
The sensor is event driven, the master starts the communication with a data transmission or a data request.
Each data telegram uses a CRC16 to check only the variable data block and a CRC8 to check all the telegram.
My main problem is the crc16, According to the datasheet the poly used to check the data block is: CRC16 = X^14 + X^12 + X^5 + 1 --> 0x5021 ??
I captured some data with a valid CRC16 and tried to replicate the expected value in order to send my own data transmission, but I can't get the same value.
I'm using the sunshine CRC calculator trying any possible combination with that poly.
I also try CRC Reveng but no results.
Here are a few data with the correct CRC16:.
Data | CRC16 (MSB LSB)
14 00 00 0A | 1B 84
15 00 00 0C | 15 88
16 00 00 18 | 08 1D
00 00 00 00 | 00 00
00 00 00 01 | 19 D8
00 00 00 02 | 33 B0
01 00 00 00 | 5A DC
08 00 00 00 | c6 c2
10 00 00 00 | 85 95
80 00 00 00 | 0C EC
ff ff ff ff | f3 99
If I send an invalid CRC16 in the telegram, the sensor send a negative acknowledge with the expected value, so I can try any data in order to test or get more examples if needed.
if useful, the sensor uses a 8bit 8051 microprocessor, and this is an example of a valid CRC8 checked with sunshine CRC:
CRC8 = X^8 + X^6 + X^3 + 1 --> 0x49
Input reflected Result reflected
control byte | Data |CRC16 | CRC8
01 0E 01 00 24 2A 06 ff ff ff ff f3 99 |-> 0F
Any help is appreciated !
Looks like a typo on the polynomial. An n-bit CRC polynomial always starts with xn. Like your correct 8-bit polynomial. The 16-bit polynomial should read X16 + X12 + X5 + 1, which in fact is a very common 16-bit CRC polynomial.
To preserve the note in the comment, the four data bytes in the examples are swapped in each pair of bytes, which needs to be undone to get the correct CRC. (The control bytes in the CRC8 example are not swapped.)
So 14 00 00 0a becomes 00 14 0a 00, for which the above-described CRC gives the expected 0x1b84.
I would guess that the CRC is stored in the stream also swapped, so the message as bytes would be 00 14 0a 00 84 1b. That results in a sequence whose total CRC is 0.
I try to find how calculate checksum form hdlc frame. I try with example:
7E A0 0A 00 02 00 23 21 93 [18 71] - checksum 7E
I tried this calculator: https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/
I put there this part of frame: A0 0A 00 02 00 23 21 93
but result didn't match...
I need your advice, guys...
Without hitting the books, I recall that 7E is not the checksum, just the Tag - first byte in an hdlc message. Do you have the whole message you can share?
Implement on python:
After calculating crc,
write higher bit first and then your lower bits, for eg
crc= "3a3b"
crc_used in packet=3b3a
you can try this:
import crcmod #pip3 install crcmod
import sys
def calculate_crc(packet):
packet=''.join(packet.split(' '))
crc16 = crcmod.mkCrcFun(0x11021, rev=True, initCrc=0x0000, xorOut=0xFFFF)
fcs=str(hex(crc16(bytes.fromhex(packet))))
crc_f=str(fcs[4:6])+str(fcs[2:4])
if len(crc_f)<4:
diff=4-len(crc_f)
crc_f= "0"*diff + crc_f
return str(crc_f).upper()
print(calculate_crc("A0 0A 00 02 00 23 21 93"))
output: 1871
I was reading Python guide about Unicode. In this section, it says:
To summarize the previous section: a Unicode string is a sequence of code points, which are numbers from 0 to 0x10ffff. This sequence needs to be represented as a set of bytes (meaning, values from 0-255) in memory. The rules for translating a Unicode string into a sequence of bytes are called an encoding.
The first encoding you might think of is an array of 32-bit integers. In this representation, the string “Python” would look like this:
P y t h o n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Why might we think of 32-bit integers if code points are numbers from 0 to 0x10ffff? Maybe is it assuming that we are on a 32-bit system?
How do you turn off the feature or stop the creation of all the .ddp files for your Delphi 7 forms? I read something about removing the designdgm60.bpl, but is that the only way? It seems that there was another way I can't remember any longer.
Update: I tried renaming the designdgm70.bpl and that just creates a ton of program errors.
Also, I'm using Delphi 7.2 on one computer and there is no design tab I can see unless its covered by something in CnWizards. 7.2 definitely creates the ddp files though.
DDP files are for Delphi diagrams (DDP stands for Delphi Diagram Portfolio) in Delphi 6-7. Delphi 5 used the DTI extension for this.
DDP files can have meaningful information. They don't get compiled into .DCU/.EXE./... as they are for documentation purposes only.
Did you create diagrams of components on your form/datamodule? I used to do that (to explain structure to co-workers) so I was actually really happy with the DDP files.
Before deleting them, inspect them to see if they contain documentation you want to keep.
You can safely delete them if they are 51 bytes long and the TDUMP of it looks like this:
000000: 07 18 44 45 4C 50 48 49 2E 44 49 41 47 52 41 4D ..DELPHI.DIAGRAM
000010: 2E 50 4F 52 54 46 4F 4C 49 4F 0F 00 00 E0 40 02 .PORTFOLIO....#.
000020: 01 09 06 09 55 6E 74 69 74 6C 65 64 31 06 00 02 ....Untitled1...
000030: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
I suppose that it's impossible to turn off .ddp creation in IDE by built-in methods, but DDevExtensions tool includes this option (File Cleaner)
You can install DDevExtensions which is free.
There is an option which you can check that automatically deletes .ddp files.