顯示具有 Arduino&樹莓蟒專區 標籤的文章。 顯示所有文章
顯示具有 Arduino&樹莓蟒專區 標籤的文章。 顯示所有文章

2021年3月8日 星期一

[Python]字串切割存入list再透過socket傳送至server端

首先先加強對Python socket的了解

Reference : https://ithelp.ithome.com.tw/articles/10205819 

socket.accept //server等待client端的連線 accept代表socket 採用阻塞式訪問


位類別名稱宣告解釋內容
familysocket.AF_UNIX於本機端進行串接
socket.AF_INET於伺服器與伺服器之間進行串接
socket.AF_INET6使用IPv6於伺服器與伺服器之間進行串接
typesocket.SOCK_STREAM使用TCP(資料流)的方式提供可靠、雙向、串流的通信頻道
socket.SOCK_DGRAM使用UDP()的方式通用的免連線訊息交換通道

Reference : https://www.itread01.com/content/1541825839.html


socket物件方法
函式 型別 描述
s.bind() 服務端用 繫結地址和埠到套接字,引數address為元組形式的(host, port)
s.listen() 服務端用 開始監聽繫結的地址埠程式(程序),引數backlog指定在拒絕連線之前,可以掛起的最大連線數量。
s.accept() 服務端用 等待客戶端的連線(阻塞式)。
s.connect() 客戶端用 主動去連線伺服器,引數address為元組形式的(host, port),如果連接出錯,返回socket.error錯誤。
s.connect_ex() 客戶端用 主動去連線伺服器,引數address為元組形式的(host, port),出錯時返回出錯碼,而不是丟擲異常。
s.recv() 公共使用 接收資料,返回位元組型字串資料,引數bufsize指定接收資料的最大長度。
s.send() 公共使用 傳送資料,返回傳送成功的位元組數,引數data是要傳送的位元組型字串資料。
s.sendall() 公共使用 完整發送資料。內部迴圈呼叫send直至資料傳送完整,引數data是要傳送的位元組型字串資料。
s.recvfrom() 公共使用 接收資料,返回值是(data, address)。data是包含接收資料的字串,address是傳送資料的套接字地址。
s.sendto() 公共使用 傳送資料,將資料傳送到套接字,address形式為(host, port)的元組,指定遠端地址。返回值是傳送位元組數。
s.close() 公共使用 關閉套接字
s.getpeername() 公共使用 返回連線套接字的遠端地址。返回值通常是元組(host, port)。
s.getsockname() 公共使用 返回套接字自己的地址。通常是一個元組(host, port)。
s.setsockopt() 公共使用 設定給定套接字選項的值。
s.getsockopt() 公共使用 返回套接字選項的值。
s.settimeout() 公共使用 設定套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。
s.gettimeout() 公共使用 返回當前超時期的值,單位是秒,如果沒有設定超時期,則返回None。
s.fileno() 公共使用 接收資料,返回位元組型字串資料,引數bufsize指定接收資料的最大長度。
s.setblocking() 公共使用 flag為0非阻塞,否則為阻塞模式(預設)。非阻塞模式調recv()或send()沒有資料,將引起socket.error異常。
s.makefile() 公共使用 建立一個與該套接字相關連的檔案。


Reference : https://www.itread01.com/content/1549100881.html

def convertRaw_and_SplitToSave(split_size):
print("[Func]splitDataAndSave")
with open(r'c:\test.jpg', 'rb') as f:
res = base64.b64encode(f.read())
print("len = " + str(len(str(res))) + " Context : " + str(res))
globals.tmp_array = re.findall('.{' + str(split_size) + '}', str(res))
globals.tmp_array.append(str(res)[(len(globals.tmp_array) * split_size):])
globals.tmp_array[0] = str(globals.tmp_array[0]).strip('b\'')
#找尋最後一筆 把'過濾掉回存 先取得長度 將陣列長度減1 strip(''') 然後回存
print("end print " + str(globals.tmp_array[0]))
另外,在轉塗作字串切割時 會有b'的特殊符號出現,必須去除
在此,參考這篇【python】去除字符串头尾的多余符号
 https://blog.csdn.net/u014636245/article/details/103120201
使用.strip('b\'')去除掉 加鞋線是因為跳脫字元'
此外針對影像串流部分:
Reference : https://www.jianshu.com/p/931cd24450ec
上傳串流部分
result, imgencode = cv2.imencode('.jpg', frame, encode_param)
        data = numpy.array(imgencode)
        stringData = data.tobytes()

        stringDataLen = str(len(stringData)).ljust(16)
        print("stringDataLength = " + stringDataLen)
        client.send(stringDataLen.encode())
        print("stringDataLen = " + stringDataLen + " Context : " + str(stringData))
        print(stringData)
        data_perform = [b'']
        data_perform = re.findall(b"[\s\S]{500}", stringData)  # 就是这里需要做小小的改造,看仔细哦
        data_perform.append(stringData[(len(data_perform) * 500):])
        #globals.tmp_array = re.findall('.{' + str(split_size) + '}', str(stringData))
        #globals.tmp_array.append(str(stringData)[(len(globals.tmp_array) * split_size):])
        print(data_perform)
        print(len(data_perform))

        for i in range(len(data_perform)):
            print(" data_perform array len = " + str(len(data_perform)) + " ,prepare to send [" + str(i) + "]:" + str(data_perform[i]))
            client.send(data_perform[i]);

        ret, frame = capture.read()# 以幀為單位獲取影象
        decimg = cv2.imdecode(data, 1)
        cv2.imshow('CLIENT', decimg)
        key = cv2.waitKey(20)

        if key == 113:  # 按q拍照, 比照ASCII碼
            cv2.imwrite("fangjian2.jpeg", frame)  # 拍照存檔檔名
            continue
        if key == 27:  # 按esc停止, 比照ASCII碼
            break
    client.close()
    cv2.destroyAllWindows()
接收串流部分
def recvall(sock, count):
    buf = b''
    while count:
        newbuf = sock.recv(count)
        if not newbuf: return None
        buf += newbuf
        count -= len(newbuf)
    return buf

