2016-05-07 92 views
1

我正在使用python(Pcan basic api)中的canbus,並希望使其更易於使用。Python中的高級別/抽象Canbus接口

通過總線連接了很多設備/模塊。他們都被允許發送數據,如果碰巧發生,最低的ID將會贏。

的數據與ID,子ID,hexvalues

爲了說明我試圖ADRESS的問題,試想一個信號的幅度舉辦幀。

要讀取的值的幀發送到

  • QuestionID QuestionSUBID QuestionData

如果具有較高優先級沒有消息(= lowerID)的回答爲寫入總線:

  • AnswerID AnswerSubID AnswerData

由於任何模塊/設備都被允許寫入總線,所以您事先不知道下一步會得到哪個答案。設置一個值的方式相同,只是使用不同的ID。因此,對於上面的例子中的振幅將具有:

  1. 4 ID和SubIds關聯具有讀/寫的問題/答案
  2. 另外的數據的lenght具有(0-8)必須指定/存儲。
  3. 由於數據是所有十六進制值解析器必須被指定以獲得人類可讀的值(例如電壓在十進制表示)

要存儲該信息我使用嵌套類型的字典:

parameters = {'Parameter_1': {'Read': {'question_ID': ID, 
             'question_SUBID': SubID, 
             'question_Data': hex_value_list, 
             'answer_ID': ..., 
             'answer_subID': ..., 
             'answer_parser': function}, 
           'Write': {'ID': ..., 
             'SubID': ..., 
             'parser' ..., 
             'answer_ID': ..., 
             'answer_subID': ...}}, 
       'Parameter_2': ... }} 

當硬件控制時,有很多工具可以顯示設置了哪個值,但只要它們是最新的,讀取參數的順序就不相關。因此,一個可能的解決方案的一個組成部分是存儲類型的字典字典整個交通:

busdata = {'firstID' : {'first_subID': {'data': data, 
             'timestamp': timestamp}, 
         'second_subID': {'data': data, 
             'timestamp': timestamp}, 

         }, 
      secondID': ...} 

由於公交車,我得到了很多答案,其他設備要求的性質 - 公交車是相當充分 - 這些不應該被解僱,因爲他們可能是我下一個需要的價值,並且不需要創造額外的流量 - 我可能會使用帶有失效日期的時間戳,但是到目前爲止我對此沒有多少考慮。

這種方法很有效,但與之合作可怕。一般來說,我想我會有大約300個參數。最終目標是通過一個(pyqt)Gui來控制設備,讀取一些像序列號這樣的值,但也可以運行測量任務。

所以最大的問題是如何定義一個更容易訪問和理解的更好的數據結構?我期待任何有關乾淨設計的建議。

主要目標將是類似於擺脫基於整個消息的問題。

編輯:我的目標是擺脫整個CAN特定消息基於形式給出的:

我想我需要一個線程的通信,它應該:

  1. 讀取緩衝區並更新我的變量
  2. 發送請求(消息)以獲取其他值/變量
  3. 定期發送一些值

所以從我希望GUI進行體健到:按名稱

  1. GET參數 - >發送帶有參數名
  2. 設定參數信號的字符串 - > STR(名稱),值(如displayedin的GUI)
  3. 獲取值週期性 - >名,間隔,持續時間(10秒或無限的)

線程必須:

  1. 日誌中的內部存儲通過生成從名稱,值信息和讀取,直到結果獲得
  2. 發送週期信號

  • 處理要求總線上的所有數據,我想有這種設計idependant實際的硬件的:

    • 我想的溶液,在上述parameters_dict

    內部存儲我想到了bus_data_dict

    不過我不知道如何:從公交線到GUI

    1. 傳遞數據(所有值與新/請求的值)
    2. 如何使用pyqt中的信號和插槽實現它
    3. 在內部存儲數據(字典或某個新的更好的想法)
    4. 如果這個設計是不錯的選擇
  • +0

    做了一個抽象出來的類...... canbus完全基於消息包,所以我不認爲你可以消除它......但是你當然可以抽象出它...... –

    +0

    當然可以。也許我確實清楚地說明了這一點。問題是如何實現這一點。我考慮了適當的getter和setter的屬性 - 仍然需要數據的內部表示。 – slepton

    回答

    0
    class MySimpleCanBus: 
         def parse_message(self,raw_message): 
          return MyMessageClass._create(*struct.unpack(FRAME_FORMAT,msg)) 
         def recieve_message(self,filter_data): 
          #code to recieve and parse a message(filtered by id) 
          raw = canbus.recv(FRAME_SIZE) 
          return self.parse_message(raw) 
         def send_message(msg_data): 
          # code to make sure the message can be sent and send the message 
          return self.recieve_message() 
    
    class MySpecificCanBus(MySimpleCanBus): 
        def get_measurement_reading(): 
         msg_data = {} #code to request a measurement 
         return self.send_message(msg_data) 
        def get_device_id(): 
         msg_data = {} # code to get device_id 
         return self.send_message(msg_data) 
    

    我可能不明白你的問題正確......也許你可以用額外的細節

    1

    使用python-can庫將讓你的網絡更新線程 - 給你一個緩衝隊列的傳入消息。該庫支持PCAN接口等。

    然後,您將創建一箇中間件層,將這些can.Message類型轉換並路由到pyqt信號中。把它看作是一對多的事件/信號源。

    我會使用另一個控制器負責發送消息到總線。它可能有任務,例如請求公交車定期測量,以及由gui驅動的需求請求。

    關於在內部存儲數據,它確實取決於您的編程風格和複雜性。我見過每個CAN消息都有自己的類的項目。

    最後,隊列是你的朋友!

    +0

    謝謝。我採取了非常相似的路線,仍然試圖將其抽象爲mvc模式。 Python只能與峯值系統示例一樣使用。我通過將Unicode轉換爲字節字符串來修復它們的代碼。 – slepton

    +0

    你是什麼意思「Python-只能用」?在任何系統中,您都必須確保將字節發送到總線。 – Hardbyte

    0

    同意使用@Hardbyte使用python-can。非常好。

    就應用層之間的消息傳遞而言,我有很多運氣,Zero MQ - 您可以將模塊設置爲基於事件,從canbus消息事件一直到更新UI等等。

    對於數據存儲/持久性,我將消息放入SQLite中,並行(使用ZMQ Pub/Sub模式)將數據傳遞到IoT中心(通過MQTT)。