From b416250d47a826e91dc3c67a40a5a79e9e4ca577 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sat, 13 Jul 2024 23:34:14 +0200 Subject: [PATCH] add transmission protocol for sd card over serial --- controller_teensy/include/logging.h | 99 +++++++++++++++++-- logdata_visualization/copyLogsFromBobbycar.py | 99 +++++++++++++++++-- 2 files changed, 183 insertions(+), 15 deletions(-) diff --git a/controller_teensy/include/logging.h b/controller_teensy/include/logging.h index 2cce473..3e4e792 100644 --- a/controller_teensy/include/logging.h +++ b/controller_teensy/include/logging.h @@ -11,6 +11,8 @@ boolean sdcard_available=false; boolean datalogging=true; String datalogging_filename="UNKNOWN.txt"; +uint16_t chunksize=128; //for bulk data transmission + #define LOGGINGINTERVAL 100 bool serialCommandEcho_Enabled=true; @@ -20,9 +22,11 @@ void loggingLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSerialComm void writeLogComment(unsigned long time, String msg); -void printFileListing(); -void printDirectory(File dir, int numTabs,String parent); +void printFileListing(bool pretty); +void printDirectory(File dir, int numTabs,String parent,bool printSize,bool printFullDirectoryNames); void printFile(String filename); +void printFilesize(String filename); +void transferFile(String filename); void removeFile(String filename); void serialCommandLoop(unsigned long loopmillis, ESCSerialComm& escFront, ESCSerialComm& escRear); float getBatteryVoltage(ESCSerialComm& escFront, ESCSerialComm& escRear); @@ -318,13 +322,29 @@ void serialCommandLoop(unsigned long loopmillis,ESCSerialComm& escFront, ESCSeri if(smessage.equals("test")) { Serial.println("OK"); }else if(smessage.equals("ls")) { - printFileListing(); + printFileListing(false); + }else if(smessage.equals("ls -a")) { + printFileListing(true); }else if(smessage.startsWith("cat")) { String _filename=smessage.substring(4); if (_filename.length()<3){ //if no filename given, use current log file _filename=getLogFilename(); } printFile(_filename); + }else if(smessage.startsWith("get")) { + String _filename=smessage.substring(4); + transferFile(_filename); + }else if(smessage.startsWith("sizeof")) { + String _filename=smessage.substring(7); + printFilesize(_filename); + }else if(smessage.startsWith("chunksize")) { //change chunksize for get command + String _chunksizestring=smessage.substring(10); + long _chunksize=_chunksizestring.toInt(); + if (_chunksize>0 && _chunksize 0) + { + inByte = Serial.read(); + + if ((byte)inByte!=checksum){ + transmiterror=true; //exit + Serial.println(); + Serial.println("TRANSMISSION ERROR WRONG CHECKSUM"); + } + } + } + + } + dataFile.close(); + } + // if the file isn't open, pop up an error: + else { + Serial.print("error opening "); Serial.println(filename); + } + +} + + void removeFile(String filename) { SD.remove(filename.c_str()); diff --git a/logdata_visualization/copyLogsFromBobbycar.py b/logdata_visualization/copyLogsFromBobbycar.py index e5f3531..813ca99 100644 --- a/logdata_visualization/copyLogsFromBobbycar.py +++ b/logdata_visualization/copyLogsFromBobbycar.py @@ -1,8 +1,17 @@ import serial import os +import time +chunksize=4096 -serialport = serial.Serial(port='/dev/ttyACM0', baudrate=115200, timeout=0.1) +#LOG0002 +#32 = 124 kbps +#128 = 263 kbps +#4096 = 416 kbps +#32768 = 427 kbps +#65536 = failed + +serialport = serial.Serial(port='/dev/ttyACM0', baudrate=115200, timeout=1) def establish_connection(): @@ -39,14 +48,38 @@ def get_filenames(): return filenames -def copy_file(source,destination): - os.makedirs(os.path.dirname(writefilename), exist_ok=True) +def get_filesize(filename): + + filesize=0 + + serialport.write(("sizeof "+str(filename)+"\n").encode()) + + response = serialport.readline() + hrresponse=response.rstrip().decode('ascii') + if(len(response))>0: + filesize=int(hrresponse) + return filesize + + +def copy_file(source,destination,expectedsize): + os.makedirs(os.path.dirname(writefilename), exist_ok=True) + + + transferstarttime=time.time() + chunkstarttime=time.time() + last_print=time.time() + with open(writefilename, 'wb') as writer: - serialport.write(("cat "+filename+"\n").encode()) + serialport.write(("chunksize "+str(chunksize)+"\n").encode()) + serialport.write(("get "+filename+"\n").encode()) + + acc_datalen=0 + while True: + ''' response = serialport.readline() hrresponse=response.rstrip().decode('ascii') if(len(response))>0: @@ -55,6 +88,45 @@ def copy_file(source,destination): else: break + ''' + + + data=serialport.read(chunksize) + + if(len(data))>0: #data received + #print("received "+str(len(data))+" bytes") + #hrresponse=data.rstrip().decode('ascii') + #print(hrresponse) + + acc_datalen+=len(data) + + checksum=(sum(data) & 0xFF) + checksumarray=bytearray([checksum]) + + writer.write(data) + serialport.write(checksumarray) #request next chunk by sending checksum of last chunk + + else: + break + + + if (time.time()-last_print>0.5): + last_print=time.time() + chunkduration=time.time()-chunkstarttime + chunkstarttime=time.time() + progress=acc_datalen/expectedsize + print(str(round(progress*100,0))+"% \t"+str(round(chunkduration*1000,3))+" ms for "+str(len(data))+" Byte \t = "+str(round((len(data)/chunkduration)/1000,3))+" kB/s") + + + fileduration=time.time()-transferstarttime + + file_stats=os.stat(writefilename) + print("Finished transfer of "+str(acc_datalen)+" B or "+str(file_stats.st_size)+" (os) Byte in "+str(fileduration)+" s \t = "+str(round(file_stats.st_size/fileduration/1000,3))+" kB/s") + + + return acc_datalen + + def log_off(): @@ -87,10 +159,24 @@ if serialport.isOpen(): #Copy all Files + failed=0 + for filename in filenames: print("Reading file "+filename) + expectedsize=get_filesize(filename) + print("Expecting "+str(expectedsize)+" Byte") + writefilename='sdcard/'+filename - copy_file(filename,writefilename) + receivedsize=copy_file(filename,writefilename,expectedsize) + + if (expectedsize!=receivedsize): + print("Warning: Filesize does not match!") + failed+=1 + + print("") + + print(str(len(filenames))+" Files copied with "+str(failed)+" failed") + #Delete all files @@ -108,4 +194,5 @@ serialport.write("echo on\n".encode()) -serialport.close() \ No newline at end of file +serialport.close() +