length = recvall(conn, 16)
            print(length)
            stringData = recvall(conn, int(length))
            data = numpy.fromstring(stringData, dtype='uint8')
            decimg = cv2.imdecode(data, 1)
            cv2.imshow('SERVER', decimg)
            cv2.waitKey(30)
            time.sleep(1)

2021年2月28日 星期日

[Python]Python執行緒thread

 Reference : https://blog.gtwang.org/programming/python-threading-multithreaded-programming-tutorial/

首先須import

import threading

threads = []

宣告空陣列並命名為threads作為thread管理與存放專用


def thread_init():

        threads.append(threading.Thread(target=do_task))

        threads.append(threading.Thread(target=ser_mod.ser_read))

        threads[0].start()

        threads[1].start()

宣告一執行緒函式 並指定對應的工作(通常為while等需長期背景執行的工作) 先增完後並將之append到宣告的thread陣列中

在thread_init中宣告兩個執行緒工作


指定並使用start啟動執行緒工作

2021年2月26日 星期五

[Python]全域變數的宣告與使用

 最近開發python程式

為了在兩個pyhton檔間控制thread因此用了flag

但發現從另一個檔案改變了flag為True後  原本檔案內的flag 印出還是False


找了網路上的這個方案,試試有效便分享之 : https://sam66.medium.com/python-%E6%80%8E%E9%BA%BC%E5%9C%A8%E5%85%A9%E5%80%8B%E6%AA%94%E6%A1%88%E4%B9%8B%E9%96%93%E5%88%86%E4%BA%AB%E5%85%A8%E5%9F%9F%E8%AE%8A%E6%95%B8-8fced72f3550



globals.py內宣告

def initialize():

 global at_module_ready

 at_module_ready = False


main.py在__name__宣告

if __name__ == '__main__':

    globals.initialize()

    print(globals.at_module_ready)  # print the initial value

    main()


接著在需要使用到global變數的地方import globals

如此就可以改變與正確共享全域變數的值




2020年8月26日 星期三

[Python]Django網頁框架應用實作

python -m pip install -U virtualenvwrapper-win  //python虛擬環境
python -m pip install -U django //安裝djan模組函式庫
python -m django --version //查看django版本


mkdir django_test   建立測試資料夾

cd django_test    切換進入測試目錄

django-admin startproject my_site //使用django-admin工具建立新站點 my_site

cd my_site   //切換進入my_site

python manage.py runserver //使用manage.py的runserver 進行django網頁部屬


python manage.py startapp catalog //建置





2020年4月6日 星期一

[Python]Python UI - tkinter

Ref : Python tkinter GUI 基本用法



from tkinter import *

root = Tk()
app = Frame(root)
hello = Label(root, text="Hello Tk!", width="30", height="5")
hello.pack()
root.mainloop() //保持視窗 不關閉

2020年3月15日 星期日

[Python] 機器&深度學習重點節錄

Ch1認識人工智慧

手寫
語音
電腦視覺
專家系統
自然語言處理
電腦遊戲
智慧機器人

機器學習處理常見 分類問題 & 回歸問題
分類 : 垃圾郵件
回歸 : 預測銷售

機器學習實務上解決五種問題 :
1.分類 : 二元分類、多元分類
2.異常值判斷 : 偵測異常情況
3.預測性分析 : 迴歸
4.分群 : 找到相似度並分析
5.協助決策 : 決定下一步 ex. Alpha Go.

機器學習種類
1.監督式學習  需要給標準答案
分類 : 是非題與分級
迴歸 : 預測
2.非監督是學習 : 分群。
3.半監督式學習 : 透過少量的有標籤資料增加分群正確度。
4.強化學習 : 無明確答案,需要依據資訊改變策略。

===============================================================
Ch2 建構TensorFlow與Keras開發環境

1.python -m pip install -U tensorflow
2.python -m pip install -U keras
3.python -m pip install --upgrade numpy

IDE選擇
Spyder / Jupyter Notebook
運行環境  nVIDIA GTX 1060 6GB顯卡 / Google Colaboratory雲端服務

Google Colaboratory => 到google drive新增 更多裏面去新增應用程式服務
開啟GPU設定 Runtime -> change runtime type



















選擇GPU















使用colaboratory 掛載 google drive外部檔案 [Ref : Google Drive 檔案存取教學]
from google.colab import drive
drive.mount("/content/drive")











透過授權允許存取google drive底下的其他檔案 如.csv等等
接著透過anaconda prompt部屬keras虛擬環境
conda create --name keras anaconda

conda env remove --name keras //刪除環境

conda env list //檢查目前anaconda環境
activate keras //啟動keras













最後使用命令conda list可以瀏覽安裝清單
==================================================================
Ch3深度學習理論基礎

人工智慧包含 機器學習 包含深度學習 => 故 深度學習是機器學習的子集合

http://playground.tensorflow.org/


圖形結構 有包含頂點與邊線 其中又依照邊線有無方向性分為無方向性圖形與方向性圖形

若路徑有數值則為加權圖形,此外有方向性可行程迴圈稱為方向性循環圖 沒有迴圈則為方向性非循環圖

微分與偏微分
 輸入(樹突) =>細胞核(神經元)=> 輸出(軸突)

人工神經元透過 判斷 輸入*權重 加總是否大於閥值來決定是否輸出為1或0
>= 閥值 => 輸出1;反之 輸出0

ANNs 類神經網路 一種泛稱其中包含 多層感知器MLP、卷積神經網路CNN、循環神經網路RNN

多層感知器(Multilayer Perceptron, MLP) : http://playground.tensorflow.org/就是典型的MLP也稱為前饋神經網路(Feedforward Neural Network, FNN) 是單向多層的傳統類神經網路
輸入資料->輸入層->隱藏層->...->隱藏層->輸出層->輸出資料
多層感知器是神經網路,若隱藏層超過一層(四層的神經網路稱為深度學習)

卷積神經網路(Convolutional Neural Network, CNN) : 專門處理影像辨識 如 分類圖片、人臉與手寫辨識等的模擬人腦視覺處理區的神經網路,也是前饋神經網路的一種,但層次上不同
輸入資料->輸入層->卷積層->池化層->...卷積層->池化層->全連接層->輸出層->輸出資料

