Capturing serial print data (ESC/POS parsing) from Wens 700 oscilloscope - Page 1
Forum section: electronics / projects

author: bborisov567
author_rank: Regular Contributor
timestamp: November 20, 2024, 09:55:28 am
content: I have this old Wens 700 (also sold as Beetech 700) all-in-one oscilloscope and DMM. The device has a RS-232 port to connect to a thermal printer (Epson M-T102 is the exact model listed). I have spent some time restoring the device and now i am look for a way to capture oscillograms. The device is sending data in ESC/POS format on the serial connection. I have found a tool called Serial Printer Logger that captures the data as PDF. The problem is that there are blank spaces horizontally across the captured image. I have tried all combination of the settings but nothing seems to fix the problem. So i have decided to try another approach - capture the raw ESC/POS data and then try to convert it. I have found another tool - ESCParser but that also doesn't work correctly. I read a bit about the ESC print code but i am not sure if the data (oscilloscope screen) is sent as ASCII characters or as image pixels? I attach a screenshot of Serial Print Logger setting, two captured images and the binary data received from the serial port. I hope somebody that has more experience with ESC/POS can take a look and say where the issue might be and also suggest an appropriate tool

author: kilobyte
author_rank: Regular Contributor
timestamp: November 20, 2024, 11:38:11 am
content: The raw dump looks fine.The graphic data starts with 1B 2A 00 A0 00 followed by 160 Bytes (0xA0) and 0x0A = \nAttached is an image where I simply have drawn all 20 lines starting with 1B 2A with a bit of python code

author: bborisov567
author_rank: Regular Contributor
timestamp: November 20, 2024, 12:53:00 pm
content: Thank you very much that works great! I just have one question - how did you manage to import the raw data into the Python code? For example i am uploding a file from the the serial port. How can i converting to an array in python?

author: kilobyte
author_rank: Regular Contributor
timestamp: November 21, 2024, 11:00:16 am
content: For the test I simply have opened your raw dump in a hex editor (HxD) and copied the 0x1B Data to Notepad++ added a \n before 1B and replaced the spaces with 0x added the square brackets.This manual process could be of course also be done directly in python.

author: adeuring
author_rank: Contributor
timestamp: November 21, 2024, 03:23:04 pm
content: Here is a version of kilobyte's script that reads your file "raw_data.log".Code:from PIL import Image, ImageDrawdef get_line(f):"""Extract the binary data following an ESC* command.This is a VERY naive implementation. Its main problem: The byte sequenceESC* might appear in the data of some other command that needs binary data.A proper parser for an ESC/POS data stream would be more robust."""# See https://download4.epson.biz/sec_pubs/pos/reference_en/escpos/esc_asterisk.html# for a description of the ESC* command.cc = b'\x00'while True:# Search for the ESC* command.while cc != 27:cc = f.read(1)if len(cc) == 0:# EOFreturn Nonecc = f.read(1)if cc != b'*':continue# Next byte is called "m" in Epson's doc. Expected to be zero in this# script. Bail out to prevent any confusion if anther value is read.cc = f.read(1)if cc != b'\x00':raise RuntimeError(f'Unexpected ESC* parameter: {cc}')# Two length bytes follow.linelength = int.from_bytes(f.read(2), 'little')# ...and finally the bitmap data.return f.read(linelength)def get_bitmap(filename):binary_data = []with open(filename, 'rb') as f:line_data = get_line(f)while line_data != None:binary_data.append(line_data)line_data = get_line(f)return binary_datadef create_bitmap(binary_data):h = len(binary_data) * 8 # bitmap data 8 pixel heightw = len(binary_data)print("W:", w, "H:", h)#Create imageimage = Image.new('RGB',(w,h),"white")pixels = image.load()# create image by setting pixelidx_height = 0for row in binary_data:#print(row)idx_width = 0for byt in row:# draw the 8 bit verticalfor n in range(8):if (byt & 1<<(7-n)):pixels[ idx_width, idx_height + n ] = (0,0,0)idx_width += 1idx_height += 8print("save")#image.save(path + image_name)print("show")# display image in viewerimage.show()def main():binary_data = get_bitmap('raw_data.log')create_bitmap(binary_data)if __name__ == '__main__':main()It could be changed to directly read from a serial interface, using the PySerial package. In that case youÄ'd need another way to detect end of the data stream. Maybe search for the byte sequence 0a 1b 33 ff 0a, which seems to appear only at the end of the data sent by the device.And please take the note from the source code seriously: The extraction of the bitmap data is indeed VERY naive. But perhaps good enough for a start.

author: bborisov567
author_rank: Regular Contributor
timestamp: December 04, 2024, 03:57:58 pm
content: Thank you very much adeuring for the code, it works perfectly for casualy capturing of oscilograms! In the mean time i found some software for displaying live data from the scope and a service and user manual for the scope so i am sharing them.