3

I am trying to use python to send a binary file over serial COM port in windows and then write that same stream to a file. In essence, I am trying to make a copy of the file, but since that is not my ultimate goal, I don't want to use shutil or other copy functions. I have one script that I intend to send the file over the COM port, and one script that is acting as the listener and file writer. The sender script seems to send the file as binary without issue, but I'm having trouble with the listener script, specifically, getting it to output the file correctly. I have posted my scripts below. Is the binary stream I'm sending from "sender" correct, and how can I alter my "listener" to correctly write the file?

Listener:

from serial import Serial

def bytes_from_file(filename, chunksize=8192):
    with open(filename, "rb") as f:
        while True:
            chunk = f.read(chunksize)
            if chunk:
                for b in chunk:
                    yield b
            else:
                break

def sendfile():
    ser = Serial("COM5", 115200, timeout=30, writeTimeout=0)
    filename = "c:\\temp\\savetestfile.txt"
    # wait for the "Sendfile" command over serial
    h = b''
    while h == b'':
        h = ser.read(ser.inWaiting())
    h = h.decode("utf-8")

    #respond with "y" if "sendfile" recieved to start data stream
    if h == "sendfile":
        ser.write(b'y')
    with open(filename, "wb") as f:
        while True:
            b=ser.read(1)
            print (b)
            if b: 
                n=f.write(b)
            else: break

if __name__ =="__main__":

    sendfile()

Sender:

from serial import Serial 

def bytes_from_file(filename, chunksize=8192):
    with open(filename, "rb") as f:
        while True:
            chunk = f.read(chunksize)
            if chunk:
                for b in chunk:
                    yield b
            else:
                break


def sendfile():
    #com = getCOMPortInfo()
    ser = Serial("COM2", 115200, timeout=10, writeTimeout=0)
    filename = askopenfilename(title="Stuff", initialdir="C:\\")
    #if filename is "":
    #   exit()
    ser.write(b"sendfile")
    ok = ""
    #while True:te

    h = ser.read()
    ok = ok + h.decode("utf-8")
    if ok is "y":
        print("yes!")
        for b in bytes_from_file(filename):
            #b = str(b).encode()
            print(b)
            ser.write(b)
    else:
        print ("Failure")
    ser.close()



# example:

if __name__ =="__main__":


    print(sendfile())
  • For anyone still hitting this question, I never found a good answer. If you come across one in your travels, please feel free to suggest. I wound up retooling my design so as not needing to send the file, but i'd still like to know how to do it if possible. – TheEmpireNeverEnded Jul 16 '20 at 16:02

1 Answers1

0

I translated binary file to \xYY format, and use "printf" command to write the cascaded strings to target file. It introdued overhead, but since I am working on small files, it is OK.

content = f.read().hex()
content = "".join(["\\x" + content[x:x + 2] for x in range(0, len(content), 2)])
write_cmds.append("printf \"" + tx_str + "\" >> " + target_file_name + "\r\n")