循環神經網路(Recurrent Neural Network, RNN) : 具有短期記憶 處理聲音語言與影片等序列資料的神經網路,實務上被改良的LSTM與GRU取代
輸入資料->輸入層->隱藏層->循環隱藏->輸出層->輸出資料

張量 維度數 = 軸數 = 等級(Rank)
0D 純量值
1D一維陣列
2D二維陣列
3D三個維度的三維陣列 or  一維的矩陣陣列  加上時間間距特性
4D 四維陣列 真實特徵資料圖片   圖片集等 就是用4D

import numpy as np

x = np.ndim() //取得軸數
x = np.shap() //取得形狀
+ - * / 直接使用
b= a.dot(s) 點積運算

============================================================
Ch4多層感知器

線性可分割與線性不可分割問題須理解

神經元又稱感知器
回歸問題使用一個神經元
二元分類問題 使用一個或兩個神經元
多元分類問題 看幾類是幾個 => 數字0~9 是10個

層數與神經元數量建議
隱藏層神經元數量為輸入層到輸出層之間
神經元數量是 輸入層2/3 加上輸出層的數量
隱藏層的神經元數量少於兩倍輸入層的神經元數量

監督學習有真實目標值(標準答案)又稱標籤,可以透過差異(損失分數)去調整權重來達到越來越準確的優化

神經網路訓練迴圈分為正向傳播 評估損失 反向傳播
正向傳播 : 計算預測值
評估損失 : 真實目標比較 算出損失
反向傳播 : 計算每一層的錯誤比例,用梯度下降法更新權重‧優化器使用反向傳播計算每一層權重需要分擔損失的梯度

sigmoid會有函數微分只有1/4 若神經網路反向傳播即多個1/4相乘 將會趨近於0造成梯度消失

(傳不到頭)

避免梯度消失問題可以使用ReLU 即輸入小於0時輸出為0;大於0則為線性函數

迴歸問題使用均方誤差
分類問題使用交叉鏑

