Python專案實踐:串列埠字串資料的讀取、分割與儲存到csv檔案
Python專案實踐:串列埠字串資料的讀取、分割與儲存到csv檔案
程式功能
1、從串列埠讀取迴圈讀取如同$4567.0,12.3,12.3#的字串,字串開始符、分隔符、結束符是規定好的
2、將字串分割為如同4567.0、12.3、12.3的浮點型資料
3、將資料儲存到csv檔案中
4、按esc結束執行
執行條件
Python 3.8.2
Python庫:
multiprocessing, csv, serial, os(python自帶)
keyboard 0.13.5
numpy 1.19.2
準備工作與說明
此程式原本開發的目的是將航模機載資料通過數傳(串列埠)傳到電腦上,供後期處理分析。
為了使串列埠除錯方便,可以通過使用arduino或者其他微控制器向串列埠按固定時間間隔輸入資料,來模模擬實數傳環境。如果有其他模擬方式也可,這不是重點。
為了便於終止程式、儲存文件(強制終止可能導致csv檔案損壞),採用雙執行緒的方式同時儲存資料和監聽鍵盤輸入。(才疏學淺,沒有找到python中斷的方法,並且目前瞭解到的鍵盤監聽不是很麻煩就是擴充性不強,因此選用雙執行緒通訊的方法解決退出的問題。)
現在期末烤漆太緊張,有空再回來完善。
程式碼解讀
import 部分
from multiprocessing import Process, Queue
import keyboard, csv, serial, os
import numpy as np
從串列埠讀取資料(函式)
def get_numbers_from_serial(target_com, begin='\r\n', end='$', cut=','):
'''
從串列埠獲得float型別資料列表
如果兩個分隔符cut相鄰或分隔符中間為無效字串(無法轉換為float的字串),在中間位置補-32768
若起始符begin不符則返回空列表
'''
data = target_com.read_until(bytes(end, encoding='utf-8')) #一直讀取直到遇到截止符end
data = data.decode('utf-8','ignore')
#print('gotten:', data)
begin_len=len(begin)
if (data[0:begin_len]!=begin): #檢測begin是否與字串開頭相符
return []
cut_len = len(cut)
pos = begin_len
num_list = []
label = True
while (data[pos:] != end):
num_str = ''
#確認目標位及其後方不為cut和end
while (data[pos:] != end and data[pos:pos+cut_len] != cut):
label = True #至少採集到了一個有效字元
num_str = num_str+data[pos]
pos = pos+1
#根據label和num_str向num_list中賦值
if label:
try:
num_list.append(float(num_str))
except Exception:
num_list.append(-32768) #num_str為無效字串
else:
num_list.append(-32768) #label為負,兩個cut相鄰
if data[pos:] != end:
pos = pos+cut_len
label = False
return num_list
對csv檔案的處理(函式)
def deal_with_csv_file(file_path='save_csv.csv', csv_head=[], mode='new'):
'''
csv檔案預處理
file_path:檔案儲存的路徑
mode兩種模式:
'new'刪除原同名檔案(如果有)並新建檔案
'add'在原檔案後續寫
csv_head是以列表形式給出的csv檔案每列標題,只有在'new'模式才有用
'''
def create_csv(csv_head=[], path='save_csv.csv'):
'''
新建csv檔案
'''
with open(path, 'w', newline='') as f:
csv_write = csv.writer(f)
if csv_head!=[]:
csv_write.writerow(csv_head)
if mode=='new': #新建模式
if os.path.isfile(file_path):
os.remove(file_path)
create_csv(csv_head, file_path)
elif mode=='add': #續寫模式
if os.path.isfile(file_path)==False:
print('原始檔缺失,自動新建')
create_csv(csv_head, file_path)
將串列埠資料讀取並儲存到csv(函式,主程式)
def serial_to_csv(q):
'''
第一程式,從串列埠儲存資料到csv檔案
'''
#初始設定
file_path = 'save_csv.csv' #儲存檔名稱
csv_head = ['速度A', '速度B', '速度C'] #資料含義
mode = 'new' #新建檔案還是在原有檔案上續寫
# mode = 'add'
ser = serial.Serial('COM4', baudrate=115200) #串列埠資訊(名稱,波特率)
ser_msg = ['\r\n$', '#', ','] #串列埠符號規定,若有換行則需在原有開始符前加\r\n
show = True #是否實時展示資料
#csv檔案預處理
deal_with_csv_file(file_path, csv_head, mode)
#開始讀數並儲存
with open(file_path,'a+', newline='') as f:
csv_write = csv.writer(f)
n = 0
while q.empty():
num_list=get_numbers_from_serial(ser, begin=ser_msg[0], end=ser_msg[1], cut=ser_msg[2])
csv_write.writerow(num_list)
if show:
print('\r', num_list, end='')
n = n+1
print('\n總共儲存了', n-1, '個資料')
鍵盤中斷(函式,第二程式)
def key_board_listen(q):
'''
第二程式,鍵盤監聽充當中斷函式
'''
keyboard.wait('esc')
q.put(1)
程式主體
if __name__ == "__main__":
'''
從串列埠儲存資料到csv檔案,具體引數設定在serial_to_csv中。
按下esc停止儲存,程式退出
'''
q = Queue()
p1 = Process(target=serial_to_csv, args=(q,))
p2 = Process(target=key_board_listen, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
全部程式碼
from multiprocessing import Process, Queue
import keyboard, csv, serial, os
import numpy as np
def get_numbers_from_serial(target_com, begin='\r\n', end='$', cut=','):
'''
從串列埠獲得float型別資料列表
如果兩個分隔符cut相鄰或分隔符中間為無效字串(無法轉換為float的字串),在中間位置補-32768
若起始符begin不符則返回空列表
'''
data = target_com.read_until(bytes(end, encoding='utf-8')) #一直讀取直到遇到截止符end
data = data.decode('utf-8','ignore')
#print('gotten:', data)
begin_len=len(begin)
if (data[0:begin_len]!=begin): #檢測begin是否與字串開頭相符
return []
cut_len = len(cut)
pos = begin_len
num_list = []
label = True
while (data[pos:] != end):
num_str = ''
#確認目標位及其後方不為cut和end
while (data[pos:] != end and data[pos:pos+cut_len] != cut):
label = True #至少採集到了一個有效字元
num_str = num_str+data[pos]
pos = pos+1
#根據label和num_str向num_list中賦值
if label:
try:
num_list.append(float(num_str))
except Exception:
num_list.append(-32768) #num_str為無效字串
else:
num_list.append(-32768) #label為負,兩個cut相鄰
if data[pos:] != end:
pos = pos+cut_len
label = False
return num_list
def deal_with_csv_file(file_path='save_csv.csv', csv_head=[], mode='new'):
'''
csv檔案預處理
file_path:檔案儲存的路徑
mode兩種模式:
'new'刪除原同名檔案(如果有)並新建檔案
'add'在原檔案後續寫
csv_head是以列表形式給出的csv檔案每列標題,只有在'new'模式才有用
'''
def create_csv(csv_head=[], path='save_csv.csv'):
'''
新建csv檔案
'''
with open(path, 'w', newline='') as f:
csv_write = csv.writer(f)
if csv_head!=[]:
csv_write.writerow(csv_head)
if mode=='new': #新建模式
if os.path.isfile(file_path):
os.remove(file_path)
create_csv(csv_head, file_path)
elif mode=='add': #續寫模式
if os.path.isfile(file_path)==False:
print('原始檔缺失,自動新建')
create_csv(csv_head, file_path)
def serial_to_csv(q):
'''
第一程式,從串列埠儲存資料到csv檔案
'''
#初始設定
file_path = 'save_csv.csv' #儲存檔名稱
csv_head = ['速度A', '速度B', '速度C'] #資料含義
mode = 'new' #新建檔案還是在原有檔案上續寫
# mode = 'add'
ser = serial.Serial('COM4', baudrate=115200) #串列埠資訊(名稱,波特率)
ser_msg = ['\r\n$', '#', ','] #串列埠符號規定,若有換行則需在原有開始符前加\r\n
show = True #是否實時展示資料
#csv檔案預處理
deal_with_csv_file(file_path, csv_head, mode)
#開始讀數並儲存
with open(file_path,'a+', newline='') as f:
csv_write = csv.writer(f)
n = 0
while q.empty():
num_list=get_numbers_from_serial(ser, begin=ser_msg[0], end=ser_msg[1], cut=ser_msg[2])
csv_write.writerow(num_list)
if show:
print('\r', num_list, end='')
n = n+1
print('\n總共儲存了', n-1, '個資料')
def key_board_listen(q):
'''
第二程式,鍵盤監聽充當中斷函式
'''
keyboard.wait('esc')
q.put(1)
if __name__ == "__main__":
'''
從串列埠儲存資料到csv檔案,具體引數設定在serial_to_csv中。
按下esc停止儲存,程式退出
'''
q = Queue()
p1 = Process(target=serial_to_csv, args=(q,))
p2 = Process(target=key_board_listen, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
幫助、參考資料(文章)
程式間通訊(multiprocessing庫):
程式間的通訊:multiprocessing庫下的Pipe類與Queue類
python多程式的理解 multiprocessing Process join run
【python】詳解multiprocessing多程式-process模組(一)
鍵盤監聽:
python串列埠的使用:
Python 之 Serial串列埠通訊 (可能不全)
csv檔案操作:
os庫的使用(系統檔案操作):
相關文章
- python讀取串列埠 資料Python串列埠
- Pandas之EXCEL資料讀取/儲存/檔案分割/檔案合併Excel
- python 使用字典讀取CSV檔案Python
- golang讀取檔案的json資料流,並解析到struct,儲存到資料庫GolangJSONStruct資料庫
- gin框架,讀取檔案的json資料流,並解析到struct,儲存到資料庫框架JSONStruct資料庫
- csv檔案的寫入和讀取
- Python中檔案讀取與儲存程式碼示例Python
- Go Web:資料儲存(2)——CSV檔案GoWeb
- CSV檔案儲存
- CSV檔案讀取效能大決戰:Julia 、Python與R語言 - DeepakPythonR語言
- Python 高階程式設計:深入解析 CSV 檔案讀取Python程式設計
- Jmeter之讀取csv檔案踩坑記JMeter
- R語言 - 讀取CSV檔案報錯R語言
- 讀取資料夾檔案
- Springboot整合MongoDB儲存檔案、讀取檔案Spring BootMongoDB
- rust 截圖儲存到檔案Rust
- PHP匯出大量資料,儲存為CSV檔案PHP
- python爬取貓眼電影top100儲存到CSVPython
- python生成CSV檔案Python
- python 讀取文字檔案Python
- python小白檔案讀取Python
- python讀取大檔案Python
- 使用yaml檔案讀取資料YAML
- python讀取兩個excel資料檔案輸出整理好以後的excel資料檔案PythonExcel
- 讀取CSV資料
- python中按照資料夾中檔案的排列順序讀取檔案內容Python
- Golang專案中讀取配置檔案Golang
- (Python基礎教程之十二)Python讀寫CSV檔案Python
- 說說在 Python 中,如何讀取檔案中的資料Python
- shell讀取構建檔案資訊生成json字串JSON字串
- 如何讀取HDFS上的csv/tsv檔案的Timestamp列 - Qiita
- python 寫入CSV檔案Python
- Python實用方法之讀取本地檔案Python
- pandas讀取csv檔案資料並使用matplotlib畫折線圖和餅圖
- 教你一招!Python讀取檔案內容為字串的方法Python字串
- python如何讀取大檔案Python
- ServiceNow如何匯出豎線分割的CSV檔案?
- QT串列埠助手(五):檔案操作QT串列埠