From 882a643b1924ee8a7ba6647ad9422a8403fbbffb Mon Sep 17 00:00:00 2001 From: Furrtek Date: Sat, 29 Sep 2018 20:41:49 +0200 Subject: [PATCH] Added serial comm. for transmitter Data size bugfix Example bitmaps --- checker.bmp | Bin 0 -> 69942 bytes img2dm.py | 103 ++++++++++++++++++++++++++++++++++++++++------------ pommes.bmp | Bin 0 -> 69942 bytes test.bmp | Bin 0 -> 69942 bytes 4 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 checker.bmp create mode 100644 pommes.bmp create mode 100644 test.bmp diff --git a/checker.bmp b/checker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6dbddf830f03e0363b3e68aa37ff5b98f82f919b GIT binary patch literal 69942 zcmeIxu?@md5JbW6mTE``rrA(TE}tBr#FE{K-mbC0!^!>5I6>%%OYTL1WEymBTx#I-Ihh5?6xcd7Du2Ius8yxK-q0s1j=s9 zB4BX@N&$-_PzsdYmPMfKwk!e`N1zn2I0B_W*=<<_%5KXdU~vRW0gEG03Y6WJMWF1q zECLospcJq;0;NFNZCM1$Zp$KIaRf>Miz849l--s^pzO9R0v1Q06tFk~r9jzjSp>>% z%OYTL1WEymBTx#I-Ihh5?6xcd7Du2Ius8yxK-q0s1j=s9B4BX@N&$-_PzsdYmPMfK zwk!e`N1zn2I0B_W*=<<_%5KXdU~vRW0gEG03Y6WJMWF1qECLospcJq;0;NFNZCM1$ zZp$KIaRf>Miz849l--s^pzO9R0v1Q06tFk~r9jzjSp>>%%OYTL1WEymBTx#I-Ihh5 z?6xcd7Du2Ius8yxK-q0s1j=s9B4BX@N&$-_PzsdYmPMfKwk!e`N1zn2I0B_W*=<<_ z%5KXdU~vRW0gEG03Y6WJMWF1qECLospcJq;0;NFNZCM1$Zp$KIaRf>Miz849l--s^ spzO9R0v1Q06tFk~r9jzjSp>>%%OYTL1WEymBTx#I-Ihh5?6xcdU!I5pQvd(} literal 0 HcmV?d00001 diff --git a/img2dm.py b/img2dm.py index 774f8d8..f9fee77 100644 --- a/img2dm.py +++ b/img2dm.py @@ -3,6 +3,7 @@ # See LICENSE from imageio import imread +import serial import sys def record_run(run_count): @@ -17,7 +18,8 @@ def record_run(run_count): if len(bits): compressed.extend(bits) -def append_crc(frame): +def terminate_frame(frame, repeats): + # Compute whole frame's CRC16 result = 0x8408 poly = 0x8408 @@ -32,6 +34,11 @@ def append_crc(frame): frame.append(result & 255) frame.append((result / 256) & 255) + frame.append(repeats & 255) # This is used internally, it's not part of the transmitted data + +def make_raw_frame(cmd): + frame = [0x85, PLID[3], PLID[2], PLID[1], PLID[0], cmd] + return frame def make_mcu_frame(cmd): frame = [0x85, PLID[3], PLID[2], PLID[1], PLID[0], 0x34, 0x00, 0x00, 0x00, cmd] @@ -43,7 +50,8 @@ def append_word(frame, value): def usage(): print("Usage:") - print("img2dm.py image barcode page x y") + print("img2dm.py port image barcode page (x y)") + print(" port: serial port") print(" image: image file") print(" barcode: 17-character barcode data") print(" page: page number to update (0~15)") @@ -51,11 +59,13 @@ def usage(): exit() arg_count = len(sys.argv) -if arg_count < 4: +if arg_count < 5: usage() + +ser = serial.Serial(sys.argv[1], 57600, timeout = 5) # 1s timeout for read # Open image file -image = imread(sys.argv[1]) +image = imread(sys.argv[2]) width = image.shape[1] height = image.shape[0] if width != 208 or height != 112: @@ -64,7 +74,7 @@ if width != 208 or height != 112: # Get PLID PLID = [0] * 4 -barcode = sys.argv[2] +barcode = sys.argv[3] if len(barcode) != 17: usage() id_value = int(barcode[2:7]) + (int(barcode[7:12]) << 16) @@ -73,17 +83,17 @@ PLID[1] = id_value & 0xFF PLID[2] = (id_value >> 24) & 0xFF PLID[3] = (id_value >> 16) & 0xFF -page = int(sys.argv[3]) +page = int(sys.argv[4]) if page < 0 or page > 15: print("Page can only be between 0 and 15.") exit() -if arg_count > 4: - pos_x = int(sys.argv[4]) +if arg_count > 5: + pos_x = int(sys.argv[5]) else: pos_x = 0 -if arg_count > 5: - pos_y = int(sys.argv[5]) +if arg_count > 6: + pos_y = int(sys.argv[6]) else: pos_y = 0 @@ -93,6 +103,7 @@ bits = [] size_raw = width * height +# Convert image to 1-bit for row in image: for rgb in row: pixels.append(int(round((0.21 * rgb[0] + 0.72 * rgb[1] + 0.07 * rgb[2]) / 255))) @@ -106,11 +117,11 @@ compressed.append(run_pixel) c = 0 for pixel in pixels[1:]: if pixel == run_pixel: - # Add to count + # Add to run run_count += 1 else: + # Record run record_run(run_count) - run_count = 1 run_pixel = pixel @@ -120,6 +131,7 @@ if run_count > 1: size_compressed = len(compressed) +# Decide on compression or not if size_compressed < size_raw: print("Compression ratio: %.1f%%" % (100 - ((size_compressed * 100) / float(size_raw)))) data = compressed @@ -129,34 +141,47 @@ else: data = pixels compression_type = 0 -# Pad to multiple of bits_per_frame +# Pad data to multiple of bits_per_frame bits_per_frame = 20 * 8 -padding = bits_per_frame - (len(data) % bits_per_frame) +data_size = len(data) +padding = bits_per_frame - (data_size % bits_per_frame) for b in range(0, padding): data.append(0) -data_size = len(data) -frame_count = data_size / bits_per_frame +padded_data_size = len(data) +frame_count = padded_data_size / bits_per_frame -print("Generating %i frames..." % frame_count) +print("Generating %i data frames..." % frame_count) frames = [] +# Ping frame +frame = make_raw_frame(0x97) +frame.append(0x01) +frame.append(0x00) +frame.append(0x00) +frame.append(0x00) +for b in range(0, 22): + frame.append(0x01) +terminate_frame(frame, 150) +frames.append(frame) + # Parameters frame frame = make_mcu_frame(0x05) byte_count = data_size / 8 append_word(frame, byte_count) frame.append(0x00) frame.append(compression_type) -frame.append(0x01) # PAGE ! +frame.append(page) append_word(frame, width) append_word(frame, height) append_word(frame, pos_x) append_word(frame, pos_y) frame.extend([0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) -append_crc(frame) +terminate_frame(frame, 2) frames.append(frame) +# Data frames i = 0 for fr in range(0, frame_count): frame = make_mcu_frame(0x20) @@ -168,12 +193,42 @@ for fr in range(0, frame_count): v += data[i + bi] frame.append(v) i += 8 - append_crc(frame) + terminate_frame(frame, 1) frames.append(frame) -f = open("out.txt", "w") # DEBUG +# Refresh frame +frame = make_mcu_frame(0x01) +for b in range(0, 22): + frame.append(0x00) +terminate_frame(frame, 1) +frames.append(frame) +# DEBUG +#f = open("out.txt", "w") +#for fr in frames: +# for b in fr: +# f.write(format(b, '02X') + " ") +# f.write("\n") +#exit() + +# Send data to IR transmitter +ser.reset_input_buffer() +i = 1 for fr in frames: - for b in fr: - f.write(format(b, '02X') + " ") - f.write("\n") + data_size = len(fr) - 1 + repeats = fr[-1] + print("Transmitting frame %u, length %u, repeated %u times." % (i, data_size, repeats)) + + ba = bytearray() + ba.append(data_size) + ba.append(repeats) + for b in range(0, len(fr) - 1): + ba.append(0x80 + (fr[b] >> 4)) + ba.append(0x80 + (fr[b] & 15)) + ser.write(ba) + ser.flush() + ser.read_until('A') + i += 1 + +ser.close() +print("Done. Please allow a few seconds for the ESL to refresh.") diff --git a/pommes.bmp b/pommes.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c42f76a8960013d26246989e03fca3e49b292b25 GIT binary patch literal 69942 zcmeHH;n6HL4C9r+KT4ni3gADzP%0gP!Hh;DJKk(Id$)JVoB3{JSyp0g=KcQ1Z$JO| z>ED09+261B_m}di`(F0N3CLsH|HZvH{{@fRPj11F{>GK}dwXN}3m#p(H?$UvWv_f+0(e&d zeiljtho_$sAG$%{wkU_ep-<=iJ7wuT5ATppeILmg7Pz%|Yb4b}%-x!_E{h%4Bdmuq z^)V$27_&*gOs2dnY*YQ$lN?BaV-AJbTB2t$T1;XjCDW0V?DVl&IY`QuxyW!F^a5Bf ztu;#yq{fm@Ew(Q7qO5rl-{IpIhzAMNDdQVrHGtF;-35UJQj{D{Awvs#FaX{{=^!Po zHQmPy<><6*-6x81!w5ti1q(8giIo;YB%Swsq??k^i});$FEYy~-43S+;6u@3(lJ^B zL@C`hOUcAa&mr=y)|lR=b=E!oCtAbTKblf`Nc6u=hy@3N1t%#}s|?_)X>!{V$r488_3HCEO~T;5s8mq@|paYCu8^rUjtfKoa1@r1hE-7npk-Y-=Eg)?(|r{!j*` z_%B`}xA*37$2H(t175sVde`;+O7>qIBeW;vF#R$xtO4&HmE2{_O7KiNMr#9v^PDK= zUI}jU>07+zAT29}EDw8bZWChQ1+Wx>dC!lxxn1e_Af?01()=7DQY zyc?_lurC+~EnZ|Op$9;V0lFoGGr{DxDmhh+iW7G*q3TCI|=mugtBGL8v9Ee(9W z>lcF+fP10@z*%4b(vd=MgXk^}Jj3UQF!7#vHUPdpN;yk-D-oBpQlF^D_-X)gJ%90u zSA`V=OMpwmoQbr!%Pk*a23T5bz7F;@K4ssDx5YE40Vflc-en$oCR-TdMS$nXaV43qHZz8*&;rg2{Ls%VJj;78{mstCXq!!It5>cwgjQ zr(Znx?#n;qE5~cxz4*oNQjCA@&26a{TwcC)k>q_XxdWH?9eRiJ3%=JK*M=vO2QwYu z2!QEF92(;26daB}N8tB=&V2@M@`4rQD-T?9;)q=41?x}0{6xdoTOt4Zj>Zws`M7c= zEALx>mh*GcySUK{7Qy$uc-4vHxDvob^E<3w@R{zocJ#csNY6Ml4(vBxBQg+o>dgTo z(M=dA0YtzhGzOSw%$gLlcmTWSz~IwH5YE|)VbDO&EbHS4cioMdLXV?sy~#unOIQI! zjWZB9Xvu_^sZ(Wo?kR_dh>^*u`(P@~0bO{40YJ+D$O5$V;AIxP1L>yasSy^ZZYjxA z{n)Mg^$%ALtRrFag4_bnWIQf*BXej~jM!}KrVLK$8G$&pN=b~I0&aC`VkLYGw7M-mj=-%o zlJZQ#fdLDESulp(YHaqIQv(|zPXJ#HCBP{j`CuI2umvSRYXrOjh#h!K$h2e=;C>}W z4gp{6Q2Y^sfsJCYzUeI9+{B8LY_&Rhlfg|!ycNlmfeC|tB~KOD4GY1?wGdJN%`pPt zvnUx@i%Z8XJ?zPJ>GtRCeDX@-~L0W^j0)KWQGS1o!=<9veaS7g+Nv=lxXn?$P}nzhc&?-D)l$X!==hD5pqi8ew*Mm_SdkhbE~2Z{P*r<-RS_)i!x0 zf%`rdp4^q|9nQYyl*4OmL1zLteJ|KL=)BBX8BRGnxb<&LVD6K^8(?t9cJRN$e0$!S zz?3J42VlT%%cV1OSAhRq+wJz61pM=jorO=&?+S+Kj+w_P81ivZwwZ?~fbV$fo~=9{2~b)K8Yv*vq(gH%_#}s*%;_F+y@JvpyKy zV4Vc|9|;~!XjPBz?g|MUJ`xl3 z(}>pg5QCCugne{w@1Dp0lb+A((Oc+ gYBsqO=uAMKQ&DyrZrM&?C$JOP3G4)R0-u<`KL+8pa{vGU literal 0 HcmV?d00001 diff --git a/test.bmp b/test.bmp new file mode 100644 index 0000000000000000000000000000000000000000..74cdc87ebcaa8eac4730acc0588688c5c9ed7658 GIT binary patch literal 69942 zcmeH`L5?N44Mcm^Ud^n01fQS};QicXj_MoPnwCKjq!}m zm_rVAz`rq{InSS zxi4JNCP#k4#-DJ8P1gC~YdmesPdm?pSNF1`J$bWFKHJOI{D9-WWt-)k4{$4waLIvp zE%7b?8kbhGY4dw`_ui9l`jk4?+GAgP+@iCpmzVe3(SA32`4jv9@%P@#-nV<#3p{5R z=iKy}FYrwN%dMZej=fKHvh8R7qkZc=r`y%}^x^Iom=1e~(-ZH>^-Q{oJxqVFKYTTv zOs{wct|;@R&AFGpjrx|3bseh~0i!@Ef@|hPdxU*XUSCj7Rgw~C;2qGWN$h1cLz*d^ zZV(OP^JWC!ctvT3*3T=zLwcLOl_a=+*V~BM&4Z!M(sE#Pib;Z@Mwy@50pMFHX=O96 z?Y@MuWYuGRhD1f@^gt%l9m+t?)GV>iZ?lVK1b8D1p{c=GrrN~nBm+56qb-W!30or6 zL>^3^py?Js#w87jVoW%*8hK^%qvn|Qi=WZ-i&$xo_)%UOaS*kioX3vo>X1viaY^i_ zFTqxbhvN)68bi*klGYU&?+?%9m3}(kODg?{C_@5^EFv76zr#A7$t%r*_{JfnnPNT* zs%ChmA>`+B>v-UhQg3Rgaa61aNn9c3lO#)52Gs%5w<2R4<7q=mJ$k5dRICS;xVD?5 zOf>vGtZdTY-}bOn%6W@ zYmq`ab1oGNZ>g#ai$xP zo^&}PAc0q8GK&nzStPB@odqcb%wd7YdarwL5VPhn_BX_i~Z0~w{+MQy1` z9qSB(H5xOe`)S(2XBTyv0C;6eq%)@L`lp{;nI=Cy$Z(iXeilPJO2b=MlwD_rXr$N= zt&KWQqP$E)hGLJ3GDFxC#F0@x-*v;cEXl~+N~@nGmSB2{kVgZ4;wbq9{VMl(&XBUM zptLl1F@)0MCXG*O6o`4?IZ9xcDPd2Hc-1EuIz0j~$r3-B1Rf$V#Krj1q&9DI(Fx7P!&Oo_L`G){ctS))Kqo2!y% zn1k=#MOs&6qz@#Jq$%dJ}uG;Xir8;+TRKTR+A#GEs$z%E_l z&Cy*T=7CxXfV!kxbgVVaSc^g2?Da`NIJV?niZZ-K5y9knpjH}4^Hb|<+?4sGZ)|3K zV>8q2&1BOnpX815y-|i|iZVj!yohz61t8WfQ4HEmDI%PlHx@;oLl#94lOJMMu^~jC zo*XHC-uL>9?`mdz<53yyiCkPKK`eSQ04QA|X(H3T-B`M6(A8G~=#tVLO4<(zNSB(j zQHz=opB%*&y@!B|<^!22&2?9I{Ksk@^XljMz1p@Pu#irt!Uu((_A(X`Iu@xVd(+OQ!4>kPb}Cykpa- zW~1lVOjCS4c`ICw7hP(Dyxj4Qpy|)TK~26S7Y?eZ`^fsJGG*65Uv_QWbZp^>Cf_7) z8n+N@Q0DymeVY5O`UFNT83FjFbjP?QOb;<9-}}>Fe>#JWn#M{a<~OU-I}tR2H90|x zTELVON|7zyJa0}H)fDi2uWSNw(nCN7qd*lfvs4_2teZ9`0!n_G+-wvq4w}8w$!OLz zFdJX$fO!coy~PH{u8Y{52DbZ6+PA zex?s=-xa1E?smC8_9v@%IB=lthySD9@rs6+=lFllO@|)9SHyeoV(;61<-sf&y5C;* zyU~(GKMJzPj`q04qaMbshk5V5-h1*}7y1hL>vmTT{0d|9kidagEb(>!8o=-@J$ai? zK3l$=D-JwuvrjwE6>qaQa^MMDe!>|de=>iE1K-;Cx8~mAVKPS@_~iCKIcwC1)PK@} zyI;cH{7-t7vsO89)2k@hRVPf&ehw^r9ydMU{X9SXM%UlTb;98*IPm&&Z)UFRKzsAb zO$Ye*!z-JEGMNsD1NbfBsz5SG2ZkK*@5*O}fGJJ~x(>)2D?wMBf^=Ys1Ld*(54TW` AaR2}S literal 0 HcmV?d00001