樣本資料集(100%中,其中訓練資料集(70%)、驗證資料集(20%)、測試資料集(10%)


==================================================================
Ch5 打造多層感知器神經網路

Keras深度學習模型其中分為
Sequential與Functional API
Sequential為線性堆疊結構 單一輸入單一輸出
Functional API若為多輸入多輸出 或共享神經層需使用之  此外Sequential是為一特殊型

model = Sequential()
model.add 增加隱藏層
編譯模型分類
輸入啟動函數       輸出啟動函數
sigmoid                  二元分類
softmax               單標籤多元分類
sigmoid               多標籤多元分類
不需要                     迴歸分析
sigmoid                回歸值在0~1間


啟動器 Initializers    https://keras.io/initializers/
zeros              //全部初始為0
ones               //全部初始為1
???_normal   //常態分布
???_uniform //均勻分布

優化器 optimizer    https://keras.io/optimizers/
sgd(隨機梯度下降法)
adm
rmsprop     //循環神經網路的最佳選擇之一

線性迴歸
/ = 正值
\ = 負值
簡單線性迴歸 y = a + b *x
多元線性迴歸 y = a + b1*x1 + b2*x2+ ... + bk*xk

迴歸問題神經網路
波士頓房屋資料集
df = pd.read_csv("./boston...")
df.head()
df.shap()

迴歸分析的神經網路

MSE(Mean Square Error)均方誤差
MAE(Mean Absolute Error)

========================================================
5-5儲存與載入神經網路模型

json_str = model.to_json() //轉換成json結構並儲存到json_str變數中
with open("xxx.config") as text_file:
      text_file.write(json_str) //寫入至xxx.config檔案中

model.save_weights("xxx.weight") //儲存權重
model.save("xxx.h5") //儲存模型結構與權重

======
分開載入結構與權重
with open("xxx.config","r") as text_file:
       json_str = text_file.read()
mode = model_from_json(json_str)

同時載入結構與權重
model = read_model("xxx.h5")
model.compile(loss="...", optimizer="...", metrics=["accuracy"])


========================================================
Ch6多層感知器的實作案例



2020年3月12日 星期四

[Python] 網路爬蟲學習重點節錄

Reference : 
1.https://www.url-encode-decode.com/
2.https://httpbin.org/
3.SelectorGadget : https://chrome.google.com/webstore/detail/selectorgadget/mhjhnkcfbdhnjickkkdbjoemdmbfginb?hl=zh-TW
4.XPath Helper : https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=zh-TW

選擇用書Python網路爬蟲與資料視覺化應用實務(旗標出版社)
Request

import requests

requests.get參數
r = requests.get(url , timeout=0.3) //設定time out
r = requests.get(url, cookies={"over18": "1"}) 透過cookies儲存超過18歲 來通過訪問ptt
nextPg = response.xpath(xpath)
url = "http://www.google.com"
timeout = 0.3
'maxResult' : 5,
headers=url_headers


例外處理 :
RequestException 請求錯誤
HTTPError 不合法回應
ConnectionError 連線錯誤
Timeout 逾時
TooManyRedirects 超過轉址值



bs4(BeautifulSoup) + request混合使用


from bs4 import BeautifulSoup
import requests

r = requests.get("http://www.google.com")
soup = BeautifulSoup(r.text, "lxml")
print(soup)

若soup要寫入檔案必須格式化 需要呼叫
prettify()
範例 :
fp = open ("xxx.txt", "w", encoding="utf8")
fp.write(soup.prettify())
print("writting")
fp.close()

============================================================
find()

find() 尋找單一條件
find_all()遍尋整個HTML網頁

find_all()加入限制條件 = >
soup.find_all("tag", class_name="class_name", limit=limit_num )
(tag, id, limit=)

============================================================
Ch4
Select()

BeautifulSoup使用select與select_one
select() 是清單式列出條件符合結果
select_one()是只列一個
css selector使用nth-of-type因此"nth-" 須改寫成=>nth-of-type
如tag.select("div:nth-of-type(3)")

============================================================
Ch5
遍歷祖先兄弟子孫

tag.content與tag.children 都可以取得子標籤
並透過for chile in tag.descendants 取得之下的所有子孫標籤
for tag in tag_ui chile //for子孫標籤
for tag in tag_ui.parent //for祖先標籤

next_sibling 兄弟標籤走訪
previous_sibling


find_previous_sibling() //找上一個兄弟(此函數會自動跳過NavigableString物件)
find_next_sibling() //找下一個兄弟(此函數會自動跳過NavigableString物件)

走訪上下元素
next_element //下一個元素
previous_elements //上一個元素
用法
next_tag = tag.next_element
print(type(next_tag), next_tag.name)

===========================================================
修改
修改僅修改python物件樹並不會修改網頁原始碼
tag.string = "str_value" //修改
del tag["tag_element"] //刪除
new_tag = tag.new_tag("tag's context")  //新增1
tag.append(new_tag) //新增2
insert_before  //插入在xxx之前
insert_after  //插入在xxx之後

Ch5-4 CSV & Json存取
寫入CSV
with open (csv_file, 'w+', newline="")as fp:
writer = csv.writer(fp)
writer =.writerow(["Data1","Data2","Data3"]) //建立Excel檔Data1~Data3的欄位頭

Json
j_str = json.dump(json_data)  //json_data字典轉j_str資料字串
json_data2 = json.loads(j_str) //j_str資料字串轉json_data2字典

j_file = "jfile.json"
with open(j_file, 'r') as fp:  //讀取j_file
json.dump(data, fp) 讀data寫入至fp

Ch5-5載圖
response = request.get(url, stream=True)
with open (path, 'wb') as fp:
  for chunk in response:
     fp.write(chunk)

或用urllib.request.urlopen(url)   開啟下載   //較有效率考量

===========================================================
Ch6 XPath 與 lxml 應用
from lxml import html


找到tag中的資源網址後點三個點點左鍵 copy... XPath 如下圖:










tag_img = tree.xpath("/html/body/section[2]/table/tbody/tr[21]/td[1]/a/img")[0]
print(tag_img.attrib["src"])

=>https://www.flag.com.tw/assets/img/bookpic/F4473.jpg

6-4XPath 基本語法 軸::節點測試[謂詞]
* : 萬用字元,表所有符合元素和屬性節點
軸 : 開始點 (軸定義請詳閱)
節點測試 : 此軸符合的節點有哪些
謂詞Predicates : 進一步過濾條件
以書中範例/child::library/child::book[2]/child::author
/child::library 代表根後子節點為library
/child::book[2] 子節點為book的第二筆
/child::author 子節點為author

XPath Helper點選 按住shift 把想查詢的地方選取 即可完成




















====================================================================
Ch7 Selenium

安裝selenium    python -m pip install -U selenium

並安裝chrome driver : https://sites.google.com/a/chromium.org/chromedriver/downloads

from selenium import webdriver //import webdriver

driver = webdriver.Chrome("./chromedriver")

driver.get(url)
tag = driver.fine_element_by_tag_name("tag")
soup = BeautifulSoup(driver.page_source, "lxml")

find_element_by_id()
find_element_by_name()
find_element_by_xpath()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_tag_name()
find_element_by_class_name()
find_element_by_css_selector()

執行google搜尋
keyword = driver.find_element_by_css_selector("#lst-ib")
keyword.send_keys("search term")
keyword.send_keys(keys.ENTER);

Keys 按鍵常數清單
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/Keys.html


Selenium Action Chains 產生一系列網頁自動操作
click()  //點選元素
click_and_hold() //按住左鍵
context_click() //按住右鍵
double_click() //按兩下元素
move_to_element() //移到元素中間
key_up() //放開某鍵
key_down() //按下某鍵
perform() //執行所有儲存動作
semd_keys()  //送出按鍵至目前的元素
release() //鬆開滑鼠按鍵

act = ActionChains(driver)
act.move_to_element(ele)
act.click(eee)
act.perform()

===============================================================
Ch8

Anaconda3/Anaconda Prompt執行conda install -c conda-forge scrapy

===============================================================
Ch9

爬蟲程式的選擇
爬取數頁網頁 => BeautifulSoup
動態網頁爬取 => Selenium
整個Web網站的大量資料 => Scrapy框架

9-1透過urljoin搭配.format來對網址序列化
例如 :
catalog = ["2317", "3018", "2308"]
for i in catalog
url = urljoin("https://tw.stock.yahoo.com/q/q?s={0}".format(i)
print(url)

===============================================================
Ch10
SQL語句
SELECT * FROM
WHERE 條件 LIKE 其中LIKE有包含的意思  %a% 包含a的字串

import pymysql
db = pymysql.connect("localhost", "root", "", "mybooks", charset="utf8")
cursor = db.cursor() //取出
cursor.execute("SELECT * FROM books") //取出

sql = """INSERT abc (......)VALUES(......)""" //存入
try:
cursor.execute(sql)//執行
db.commit()//確定送出

2020年3月11日 星期三

[Python] Anaconda 環境設定之章

安裝完anaconda後,在安裝套件時出現ssl error但是import ssl是有效的
找到網路上這篇 : https://blog.csdn.net/sudakuang/article/details/88668049

若要將Anaconda設定環境變數使cmd可以呼叫python安裝套件
必須新增


C:\ProgramData\Anaconda3; 
C:\ProgramData\Anaconda3\Scripts; 
C:\ProgramData\Anaconda3\Library\bin 


經調試後 已正常

2017年8月21日 星期一

[Python] Python OpenCV 視訊應用與比圖運算

#https://stackoverflow.com/questions/33650974/opencv-python-read-specific-frame-using-videocapture?newreg=2495db9d80934aa3b199f6d8d7489f89
#opencv for python3 => http://www.lfd.uci.edu/~gohlke/pythonlibs/
#video guide : https://www.youtube.com/watch?v=ulJdZn0qBCQ
 

2021/3/29 更新 : python打印raw date : b'.............' 一個jpeg開始於\xff\xd8\xff\


2021/03/10 更新 : python3.8 在pycharm程式中 可以在File -> Setting -> Python Interpreter安裝
透過找尋opencv-python
或用 pip install opencv-python
確保python目錄下有cv2.cp38-win_amd64 重開pycharm即可使用

2021/03/11 更新
若安裝完opencv-python還是出現問題 如 :
https://blog.csdn.net/qq_37369201/article/details/108936470
使用系統管理者身分執行cmd : python -m pip -U opencv-contrib-python

Python OpenCV應用總整理
https://jennaweng0621.pixnet.net/blog/post/403630133-%5bpython%5d-opencv%E6%87%89%E7%94%A8%E7%B8%BD%E6%95%B4%E7%90%86

超完整版程式開始

import matplotlib
import numpy as np
import cv2
import imutils //https://stackoverflow.com/questions/29645278/webcam-open-cv-python-black-screen

cv2.namedWindow("preview") #設定視訊框的名稱
#此層放置了可讓 cv2.VideoCapture的視訊源範例
capture= cv2.VideoCapture(0) #新增一個視訊擷取物件為vc
#capture= cv2.VideoCapture('my_video.avi') #改寫成這樣就是放影片
#capture= cv2.VideoCapture("rtsp://user:password@192.168.2.0/h264") #改寫成這樣就是放串流
#reference :https://www.wongwonggoods.com/python/python-opencv-rtsp/
#此層放置了可讓 cv2.VideoCapture的視訊源範例


#capture.set(3,640) //3 = 寬 https://stackoverflow.com/questions/29645278/webcam-open-cv-python-black-screen
#capture.set(4,480) //4 = 高 https://stackoverflow.com/questions/29645278/webcam-open-cv-python-black-screen
#以上或可寫成: 
#capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
#capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
width = capture.get(cv2.CAP_PROP_FRAME_WIDTH) #取得訊框寬
height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT) #取得訊框高
print("Image Size: %d x %d" % (width, height)) #印出訊框寬高


# 若要儲存視訊可用
sz = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
#fourcc = cv2.VideoWriter_fourcc(*'mpeg')
#fps=25
#out = cv2.VideoWriter('./videoCapture/output2.avi', fourcc,fps,sz)
# 若要儲存視訊可用


# 取得 Codec 名稱
fourcc = capture.get(cv2.CAP_PROP_FOURCC)
fourcc = int(fourcc)
codec = "".join([chr((fourcc >> 8 * i) & 0xFF) for i in range(4)])
print("Codec: " + codec)
# 取得 Codec 名稱

if capture.isOpened():  #嘗試打開capture物件並取得偵
    rval, frame = capture.read() #讀取偵並返回其布林直確定可以讀取
else:
    rval = False

while rval: #假設可以打開  也可使用capture.isOpened()來判斷
    
    # 若要儲存視訊可用
    #out.write(frame) # 開始儲存視訊
    # 若要儲存視訊可用


    cv2.imshow("preview", frame) #將cv2視訊框裡投放 capture物件讀取的frame訊框
    
    #設定成灰階
    #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    #cv2.imshow('frame', gray)
    #設定成灰階

    rval, frame = vc.read() # 一幀一幀的獲取影象 while 持續讀取
   #frame = imutils.resize(frame, width=400) //https://stackoverflow.com/questions/29645278/webcam-open-cv-python-black-screen
    key = cv2.waitKey(20)
    if key == 113: # 按q拍照, 比照ASCII碼
        cv2.imwrite("fangjian2.jpeg", frame) #拍照存檔檔名
        break
    if key == 27: # 按esc停止, 比照ASCII碼
        break
capture.release()
cv2.destroyAllWindows() #強制摧毀所有頁框
cv2.destroyWindow("preview") #摧毀名為preview的視訊框


#While可以存在更多的功能鍵,只要比對ASCII碼即可‧



Python - OpenCV 播放影片
https://ricky10116.pixnet.net/blog/post/265683920-python---opencv-%E6%92%AD%E6%94%BE%E5%BD%B1%E7%89%87
import cv2
import time 
# 開啟影片檔案
cap = cv2.VideoCapture('C:\\Users\\Ricky\\Desktop\\Jurassic Park Trailer.webm')

# 以迴圈從影片檔案讀取影格,並顯示出來
while(cap.isOpened()):
  ret, frame = cap.read()
  #time.sleep(0.05) 
  cv2.imshow('frame',frame)
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break

cap.release()
cv2.destroyAllWindows()


opencv-python啟用攝像頭錄影
https://www.itread01.com/content/1547376124.html
import cv2

cap = cv2.VideoCapture(0)
cap.set(3,320)#寬
cap.set(4,240)#高
sz = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
       int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# 為儲存視訊做準備
fourcc = cv2.VideoWriter_fourcc(*'mpeg')
fps=25
out = cv2.VideoWriter('./videoCapture/output2.avi', fourcc,fps,sz)
while True:
    # 一幀一幀的獲取影象
    ret,frame = cap.read()
    if ret == True:
        frame = cv2.flip(frame, 1)
        # 在幀上進行操作
        # gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        # 開始儲存視訊
        out.write(frame)
        # 顯示結果幀
        cv2.imshow("frame", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
# 釋放攝像頭資源
cap.release()
out.release()
cv2.destroyAllWindows()

2017年8月8日 星期二

[Python] Python 網路爬蟲與資料分析 應用BeautiSoup



import urllib
from urllib import request
from bs4 import BeautifulSoup

x = urllib.request.urlopen('https://www.google.com');
print(x.read()); #呈現請求後的結果…出現一堆看不懂的資料

try:
url = 'https://www.google.com.tw/search?q=python';
#url = 'https://www.google.com.tw/#q=python'; #雖然在google網址上看到搜尋時是這個方式,但是實際操作起來是不成功的 headers = {};
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.27 Safari/537.17';
#headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0'; req = urllib.request.Request(url, headers=headers);
resp = urllib.request.urlopen(req);
respData = str(resp.read().decode('utf-8')); #將所得的資料解碼 saveFile = open('withHeaders.txt','w', encoding='utf8');
saveFile.write(str(respData));
saveFile.close();
except Exception as e:
print(str(e));

2017年8月7日 星期一

[Python] Python資料分析與儲存 - 使用xlsxwriter模組

程式碼參考 :
https://github.com/kunhsien/PyExample/tree/master/PyXlsxWriter

範例的程式進入點 main 位於Battery_analysis.py

def main():
    sendThr = threading.Thread(target=parse_value)
    sendThr.start()

if __name__ == '__main__':
    main()

我們用了threading的模組 去重複執行parse_value


def parse_value():
 index_Volt = 6
 index_Cap = 2
 indwx_Temp = 10
    for i in range(1000):
        message = "[battery_check]BATT cap 99 cap_count 0 vol 3981000 vol_count 0 temp 229 temp_count 0 batt_no_count 0 \r\n'"
        s_toke = message
        s_token = re.split(' ', s_toke)
        print(str(s_token))
        Volt_value = s_token[index_Volt]
        Cap_value = s_token[index_Cap]
        Temp_value = s_token[indwx_Temp]
        print("[Battery_analysis] - Volt_value: " + str(Volt_value) + ", Cap_value: " + str(Cap_value) + ", Temp_value: " + str(Temp_value) +"\n")
        for key in range(0,15):
            xls_report.VOLTAGE_QUEUE[key].append(Volt_value)
            xls_report.CAPACITY_QUEUE[key].append(Cap_value)
            xls_report.TEMPERTURE_QUEUE[key].append(Temp_value)
    for key_print in range(0, 15):
        print("KEY" + str(key_print) +" temperture : " + str(xls_report.TEMPERTURE_QUEUE[key_print]) + ".\n")
        print("KEY" + str(key_print) + " capacity : " + str(xls_report.CAPACITY_QUEUE[key_print]) + ".\n")
        print("KEY" + str(key_print) + " voltage : " + str(xls_report.VOLTAGE_QUEUE[key_print]) + ".\n")
    xls_report.battery_queue_finish = True
    xls_report.write_to_excel()


在parse_value中我們使用for迴圈對15個key component塞了三個資料 電壓 溫度 容量
塞進去queue之後 我們塞了一個flag 告訴系統 我們完成塞queue的動作了
最後執行write_to_excel函式

def write_to_excel():
    #if (battery_queue_finish == True):
        WORKBOOK = xlsxwriter.Workbook("Battery_values.xlsx") # 新增excel檔案
        sheet_Capacity = WORKBOOK.add_worksheet("Capacity") #新增表單 命名Capacity
        sheet_Voltage = WORKBOOK.add_worksheet("Voltage") #新增表單 命名Voltage
        sheet_Temperture = WORKBOOK.add_worksheet("Temperture") #新增表單 命名Temperture
        for index_num in range(len(Title_ADDR)):
            sheet_Capacity.write(Title_ADDR[index_num], "Key" + str(index_num))
            sheet_Voltage.write(Title_ADDR[index_num], "Key" + str(index_num))
            sheet_Temperture.write(Title_ADDR[index_num], "Key" + str(index_num))
        print("[Xls_report] - Write_to_excel: Sheet -  \n")
        for key_index in range(0,15):
            print("Saving Battery information for Key(" +str(key_index)+")...\n")
            for TempQ_index in range(len(TEMPERTURE_QUEUE[key_index])):
                TempAddr = GetAndIncrease_Addr(key_index, 'Temperture')
                print(str(TempAddr))
                sheet_Temperture.write(TempAddr, TEMPERTURE_QUEUE[key_index][TempQ_index])
            for CapaQ_index in range(len(CAPACITY_QUEUE[key_index])):
                CapaAddr = GetAndIncrease_Addr(key_index, 'Capacity')
                sheet_Capacity.write(CapaAddr, CAPACITY_QUEUE[key_index][CapaQ_index])
            for VoltQ_index in range(len(VOLTAGE_QUEUE[key_index])):
                VoltAddr = GetAndIncrease_Addr(key_index, 'Voltage') #傳入key值回傳該key於該sheet的現在寫入位址並將位址地增加1
                sheet_Voltage.write(VoltAddr, VOLTAGE_QUEUE[key_index][VoltQ_index])
#寫入該值 到該key的該位址
        print("Excel file write end.\n")
    #else:
        #pass

write_to_excel()函式就是xlsxwriter的使用技巧,其中會呼叫自創函式GetAndIncrease_Addr 定義如下:

#這個函式就不多解釋了,純粹字串跟list的轉換跟應用
def GetAndIncrease_Addr(key, sheet_name):
    str_ADDR = ''
    NOW_ADDR = ''
    NEW_ADDR = ''
    if sheet_name == "Capacity":
        NOW_ADDR = CAPACITY_SHEET_ADDR[key]
    elif sheet_name == "Temperture":
        NOW_ADDR = TEMPERTURE_SHEET_ADDR[key]
    elif sheet_name == "Voltage":
        NOW_ADDR = VOLTAGE_SHEET_ADDR[key]
    ADDR_header_temp = NOW_ADDR[0]
    ADDR_header = ADDR_header_temp
    sNOW_ADDR = NOW_ADDR.strip(ADDR_header_temp)
    iNEW_ADDR = int(sNOW_ADDR) + 1
    if sheet_name == "Capacity":
        CAPACITY_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    elif sheet_name == "Temperture":
        TEMPERTURE_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    elif sheet_name == "Voltage":
        VOLTAGE_SHEET_ADDR[key] = ADDR_header + str(iNEW_ADDR)
    else:
        print("Can't mapping any sheet name.\n")
    print("NOW_ADDR: " + str(NOW_ADDR))
    return NOW_ADDR

後記 :
format1 = work.add_format() #新增一個字形格式
format1.set_font_size(SIZE) #設定字形格式的大小為SIZE
format1.set_font_color("red") #設定字形格式的顏色
format1.set_bold() #設定字形格式為粗體
format1.set_italic() #設定字形格式為斜體
format1.set_font_strikeout() #設定字形格式為刪節號
format1.set_font_underline() #設定字形格式為底線
format1.set_align(LOCATE) #設定字形格式的對齊 ..
                           # center, right, fill, justify, center_across
format1.set_text_wrap()  #設定字形格式為符合寬度換行
format1.set_bg_color()  #設定字形格式的背景顏色

worksheet.write()

2017年2月19日 星期日

[科技見談] 關於自動化測試

前言
自動化測試是結合 程式開發 與 品質管理的一項領域技術
有鑑於無人自動化的開發 電腦可以取代人
做營運管理的項目越多 -- 品質測試與管理 也被拿來評估與討論

濫觴
2015年底,我進入了自動化測試領域
因為客戶的需求及老闆的建議下 我開始了Python之路
而我也因此認識了Python 跟它談了 "一整年的戀愛"
Python  強調程式應優美、簡單、明瞭,像佛教的"禪"

禪的意境
禪是種意境,像風一樣,雖看不見但卻無所不在,我很嚮往 -- 逃離紛擾 邁向空無。
心靈的禪學=>我還在追尋,但至少Python的藝術 讓我領略到了這種意境。
至此之後,我認為概念式或邏輯的開發上我應該使用Python來開發並驗證
不管是在自動化系統開發或是物聯網的領域上,甚至是機器學習 大數據分析等等
Python已經提供了完整的API包 -- 讓我們站在巨人的肩膀上看世界!!!


開始的一切是如此原始

有別於一般iOS的自動化測試使用Selenium for iOS 或是 Android app的自動化測試使用 Selendroid (Selendroid for Android)

一開始的自動化測試,我使用的是 "腳本化開發方法"從Serial的驗證 到 IEEE488規範的儀器(GPIB,如電源供應器)的控制我用的是一條腸子通到底的腳本式語言很快我遇到了瓶頸 ~~ => 非常不好維護我開始分門別類地將不同的模組寫在不同的.py檔內
到了第二階段的類 C語言的開發 =>程式開始有點規模了
使用這樣的方式開發 除了乾淨外,之後的擴充或是維護 都是很好管理的


系統化的架構思維
在自動化測試系統的開發中,很多時候需要將架構開發與測試行為發展進行切割
我認為需要更好的分工模式來進行 自動化 及 測試兩個功能
所以RD專心自動化   QA專心寫測試腳本(Test cases) -- 合作無間。
這時候我認為系統還介於第二階段與第三階段之間 -- Stage 2.5 of Auto-test system.
第三代的完成 我認為除了導入了SW-QA撰寫的xml檔(test cases)機制外,還有test command與check command兩邊的分工,我將測試步驟分兩塊 -- 步驟測試(Tester)與步驟確認(Checker)

何謂步驟測試(Tester)??
SW-QA將測試程式分成很多個小步驟 除了前期判斷Pre-condition外,就是測試步驟的進行
測試步驟會分為很多模組
Charging test、Hardkey test、Touch Pannel test等等
tp我們會先在產品端埋入老化程式(大陸朋友的理解) 我跟德國佬 都稱它為 Test Proxy
Test Proxy它是代理人 會接收我們送給它的訊息從UART或是I2C...等等溝通的介面接口(Interface),它會將我們送給它的指令轉送給產品端的其他介面或是 -- 直接控制!!!
這邊很多測試都是非常直觀的,在這裏我們還會導入Arduino去幫我們控制一些電源輸入等等透過Relay的控制來決定產品是否充電...

rejection test(排除測試)為在RD端測試過程需要確認測試手法能否付現、經由付現率從100%降至0%以確保問題解決的過程,以車用產品來說,我們使用V model來對應整個產品從RD開發到最後產品到使用者手上的測試‧


何謂步驟確認(Checker)???
我們需要透過步驟確認這個動作,來完成測試的目的
如何確認 方法很多 除了Log checker外 我們可以透過DumpUI 以及外拍存圖比對的手法達到

疑惑、迷惑還是迷失??
很多RD很輕易地傲慢,認為他們創造了一切,如此一廂情願,從一開始的疑惑到熟稔技術後會變成迷惑,最後我迷失了自己   中止迷失最重要的是 他們要認清  一切的一切應該以人為本

我們太過相信電腦處理程式的速度與能力,總認為技術與架構上能夠駕馭 我們能夠駕馭一切
但實際上的狀況是  -- 電腦還是會出錯,至少在我們教會它們學會自我學習之前。
程式開發以人為本的概念就是,想辦法讓電腦像個人

在這個階段我獲得了一些指導跟方向
我們不能 一廂情願 更不能"射後不理"
在此向資深的同事們學習 車用電子的精隨 -- 嚴謹
需要透過狀態的確認 我認為這是第四代的自動化測試
即使是我所知道的 其他團隊開發的自動化測試 雖然是不同的寫法 OO
但那始終是Coding style的不同,對於自動化測試中代數的演進,我認為是無差別。


下一個里程碑
2016~2017 我們在自動化的浪潮之上時而被新的資訊與技術 淹沒 但又像勇敢冒險的衝浪客 克服技術(湧浪)的困難與瓶頸 爬上浪尖
我認為自動化測試,應該結合人工智慧(機器學習)並透過類神經網路模組去學習行為
這樣的配置或許過於豪華 但我認為是必須的弊
在我跟同事們合作的過程中,我們花了大部份的時間 分析test cases行為的合理性並Debug
我始終認為好的程式 應該是幫助人類 而非證人入罪
之所以會自動化是因為 人需要休息並且人會出錯
我們給了機器思考跟學習的能力 我們除了一開始教他之外,剩下的時間
我們應該把時間花在教它更多新的事物 而非 找尋跟修正我們自己的錯誤

只是 那條路...還很漫長~~~ 那是最後一哩路


2016年10月24日 星期一

[Python]Python中各種溝通控制介面介紹 UART(Serial) I2C SPI GPIB Socket等等

PySerial(UART)
import serial
#串口打开方式:
#1)带串口号和波特率
ser. interCharTimeout #字符間隔超時
print ser.portstr #能看到第一個serial的標示,windows下是COM1
ser #來查看當前serial的狀態


serial.Serial類——原生端口
class serial.Serial
{
    __init__(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)
    #其中:
    #  bytesize:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS
    #  parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
    #  stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
    #異常:
    #ValueError:參數錯誤
    #SerialException:找不到設備或不能配置
   ser = serial.Serial('COM6',115200)
    ser.open():打開串口
    ser.close():立即關閉串口
   ser.isOpen()   #確認ser物件是否已經被打開 若被打開回船True
    __del__():析構函數


    #只讀屬性:
    name:設備名字
    portstr:已廢棄,用name代替
    ser.port:讀或者寫端口
    ser.baudrate:鮑率      #9600   #115200
    ser.bytesize:字節大小   #8      #serial.EiGHTBITS   八位數據位
    ser.parity:校驗位     serial.PARITY_NONE #無校驗    serial.PARITY_EVEN  #偶校驗   serial.PARITY_ODD
    ser.stopbits:停止位
    ser.timeout:讀超時設置
    ser.writeTimeout:寫超時
    ser.xonxoff:軟體流程控制
    ser.rtscts:硬體流程控制
    ser.dsrdtr:硬體流程控制
    interCharTimeout:字符間隔超時

    #端口設置可以被讀入字典,也可從字典加載設置:
    getSettingDict():返回當前串口設置的字典
    applySettingDict(d):應用字典到串口設置
    #對提供io庫的系統(python 2.6或以上),Serial從io.RawIOBase派生。對其它系統,從FileLike派生。
    #異常:
    exception serial.SerialException
    exception serial.SerialTimeoutException
    #常量:
    serial.VERSION:pyserial版本
    #模塊函數和屬性:
    serial.device(number)
    serial.serial_for_url(url, *args, **kwargs)
    serial.protocol_handler_packages()
    serial.to_bytes(sequence):接收一個字符串或整數列表sequence,返回bytes實例
}


ser.write(“hello") #就是往serial裡面寫訊息hello


Serial write用法

write(data):發送data,並返回發送字節數。如果bytes和bytearray可用(python 2.6以上),則接受其作為參數;否則接受str作為參數。

    #異常:SerialTimeoutException——配置了寫超時並發生超時時發生此異常。

    inWaiting():返回接收緩存中的字節數

    flush():等待所有數據寫出。

    flushInput():丟棄接收緩存中的所有數據

    flushOutput():終止當前寫操作,並丟棄發送緩存中的數據。

    sendBreadk(duration=0.25):發送BREAK條件,並於duration時間之後返回IDLE

    setBreak(level=True):根據level設置break條件。

    setRTS(level=True)

    setDTR(level=True)

    getCTS()

    getDSR()

    getRI()

    getCD()



data = ser.read() #讀一個字節

read(size=1):從串口讀size個字節。如果指定超時,則可能在超時後返回較少的字節;如果沒有指定超時,則會一直等到收完指定的字節數。
data = ser.read(20) #讀20個字節
data = ser.readline() #一次讀一行,直到讀到/n當作结束,要是没有/n就會一直讀。

Readline方法的使用

        是讀一行,以/n結束,要是沒有/n就一直讀,阻塞。

        使用readline()時應該注意:打開串口時應該指定超時,否則如果串口沒有收到新行,則會一直等待。如果沒有超時,readline會報異常。
data = ser.readlines() #和ser.xreadlines()都需要設定超時時間
ser.next() #讀下一個
===================================================================
i2C




===================================================================
SPI



===================================================================
GPIB(IEEE488) - Python GPIB控制 結合 NI VISA api
如此我們就可以透過python指令在cmd模式下 安裝pyvisa套件了 :
python -m pip 可以查看模組    pip模組介紹  pip套件官網(取代easy_install的python套件安裝神器)
python -m pip install -U pip 可以更新pip模組
python -m pip install -U pyvisa 可以安裝pyvisa模組,並更新到最新版本   pyvisa官網
 
為了確定此兩套件順利安裝,我們可以在cmd打python進入python mode或是開啟python專用的IDE (IDLE) 並打入
import visa(enter鍵送出)
來確定是否有錯誤訊息跳出,若順利執行則安裝成功
Q&A

Q:鍵入 import visa 時會出現下列錯誤訊息:
Traceback (most recent call last):
  File "", line 1, in 
  File "C:\Python27\lib\site-packages\visa.py", line 18, in 
    from pyvisa import logger, __version__, log_to_screen
  File "C:\Python27\lib\site-packages\pyvisa\__init__.py", line 20, in 
    import pkg_resources
ImportError: No module named pkg_resources
A:這是缺少 pkg_resources 模組所致,請到是德科技網站 http://www.keysight.com/ 下載 IO Libraries Suite 軟體,下載頁 http://www.keysight.com/main/software.jspx?ckey=1184883&lc=cht&cc=TW&nid=-11143.0.00&id=1184883
Q:Windows ERROR 126 A:詳 http://sourceforge.net/p/pyvisa/bugs/15/
程式碼範例 import visa rm = visa.ResourceManager() my_instrument = rm.open_resource('GPIB::14') my_instrument.write("*IDN?") print(my_instrument.read())
=================//作業系統NI 環境安裝//====================
安裝 NI-VISA 5.4.1

切換網頁到http://www.ni.com/download/ni-visa-5.4.1/4626/en/,點擊NIVISA541full_downloader.exe。它會要求您建立使用者帳號,如下圖。

如果您已經註冊過那麼就點擊「登入」,輸入正確的使用者名稱和密碼,然後再次點擊 NIVISA541full_downloader.exe  接著再雙擊下載的檔案NIVISA541full.exe,然後依照安裝視窗指示進行即可。



===================================================================
Socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')

while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ) :
        break
    print (data);

mysock.close()


===================================================================
CANBus(Kvaser) - Python結合CAN Bus的初勘-以Kvaser為例
最近工作上需要使用Python透過CAN Bus的工具來跟車機(BDC)做溝通控制。
以CAN tool來說,除了NI以外Vector solution for CAN也非常有名。
但礙於經費,手上只有一條Kvaser的產品

我們來到其 官網的下載區,找到了CANKing以及kvaser driver,進行溝通模擬以綽綽有餘。
若需要利用第三方平台來開發工具進行連接,我們需要Kvaser CANlib SDK。

CANlib SDK中各種api的呼叫以及回傳表 : 點此連結

因為其工作需求,需要用Python開發,找到下列三部曲連結:

  1. Accessing Kvaser CANlib from Python
  2. Using Python to connect to your remote device
  3. A more object oriented approach on accessing your Kvaser device from Python
我使用第一部曲就已綽綽有餘!!!!



===================================================================